diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict
index 07288644886b4c72cebd13cd2971df0d972cca6c..d3018d209d1649ed53ae0fe4edebd83ae7fce80b 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict
+++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMeshDict
@@ -63,6 +63,10 @@ extrudeModel        wedge;
 //- Extrudes into sphere with grading according to pressure (atmospherics)
 //extrudeModel        sigmaRadial;
 
+//- Extrudes by interpolating along path inbetween two (topologically identical)
+//  surfaces (e.g. one is an offsetted version of the other)
+//extrudeModel        offsetSurface;
+
 nLayers             10;
 
 expansionRatio      1.0;
@@ -105,6 +109,16 @@ sigmaRadialCoeffs
     pStrat          1;
 }
 
+offsetSurfaceCoeffs
+{
+    // Surface that mesh has been meshed to
+    baseSurface "$FOAM_CASE/constant/triSurface/DTC-scaled-inflated.obj";
+
+    // Surface to fill in to
+    offsetSurface "$FOAM_CASE/constant/triSurface/DTC-scaled.obj";
+}
+
+
 // Do front and back need to be merged? Usually only makes sense for 360
 // degree wedges.
 mergeFaces false;
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options
index 44c1d87758d5258e02108d66f7a3ce1d089c6826..bad58b9d588786375ccdde15117e3b5a64052c54 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/Make/options
@@ -16,6 +16,7 @@ EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
     -I$(LIB_SRC)/edgeMesh/lnInclude \
     -I$(LIB_SRC)/fileFormats/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
@@ -29,6 +30,7 @@ EXE_INC = \
 LIB_LIBS = \
     ${CGAL_LIBS} \
     -lmeshTools \
+    -ldecompose \
     -ledgeMesh \
     -lfileFormats \
     -ltriSurface \
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
index 25e0f9a73e73b81c545e522f80914719b4d36358..b4428c3df84fb14cfc4a2bf7e41ccc79bcb056e0 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
@@ -30,6 +30,7 @@ License
 #include "Time.H"
 #include "Random.H"
 #include "pointConversion.H"
+#include "decompositionModel.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -149,7 +150,8 @@ void Foam::backgroundMeshDecomposition::initialRefinement()
 
     const conformationSurfaces& geometry = geometryToConformTo_;
 
-    decompositionMethod& decomposer = decomposerPtr_();
+    decompositionMethod& decomposer =
+        decompositionModel::New(mesh_).decomposer();
 
     volScalarField::InternalField& icellWeights = cellWeights.internalField();
 
@@ -782,7 +784,8 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
     const Time& runTime,
     Random& rndGen,
     const conformationSurfaces& geometryToConformTo,
-    const dictionary& coeffsDict
+    const dictionary& coeffsDict,
+    const fileName& decompDictFile
 )
 :
     runTime_(runTime),
@@ -810,18 +813,6 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
     bFTreePtr_(),
     allBackgroundMeshBounds_(Pstream::nProcs()),
     globalBackgroundBounds_(),
-    decomposeDict_
-    (
-        IOobject
-        (
-            "decomposeParDict",
-            runTime_.system(),
-            runTime_,
-            IOobject::MUST_READ_IF_MODIFIED,
-            IOobject::NO_WRITE
-        )
-    ),
-    decomposerPtr_(decompositionMethod::New(decomposeDict_)),
     mergeDist_(1e-6*mesh_.bounds().mag()),
     spanScale_(readScalar(coeffsDict.lookup("spanScale"))),
     minCellSizeLimit_
@@ -846,14 +837,17 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
             << exit(FatalError);
     }
 
-    if (!decomposerPtr_().parallelAware())
+    const decompositionMethod& decomposer =
+        decompositionModel::New(mesh_, decompDictFile).decomposer();
+
+    if (!decomposer.parallelAware())
     {
         FatalErrorIn
         (
             "void Foam::backgroundMeshDecomposition::initialRefinement() const"
         )
             << "You have selected decomposition method "
-            << decomposerPtr_().typeName
+            << decomposer.typeName
             << " which is not parallel aware." << endl
             << exit(FatalError);
     }
@@ -1008,7 +1002,10 @@ Foam::backgroundMeshDecomposition::distribute
             << endl;
     }
 
-    labelList newDecomp = decomposerPtr_().decompose
+    decompositionMethod& decomposer =
+        decompositionModel::New(mesh_).decomposer();
+
+    labelList newDecomp = decomposer.decompose
     (
         mesh_,
         mesh_.cellCentres(),
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
index 90dde14aa4a8e1ff1aefd20f42d3e16c308654cb..9d597732cb7e8647ac847666114e753b82c30437 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
@@ -127,13 +127,7 @@ class backgroundMeshDecomposition
         //  a point that is not found on any processor is in the domain at all
         treeBoundBox globalBackgroundBounds_;
 
-        //- Decomposition dictionary
-        IOdictionary decomposeDict_;
-
-        //- Decomposition method
-        autoPtr<decompositionMethod> decomposerPtr_;
-
-        //- Merge distance required by fvMeshDistribute
+        //- merge distance required by fvMeshDistribute
         scalar mergeDist_;
 
         //- Scale of a cell span vs cell size used to decide to refine a cell
@@ -204,7 +198,8 @@ public:
             const Time& runTime,
             Random& rndGen,
             const conformationSurfaces& geometryToConformTo,
-            const dictionary& coeffsDict
+            const dictionary& coeffsDict,
+            const fileName& decompDictFile = ""
         );
 
 
@@ -324,8 +319,6 @@ public:
             //- Return the point level of the underlying mesh
             inline const labelList& pointLevel() const;
 
-            //- Return the current decomposition method
-            inline const decompositionMethod& decomposer() const;
 };
 
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H
index 199f4ae4ff0152fa283c52e38992c3b298612034..b8dcb5187f151844e36013c14fa441a3da869fd1 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H
@@ -57,11 +57,4 @@ const Foam::labelList& Foam::backgroundMeshDecomposition::pointLevel() const
 }
 
 
-const Foam::decompositionMethod&
-Foam::backgroundMeshDecomposition::decomposer() const
-{
-    return decomposerPtr_();
-}
-
-
 // ************************************************************************* //
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
index e7f7f5816c275755708d215f50877255812d2e38..9b6f71ffac5dc8dcd020caf744c80eb4cca754ee 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
@@ -392,61 +392,59 @@ Foam::cellShapeControlMesh::cellShapeControlMesh(const Time& runTime)
 
         if (mesh.nPoints() == this->vertexCount())
         {
-            pointScalarField sizes
+            IOobject io
             (
-                IOobject
-                (
-                    "sizes",
-                    runTime.timeName(),
-                    meshSubDir,
-                    runTime,
-                    IOobject::READ_IF_PRESENT,
-                    IOobject::NO_WRITE,
-                    false
-                ),
-                pointMesh::New(mesh)
-            );
-
-            triadIOField alignments
-            (
-                IOobject
-                (
-                    "alignments",
-                    mesh.time().timeName(),
-                    meshSubDir,
-                    mesh.time(),
-                    IOobject::READ_IF_PRESENT,
-                    IOobject::AUTO_WRITE,
-                    false
-                )
+                "sizes",
+                runTime.timeName(),
+                meshSubDir,
+                runTime,
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE,
+                false
             );
 
-            if
-            (
-                sizes.size() == this->vertexCount()
-             && alignments.size() == this->vertexCount()
-            )
+            if (io.headerOk())
             {
-                for
+                pointScalarField sizes(io, pointMesh::New(mesh));
+
+                triadIOField alignments
                 (
-                    Finite_vertices_iterator vit = finite_vertices_begin();
-                    vit != finite_vertices_end();
-                    ++vit
-                )
+                    IOobject
+                    (
+                        "alignments",
+                        mesh.time().timeName(),
+                        meshSubDir,
+                        mesh.time(),
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE,
+                        false
+                    )
+                );
+
+                if (alignments.size() == this->vertexCount())
                 {
-                    vit->targetCellSize() = sizes[vit->index()];
-                    vit->alignment() = alignments[vit->index()];
+                    for
+                    (
+                        Finite_vertices_iterator vit = finite_vertices_begin();
+                        vit != finite_vertices_end();
+                        ++vit
+                    )
+                    {
+                        vit->targetCellSize() = sizes[vit->index()];
+                        vit->alignment() = alignments[vit->index()];
+                    }
+                }
+                else
+                {
+                    FatalErrorIn
+                    (
+                        "Foam::cellShapeControlMesh::cellShapeControlMesh"
+                        "(const Time&)"
+                    )   << "Cell alignments point field " << alignments.size()
+                        << " is not the same size as the number of vertices"
+                        << " in the mesh " << this->vertexCount()
+                        << abort(FatalError);
                 }
-            }
-            else
-            {
-                FatalErrorIn
-                (
-                    "Foam::cellShapeControlMesh::cellShapeControlMesh"
-                    "(const Time&)"
-                )   << "Cell size point field is not the same size as the "
-                    << "mesh."
-                    << abort(FatalError);
             }
         }
     }
@@ -672,7 +670,7 @@ void Foam::cellShapeControlMesh::write() const
             IOobject::AUTO_WRITE
         ),
         pointMesh::New(mesh),
-        scalar(0)
+        dimensionedScalar("zero", dimLength, scalar(0))
     );
 
     triadIOField alignments
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
index 9cc9862129a2a130ce8305a7f825537dfbdc06cd..a10f19be224ee191fa7f2781a63c4402a33f4837 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
@@ -837,7 +837,8 @@ bool Foam::conformalVoronoiMesh::ownerAndNeighbour
 Foam::conformalVoronoiMesh::conformalVoronoiMesh
 (
     const Time& runTime,
-    const dictionary& foamyHexMeshDict
+    const dictionary& foamyHexMeshDict,
+    const fileName& decompDictFile
 )
 :
     DistributedDelaunayMesh<Delaunay>(runTime),
@@ -876,7 +877,8 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh
             foamyHexMeshControls().foamyHexMeshDict().subDict
             (
                 "backgroundMeshDecomposition"
-            )
+            ),
+            decompDictFile
         )
       : NULL
     ),
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
index f6d44489b78de107ea77849ebd8774edbaedd3b7..59fbba90a960e731eedff8c88ac2c225f65410b9 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
@@ -163,10 +163,8 @@ private:
         //- Limiting bound box before infinity begins
         treeBoundBox limitBounds_;
 
-        //-
         mutable pointPairs<Delaunay> ptPairs_;
 
-        //-
         featurePointConformer ftPtConformer_;
 
         //- Search tree for edge point locations
@@ -546,7 +544,7 @@ private:
         ) const;
 
         //- Check if a location is in the exclusion range of an existing feature
-        //- Edge conformation location
+        //  edge conformation location
         bool nearFeatureEdgeLocation
         (
             const pointIndexHit& pHit,
@@ -730,8 +728,7 @@ private:
 
         label classifyBoundaryPoint(Cell_handle cit) const;
 
-        //- Index all of the the Delaunay cells and calculate their
-        //- Dual points
+        //- Index all of the the Delaunay cells and calculate their dual points
         void indexDualVertices
         (
             pointField& pts,
@@ -874,7 +871,8 @@ public:
         conformalVoronoiMesh
         (
             const Time& runTime,
-            const dictionary& foamyHexMeshDict
+            const dictionary& foamyHexMeshDict,
+            const fileName& decompDictFile = ""
         );
 
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
index e88ee943690b8f05742b05845965c4e50dc791ab..85c49a9ccdd1b6dc7429410be942210262be6195 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
@@ -1292,9 +1292,9 @@ void Foam::conformalVoronoiMesh::indexDualVertices
         }
     }
 
-    OBJstream snapping1("snapToSurface1.obj");
-    OBJstream snapping2("snapToSurface2.obj");
-    OFstream tetToSnapTo("tetsToSnapTo.obj");
+    //OBJstream snapping1("snapToSurface1.obj");
+    //OBJstream snapping2("snapToSurface2.obj");
+    //OFstream tetToSnapTo("tetsToSnapTo.obj");
 
     for
     (
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H
index a2eeb21c99135da690d8b19734a365cacd2ecbc6..7a19a25ba212a8e65d205c3d02289381864925d8 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell/indexedCell.H
@@ -88,15 +88,13 @@ class indexedCell
     // Private data
 
         //- The index for this Delaunay tetrahedral cell.  Type information is
-        //- Also carried:
-
+        //  also carried:
         //  ctFar : the dual point of this cell does not form part of the
         //          internal or boundary of the dual mesh
         //  >=0   : the (local) index of an internal or boundary dual point,
         //           not on a processor face
         //  < 0 && > ctFar : the (global) index of a dual point on a processor
         //                   face
-
         Foam::label index_;
 
         //- The number of times that this Delaunay cell has been limited
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options
index b3f2e7dd7ceed3f5a69ecb53a20f978ea2a58abf..7aa621f26e126d3e3f8c07c0c6bd700821eea678 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/Make/options
@@ -30,7 +30,8 @@ EXE_LIBS = \
     -lconformalVoronoiMesh \
     -lmeshTools \
     -ldecompositionMethods \
-    -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
+    -ldecompose \
+    -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp -lscotchDecomp \
     -ledgeMesh \
     -lfileFormats \
     -ltriSurface \
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C
index 6e68f1c80e616956753d45207e4ec87fb6b4b369..c83800e03133c255e590dcfbe90484e24a248b4b 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMesh.C
@@ -62,6 +62,17 @@ int main(int argc, char *argv[])
     const bool checkGeometry = args.optionFound("checkGeometry");
     const bool conformationOnly = args.optionFound("conformationOnly");
 
+    // Allow override of decomposeParDict location
+    fileName decompDictFile;
+    if (args.optionReadIfPresent("decomposeParDict", decompDictFile))
+    {
+        if (isDir(decompDictFile))
+        {
+            decompDictFile = decompDictFile / "decomposeParDict";
+        }
+    }
+
+
     IOdictionary foamyHexMeshDict
     (
         IOobject
@@ -114,7 +125,7 @@ int main(int argc, char *argv[])
 
     Info<< "Create mesh for time = " << runTime.timeName() << nl << endl;
 
-    conformalVoronoiMesh mesh(runTime, foamyHexMeshDict);
+    conformalVoronoiMesh mesh(runTime, foamyHexMeshDict, decompDictFile);
 
 
     if (conformationOnly)
@@ -145,7 +156,7 @@ int main(int argc, char *argv[])
     }
 
 
-    Info<< nl << "End" << nl << endl;
+    Info<< "\nEnd\n" << endl;
 
     return 0;
 }
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict
index deca4e0edb24a5505535b6250d994fdd9e14db56..78f22b4e49283202d8b8173ca418c49a0ff375b8 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMesh/foamyHexMeshDict
@@ -271,11 +271,18 @@ motionControl
             forceInitialPointInsertion  on;
             priority                    1;
             mode                        inside;
+
+            // Cell size at surface
             surfaceCellSizeFunction     uniformValue;
             uniformValueCoeffs
             {
                 surfaceCellSizeCoeff    0.5;
             }
+
+            // Cell size inside domain by having a region of thickness
+            // surfaceOffsetaround the surface with the surface cell size
+            // (so constant) and then down to distanceCellSize over a distance
+            // of linearDistance.
             cellSizeFunction            surfaceOffsetLinearDistance;
             surfaceOffsetLinearDistanceCoeffs
             {
@@ -375,9 +382,17 @@ polyMeshFiltering
     // Filter small and sliver faces
     filterFaces                             off;
 
-    // Write the underlying Delaunay tet mesh at output time
+    // Write the underlying Delaunay tet mesh (at output time)
     writeTetDualMesh                        false;
 
+    // Write the Delaunay tet mesh used for interpolating cell size and
+    // alignment (at output time)
+    writeCellShapeControlMesh           true;
+
+    // Write the hex/split-hex mesh used for parallel load balancing
+    // (at output time)
+    writeBackgroundMeshDecomposition    true;
+
     // Upper limit on the size of faces to be filtered.
     // fraction of the local target cell size
     filterSizeCoeff                         0.2;
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options
index 07f6800de62364583b2cf2105c5c654ac066e319..00d889c6c603f24a4dc4e96309926138039f0502 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/Make/options
@@ -9,6 +9,7 @@ EXE_INC = \
     ${CGAL_INC} \
     -I../conformalVoronoiMesh/lnInclude \
     -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
     -I$(LIB_SRC)/edgeMesh/lnInclude \
     -I$(LIB_SRC)/mesh/autoMesh/lnInclude \
     -I$(LIB_SRC)/triSurface/lnInclude \
@@ -26,6 +27,7 @@ EXE_LIBS = \
     -lgmp \
     -lconformalVoronoiMesh \
     -ldecompositionMethods /* -L$(FOAM_LIBBIN)/dummy -lscotchDecomp */ \
+    -ldecompose \
     -ledgeMesh \
     -ltriSurface \
     -lmeshTools \
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C
index fc99f0fd0545c94e0907a7f4486c9818c635591e..62be3f1efed769e18ef7a725c230301927afd790 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C
@@ -44,6 +44,7 @@ Description
 #include "isoSurfaceCell.H"
 #include "vtkSurfaceWriter.H"
 #include "syncTools.H"
+#include "decompositionModel.H"
 
 using namespace Foam;
 
@@ -467,7 +468,7 @@ int main(int argc, char *argv[])
 
         // Determine the number of cells in each direction.
         const vector span = bb.span();
-        vector nScalarCells = span/cellShapeControls().defaultCellSize();
+        vector nScalarCells = span/cellShapeControls.defaultCellSize();
 
         // Calculate initial cell size to be a little bit smaller than the
         // defaultCellSize to avoid initial refinement triggering.
@@ -521,28 +522,21 @@ int main(int argc, char *argv[])
         Info<< "Loaded mesh:" << endl;
         printMeshData(mesh);
 
-        // Allocate a decomposer
-        IOdictionary decompositionDict
-        (
-            IOobject
-            (
-                "decomposeParDict",
-                runTime.system(),
-                mesh,
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE
-            )
-        );
+        // Allow override of decomposeParDict location
+        fileName decompDictFile;
+        if (args.optionReadIfPresent("decomposeParDict", decompDictFile))
+        {
+            if (isDir(decompDictFile))
+            {
+                decompDictFile = decompDictFile / "decomposeParDict";
+            }
+        }
 
-        autoPtr<decompositionMethod> decomposer
+        labelList decomp = decompositionModel::New
         (
-            decompositionMethod::New
-            (
-                decompositionDict
-            )
-        );
-
-        labelList decomp = decomposer().decompose(mesh, mesh.cellCentres());
+            mesh,
+            decompDictFile
+        ).decomposer().decompose(mesh, mesh.cellCentres());
 
         // Global matching tolerance
         const scalar tolDim = getMergeDistance
@@ -574,18 +568,15 @@ int main(int argc, char *argv[])
     Info<< "Refining backgroud mesh according to cell size specification" << nl
         << endl;
 
+    const dictionary& backgroundMeshDict =
+        foamyHexMeshDict.subDict("backgroundMeshDecomposition");
+
     backgroundMeshDecomposition backgroundMesh
     (
-        1.0,    //spanScale,ratio of poly cell size v.s. hex cell size
-        0.0,    //minCellSizeLimit
-        0,      //minLevels
-        4,      //volRes, check multiple points per cell
-        20.0,   //maxCellWeightCoeff
         runTime,
-        geometryToConformTo,
-        cellShapeControls(),
         rndGen,
-        foamyHexMeshDict
+        geometryToConformTo,
+        backgroundMeshDict
     );
 
     if (writeMesh)
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C
index 066bc8205c268a233f8dd90e2c71044cd59713f9..997726bba6b0a272d53442af9cee12f6469ffec5 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/foamyQuadMesh.C
@@ -221,7 +221,7 @@ int main(int argc, char *argv[])
     Info<< "Finished extruding in = "
         << runTime.cpuTimeIncrement() << " s." << endl;
 
-    Info<< nl << "End\n" << endl;
+    Info<< "\nEnd\n" << endl;
 
     return 0;
 }
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/Make/options b/applications/utilities/mesh/generation/snappyHexMesh/Make/options
index 219e3d419c848efd02e7e363825c5ebece691a80..d62b82a23949f7d27e553f79820f900678fedfcb 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/Make/options
+++ b/applications/utilities/mesh/generation/snappyHexMesh/Make/options
@@ -8,14 +8,18 @@ EXE_INC = \
     -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/edgeMesh/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude
 
 EXE_LIBS = \
     -lfiniteVolume \
     -ldecompositionMethods \
     -L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
+    /* note: scotch < 6.0 does not like both scotch and ptscotch together */ \
+    -lscotchDecomp \
     -lmeshTools \
     -lsurfMesh \
     -lfileFormats \
     -ldynamicMesh \
+    -ldecompose \
     -lautoMesh
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
index 7b4d8577c4e7ace8293bf50a703c234bcc3193f2..15bd5e965fd74de974b3bb152ac6bc2135b028ae 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -57,6 +57,7 @@ Description
 #include "MeshedSurface.H"
 #include "globalIndex.H"
 #include "IOmanip.H"
+#include "decompositionModel.H"
 
 using namespace Foam;
 
@@ -819,15 +820,28 @@ int main(int argc, char *argv[])
     {
         if (Pstream::parRun())
         {
+            fileName decompDictFile;
+            if (args.optionReadIfPresent("decomposeParDict", decompDictFile))
+            {
+                if (isDir(decompDictFile))
+                {
+                    decompDictFile = decompDictFile/"decomposeParDict";
+                }
+            }
+
             decomposeDict = IOdictionary
             (
-                IOobject
+                decompositionModel::selectIO
                 (
-                    "decomposeParDict",
-                    runTime.system(),
-                    mesh,
-                    IOobject::MUST_READ_IF_MODIFIED,
-                    IOobject::NO_WRITE
+                    IOobject
+                    (
+                        "decomposeParDict",
+                        runTime.system(),
+                        mesh,
+                        IOobject::MUST_READ_IF_MODIFIED,
+                        IOobject::NO_WRITE
+                    ),
+                    decompDictFile
                 )
             );
         }
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index 63303d9f8c5b1a63ecb7e18acad49adfcce7f0bd..9c62a1283705006dd641d850940a9f63306631a7 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -143,7 +143,7 @@ int main(int argc, char *argv[])
     );
 
     argList::noParallel();
-    Foam::argList::addOption
+    argList::addOption
     (
         "decomposeParDict",
         "file",
diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options
index 518432cbd9ef33a2e7edcffd1e7ea19f429406a6..0d74d0b44ca05ad8d253ab552452c486c057d5bf 100644
--- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options
+++ b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/Make/options
@@ -1,9 +1,8 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
-    -I$(LIB_SRC)/meshTools/lnInclude
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/postProcessing/functionObjects/jobControl/lnInclude
 
 EXE_LIBS = \
-    -lturbulenceModels \
-    -lcompressibleTurbulenceModels \
     -lfiniteVolume \
-    -lmeshTools
+    -ljobControl
diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C
index 3b9ed64abb35d0f1ba4dd798e315c9736addef0e..51818b378741ee10d3cf18fa4dac9dc0d0f8a9bf 100644
--- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C
+++ b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometry.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -26,15 +26,19 @@ Application
 
 Description
     Application to generate the patch geometry (points and faces) for use
-    with the externalCoupled boundary condition.
+    with the externalCoupled functionObject.
 
-    Usage:
+Usage
+    - createExternalCoupledPatchGeometry \<patchGroup\> [OPTION]
 
-        createExternalCoupledPatchGeometry \<fieldName\>
+    \param -commsDir \<commsDir\> \n
+    Specify an alternative communications directory (default is comms
+    in the case directory)
 
-    On execution, the field \<fieldName\> is read, and its boundary conditions
-    interrogated for the presence of an \c externalCoupled type.  If found,
-    the patch geometry (points and faces) for the coupled patches are output
+    \param -region \<name\> \n
+    Specify an alternative mesh region.
+
+    On execution, the combined patch geometry (points and faces) are output
     to the communications directory.
 
 Note:
@@ -42,12 +46,12 @@ Note:
     used for face addressing starts at index 0.
 
 SeeAlso
-    externalCoupledMixedFvPatchField
+    externalCoupledFunctionObject
 
 \*---------------------------------------------------------------------------*/
 
 #include "fvCFD.H"
-#include "createExternalCoupledPatchGeometryTemplates.H"
+#include "externalCoupledFunctionObject.H"
 #include "IOobjectList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -55,28 +59,25 @@ SeeAlso
 int main(int argc, char *argv[])
 {
     #include "addRegionOption.H"
-    argList::validArgs.append("fieldName");
+    argList::validArgs.append("patchGroup");
+    argList::addOption
+    (
+        "commsDir",
+        "dir",
+        "specify alternate communications directory. default is 'comms'"
+    );
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createNamedMesh.H"
 
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-    const word fieldName = args[1];
-
-    IOobjectList objects(IOobjectList(mesh, mesh.time().timeName()));
+    const wordRe patchGroup(args[1]);
 
-    label processed = -1;
-    processField<scalar>(mesh, objects, fieldName, processed);
-    processField<vector>(mesh, objects, fieldName, processed);
-    processField<sphericalTensor>(mesh, objects, fieldName, processed);
-    processField<symmTensor>(mesh, objects, fieldName, processed);
-    processField<tensor>(mesh, objects, fieldName, processed);
+    fileName commsDir(runTime.path()/"comms");
+    args.optionReadIfPresent("commsDir", commsDir);
 
-    if (processed == -1)
-    {
-        Info<< "Field " << fieldName << " not found" << endl;
-    }
+    externalCoupledFunctionObject::writeGeometry(mesh, commsDir, patchGroup);
 
     Info<< "\nEnd\n" << endl;
 
diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C b/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C
deleted file mode 100644
index c5d842237e157e1208c779215e883fd05129df00..0000000000000000000000000000000000000000
--- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.C
+++ /dev/null
@@ -1,90 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "createExternalCoupledPatchGeometryTemplates.H"
-#include "externalCoupledMixedFvPatchField.H"
-#include "IOobjectList.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void processField
-(
-    const fvMesh& mesh,
-    const IOobjectList& objects,
-    const word& fieldName,
-    label& processed
-)
-{
-    if (processed != -1)
-    {
-        return;
-    }
-
-    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
-
-    const word timeName(mesh.time().timeName());
-
-    IOobjectList fieldObjbjects(objects.lookupClass(fieldType::typeName));
-
-    if (fieldObjbjects.lookup(fieldName) != NULL)
-    {
-        fieldType vtf(*fieldObjbjects.lookup(fieldName), mesh);
-        const typename fieldType::GeometricBoundaryField& bf =
-            vtf.boundaryField();
-
-        forAll(bf, patchI)
-        {
-            if (isA<externalCoupledMixedFvPatchField<Type> >(bf[patchI]))
-            {
-                Info<< "Generating external coupled geometry for field "
-                    << fieldName << endl;
-
-                const externalCoupledMixedFvPatchField<Type>& pf =
-                    refCast<const externalCoupledMixedFvPatchField<Type> >
-                    (
-                        bf[patchI]
-                    );
-
-                pf.writeGeometry();
-                processed = 1;
-
-                break;
-            }
-        }
-
-        if (processed != 1)
-        {
-            processed = 0;
-
-            Info<< "Field " << fieldName << " found, but does not have any "
-                << externalCoupledMixedFvPatchField<Type>::typeName
-                << " boundary conditions" << endl;
-        }
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/preProcessing/mapFields/Make/options b/applications/utilities/preProcessing/mapFields/Make/options
index 7bd964094e47227f22d57a6b880ef940b5579b16..383ac3c12c66d86a5d14ea1f9cfcaf0f7e39164a 100644
--- a/applications/utilities/preProcessing/mapFields/Make/options
+++ b/applications/utilities/preProcessing/mapFields/Make/options
@@ -2,6 +2,8 @@ EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude
 
 EXE_LIBS = \
@@ -9,4 +11,5 @@ EXE_LIBS = \
     -lmeshTools \
     -llagrangian \
     -lfiniteVolume \
+    -ldecompose \
     -lgenericPatchFields
diff --git a/applications/utilities/preProcessing/mapFields/mapFields.C b/applications/utilities/preProcessing/mapFields/mapFields.C
index 929776d9df6a38d2982f8fb669119b898d5d4bc8..6f72053a08a9dc22594ced979a56cfcb5bceb172 100644
--- a/applications/utilities/preProcessing/mapFields/mapFields.C
+++ b/applications/utilities/preProcessing/mapFields/mapFields.C
@@ -36,9 +36,48 @@ Description
 #include "meshToMesh0.H"
 #include "processorFvPatch.H"
 #include "MapMeshes.H"
+#include "decompositionModel.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+int readNumProcs
+(
+    const argList& args,
+    const word& optionName,
+    const Time& runTime
+)
+{
+    fileName dictFile;
+    if (args.optionReadIfPresent(optionName, dictFile))
+    {
+        if (isDir(dictFile))
+        {
+            dictFile = dictFile/"decomposeParDict";
+        }
+    }
+
+    return readInt
+    (
+        IOdictionary
+        (
+            decompositionModel::selectIO
+            (
+                IOobject
+                (
+                    "decomposeParDict",
+                    runTime.system(),
+                    runTime,
+                    IOobject::MUST_READ_IF_MODIFIED,
+                    IOobject::NO_WRITE,
+                    false
+                ),
+                dictFile
+            )
+        ).lookup("numberOfSubdomains")
+    );
+}
+
+
 void mapConsistentMesh
 (
     const fvMesh& meshSource,
@@ -225,6 +264,19 @@ int main(int argc, char *argv[])
         "subtract",
         "subtract mapped source from target"
     );
+    argList::addOption
+    (
+        "sourceDecomposeParDict",
+        "file",
+        "read decomposePar dictionary from specified location"
+    );
+    argList::addOption
+    (
+        "targetDecomposeParDict",
+        "file",
+        "read decomposePar dictionary from specified location"
+    );
+
 
     argList args(argc, argv);
 
@@ -320,20 +372,13 @@ int main(int argc, char *argv[])
 
     if (parallelSource && !parallelTarget)
     {
-        IOdictionary decompositionDict
+        int nProcs = readNumProcs
         (
-            IOobject
-            (
-                "decomposeParDict",
-                runTimeSource.system(),
-                runTimeSource,
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE
-            )
+            args,
+            "sourceDecomposeParDict",
+            runTimeSource
         );
 
-        int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
-
         Info<< "Create target mesh\n" << endl;
 
         fvMesh meshTarget
@@ -399,19 +444,13 @@ int main(int argc, char *argv[])
     }
     else if (!parallelSource && parallelTarget)
     {
-        IOdictionary decompositionDict
+        int nProcs = readNumProcs
         (
-            IOobject
-            (
-                "decomposeParDict",
-                runTimeTarget.system(),
-                runTimeTarget,
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE
-            )
+            args,
+            "targetDecomposeParDict",
+            runTimeTarget
         );
 
-        int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
 
         Info<< "Create source mesh\n" << endl;
 
@@ -478,39 +517,17 @@ int main(int argc, char *argv[])
     }
     else if (parallelSource && parallelTarget)
     {
-        IOdictionary decompositionDictSource
+        int nProcsSource = readNumProcs
         (
-            IOobject
-            (
-                "decomposeParDict",
-                runTimeSource.system(),
-                runTimeSource,
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE
-            )
+            args,
+            "sourceDecomposeParDict",
+            runTimeSource
         );
-
-        int nProcsSource
-        (
-            readInt(decompositionDictSource.lookup("numberOfSubdomains"))
-        );
-
-
-        IOdictionary decompositionDictTarget
-        (
-            IOobject
-            (
-                "decomposeParDict",
-                runTimeTarget.system(),
-                runTimeTarget,
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE
-            )
-        );
-
-        int nProcsTarget
+        int nProcsTarget = readNumProcs
         (
-            readInt(decompositionDictTarget.lookup("numberOfSubdomains"))
+            args,
+            "targetDecomposeParDict",
+            runTimeTarget
         );
 
         List<boundBox> bbsTarget(nProcsTarget);
diff --git a/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H b/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H
index e0455221456ce198a574607ca734a93335ce4b0e..d1a010ce21e19e37d378e1be7bf587a0e0a4ca65 100644
--- a/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H
+++ b/applications/utilities/preProcessing/mapFieldsPar/MapLagrangianFields.H
@@ -104,6 +104,8 @@ void MapLagrangianFields
             Info<< "    mapping lagrangian fieldField " << fieldName << endl;
 
             // Read field (does not need mesh)
+            // Note: some fieldFields are 0 size (e.g. collision records) if
+            //       not used
             IOField<Field<Type> > fieldSource(*fieldIter());
 
             // Map - use CompactIOField to automatically write in
@@ -120,12 +122,22 @@ void MapLagrangianFields
                     IOobject::NO_WRITE,
                     false
                 ),
-                addParticles.size()
+                min(fieldSource.size(), addParticles.size()) // handle 0 size
             );
 
-            forAll(addParticles, i)
+            if (fieldSource.size())
             {
-                fieldTarget[i] = fieldSource[addParticles[i]];
+                forAll(addParticles, i)
+                {
+                    fieldTarget[i] = fieldSource[addParticles[i]];
+                }
+            }
+            else if (cloud::debug)
+            {
+                Pout<< "Not mapping " << fieldName << " since source size "
+                    << fieldSource.size() << " different to"
+                    << " cloud size " << addParticles.size()
+                    << endl;
             }
 
             // Write field
@@ -139,8 +151,9 @@ void MapLagrangianFields
 
         forAllIter(IOobjectList, fieldFields, fieldIter)
         {
-            Info<< "    mapping lagrangian fieldField "
-                << fieldIter()->name() << endl;
+            const word& fieldName = fieldIter()->name();
+
+            Info<< "    mapping lagrangian fieldField " << fieldName << endl;
 
             // Read field (does not need mesh)
             CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
@@ -150,7 +163,7 @@ void MapLagrangianFields
             (
                 IOobject
                 (
-                    fieldIter()->name(),
+                    fieldName,
                     meshTarget.time().timeName(),
                     cloud::prefix/cloudName,
                     meshTarget,
@@ -158,12 +171,22 @@ void MapLagrangianFields
                     IOobject::NO_WRITE,
                     false
                 ),
-                addParticles.size()
+                min(fieldSource.size(), addParticles.size()) // handle 0 size
             );
 
-            forAll(addParticles, i)
+            if (fieldSource.size())
             {
-                fieldTarget[i] = fieldSource[addParticles[i]];
+                forAll(addParticles, i)
+                {
+                    fieldTarget[i] = fieldSource[addParticles[i]];
+                }
+            }
+            else if (cloud::debug)
+            {
+                Pout<< "Not mapping " << fieldName << " since source size "
+                    << fieldSource.size() << " different to"
+                    << " cloud size " << addParticles.size()
+                    << endl;
             }
 
             // Write field
diff --git a/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C b/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C
index d2ed7da591a3a3621b158136433c22148aeca02f..6196b5e5e59b01dd0843f4e0b7aa705bb665d8ba 100644
--- a/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C
+++ b/applications/utilities/preProcessing/mapFieldsPar/mapLagrangian.C
@@ -110,9 +110,10 @@ void mapLagrangian(const meshToMesh& interp)
             cloud::prefix/cloudDirs[cloudI]
         );
 
-        IOobject* positionsPtr = objects.lookup(word("positions"));
+        bool foundPositions =
+            returnReduce(objects.found("positions"), orOp<bool>());;
 
-        if (positionsPtr)
+        if (foundPositions)
         {
             Info<< nl << "    processing cloud " << cloudDirs[cloudI] << endl;
 
diff --git a/applications/utilities/preProcessing/viewFactorsGen/shootRays.H b/applications/utilities/preProcessing/viewFactorsGen/shootRays.H
index d20b204f0360b9dd06d655d12977bdca92245c29..8b5dcd6db7708ae52bccc98803980f361bcb9642 100644
--- a/applications/utilities/preProcessing/viewFactorsGen/shootRays.H
+++ b/applications/utilities/preProcessing/viewFactorsGen/shootRays.H
@@ -89,7 +89,7 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++)
 
     DynamicList<label> dRayIs;
 
-    // Collect the rays which has not abstacle in bettween in rayStartFace
+    // Collect the rays which has not hit obstacle inbetween rayStartFace
     // and rayEndFace. If the ray hit itself get stored in dRayIs
     forAll(hitInfo, rayI)
     {
diff --git a/src/OpenFOAM/db/Time/timeSelector.H b/src/OpenFOAM/db/Time/timeSelector.H
index 836264f1da76e6cb5e70785136ce754d60fb6fa6..197f558f61906e42356965481ea8c16b15ffd083 100644
--- a/src/OpenFOAM/db/Time/timeSelector.H
+++ b/src/OpenFOAM/db/Time/timeSelector.H
@@ -162,7 +162,7 @@ public:
 
         //- Return the set of times selected based on the argList options
         //  including support for \b -newTimes in which times are selected
-        //  if the file <fName> does not exist in the time directory.
+        //  if the file \<fName\> does not exist in the time directory.
         //  Also set the runTime to the first instance or the
         //  \c constant/ directory if no instances are specified or available
         static instantList select
diff --git a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C
index 5ddb9d564baf86a642f69c9975ce5860a6d1a5e1..e220d9a4c4aa02e2630360d9908222d206cbda4a 100644
--- a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C
+++ b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -31,7 +31,7 @@ License
 namespace Foam
 {
     template<>
-    const char* NamedEnum<outputFilterOutputControl::outputControls, 7>::
+    const char* NamedEnum<outputFilterOutputControl::outputControls, 8>::
     names[] =
     {
         "timeStep",
@@ -40,11 +40,12 @@ namespace Foam
         "runTime",
         "clockTime",
         "cpuTime",
+        "onEnd",
         "none"
     };
 }
 
-const Foam::NamedEnum<Foam::outputFilterOutputControl::outputControls, 7>
+const Foam::NamedEnum<Foam::outputFilterOutputControl::outputControls, 8>
     Foam::outputFilterOutputControl::outputControlNames_;
 
 
@@ -113,6 +114,7 @@ void Foam::outputFilterOutputControl::read(const dictionary& dict)
             break;
         }
 
+        case ocOnEnd:
         default:
         {
             // do nothing
@@ -196,6 +198,13 @@ bool Foam::outputFilterOutputControl::output()
             break;
         }
 
+        case ocOnEnd:
+        {
+            scalar endTime = time_.endTime().value() - 0.5*time_.deltaTValue();
+            return time_.value() > endTime;
+            break;
+        }
+
         case ocNone:
         {
             return false;
diff --git a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H
index 1818fe17009da1beab37ff6ed12c650b57364f58..6cef209c15ac76cf11be82eefe5983d2ba30213a 100644
--- a/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H
+++ b/src/OpenFOAM/db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -62,6 +62,7 @@ public:
         ocRunTime,        /*!< run time for dumping */
         ocClockTime,      /*!< clock time for dumping */
         ocCpuTime,        /*!< cpu time for dumping */
+        ocOnEnd,          /*!< on end of run*/
         ocNone            /*!< no output */
     };
 
@@ -77,7 +78,7 @@ private:
         const word prefix_;
 
         //- String representation of outputControls enums
-        static const NamedEnum<outputControls, 7> outputControlNames_;
+        static const NamedEnum<outputControls, 8> outputControlNames_;
 
         //- Type of output
         outputControls outputControl_;
diff --git a/src/TurbulenceModels/compressible/Make/files b/src/TurbulenceModels/compressible/Make/files
index c4aab942510cd628afd489cab84fe998245e32d0..2c2366c37dcfa6a8f31b1ba7c3c385eecc664898 100644
--- a/src/TurbulenceModels/compressible/Make/files
+++ b/src/TurbulenceModels/compressible/Make/files
@@ -10,7 +10,6 @@ $(BCs)/totalFlowRateAdvectiveDiffusive/totalFlowRateAdvectiveDiffusiveFvPatchSca
 $(BCs)/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C
 $(BCs)/externalWallHeatFluxTemperature/externalWallHeatFluxTemperatureFvPatchScalarField.C
 $(BCs)/wallHeatTransfer/wallHeatTransferFvPatchScalarField.C
-$(BCs)/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
 $(BCs)/convectiveHeatTransfer/convectiveHeatTransferFvPatchScalarField.C
 
 turbulentFluidThermoModels/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.C
diff --git a/src/TurbulenceModels/compressible/turbulenceModelDoc.H b/src/TurbulenceModels/compressible/turbulenceModelDoc.H
index 5722cee54e88064bceebbb4f56a89404dd989583..941e205368208e83151d1e10358fec60d7a354ca 100644
--- a/src/TurbulenceModels/compressible/turbulenceModelDoc.H
+++ b/src/TurbulenceModels/compressible/turbulenceModelDoc.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 \defgroup grpCmpTurbulence Compressible turbulence
 @{
+    \ingroup grpTurbulence
     This group contains compressible turbulence models.
 @}
 
diff --git a/src/TurbulenceModels/incompressible/turbulenceModelDoc.H b/src/TurbulenceModels/incompressible/turbulenceModelDoc.H
index 2e5547351f1a35a65c933524b4b2c24385aa5160..a0357f18d1c7b0b357d4f0edb3e021c0c102e992 100644
--- a/src/TurbulenceModels/incompressible/turbulenceModelDoc.H
+++ b/src/TurbulenceModels/incompressible/turbulenceModelDoc.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 \defgroup grpIcoTurbulence Incompressible turbulence
 @{
+    \ingroup grpTurbulence
     This group contains incompressible turbulence models.
 @}
 
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 3dec7db1683466ad4add2cba78691d5b022d0475..1c159ff7cb802320276f78394a7745c751256405 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -133,7 +133,6 @@ $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C
 $(derivedFvPatchFields)/codedFixedValue/codedFixedValueFvPatchFields.C
 $(derivedFvPatchFields)/codedMixed/codedMixedFvPatchFields.C
 $(derivedFvPatchFields)/cylindricalInletVelocity/cylindricalInletVelocityFvPatchVectorField.C
-$(derivedFvPatchFields)/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
 $(derivedFvPatchFields)/fan/fanFvPatchFields.C
 $(derivedFvPatchFields)/fanPressure/fanPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C
@@ -168,6 +167,7 @@ $(derivedFvPatchFields)/pressureInletOutletVelocity/pressureInletOutletVelocityF
 $(derivedFvPatchFields)/pressureInletUniformVelocity/pressureInletUniformVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/pressureInletVelocity/pressureInletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/pressureNormalInletOutletVelocity/pressureNormalInletOutletVelocityFvPatchVectorField.C
+$(derivedFvPatchFields)/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/fixedNormalInletOutletVelocity/fixedNormalInletOutletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/rotatingPressureInletOutletVelocity/rotatingPressureInletOutletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/rotatingTotalPressure/rotatingTotalPressureFvPatchScalarField.C
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C
deleted file mode 100644
index f930a1ef5c705682a36e7a20fe0f4c98fd8b412f..0000000000000000000000000000000000000000
--- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.C
+++ /dev/null
@@ -1,851 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "externalCoupledMixedFvPatchField.H"
-#include "fvPatchFieldMapper.H"
-#include "volFields.H"
-#include "IFstream.H"
-#include "globalIndex.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-template<class Type>
-Foam::word Foam::externalCoupledMixedFvPatchField<Type>::lockName = "OpenFOAM";
-
-template<class Type>
-Foam::string
-Foam::externalCoupledMixedFvPatchField<Type>::patchKey = "# Patch: ";
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-template<class Type>
-Foam::fileName Foam::externalCoupledMixedFvPatchField<Type>::baseDir() const
-{
-    word regionName(this->dimensionedInternalField().mesh().name());
-    if (regionName == polyMesh::defaultRegion)
-    {
-        regionName = ".";
-    }
-
-    fileName result(commsDir_/regionName);
-    result.clean();
-
-    return result;
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::setMaster
-(
-    const labelList& patchIDs
-)
-{
-    const volFieldType& cvf =
-        static_cast<const volFieldType&>(this->dimensionedInternalField());
-
-    volFieldType& vf = const_cast<volFieldType&>(cvf);
-
-    typename volFieldType::GeometricBoundaryField& bf = vf.boundaryField();
-
-    // number of patches can be different in parallel...
-    label nPatch = bf.size();
-    reduce(nPatch, maxOp<label>());
-
-    offsets_.setSize(nPatch);
-    forAll(offsets_, i)
-    {
-        offsets_[i].setSize(Pstream::nProcs());
-        offsets_[i] = 0;
-    }
-
-    // set the master patch
-    forAll(patchIDs, i)
-    {
-        label patchI = patchIDs[i];
-
-        patchType& pf = refCast<patchType>(bf[patchI]);
-
-        offsets_[patchI][Pstream::myProcNo()] = pf.size();
-
-        if (i == 0)
-        {
-            pf.master() = true;
-        }
-        else
-        {
-            pf.master() = false;
-        }
-    }
-
-    // set the patch offsets
-    int tag = Pstream::msgType() + 1;
-    forAll(offsets_, i)
-    {
-        Pstream::gatherList(offsets_[i], tag);
-        Pstream::scatterList(offsets_[i], tag);
-    }
-
-    label patchOffset = 0;
-    forAll(offsets_, patchI)
-    {
-        label sumOffset = 0;
-        List<label>& procOffsets = offsets_[patchI];
-
-        forAll(procOffsets, procI)
-        {
-            label o = procOffsets[procI];
-            if (o > 0)
-            {
-                procOffsets[procI] = patchOffset + sumOffset;
-                sumOffset += o;
-            }
-        }
-        patchOffset += sumOffset;
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::writeGeometry
-(
-    OFstream& osPoints,
-    OFstream& osFaces
-) const
-{
-    int tag = Pstream::msgType() + 1;
-
-    const label procI = Pstream::myProcNo();
-    const polyPatch& p = this->patch().patch();
-    const polyMesh& mesh = p.boundaryMesh().mesh();
-
-    labelList pointToGlobal;
-    labelList uniquePointIDs;
-    (void)mesh.globalData().mergePoints
-    (
-        p.meshPoints(),
-        p.meshPointMap(),
-        pointToGlobal,
-        uniquePointIDs
-    );
-
-    List<pointField> allPoints(Pstream::nProcs());
-    allPoints[procI] = pointField(mesh.points(), uniquePointIDs);
-    Pstream::gatherList(allPoints, tag);
-
-    List<faceList> allFaces(Pstream::nProcs());
-    faceList& patchFaces = allFaces[procI];
-    patchFaces = p.localFaces();
-    forAll(patchFaces, faceI)
-    {
-        inplaceRenumber(pointToGlobal, patchFaces[faceI]);
-    }
-
-    Pstream::gatherList(allFaces, tag);
-
-    if (Pstream::master())
-    {
-        pointField pts
-        (
-            ListListOps::combine<pointField>(allPoints, accessOp<pointField>())
-        );
-
-        // write points
-        osPoints << patchKey.c_str() << this->patch().name() << pts << endl;
-
-        faceList fcs
-        (
-            ListListOps::combine<faceList>(allFaces, accessOp<faceList>())
-        );
-
-        // write faces
-        osFaces<< patchKey.c_str() << this->patch().name() << fcs << endl;
-    }
-}
-
-
-template<class Type>
-Foam::fileName Foam::externalCoupledMixedFvPatchField<Type>::lockFile() const
-{
-    return fileName(baseDir()/(lockName + ".lock"));
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::createLockFile() const
-{
-    if (!master_ || !Pstream::master())
-    {
-        return;
-    }
-
-    const fileName fName(lockFile());
-    IFstream is(fName);
-
-    // only create lock file if it doesn't already exist
-    if (!is.good())
-    {
-        if (log_)
-        {
-            Info<< type() << ": creating lock file" << endl;
-        }
-
-        OFstream os(fName);
-        os  << "lock file";
-        os.flush();
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::removeLockFile() const
-{
-    if (!master_ || !Pstream::master())
-    {
-        return;
-    }
-
-    if (log_)
-    {
-        Info<< type() << ": removing lock file" << endl;
-    }
-
-    rm(lockFile());
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::startWait() const
-{
-    // only wait on master patch
-
-    const volFieldType& cvf =
-        static_cast<const volFieldType&>(this->dimensionedInternalField());
-
-    const typename volFieldType::GeometricBoundaryField& bf =
-        cvf.boundaryField();
-
-    forAll(coupledPatchIDs_, i)
-    {
-        label patchI = coupledPatchIDs_[i];
-
-        const patchType& pf = refCast<const patchType>(bf[patchI]);
-
-        if (pf.master())
-        {
-            pf.wait();
-            break;
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::wait() const
-{
-    const fileName fName(lockFile());
-    label found = 0;
-    label totalTime = 0;
-
-    if (log_)
-    {
-        Info<< type() << ": beginning wait for lock file " << fName << endl;
-    }
-
-    while (found == 0)
-    {
-        if (Pstream::master())
-        {
-            if (totalTime > timeOut_)
-            {
-                FatalErrorIn
-                (
-                    "void "
-                    "Foam::externalCoupledMixedFvPatchField<Type>::wait() "
-                    "const"
-                )
-                    << "Wait time exceeded time out time of " << timeOut_
-                    << " s" << abort(FatalError);
-            }
-
-            IFstream is(fName);
-
-            if (is.good())
-            {
-                found++;
-
-                if (log_)
-                {
-                    Info<< type() << ": found lock file " << fName << endl;
-                }
-            }
-            else
-            {
-                sleep(waitInterval_);
-                totalTime += waitInterval_;
-
-                if (log_)
-                {
-                    Info<< type() << ": wait time = " << totalTime << endl;
-                }
-            }
-        }
-
-        // prevent other procs from racing ahead
-        reduce(found, sumOp<label>());
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::initialiseRead
-(
-    IFstream& is
-) const
-{
-    if (!is.good())
-    {
-        FatalErrorIn
-        (
-            "void Foam::externalCoupledMixedFvPatchField<Type>::"
-            "initialiseRead"
-            "("
-                "IFstream&"
-            ") const"
-        )
-            << "Unable to open data transfer file " << is.name()
-            << " for patch " << this->patch().name()
-            << exit(FatalError);
-    }
-
-    label offset = offsets_[this->patch().index()][Pstream::myProcNo()];
-
-    // scan forward to start reading at relevant line/position
-    string line;
-    for (label i = 0; i < offset; i++)
-    {
-        if (is.good())
-        {
-            is.getLine(line);
-        }
-        else
-        {
-            FatalErrorIn
-            (
-                "void Foam::externalCoupledMixedFvPatchField<Type>::"
-                "initialiseRead"
-                "("
-                    "IFstream&"
-                ") const"
-            )
-                << "Unable to scan forward to appropriate read position for "
-                << "data transfer file " << is.name()
-                << " for patch " << this->patch().name()
-                << exit(FatalError);
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::readData
-(
-    const fileName& transferFile
-)
-{
-    // read data passed back from external source
-    IFstream is(transferFile + ".in");
-
-    // pre-process the input transfer file
-    initialiseRead(is);
-
-    // read data from file
-    forAll(this->patch(), faceI)
-    {
-        if (is.good())
-        {
-            is  >> this->refValue()[faceI]
-                >> this->refGrad()[faceI]
-                >> this->valueFraction()[faceI];
-        }
-        else
-        {
-            FatalErrorIn
-            (
-                "void Foam::externalCoupledMixedFvPatchField<Type>::readData"
-                "("
-                    "const fileName&"
-                ")"
-            )
-                << "Insufficient data for patch "
-                << this->patch().name()
-                << " in file " << is.name()
-                << exit(FatalError);
-        }
-    }
-
-    initialised_ = true;
-
-    // update the value from the mixed condition
-    mixedFvPatchField<Type>::evaluate();
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::writeData
-(
-    const fileName& transferFile
-) const
-{
-    if (!master_)
-    {
-        return;
-    }
-
-    OFstream os(transferFile);
-
-    writeHeader(os);
-
-    const volFieldType& cvf =
-        static_cast<const volFieldType&>(this->dimensionedInternalField());
-
-    const typename volFieldType::GeometricBoundaryField& bf =
-        cvf.boundaryField();
-
-    forAll(coupledPatchIDs_, i)
-    {
-        label patchI = coupledPatchIDs_[i];
-
-        const patchType& pf = refCast<const patchType>(bf[patchI]);
-
-        pf.transferData(os);
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::writeHeader
-(
-    OFstream& os
-) const
-{
-    os  << "# Values: magSf value snGrad" << endl;
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-externalCoupledMixedFvPatchField
-(
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF
-)
-:
-    mixedFvPatchField<Type>(p, iF),
-    commsDir_("unknown-commsDir"),
-    fName_("unknown-fName"),
-    waitInterval_(0),
-    timeOut_(0),
-    calcFrequency_(0),
-    initByExternal_(false),
-    log_(false),
-    master_(false),
-    offsets_(),
-    initialised_(false),
-    coupledPatchIDs_()
-{
-    this->refValue() = pTraits<Type>::zero;
-    this->refGrad() = pTraits<Type>::zero;
-    this->valueFraction() = 0.0;
-}
-
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-externalCoupledMixedFvPatchField
-(
-    const externalCoupledMixedFvPatchField& ptf,
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF,
-    const fvPatchFieldMapper& mapper
-)
-:
-    mixedFvPatchField<Type>(ptf, p, iF, mapper),
-    commsDir_(ptf.commsDir_),
-    fName_(ptf.fName_),
-    waitInterval_(ptf.waitInterval_),
-    timeOut_(ptf.timeOut_),
-    calcFrequency_(ptf.calcFrequency_),
-    initByExternal_(ptf.initByExternal_),
-    log_(ptf.log_),
-    master_(ptf.master_),
-    offsets_(ptf.offsets_),
-    initialised_(ptf.initialised_),
-    coupledPatchIDs_(ptf.coupledPatchIDs_)
-{}
-
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-externalCoupledMixedFvPatchField
-(
-    const fvPatch& p,
-    const DimensionedField<Type, volMesh>& iF,
-    const dictionary& dict
-)
-:
-    mixedFvPatchField<Type>(p, iF),
-    commsDir_(dict.lookup("commsDir")),
-    fName_(dict.lookup("fileName")),
-    waitInterval_(dict.lookupOrDefault("waitInterval", 1)),
-    timeOut_(dict.lookupOrDefault("timeOut", 100*waitInterval_)),
-    calcFrequency_(dict.lookupOrDefault("calcFrequency", 1)),
-    initByExternal_(readBool(dict.lookup("initByExternal"))),
-    log_(dict.lookupOrDefault("log", false)),
-    master_(true),
-    offsets_(),
-    initialised_(false),
-    coupledPatchIDs_()
-{
-    if (dict.found("value"))
-    {
-        fvPatchField<Type>::operator=
-        (
-            Field<Type>("value", dict, p.size())
-        );
-    }
-    else
-    {
-        fvPatchField<Type>::operator=(this->patchInternalField());
-    }
-
-    commsDir_.expand();
-
-    if (Pstream::master())
-    {
-        mkDir(baseDir());
-    }
-
-    if (!initByExternal_)
-    {
-        createLockFile();
-    }
-
-    // initialise as a fixed value
-    this->refValue() = *this;
-    this->refGrad() = pTraits<Type>::zero;
-    this->valueFraction() = 1.0;
-}
-
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-externalCoupledMixedFvPatchField
-(
-    const externalCoupledMixedFvPatchField& ecmpf
-)
-:
-    mixedFvPatchField<Type>(ecmpf),
-    commsDir_(ecmpf.commsDir_),
-    fName_(ecmpf.fName_),
-    waitInterval_(ecmpf.waitInterval_),
-    timeOut_(ecmpf.timeOut_),
-    calcFrequency_(ecmpf.calcFrequency_),
-    initByExternal_(ecmpf.initByExternal_),
-    log_(ecmpf.log_),
-    master_(ecmpf.master_),
-    offsets_(ecmpf.offsets_),
-    initialised_(ecmpf.initialised_),
-    coupledPatchIDs_(ecmpf.coupledPatchIDs_)
-{}
-
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-externalCoupledMixedFvPatchField
-(
-    const externalCoupledMixedFvPatchField& ecmpf,
-    const DimensionedField<Type, volMesh>& iF
-)
-:
-    mixedFvPatchField<Type>(ecmpf, iF),
-    commsDir_(ecmpf.commsDir_),
-    fName_(ecmpf.fName_),
-    waitInterval_(ecmpf.waitInterval_),
-    timeOut_(ecmpf.timeOut_),
-    calcFrequency_(ecmpf.calcFrequency_),
-    initByExternal_(ecmpf.initByExternal_),
-    log_(ecmpf.log_),
-    master_(ecmpf.master_),
-    offsets_(ecmpf.offsets_),
-    initialised_(ecmpf.initialised_),
-    coupledPatchIDs_(ecmpf.coupledPatchIDs_)
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-template<class Type>
-Foam::externalCoupledMixedFvPatchField<Type>::
-~externalCoupledMixedFvPatchField()
-{
-    removeLockFile();
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::initialise
-(
-    const fileName& transferFile
-)
-{
-    if (initialised_)
-    {
-        return;
-    }
-
-    const volFieldType& cvf =
-        static_cast<const volFieldType&>(this->dimensionedInternalField());
-
-    volFieldType& vf = const_cast<volFieldType&>(cvf);
-
-    typename volFieldType::GeometricBoundaryField& bf = vf.boundaryField();
-
-    // identify all coupled patches
-    DynamicList<label> coupledPatchIDs(bf.size());
-
-    forAll(bf, patchI)
-    {
-        if (isA<patchType>(bf[patchI]))
-        {
-            coupledPatchIDs.append(patchI);
-        }
-    }
-
-    coupledPatchIDs_.transfer(coupledPatchIDs);
-
-
-    // initialise by external solver, or just set the master patch
-    if (initByExternal_)
-    {
-        // remove lock file, signalling external source to execute
-//        removeLockFile();
-
-        forAll(coupledPatchIDs_, i)
-        {
-            label patchI = coupledPatchIDs_[i];
-
-            patchType& pf = refCast<patchType>(bf[patchI]);
-
-            pf.setMaster(coupledPatchIDs_);
-        }
-
-
-        // wait for initial data to be made available
-        startWait();
-
-        // read the initial data
-        if (master_)
-        {
-            forAll(coupledPatchIDs_, i)
-            {
-                label patchI = coupledPatchIDs_[i];
-
-                patchType& pf = refCast<patchType>(bf[patchI]);
-
-                pf.readData(transferFile);
-            }
-        }
-    }
-    else
-    {
-        setMaster(coupledPatchIDs_);
-    }
-
-    initialised_ = true;
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::evaluate
-(
-    const Pstream::commsTypes comms
-)
-{
-    if (!initialised_ || this->db().time().timeIndex() % calcFrequency_ == 0)
-    {
-        const fileName transferFile(baseDir()/fName_);
-
-        // initialise the coupling
-        initialise(transferFile);
-
-        // write data for external source
-        writeData(transferFile + ".out");
-
-        // remove lock file, signalling external source to execute
-        removeLockFile();
-
-        // wait for response
-        startWait();
-
-        if (master_ && Pstream::master())
-        {
-            // remove old data file from OpenFOAM
-            rm(transferFile + ".out");
-        }
-
-        // read data passed back from external source
-        readData(transferFile);
-
-        // create lock file for external source
-        createLockFile();
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::transferData
-(
-    OFstream& os
-) const
-{
-    if (log_)
-    {
-        Info<< type() << ": writing data to " << os.name()  << endl;
-    }
-
-    if (Pstream::parRun())
-    {
-        int tag = Pstream::msgType() + 1;
-
-        List<Field<scalar> > magSfs(Pstream::nProcs());
-        magSfs[Pstream::myProcNo()].setSize(this->patch().size());
-        magSfs[Pstream::myProcNo()] = this->patch().magSf();
-        Pstream::gatherList(magSfs, tag);
-
-        List<Field<Type> > values(Pstream::nProcs());
-        values[Pstream::myProcNo()].setSize(this->patch().size());
-        values[Pstream::myProcNo()] = this->refValue();
-        Pstream::gatherList(values, tag);
-
-        List<Field<Type> > snGrads(Pstream::nProcs());
-        snGrads[Pstream::myProcNo()].setSize(this->patch().size());
-        snGrads[Pstream::myProcNo()] = this->snGrad();
-        Pstream::gatherList(snGrads, tag);
-
-        if (Pstream::master())
-        {
-            forAll(values, procI)
-            {
-                const Field<scalar>& magSf = magSfs[procI];
-                const Field<Type>& value = values[procI];
-                const Field<Type>& snGrad = snGrads[procI];
-
-                forAll(magSf, faceI)
-                {
-                    os  << magSf[faceI] << token::SPACE
-                        << value[faceI] << token::SPACE
-                        << snGrad[faceI] << nl;
-                }
-            }
-
-            os.flush();
-        }
-    }
-    else
-    {
-        const Field<scalar>& magSf(this->patch().magSf());
-        const Field<Type>& value(this->refValue());
-        const Field<Type> snGrad(this->snGrad());
-
-        forAll(magSf, faceI)
-        {
-            os  << magSf[faceI] << token::SPACE
-                << value[faceI] << token::SPACE
-                << snGrad[faceI] << nl;
-        }
-
-        os.flush();
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::writeGeometry() const
-{
-    const volFieldType& cvf =
-        static_cast<const volFieldType&>(this->dimensionedInternalField());
-
-    const typename volFieldType::GeometricBoundaryField& bf =
-        cvf.boundaryField();
-
-    OFstream osPoints(baseDir()/"patchPoints");
-    OFstream osFaces(baseDir()/"patchFaces");
-
-    if (log_)
-    {
-        Info<< "writing collated patch points to: " << osPoints.name() << nl
-            << "writing collated patch faces to: " << osFaces.name() << endl;
-    }
-
-    forAll(bf, patchI)
-    {
-        if (isA<patchType>(bf[patchI]))
-        {
-            const patchType& pf = refCast<const patchType>(bf[patchI]);
-
-            pf.writeGeometry(osPoints, osFaces);
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::externalCoupledMixedFvPatchField<Type>::write(Ostream& os) const
-{
-    mixedFvPatchField<Type>::write(os);
-
-    os.writeKeyword("commsDir") << commsDir_ << token::END_STATEMENT << nl;
-    os.writeKeyword("fileName") << fName_ << token::END_STATEMENT << nl;
-    os.writeKeyword("waitInterval") << waitInterval_ << token::END_STATEMENT
-        << nl;
-    os.writeKeyword("timeOut") << timeOut_ << token::END_STATEMENT << nl;
-    os.writeKeyword("calcFrequency") << calcFrequency_ << token::END_STATEMENT
-        << nl;
-    os.writeKeyword("initByExternal") << initByExternal_ << token::END_STATEMENT
-        << nl;
-    os.writeKeyword("log") << log_ << token::END_STATEMENT << nl;
-
-    this->writeEntry("value", os);
-}
-
-
-// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H
deleted file mode 100644
index 322ba3810b71d0bec8b025054b7893130baeecae..0000000000000000000000000000000000000000
--- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchField.H
+++ /dev/null
@@ -1,355 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::externalCoupledMixedFvPatchField
-
-Group
-    grpGenericBoundaryConditions grpCoupledBoundaryConditions
-
-Description
-    This boundary condition provides an interface to an external application.
-    Values are transferred as plain text files, where OpenFOAM data is written
-    as:
-
-        # Patch: <patch name>
-        <magSf1> <value1> <surfaceNormalGradient1>
-        <magSf2> <value2> <surfaceNormalGradient2>
-        <magSf3> <value3> <surfaceNormalGradient3>
-        ...
-        <magSfN> <valueN> <surfaceNormalGradientN>
-
-    and received as the constituent pieces of the `mixed' condition, i.e.
-
-        # Patch: <patch name>
-        <value1> <gradient1> <valueFracion1>
-        <value2> <gradient2> <valueFracion2>
-        <value3> <gradient3> <valueFracion3>
-        ...
-        <valueN> <gradientN> <valueFracionN>
-
-    Data is sent/received as a single file for all patches from the directory
-
-        $FOAM_CASE/<commsDir>
-
-    At start-up, the boundary creates a lock file, i.e..
-
-        OpenFOAM.lock
-
-    ... to signal the external source to wait.  During the boundary condition
-    update, boundary values are written to file, e.g.
-
-        <fileName>.out
-
-    The lock file is then removed, instructing the external source to take
-    control of the program execution.  When ready, the external program
-    should create the return values, e.g. to file
-
-        <fileName>.in
-
-    ... and then re-instate the lock file.  The boundary condition will then
-    read the return values, and pass program execution back to OpenFOAM.
-
-
-    \heading Patch usage
-
-    \table
-        Property     | Description             | Required    | Default value
-        commsDir     | communications directory   | yes         |
-        fileName     | transfer file name      | yes         |
-        waitInterval | interval [s] between file checks | no | 1
-        timeOut      | time after which error invoked [s] |no |100*waitInterval
-        calcFrequency | calculation frequency  | no          | 1
-        initByExternal | external app to initialises values  | yes |
-        log          | log program control     | no          | no
-    \endtable
-
-    Example of the boundary condition specification:
-    \verbatim
-    myPatch
-    {
-        type            externalCoupled;
-        commsDir        "$FOAM_CASE/comms";
-        fileName        data;
-        calcFrequency   1;
-        initByExternal  yes;
-    }
-    \endverbatim
-
-SeeAlso
-    mixedFvPatchField
-
-SourceFiles
-    externalCoupledMixedFvPatchField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef externalCoupledMixedFvPatchField_H
-#define externalCoupledMixedFvPatchField_H
-
-#include "mixedFvPatchFields.H"
-#include "OFstream.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-class IFstream;
-
-/*---------------------------------------------------------------------------*\
-              Class externalCoupledMixedFvPatchField Declaration
-\*---------------------------------------------------------------------------*/
-
-template<class Type>
-class externalCoupledMixedFvPatchField
-:
-    public mixedFvPatchField<Type>
-{
-
-private:
-
-    // Private data
-
-        //- Convenience typedefs
-        typedef externalCoupledMixedFvPatchField<Type> patchType;
-        typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
-
-        //- Path to communications directory
-        fileName commsDir_;
-
-        //- Name of data file
-        word fName_;
-
-        //- Interval time between checking for return data [s]
-        label waitInterval_;
-
-        //- Time out time [s]
-        label timeOut_;
-
-        //- Calculation frequency
-        label calcFrequency_;
-
-        //- Flag to indicate values are initialised by external application
-        bool initByExternal_;
-
-        //- Log flag
-        bool log_;
-
-        //- Master patch flag - controls when to pause/resume execution
-        //  Note: only valid when collate option is selected
-        bool master_;
-
-        //- Offsets in data file to start reading at correct position
-        List<List<label> > offsets_;
-
-        //- Initialised flag
-        bool initialised_;
-
-        //- List of coupled patch IDs
-        List<label> coupledPatchIDs_;
-
-
-    // Private Member Functions
-
-        //- Initialise
-        void initialise(const fileName& transferFile);
-
-        //- Set the master flag when collate option is selected
-        void setMaster(const labelList& patchIDs);
-
-        //- Return the file path to the base communications directory
-        fileName baseDir() const;
-
-        //- Write the geometry to the comms dir
-        void writeGeometry(OFstream& osPoints, OFstream& osFaces) const;
-
-        //- Return the file path to the lock file
-        fileName lockFile() const;
-
-        //- Create lock file
-        void createLockFile() const;
-
-        //- Remove lock file
-        void removeLockFile() const;
-
-        //- Wait for response from external source
-        void startWait() const;
-
-        //- Wait for response from external source
-        void wait() const;
-
-        //- Initialise input stream for reading
-        void initialiseRead(IFstream& is) const;
-
-
-protected:
-
-    // Protected Member Functions
-
-        //- Read data from external source
-        virtual void readData(const fileName& transferFile);
-
-        //- Write data for external source - calls transferData
-        virtual void writeData(const fileName& transferFile) const;
-
-        //- Write header to transfer file
-        virtual void writeHeader(OFstream& os) const;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("externalCoupled");
-
-    //- Name of lock file
-    static word lockName;
-
-    //- Name of patch key, e.g. '# Patch:' when looking for start of patch data
-    static string patchKey;
-
-
-    // Constructors
-
-        //- Construct from patch and internal field
-        externalCoupledMixedFvPatchField
-        (
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&
-        );
-
-        //- Construct from patch, internal field and dictionary
-        externalCoupledMixedFvPatchField
-        (
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&,
-            const dictionary&
-        );
-
-        //- Construct by mapping given externalCoupledMixedFvPatchField
-        //  onto a new patch
-        externalCoupledMixedFvPatchField
-        (
-            const externalCoupledMixedFvPatchField<Type>&,
-            const fvPatch&,
-            const DimensionedField<Type, volMesh>&,
-            const fvPatchFieldMapper&
-        );
-
-        //- Construct as copy
-        externalCoupledMixedFvPatchField
-        (
-            const externalCoupledMixedFvPatchField&
-        );
-
-        //- Construct and return a clone
-        virtual tmp<fvPatchField<Type> > clone() const
-        {
-            return tmp<fvPatchField<Type> >
-            (
-                new externalCoupledMixedFvPatchField<Type>(*this)
-            );
-        }
-
-        //- Construct as copy setting internal field reference
-        externalCoupledMixedFvPatchField
-        (
-            const externalCoupledMixedFvPatchField&,
-            const DimensionedField<Type, volMesh>&
-        );
-
-        //- Construct and return a clone setting internal field reference
-        virtual tmp<fvPatchField<Type> > clone
-        (
-            const DimensionedField<Type, volMesh>& iF
-        ) const
-        {
-            return tmp<fvPatchField<Type> >
-            (
-                new externalCoupledMixedFvPatchField<Type>(*this, iF)
-            );
-        }
-
-
-    //- Destructor
-    virtual ~externalCoupledMixedFvPatchField();
-
-
-    // Member functions
-
-        // Access
-
-            //- Return the log flag
-            bool log() const
-            {
-                return log_;
-            }
-
-            //- Return the master flag
-            bool master() const
-            {
-                return master_;
-            }
-
-            //- Return the master flag
-            bool& master()
-            {
-                return master_;
-            }
-
-
-        // Evaluation functions
-
-            //- Evaluate the patch field
-            virtual void evaluate
-            (
-                const Pstream::commsTypes commsType=Pstream::blocking
-            );
-
-            //- Transfer data for external source
-            virtual void transferData(OFstream& os) const;
-
-
-        //- Write the geometry to the comms dir
-        void writeGeometry() const;
-
-        //- Write
-        virtual void write(Ostream&) const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-#   include "externalCoupledMixedFvPatchField.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C
new file mode 100644
index 0000000000000000000000000000000000000000..b7d36f1a6da272499521f07fc2c6979eca885e12
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.C
@@ -0,0 +1,438 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "pressurePIDControlInletVelocityFvPatchVectorField.H"
+#include "volFields.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvPatchFieldMapper.H"
+#include "surfaceFields.H"
+#include "linear.H"
+#include "steadyStateDdtScheme.H"
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+const Foam::surfaceScalarField&
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::facePressure() const
+{
+    const volScalarField& p(db().lookupObject<volScalarField>(pName_));
+
+    const word pfName(pName_ + "f");
+
+    if (!db().foundObject<surfaceScalarField>(pfName))
+    {
+        surfaceScalarField* pfPtr
+        (
+            new surfaceScalarField(pfName, linearInterpolate(p))
+        );
+
+        pfPtr->store();
+    }
+
+    surfaceScalarField& pf
+    (
+        const_cast<surfaceScalarField&>
+        (
+            db().lookupObject<surfaceScalarField>(pfName)
+        )
+    );
+
+    if (!pf.upToDate(p))
+    {
+        pf = linearInterpolate(p);
+    }
+
+    return pf;
+}
+
+
+template <class Type>
+void Foam::pressurePIDControlInletVelocityFvPatchVectorField::faceZoneAverage
+(
+    const word& name,
+    const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
+    scalar& area,
+    Type& average
+) const
+{
+    const fvMesh& mesh(patch().boundaryMesh().mesh());
+
+    const faceZone& zone = mesh.faceZones()[name];
+
+    area = 0;
+    average = pTraits<Type>::zero;
+
+    forAll(zone, faceI)
+    {
+        const label f(zone[faceI]);
+
+        const scalar da(mesh.magSf()[f]);
+
+        area += da;
+        average += da*field[f];
+    }
+
+    reduce(area, sumOp<scalar>());
+    reduce(average, sumOp<Type>());
+
+    average /= area;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::
+pressurePIDControlInletVelocityFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    fixedValueFvPatchField<vector>(p, iF),
+    upstreamName_(word::null),
+    downstreamName_(word::null),
+    deltaP_(1),
+    shapeFactor_(0),
+    pName_("p"),
+    phiName_("phi"),
+    rhoName_("none"),
+    P_(0),
+    I_(0),
+    D_(0),
+    Q_(- gSum(*this & patch().Sf())),
+    error_(0),
+    errorIntegral_(0),
+    oldQ_(0),
+    oldError_(0),
+    oldErrorIntegral_(0),
+    timeIndex_(db().time().timeIndex())
+{}
+
+
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::
+pressurePIDControlInletVelocityFvPatchVectorField
+(
+    const pressurePIDControlInletVelocityFvPatchVectorField& ptf,
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
+    upstreamName_(ptf.upstreamName_),
+    downstreamName_(ptf.downstreamName_),
+    deltaP_(ptf.deltaP_),
+    shapeFactor_(ptf.shapeFactor_),
+    pName_(ptf.pName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    P_(ptf.P_),
+    I_(ptf.I_),
+    D_(ptf.D_),
+    Q_(ptf.Q_),
+    error_(ptf.error_),
+    errorIntegral_(ptf.errorIntegral_),
+    oldQ_(ptf.oldQ_),
+    oldError_(ptf.oldError_),
+    oldErrorIntegral_(ptf.oldErrorIntegral_),
+    timeIndex_(ptf.timeIndex_)
+{}
+
+
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::
+pressurePIDControlInletVelocityFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    fixedValueFvPatchField<vector>(p, iF, dict),
+    upstreamName_(dict.lookup("upstream")),
+    downstreamName_(dict.lookup("downstream")),
+    deltaP_(readScalar(dict.lookup("deltaP"))),
+    shapeFactor_(dict.lookupOrDefault<scalar>("shapeFactor", 0)),
+    pName_(dict.lookupOrDefault<word>("p", "p")),
+    phiName_(dict.lookupOrDefault<word>("phi", "phi")),
+    rhoName_(dict.lookupOrDefault<word>("rho", "none")),
+    P_(readScalar(dict.lookup("P"))),
+    I_(readScalar(dict.lookup("I"))),
+    D_(readScalar(dict.lookup("D"))),
+    Q_(- gSum(*this & patch().Sf())),
+    error_(dict.lookupOrDefault<scalar>("error", 0)),
+    errorIntegral_(dict.lookupOrDefault<scalar>("errorIntegral", 0)),
+    oldQ_(0),
+    oldError_(0),
+    oldErrorIntegral_(0),
+    timeIndex_(db().time().timeIndex())
+{}
+
+
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::
+pressurePIDControlInletVelocityFvPatchVectorField
+(
+    const pressurePIDControlInletVelocityFvPatchVectorField& ptf
+)
+:
+    fixedValueFvPatchField<vector>(ptf),
+    upstreamName_(ptf.upstreamName_),
+    downstreamName_(ptf.downstreamName_),
+    deltaP_(ptf.deltaP_),
+    shapeFactor_(ptf.shapeFactor_),
+    pName_(ptf.pName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    P_(ptf.P_),
+    I_(ptf.I_),
+    D_(ptf.D_),
+    Q_(ptf.Q_),
+    error_(ptf.error_),
+    errorIntegral_(ptf.errorIntegral_),
+    oldQ_(ptf.oldQ_),
+    oldError_(ptf.oldError_),
+    oldErrorIntegral_(ptf.oldErrorIntegral_),
+    timeIndex_(ptf.timeIndex_)
+{}
+
+
+Foam::pressurePIDControlInletVelocityFvPatchVectorField::
+pressurePIDControlInletVelocityFvPatchVectorField
+(
+    const pressurePIDControlInletVelocityFvPatchVectorField& ptf,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    fixedValueFvPatchField<vector>(ptf, iF),
+    upstreamName_(ptf.upstreamName_),
+    downstreamName_(ptf.downstreamName_),
+    deltaP_(ptf.deltaP_),
+    shapeFactor_(ptf.shapeFactor_),
+    pName_(ptf.pName_),
+    phiName_(ptf.phiName_),
+    rhoName_(ptf.rhoName_),
+    P_(ptf.P_),
+    I_(ptf.I_),
+    D_(ptf.D_),
+    Q_(ptf.Q_),
+    error_(ptf.error_),
+    errorIntegral_(ptf.errorIntegral_),
+    oldQ_(ptf.oldQ_),
+    oldError_(ptf.oldError_),
+    oldErrorIntegral_(ptf.oldErrorIntegral_),
+    timeIndex_(ptf.timeIndex_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::pressurePIDControlInletVelocityFvPatchVectorField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    // Get the mesh
+    const fvMesh& mesh(patch().boundaryMesh().mesh());
+
+    // Get the time step
+    const scalar deltaT(db().time().deltaTValue());
+
+    // Get the flux field
+    const surfaceScalarField& phi
+    (
+        db().lookupObject<surfaceScalarField>(phiName_)
+    );
+
+    // Update the old-time quantities
+    if (timeIndex_ != db().time().timeIndex())
+    {
+        timeIndex_ = db().time().timeIndex();
+        oldQ_ = Q_;
+        oldError_ = error_;
+        oldErrorIntegral_ = errorIntegral_;
+    }
+
+    // Get the density
+    scalar rho = 1;
+    if (phi.dimensions() == dimVelocity*dimArea)
+    {
+        // do nothing ...
+    }
+    else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
+    {
+        const fvPatchField<scalar>& rhoField =
+            patch().lookupPatchField<volScalarField, scalar>(rhoName_);
+
+        rho = gSum(rhoField*patch().magSf())/gSum(patch().magSf());
+    }
+    else
+    {
+        FatalErrorIn
+        (
+            "void Foam::"
+            "pressurePIDControlInletVelocityFvPatchVectorField::"
+            "updateCoeffs()"
+        )   << "The dimensions of the field " << phiName_
+            << "are not recognised. The dimensions are " << phi.dimensions()
+            << ". The dimensions should be either " << dimVelocity*dimArea
+            << " for an incompressible case, or "
+            << dimDensity*dimVelocity*dimArea << " for a compressible case."
+            << exit(FatalError);
+    }
+
+    // Patch properties
+    const scalar patchA = gSum(patch().magSf());
+    Q_ = - gSum(*this & patch().Sf());
+
+    // Face-zone properties (a is upstream, b is downstream)
+    scalar Aa, Ab;
+    vector xa, xb;
+    faceZoneAverage(upstreamName_, mesh.Cf(), Aa, xa);
+    faceZoneAverage(downstreamName_, mesh.Cf(), Ab, xb);
+    const scalar L = mag(xa - xb);
+    const scalar LbyALinear = L/(Aa - Ab)*log(Aa/Ab);
+    const scalar LbyAStep = L/2*(1/Aa + 1/Ab);
+    const scalar LbyA = (1 - shapeFactor_)*LbyALinear + shapeFactor_*LbyAStep;
+
+    // Initialise the pressure drop. If the pressure field does not exist, the
+    // pressure drop is assumed to be that specified. This removes the error,
+    // so there is no control and the analytic inlet velocity is applied. This
+    // scenario only ever going to be applicable to potentialFoam.
+    scalar deltaP = deltaP_;
+    if (db().foundObject<volScalarField>(pName_))
+    {
+        scalar pa, pb;
+        faceZoneAverage(upstreamName_, facePressure(), Aa, pa);
+        faceZoneAverage(downstreamName_, facePressure(), Ab, pb);
+        deltaP = pa - pb;
+    }
+    else
+    {
+        WarningIn
+        (
+            "void Foam::pressurePIDControlInletVelocityFvPatchVectorField::"
+            "updateCoeffs()"
+        )   << "The pressure field name, \"pName\", is \"" << pName_ << "\", "
+            << "but a field of that name was not found. The inlet velocity "
+            << "will be set to an analytical value calculated from the "
+            << "specified pressure drop. No PID control will be done and "
+            << "transient effects will be ignored. This behaviour is designed "
+            << "to be appropriate for potentialFoam solutions. If you are "
+            << "getting this warning from another solver, you have probably "
+            << "specified an incorrect pressure name."
+            << endl << endl;
+    }
+
+    // Target and measured flow rates
+    scalar QTarget, QMeasured;
+    const scalar a = (1/sqr(Ab) - 1/sqr(Aa))/(2*rho);
+    if (!mesh.steady() && db().foundObject<volScalarField>(pName_))
+    {
+        const scalar b = LbyA/deltaT;
+        const scalar c = - LbyA/deltaT*oldQ_ /* - deltaP */;
+        QTarget = (- b + sqrt(sqr(b) - 4*a*(c - deltaP_)))/(2*a);
+        QMeasured = (- b + sqrt(sqr(b) - 4*a*(c - deltaP)))/(2*a);
+    }
+    else
+    {
+        QTarget = sqrt(deltaP_/a);
+        QMeasured = sqrt(deltaP/a);
+    }
+
+    // Errors
+    error_ = QTarget - QMeasured;
+    errorIntegral_ = oldErrorIntegral_ + 0.5*(error_ + oldError_);
+    const scalar errorDifferential = oldError_ - error_;
+
+    // Update the field
+    operator==
+    (
+      - patch().nf()
+       *(
+            QTarget
+          + P_*error_
+          + I_*errorIntegral_
+          + D_*errorDifferential
+        )/patchA
+    );
+
+    // Log output
+    if (debug)
+    {
+        const dimensionSet pDimensions(phi.dimensions()*dimVelocity/dimArea);
+        const scalar error = deltaP/deltaP_ - 1;
+        const scalar newQ = - gSum(*this & patch().Sf());
+        Info<< "pressurePIDControlInletVelocityFvPatchField " << patch().name()
+            << endl << "         "
+            << dimensionedScalar("U", dimVelocity, newQ/patchA)
+            << endl << "    "
+            << dimensionedScalar("deltaP", pDimensions, deltaP)
+            << " (" << mag(error)*100 << "\% "
+            << (error < 0 ? "below" : "above") << " the target)" << endl;
+    }
+
+    fixedValueFvPatchField<vector>::updateCoeffs();
+}
+
+
+void Foam::pressurePIDControlInletVelocityFvPatchVectorField::write
+(
+    Ostream& os
+) const
+{
+    fvPatchField<vector>::write(os);
+
+    os.writeKeyword("deltaP") << deltaP_ << token::END_STATEMENT << nl;
+    os.writeKeyword("upstream") << upstreamName_ << token::END_STATEMENT << nl;
+    os.writeKeyword("downstream")
+        << downstreamName_ << token::END_STATEMENT << nl;
+    os.writeKeyword("shapeFactor") << shapeFactor_
+        << token::END_STATEMENT << nl;
+    writeEntryIfDifferent<word>(os, "p", "p", pName_);
+    writeEntryIfDifferent<word>(os, "rho", "none", rhoName_);
+    os.writeKeyword("P") << P_ << token::END_STATEMENT << nl;
+    os.writeKeyword("I") << I_ << token::END_STATEMENT << nl;
+    os.writeKeyword("D") << D_ << token::END_STATEMENT << nl;
+    os.writeKeyword("error") << error_ << token::END_STATEMENT << nl;
+    os.writeKeyword("errorIntegral")
+        << errorIntegral_ << token::END_STATEMENT << nl;
+
+    writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+   makePatchTypeField
+   (
+       fvPatchVectorField,
+       pressurePIDControlInletVelocityFvPatchVectorField
+   );
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H
new file mode 100644
index 0000000000000000000000000000000000000000..d6f6cf765e5137971cece89b50c19c6f7734401d
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorField.H
@@ -0,0 +1,279 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::pressurePIDControlInletVelocityFvPatchVectorField
+
+Group
+    grpInletBoundaryConditions
+
+Description
+    This boundary condition tries to generate an inlet velocity that maintains
+    a specified pressure drop between two face zones downstream. The zones
+    should fully span a duct through which all the inlet flow passes.
+
+    An incompressible, lossless analysis of the flow between the inlet and the
+    two face-zones is performed. An ideal inlet velocity is thereby calculated
+    from the user-specified pressure drop. This analysis can include the
+    transient effect of the inlet velocity change. In this case, a shape factor
+    is included to represent non-linearity in the duct cross section.
+
+    The average pressure drop between the two face zones is measured. The same
+    incompressible, lossless analysis is performed using this pressure drop.
+    The difference between the two computed velocities is considered as an
+    error. The ideal inlet is modified so as to drive this error to zero. This
+    is accomplished by means of a PID control algorithm, for which
+    non-dimensional gains are specified by the user.
+
+    The shape factor takes a value of 0 for a linear change in cross sectional
+    area between the two face zones. A value of 1 represents a step change in
+    area at the mid-point between the zones. A smooth cubic or cosine profile
+    between two zones with zero divergence is typically represented by a factor
+    of between 0.2 and 0.25.
+
+    \heading Patch usage
+
+    \table
+        Property    | Description                 | Required | Default value
+        upstream    | upstream face zone name     | yes      |
+        downstream  | downstream face zone name   | yes      |
+        deltaP      | desired pressure drop       | yes      |
+        shapeFactor | non-linearity in the nozzle | no       | 0
+        p           | pressure field name         | no       | p
+        phi         | flux field name             | yes      | phi
+        rho         | density field name          | no       | none
+        P           | proportional gain           | yes      |
+        I           | integral gain               | yes      |
+        D           | differential gain           | yes      |
+    \endtable
+
+    Example of the boundary condition specification:
+
+    \verbatim
+    myPatch
+    {
+        type            pressurePIDControlInletVelocity;
+        upstream        upstream;
+        downstream      downstream;
+        deltaP          200;
+        shapeFactor     0;
+        p               p;
+        phi             phi;
+        rho             none;
+        P               0.5;
+        I               0.5;
+        D               0.1;
+        value           uniform (0 0 0);
+    }
+
+SeeAlso
+    Foam::fixedValueFvPatchField
+
+SourceFiles
+    pressurePIDControlInletVelocityFvPatchVectorField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef pressurePIDControlInletVelocityFvPatchVectorField_H
+#define pressurePIDControlInletVelocityFvPatchVectorField_H
+
+#include "fixedValueFvPatchFields.H"
+#include "Switch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+/*---------------------------------------------------------------------------*\
+     Class pressurePIDControlInletVelocityFvPatchVectorField Declaration
+\*---------------------------------------------------------------------------*/
+
+class pressurePIDControlInletVelocityFvPatchVectorField
+:
+    public fixedValueFvPatchVectorField
+{
+    // Private data
+
+        //- Name of the upstream face zone
+        const word upstreamName_;
+
+        //- Name of the downstream face zone
+        const word downstreamName_;
+
+        //- Desired pressure difference between upstream and downstream
+        const scalar deltaP_;
+
+        //- Nozzle shape factor
+        const scalar shapeFactor_;
+
+        //- Name of the pressure field
+        const word pName_;
+
+        //- Name of the flux field
+        const word phiName_;
+
+        //- Name of the density field (if any)
+        const word rhoName_;
+
+        //- Proportional gain
+        const scalar P_;
+
+        //- Integral gain
+        const scalar I_;
+
+        //- Derivative gain
+        const scalar D_;
+
+        //- Volumetric flow rate
+        scalar Q_;
+
+        //- Error
+        scalar error_;
+
+        //- Error integral w.r.t. time
+        scalar errorIntegral_;
+
+        //- Old volumetric flow rate
+        scalar oldQ_;
+
+        //- Old error
+        scalar oldError_;
+
+        //- Old error integral w.r.t. time
+        scalar oldErrorIntegral_;
+
+        //- Time index of the last update
+        label timeIndex_;
+
+
+    // Private member functions
+
+        //- Return the pressure interpolated to the faces
+        const surfaceScalarField& facePressure() const;
+
+        //- Calculate the average on a face zone
+        template <class Type>
+        void faceZoneAverage
+        (
+            const word& name,
+            const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
+            scalar& area,
+            Type& average
+        ) const;
+
+
+public:
+
+   //- Runtime type information
+   TypeName("pressurePIDControlInletVelocity");
+
+
+   // Constructors
+
+        //- Construct from patch and internal field
+        pressurePIDControlInletVelocityFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        pressurePIDControlInletVelocityFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given
+        //  flowRateInletVelocityFvPatchVectorField
+        //  onto a new patch
+        pressurePIDControlInletVelocityFvPatchVectorField
+        (
+            const pressurePIDControlInletVelocityFvPatchVectorField&,
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        pressurePIDControlInletVelocityFvPatchVectorField
+        (
+            const pressurePIDControlInletVelocityFvPatchVectorField&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchVectorField> clone() const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new pressurePIDControlInletVelocityFvPatchVectorField
+                (
+                    *this
+                )
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        pressurePIDControlInletVelocityFvPatchVectorField
+        (
+            const pressurePIDControlInletVelocityFvPatchVectorField&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchVectorField> clone
+        (
+            const DimensionedField<vector, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new pressurePIDControlInletVelocityFvPatchVectorField
+                (
+                    *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/finiteVolume/fvc/fvcCellReduce.C b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C
index 63c718375bf950119b8592ddd0966eb3cc796d64..7d8294b1e68c796c4c51f78a79766c6d3965a333 100644
--- a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C
+++ b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -45,7 +45,8 @@ template<class Type, class CombineOp>
 tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
 (
     const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf,
-    const CombineOp& cop
+    const CombineOp& cop,
+    const Type& nullValue
 )
 {
     typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
@@ -65,7 +66,7 @@ tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
                 IOobject::NO_WRITE
             ),
             mesh,
-            dimensioned<Type>("0", ssf.dimensions(), pTraits<Type>::zero),
+            dimensioned<Type>("initialValue", ssf.dimensions(), nullValue),
             zeroGradientFvPatchField<Type>::typeName
         )
     );
@@ -75,15 +76,29 @@ tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
     const labelUList& own = mesh.owner();
     const labelUList& nbr = mesh.neighbour();
 
-    forAll(own, i)
+    // Internal field
+    const Field<Type>& iField = ssf.internalField();
+    forAll(iField, faceI)
     {
-        label cellI = own[i];
-        cop(result[cellI], ssf[i]);
+        label cellOwn = own[faceI];
+        cop(result[cellOwn], iField[faceI]);
+
+        label cellNbr = nbr[faceI];
+        cop(result[cellNbr], iField[faceI]);
     }
-    forAll(nbr, i)
+
+    // Boundary field
+    forAll(ssf.boundaryField(), patchI)
     {
-        label cellI = nbr[i];
-        cop(result[cellI], ssf[i]);
+        const fvsPatchField<Type>& pf = ssf.boundaryField()[patchI];
+        const label start = pf.patch().start();
+
+        forAll(pf, i)
+        {
+            label faceI = start + i;
+            label cellI = own[faceI];
+            cop(result[cellI], pf[i]);
+        }
     }
 
     result.correctBoundaryConditions();
@@ -96,13 +111,14 @@ template<class Type, class CombineOp>
 tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
 (
     const tmp<GeometricField<Type, fvsPatchField, surfaceMesh>&> tssf,
-    const CombineOp& cop
+    const CombineOp& cop,
+    const Type& nullValue
 )
 {
     tmp<GeometricField<Type, fvPatchField, volMesh> >
-        tvf(cellReduce(cop, tssf));
+        tvf(cellReduce(cop, tssf, nullValue));
 
-   tssf.clear();
+    tssf.clear();
     return tvf;
 }
 
diff --git a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H
index 19bd24135af0a4dd75a11ca446192301e0e6443a..d355fd4a51bf9f6c0ea5f4dddc6b0ce3c44fdf29 100644
--- a/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H
+++ b/src/finiteVolume/finiteVolume/fvc/fvcCellReduce.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -53,14 +53,16 @@ namespace fvc
     tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
     (
         const GeometricField<Type, fvsPatchField, surfaceMesh>&,
-        const CombineOp& cop
+        const CombineOp& cop,
+        const Type& nullValue = pTraits<Type>::zero
     );
 
     template<class Type, class CombineOp>
     tmp<GeometricField<Type, fvPatchField, volMesh> > cellReduce
     (
         const tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >&,
-        const CombineOp& cop
+        const CombineOp& cop,
+        const Type& nullValue = pTraits<Type>::zero
     );
 }
 
diff --git a/src/mesh/extrudeModel/Make/files b/src/mesh/extrudeModel/Make/files
index f6c2f50b04edb8f625e1c867315d7369e3890a07..e18ad638e171829cbf7c1e7179b39142b9c7a75f 100644
--- a/src/mesh/extrudeModel/Make/files
+++ b/src/mesh/extrudeModel/Make/files
@@ -4,6 +4,7 @@ linearNormal/linearNormal.C
 planeExtrusion/planeExtrusion.C
 linearDirection/linearDirection.C
 linearRadial/linearRadial.C
+offsetSurface/offsetSurface.C
 radial/radial.C
 sigmaRadial/sigmaRadial.C
 sector/sector.C
diff --git a/src/mesh/extrudeModel/Make/options b/src/mesh/extrudeModel/Make/options
index eabd0b53a8ffd8a16a228d71ae038fac7e2ea6a2..2dd02e7d86ab8098d1cd1605d70c1bc4423d0bde 100644
--- a/src/mesh/extrudeModel/Make/options
+++ b/src/mesh/extrudeModel/Make/options
@@ -1,5 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/triSurface/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude
 
 LIB_LIBS = \
diff --git a/src/mesh/extrudeModel/offsetSurface/offsetSurface.C b/src/mesh/extrudeModel/offsetSurface/offsetSurface.C
new file mode 100644
index 0000000000000000000000000000000000000000..1b2872279f0d08e55956dce9156d030d17329fca
--- /dev/null
+++ b/src/mesh/extrudeModel/offsetSurface/offsetSurface.C
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2014 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "offsetSurface.H"
+#include "addToRunTimeSelectionTable.H"
+#include "triSurface.H"
+#include "triSurfaceSearch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace extrudeModels
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(offsetSurface, 0);
+
+addToRunTimeSelectionTable(extrudeModel, offsetSurface, dictionary);
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+offsetSurface::offsetSurface(const dictionary& dict)
+:
+    extrudeModel(typeName, dict),
+    project_(coeffDict_.lookupOrDefault("project", false))
+{
+    // Read surface
+    fileName baseName(coeffDict_.lookup("baseSurface"));
+    baseName.expand();
+    baseSurfPtr_.reset(new triSurface(baseName));
+
+    // Construct search engine
+    baseSearchPtr_.reset(new triSurfaceSearch(baseSurfPtr_()));
+
+    // Read offsetted surface
+    fileName offsetName(coeffDict_.lookup("offsetSurface"));
+    offsetName.expand();
+    offsetSurfPtr_.reset(new triSurface(offsetName));
+
+    // Construct search engine
+    offsetSearchPtr_.reset(new triSurfaceSearch(offsetSurfPtr_()));
+
+
+    const triSurface& b = baseSurfPtr_();
+    const triSurface& o = offsetSurfPtr_();
+
+    if
+    (
+        b.size() != o.size()
+     || b.nPoints() != o.nPoints()
+     || b.nEdges() != o.nEdges()
+    )
+    {
+        FatalIOErrorIn("offsetSurface::offsetSurface(const dictionary&)", dict)
+            << "offsetSurface " << offsetName
+            << " should have exactly the same topology as the baseSurface "
+            << baseName << exit(FatalIOError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+offsetSurface::~offsetSurface()
+{}
+
+
+// * * * * * * * * * * * * * * * * Operators * * * * * * * * * * * * * * * * //
+
+point offsetSurface::operator()
+(
+    const point& surfacePoint,
+    const vector& surfaceNormal,
+    const label layer
+) const
+{
+    if (layer == 0)
+    {
+        return surfacePoint;
+    }
+    else
+    {
+        pointField samples(1, surfacePoint);
+        scalarField nearestDistSqr(1, GREAT);
+        List<pointIndexHit> info;
+        baseSearchPtr_().findNearest(samples, nearestDistSqr, info);
+
+        label triI = info[0].index();
+
+
+        const triSurface& base = baseSurfPtr_();
+        const triPointRef baseTri(base[triI].tri(base.points()));
+
+        List<scalar> bary;
+        baseTri.barycentric(surfacePoint, bary);
+
+        const triSurface& offset = offsetSurfPtr_();
+        const triPointRef offsetTri(offset[triI].tri(offset.points()));
+
+        const point offsetPoint
+        (
+            bary[0]*offsetTri.a()
+           +bary[1]*offsetTri.b()
+           +bary[2]*offsetTri.c()
+        );
+
+        point interpolatedPoint
+        (
+            surfacePoint + sumThickness(layer)*(offsetPoint-surfacePoint)
+        );
+
+
+        //- Either return interpolatedPoint or re-project onto surface (since
+        //  snapping might not have do so exactly)
+
+        if (project_)
+        {
+            // Re-project onto surface
+            offsetSearchPtr_().findNearest
+            (
+                pointField(1, interpolatedPoint),
+                scalarField(1, GREAT),
+                info
+            );
+            return info[0].hitPoint();
+        }
+        else
+        {
+            return interpolatedPoint;
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace extrudeModels
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/mesh/extrudeModel/offsetSurface/offsetSurface.H b/src/mesh/extrudeModel/offsetSurface/offsetSurface.H
new file mode 100644
index 0000000000000000000000000000000000000000..f5df55cfd8d6859a89b7ff9abdf14489dcab7966
--- /dev/null
+++ b/src/mesh/extrudeModel/offsetSurface/offsetSurface.H
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2014 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::extrudeModels::offsetSurface
+
+Description
+    Extrudes by interpolating points from one surface to the other. Surfaces
+    have to be topologically identical i.e. one has to be an offsetted version
+    of the other.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef offsetSurface_H
+#define offsetSurface_H
+
+#include "point.H"
+#include "extrudeModel.H"
+#include "Switch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class triSurface;
+class triSurfaceSearch;
+
+
+namespace extrudeModels
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class offsetSurface Declaration
+\*---------------------------------------------------------------------------*/
+
+class offsetSurface
+:
+    public extrudeModel
+{
+    // Private data
+
+        //- surface
+        autoPtr<triSurface> baseSurfPtr_;
+
+        //- search engine
+        autoPtr<triSurfaceSearch> baseSearchPtr_;
+
+        //- offsets
+        autoPtr<triSurface> offsetSurfPtr_;
+
+        //- search engine
+        autoPtr<triSurfaceSearch> offsetSearchPtr_;
+
+        // Whether to re-project onto offsetted surface
+        const Switch project_;
+
+public:
+
+    //- Runtime type information
+    TypeName("offsetSurface");
+
+    // Constructors
+
+        //- Construct from dictionary
+        offsetSurface(const dictionary& dict);
+
+
+    //- Destructor
+    virtual ~offsetSurface();
+
+
+    // Member Operators
+
+        //- Return point
+        point operator()
+        (
+            const point& surfacePoint,
+            const vector& surfaceNormal,
+            const label layer
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace extrudeModels
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C
index cb3cfc7d5a91f4b21056cb55086938baa2e3fd38..9c5055de5d0f9ad38f21443a35af605d5ce7aa32 100644
--- a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C
+++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2014 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -49,7 +49,8 @@ Foam::partialWrite::partialWrite
 )
 :
     name_(name),
-    obr_(obr)
+    obr_(obr),
+    log_(true)
 {
     read(dict);
 }
@@ -65,16 +66,39 @@ Foam::partialWrite::~partialWrite()
 
 void Foam::partialWrite::read(const dictionary& dict)
 {
+    log_.readIfPresent("log", dict);
     dict.lookup("objectNames") >> objectNames_;
     dict.lookup("writeInterval") >> writeInterval_;
     writeInstance_ = 0;
 
-    Info<< type() << " " << name() << ":" << nl
-        << "    dumping every " << writeInterval_
-        << " th outputTime : " << nl << endl ;
-    forAllConstIter(HashSet<word>, objectNames_, iter)
+    if (log_)
     {
-        Info<< ' ' << iter.key();
+        Info<< type() << " " << name() << ":" << nl
+            << "    dumping every outputTime :";
+
+        forAllConstIter(HashSet<word>, objectNames_, iter)
+        {
+            Info<< ' ' << iter.key();
+        }
+
+        word postStr = "";
+        if (writeInterval_ == 2)
+        {
+            postStr = "nd ";
+        }
+        else if (writeInterval_ == 3)
+        {
+            postStr = "rd ";
+        }
+        else
+        {
+            postStr = "th ";
+        }
+
+        Info<< nl
+            << "    dumping all other fields every "
+            << writeInterval_ << postStr << " outputTime" << nl
+            << endl;
     }
 
     if (writeInterval_ < 1)
diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H
index 09197a671d84e4aa9108b8bdad8a381b02a76465..95c3f2f5000e78c621dceb866a2c1c45186dea67 100644
--- a/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H
+++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWrite.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -50,6 +50,7 @@ Description
         type         | type name: partialWrite | yes         |
         objectNames  | objects to write        | yes         |
         writeInterval | write interval         | yes         |
+        log          | Log to standard output  | no          | yes
     \endtable
 
 SeeAlso
@@ -91,11 +92,15 @@ protected:
 
     // Private data
 
-        //- Name of this set of partialWrite
+        //- Name of this set of partialWrite object
         word name_;
 
+        //- Refefence to the database
         const objectRegistry& obr_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
         //- Loaded fields
         UPtrList<volScalarField> vsf_;
         UPtrList<volVectorField> vvf_;
diff --git a/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C b/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C
index 56e00893131b54fcdb7315f063e417faab71dc1b..16551f4b79d1aeb08affecb156712a7c09be9455 100644
--- a/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C
+++ b/src/postProcessing/functionObjects/IO/partialWrite/partialWriteTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -68,7 +68,7 @@ void Foam::partialWrite::loadField
                 << " found in database" << endl;
         }
 
-         sfType& sField =
+        sfType& sField =
             const_cast<sfType&>
             (
                 obr_.lookupObject<sfType>(fieldName)
diff --git a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C
index 28bb18292eb5ba423f00f42f863c8b04f797a651..fee807a9a63ec7eaf663a4f2a310120860bb6299 100644
--- a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C
+++ b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,7 +31,7 @@ License
 
 namespace Foam
 {
-defineTypeNameAndDebug(removeRegisteredObject, 0);
+    defineTypeNameAndDebug(removeRegisteredObject, 0);
 }
 
 
@@ -47,7 +47,8 @@ Foam::removeRegisteredObject::removeRegisteredObject
 :
     name_(name),
     obr_(obr),
-    objectNames_()
+    objectNames_(),
+    log_(true)
 {
     read(dict);
 }
@@ -78,7 +79,8 @@ void Foam::removeRegisteredObject::execute()
 
             if (obj.ownedByRegistry())
             {
-                Info<< type() << " " << name_ << " output:" << nl
+                if (log_) Info
+                    << type() << " " << name_ << " output:" << nl
                     << "    removing object " << obj.name() << nl
                     << endl;
 
diff --git a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H
index fc02432ad89c246a840a64cd2e7e9bce87ee4584..42aa1f3546366553ef08bb3846ac2ee9bdafce4f 100644
--- a/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H
+++ b/src/postProcessing/functionObjects/IO/removeRegisteredObject/removeRegisteredObject.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -46,6 +46,7 @@ Description
         Property     | Description             | Required    | Default value
         type         | type name: removeRegisteredObject | yes |
         objectNames  | objects to remove       | yes         |
+        log          | Log to standard output  | no          | yes
     \endtable
 
 SeeAlso
@@ -63,6 +64,7 @@ SourceFiles
 
 #include "wordList.H"
 #include "runTimeSelectionTables.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -85,9 +87,10 @@ protected:
 
     // Private data
 
-        //- Name of this set of removeRegisteredObject
+        //- Name of this set of removeRegisteredObject object
         word name_;
 
+        //- Refefence to the database
         const objectRegistry& obr_;
 
         // Read from dictionary
@@ -95,6 +98,9 @@ protected:
             //- Names of objects to control
             wordList objectNames_;
 
+            //- Switch to send output to Info as well as to file
+            Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C
index 81b58a1a5cdfdf800112297ca347c923b7753b6e..f450c11093c7bdb85a3e60675499c9f49858f74e 100644
--- a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C
+++ b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -48,7 +48,8 @@ Foam::writeRegisteredObject::writeRegisteredObject
     name_(name),
     exclusiveWriting_(false),
     obr_(obr),
-    objectNames_()
+    objectNames_(),
+    log_(true)
 {
     read(dict);
 }
@@ -64,6 +65,8 @@ Foam::writeRegisteredObject::~writeRegisteredObject()
 
 void Foam::writeRegisteredObject::read(const dictionary& dict)
 {
+    log_.readIfPresent("log", dict);
+
     dict.lookup("objectNames") >> objectNames_;
     dict.readIfPresent("exclusiveWriting", exclusiveWriting_);
 }
@@ -89,7 +92,7 @@ void Foam::writeRegisteredObject::timeSet()
 
 void Foam::writeRegisteredObject::write()
 {
-    Info<< type() << " " << name_ << " output:" << nl;
+    if (log_) Info<< type() << " " << name_ << " output:" << nl;
 
     DynamicList<word> allNames(obr_.toc().size());
     forAll(objectNames_, i)
@@ -123,7 +126,7 @@ void Foam::writeRegisteredObject::write()
             obj.writeOpt() = IOobject::NO_WRITE;
         }
 
-        Info<< "    writing object " << obj.name() << nl << endl;
+        if (log_) Info<< "    writing object " << obj.name() << nl << endl;
 
         obj.write();
     }
diff --git a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H
index d08dc7c914c5d97a1cd574563e08f863650135fe..c3f282bfa576e03dd961bb9ea9dcf4f3879fd0e2 100644
--- a/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H
+++ b/src/postProcessing/functionObjects/IO/writeRegisteredObject/writeRegisteredObject.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -30,13 +30,13 @@ Group
 Description
     This function object allows specification of different writing frequency
     of objects registered to the database. It has similar functionality
-    as the main time database through the outputControl setting:
-        timeStep
-        outputTime
-        adjustableTime
-        runTime
-        clockTime
-        cpuTime
+    as the main time database through the \c outputControl setting:
+    - timeStep
+    - outputTime
+    - adjustableTime
+    - runTime
+    - clockTime
+    - cpuTime
 
     Example of function object specification:
     \verbatim
@@ -56,6 +56,7 @@ Description
         type         | type name: writeRegisteredObject | yes |
         objectNames  | objects to write        | yes         |
         exclusiveWriting    | Takes over object writing | no | yes
+        log          | Log to standard output  | no          | yes
     \endtable
 
     exclusiveWriting disables automatic writing (i.e through database) of the
@@ -76,6 +77,7 @@ SourceFiles
 
 #include "wordReList.H"
 #include "runTimeSelectionTables.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -104,7 +106,7 @@ protected:
         //- Takes over the writing from Db
         bool exclusiveWriting_;
 
-        //- Refererence to Db
+        //- Refererence to the database
         const objectRegistry& obr_;
 
         // Read from dictionary
@@ -112,6 +114,9 @@ protected:
             //- Names of objects to control
             wordReList objectNames_;
 
+            //- Switch to send output to Info as well as to file
+            Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C
index fd58741bd7419a3aa5d40cd19aacde1361b35c22..fabdc11b756e5b9c674df6166b3f2b31c0e10eee 100644
--- a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C
+++ b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C
@@ -172,16 +172,14 @@ void Foam::cloudInfo::write()
                     << endl;
             }
 
-            if (log_)
-            {
-                Info<< type() << " " << name_ <<  " output:" << nl
-                    << "    number of parcels : " << nParcels << nl
-                    << "    mass in system    : " << massInSystem << nl
-                    << "    maximum diameter  : " << Dmax << nl
-                    << "    D10 diameter      : " << D10 << nl
-                    << "    D32 diameter      : " << D32 << nl
-                    << endl;
-            }
+            if (log_) Info
+                << type() << " " << name_ <<  " output:" << nl
+                << "    number of parcels : " << nParcels << nl
+                << "    mass in system    : " << massInSystem << nl
+                << "    maximum diameter  : " << Dmax << nl
+                << "    D10 diameter      : " << D10 << nl
+                << "    D32 diameter      : " << D32 << nl
+                << endl;
         }
     }
 }
diff --git a/src/postProcessing/functionObjects/doc/functionObjects.dox b/src/postProcessing/functionObjects/doc/functionObjects.dox
index dc0b395fe8c3efb6b17360e24de7b5c47f8205ec..5651f5554510aae50a6ea424b7bbbc17c8af3c0a 100644
--- a/src/postProcessing/functionObjects/doc/functionObjects.dox
+++ b/src/postProcessing/functionObjects/doc/functionObjects.dox
@@ -40,6 +40,7 @@ The current range of features comprises of:
 - \ref grpFieldFunctionObjects
 - \ref grpForcesFunctionObjects
 - \ref grpFVFunctionObjects
+- \ref grpGraphicsFunctionObjects
 - \ref grpIOFunctionObjects
 - \ref grpJobControlFunctionObjects
 - \ref grpUtilitiesFunctionObjects
diff --git a/src/postProcessing/functionObjects/field/Make/files b/src/postProcessing/functionObjects/field/Make/files
index 75464c40139f6cd10a231b39aa23a81f4fbbf873..3f2b8f9f50c4c31aa4ae522d16474e2997ebc229 100644
--- a/src/postProcessing/functionObjects/field/Make/files
+++ b/src/postProcessing/functionObjects/field/Make/files
@@ -30,20 +30,24 @@ readFields/readFields.C
 readFields/readFieldsFunctionObject.C
 
 streamLine/streamLine.C
+streamLine/streamLineBase.C
 streamLine/streamLineParticle.C
 streamLine/streamLineParticleCloud.C
 streamLine/streamLineFunctionObject.C
 
-wallBoundedStreamLine/wallBoundedStreamLine.C
-wallBoundedStreamLine/wallBoundedStreamLineFunctionObject.C
-wallBoundedStreamLine/wallBoundedStreamLineParticle.C
-wallBoundedStreamLine/wallBoundedStreamLineParticleCloud.C
-wallBoundedStreamLine/wallBoundedParticle.C
-
 surfaceInterpolateFields/surfaceInterpolateFields.C
 surfaceInterpolateFields/surfaceInterpolateFieldsFunctionObject.C
 
 regionSizeDistribution/regionSizeDistribution.C
 regionSizeDistribution/regionSizeDistributionFunctionObject.C
 
+valueAverage/valueAverage.C
+valueAverage/valueAverageFunctionObject.C
+
+wallBoundedStreamLine/wallBoundedStreamLine.C
+wallBoundedStreamLine/wallBoundedStreamLineFunctionObject.C
+wallBoundedStreamLine/wallBoundedStreamLineParticle.C
+wallBoundedStreamLine/wallBoundedStreamLineParticleCloud.C
+wallBoundedStreamLine/wallBoundedParticle.C
+
 LIB = $(FOAM_LIBBIN)/libfieldFunctionObjects
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
index 5652904ffa30b7df27e6d0971ef16709c2400aea..08dcd5aa732c9691068952f72e722a748fcfb227 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
@@ -124,11 +124,9 @@ void Foam::fieldAverage::calcAverages()
         prevTimeIndex_ = currentTimeIndex;
     }
 
-    if (log_)
-    {
-        Info<< type() << " " << name_ << " output:" << nl
-            << "    Calculating averages" << nl;
-    }
+    if (log_) Info
+        << type() << " " << name_ << " output:" << nl
+        << "    Calculating averages" << nl;
 
     addMeanSqrToPrime2Mean<scalar, scalar>();
     addMeanSqrToPrime2Mean<vector, symmTensor>();
@@ -204,21 +202,17 @@ void Foam::fieldAverage::readAveragingProperties()
                 totalIter_[fieldI] = readLabel(fieldDict.lookup("totalIter"));
                 totalTime_[fieldI] = readScalar(fieldDict.lookup("totalTime"));
 
-                if (log_)
-                {
-                    Info<< "        " << fieldName
-                        << " iters = " << totalIter_[fieldI]
-                        << " time = " << totalTime_[fieldI] << nl;
-                }
+                if (log_) Info
+                    << "        " << fieldName
+                    << " iters = " << totalIter_[fieldI]
+                    << " time = " << totalTime_[fieldI] << nl;
             }
             else
             {
-                if (log_)
-                {
-                    Info<< "        " << fieldName
-                        << ": starting averaging at time "
-                        << obr_.time().timeName() << endl;
-                }
+                if (log_) Info
+                    << "        " << fieldName
+                    << ": starting averaging at time "
+                    << obr_.time().timeName() << endl;
             }
         }
     }
@@ -315,11 +309,9 @@ void Foam::fieldAverage::write()
 
         if (resetOnOutput_)
         {
-            if (log_)
-            {
-                Info<< "    Restarting averaging at time " << obr_.time().timeName()
-                    << nl << endl;
-            }
+            if (log_) Info
+                << "    Restarting averaging at time " << obr_.time().timeName()
+                << nl << endl;
 
             totalIter_.clear();
             totalIter_.setSize(faItems_.size(), 1);
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
index 4f3a2d7cab670b971b0bac60ffb5d30f5ce69f10..2e20c4ab0195723ac6cde1a3aedfb934b3227404 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C
@@ -46,12 +46,10 @@ void Foam::fieldAverage::addMeanFieldType(const label fieldI)
     }
     else if (obr_.found(meanFieldName))
     {
-        if (log_)
-        {
-            Info<< "    Cannot allocate average field " << meanFieldName
-                << " since an object with that name already exists."
-                << " Disabling averaging for field." << endl;
-        }
+        if (log_) Info
+            << "    Cannot allocate average field " << meanFieldName
+            << " since an object with that name already exists."
+            << " Disabling averaging for field." << endl;
 
         faItems_[fieldI].mean() = false;
     }
@@ -110,10 +108,8 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI)
     const word& meanFieldName = faItems_[fieldI].meanFieldName();
     const word& prime2MeanFieldName = faItems_[fieldI].prime2MeanFieldName();
 
-    if (log_)
-    {
-        Info << "    Reading/initialising field " << prime2MeanFieldName << nl;
-    }
+    if (log_) Info
+        << "    Reading/initialising field " << prime2MeanFieldName << endl;
 
     if (obr_.foundObject<Type2>(prime2MeanFieldName))
     {
@@ -121,12 +117,10 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI)
     }
     else if (obr_.found(prime2MeanFieldName))
     {
-        if (log_)
-        {
-            Info<< "    Cannot allocate average field " << prime2MeanFieldName
-                << " since an object with that name already exists."
-                << " Disabling averaging for field." << nl;
-        }
+        if (log_) Info
+            << "    Cannot allocate average field " << prime2MeanFieldName
+            << " since an object with that name already exists."
+            << " Disabling averaging for field." << endl;
 
         faItems_[fieldI].prime2Mean() = false;
     }
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
index 4e30b881ca63036130f5c1c53171220aef266c66..844a15cb36551ab4192a289bb2cbec364e6fecd8 100644
--- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
@@ -48,14 +48,16 @@ Foam::fieldCoordinateSystemTransform::fieldCoordinateSystemTransform
     obr_(obr),
     active_(true),
     fieldSet_(),
-    coordSys_(obr, dict)
+    coordSys_(obr, dict),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
     if (isA<fvMesh>(obr_))
     {
         read(dict);
 
-        Info<< type() << " " << name_ << ":" << nl
+        if (log_) Info
+            << type() << " " << name_ << ":" << nl
             << "   Applying transformation from global Cartesian to local "
             << coordSys_ << nl << endl;
     }
@@ -89,6 +91,7 @@ void Foam::fieldCoordinateSystemTransform::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
         dict.lookup("fields") >> fieldSet_;
     }
 }
@@ -98,7 +101,7 @@ void Foam::fieldCoordinateSystemTransform::execute()
 {
     if (active_)
     {
-        Info<< type() << " " << name_ << " output:" << nl;
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
 
         forAll(fieldSet_, fieldI)
         {
@@ -132,7 +135,7 @@ void Foam::fieldCoordinateSystemTransform::write()
 {
     if (active_)
     {
-        Info<< type() << " " << name_ << " output:" << nl;
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
 
         forAll(fieldSet_, fieldI)
         {
@@ -141,12 +144,12 @@ void Foam::fieldCoordinateSystemTransform::write()
             const regIOobject& field =
                 obr_.lookupObject<regIOobject>(fieldName);
 
-            Info<< "    writing field " << field.name() << nl;
+            if (log_) Info << "    writing field " << field.name() << nl;
 
             field.write();
         }
 
-        Info<< endl;
+        if (log_) Info<< endl;
     }
 }
 
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H
index edd1f13b502437f9d545a0e26ecb5689d83d1f85..f18e90ca05e65bb902b1630bb3e767786e3b5f84 100644
--- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,6 +60,7 @@ Description
         type         | type name: fieldCoordinateSystemTransform | yes |
         fields       | list of fields to be transformed |yes |
         coordinateSystem | local co-ordinate system | yes    |
+        log          | Log to standard output  | no          | yes
     \endtable
 
 SeeAlso
@@ -117,6 +118,9 @@ protected:
         //- Co-ordinate system to transform to
         coordinateSystem coordSys_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Protected Member Functions
 
diff --git a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C
index 627414b9e4e29d61925f598373c7eeedf5608738..d56aa1e71af45f896ab1777bfadacb3dd4a7aa1e 100644
--- a/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C
+++ b/src/postProcessing/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransformTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -67,7 +67,7 @@ void Foam::fieldCoordinateSystemTransform::transformField
 
     Foam::transform(transField, R, transField);
 
-    Info<< "    writing field " << transField.name() << nl << endl;
+    if (log_) Info<< "    writing field " << transField.name() << nl << endl;
 
     transField.write();
 }
diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C
index 6e8db76804f50f5a30e76cfe9b231f4525e9d69b..a255ed8b188f118c91e30eb5d179bae101eca648 100644
--- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C
+++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C
@@ -144,14 +144,12 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict)
 
     volume_ = volume();
 
-    if (log_)
-    {
-        Info<< type() << " " << name_ << ":"
-            << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
-            << "    total cells  = " << nCells_ << nl
-            << "    total volume = " << volume_
-            << nl << endl;
-    }
+    if (log_) Info
+        << type() << " " << name_ << ":"
+        << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
+        << "    total cells  = " << nCells_ << nl
+        << "    total volume = " << volume_
+        << nl << endl;
 
     if (dict.readIfPresent("weightField", weightFieldName_))
     {
diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C
index f6f67d55e620a50efc74afb2680fed7c3879183b..28102fc892c026d86f9714bd52dddc137c60db03 100644
--- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C
+++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C
@@ -217,12 +217,10 @@ bool Foam::fieldValues::cellSource::writeValues
 
         file()<< tab << result;
 
-        if (log_)
-        {
-            Info<< "    " << operationTypeNames_[operation_]
-                << "(" << sourceName_ << ") of " << fieldName
-                <<  " = " << result << endl;
-        }
+        if (log_) Info
+            << "    " << operationTypeNames_[operation_]
+            << "(" << sourceName_ << ") of " << fieldName
+            <<  " = " << result << endl;
 
         // write state/results information
         const word& opName = operationTypeNames_[operation_];
diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C
index 1598eb881fac32047c25c10567bdf8711e075722..504f4a7d1585ca907a66a2ff81edd42b4c4616cd 100644
--- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C
+++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C
@@ -366,12 +366,10 @@ bool Foam::fieldValues::faceSource::writeValues
 
         file()<< tab << result;
 
-        if (log_)
-        {
-            Info<< "    " << operationTypeNames_[operation_]
-                << "(" << sourceName_ << ") for " << fieldName
-                <<  " = " << result << endl;
-        }
+        if (log_) Info
+            << "    " << operationTypeNames_[operation_]
+            << "(" << sourceName_ << ") for " << fieldName
+            <<  " = " << result << endl;
 
         // Write state/results information
         const word& opName = operationTypeNames_[operation_];
diff --git a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H
index 014313b2aad3129775db79822811d97135206752..9fcfa0ccee4bb7ac709a8711dc228928fcddb500 100644
--- a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H
+++ b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFields.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -55,9 +55,10 @@ Description
     \table
         Property | Description               | Required    | Default value
         type     | type name: nearWallFields | yes         |
-        fields   | list of fields with correspoding output field names | yes |
+        fields   | list of fields with corresponding output field names | yes |
         patches  | list of patches to sample | yes         |
         distance | distance from patch to sample | yes     |
+        log      | Log to standard output    | no          | yes
     \endtable
 
 SeeAlso
@@ -111,6 +112,9 @@ protected:
             //- Fields to process
             List<Tuple2<word, word> > fieldSet_;
 
+            //- Switch to send output to Info as well as to file
+            Switch log_;
+
             //- Patches to sample
             labelHashSet patchSet_;
 
diff --git a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C
index 42b1b2abef16bae5e1b093897e786a1f584f2e1d..ab7fe8878727dafaf1568f9c6abacf6f0171508e 100644
--- a/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C
+++ b/src/postProcessing/functionObjects/field/nearWallFields/nearWallFieldsTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -47,8 +47,15 @@ void Foam::nearWallFields::createFields
 
             if (obr_.found(sampleFldName))
             {
-                Info<< "    a field " << sampleFldName
-                    << " already exists on the mesh."
+                WarningIn
+                (
+                    "void Foam::nearWallFields::createFields"
+                    "("
+                        "PtrList<GeometricField<Type, fvPatchField, volMesh> >&"
+                    ") const"
+                )
+                    << "    a field named " << sampleFldName
+                    << " already exists on the mesh"
                     << endl;
             }
             else
@@ -63,7 +70,8 @@ void Foam::nearWallFields::createFields
 
                 sflds.set(sz, new vfType(io, fld));
 
-                Info<< "    created " << sflds[sz].name() << " to sample "
+                if (log_) Info
+                    << "    created " << sflds[sz].name() << " to sample "
                     << fld.name() << endl;
             }
         }
diff --git a/src/postProcessing/functionObjects/field/processorField/processorField.C b/src/postProcessing/functionObjects/field/processorField/processorField.C
index a57ee9a293026fa8c7ed30f13ebc12e716911192..73b7a89978739f76495b8f4d593307bbaf131722 100644
--- a/src/postProcessing/functionObjects/field/processorField/processorField.C
+++ b/src/postProcessing/functionObjects/field/processorField/processorField.C
@@ -47,7 +47,9 @@ Foam::processorField::processorField
 :
     name_(name),
     obr_(obr),
-    active_(true)
+    active_(true),
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
     if (isA<fvMesh>(obr_))
@@ -62,7 +64,7 @@ Foam::processorField::processorField
             (
                 IOobject
                 (
-                    "processorID",
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -103,7 +105,10 @@ Foam::processorField::~processorField()
 
 void Foam::processorField::read(const dictionary& dict)
 {
-    // do nothing
+    if (active_)
+    {
+        log_.readIfPresent("log", dict);
+    }
 }
 
 
@@ -112,7 +117,7 @@ void Foam::processorField::execute()
     if (active_)
     {
         const volScalarField& procField =
-            obr_.lookupObject<volScalarField>("processorID");
+            obr_.lookupObject<volScalarField>(resultName_);
 
         const_cast<volScalarField&>(procField) ==
             dimensionedScalar("procI", dimless, Pstream::myProcNo());
@@ -140,7 +145,12 @@ void Foam::processorField::write()
     if (active_)
     {
         const volScalarField& procField =
-            obr_.lookupObject<volScalarField>("processorID");
+            obr_.lookupObject<volScalarField>(resultName_);
+
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    writing field " << procField.name() << nl
+            << endl;
 
         procField.write();
     }
diff --git a/src/postProcessing/functionObjects/field/processorField/processorField.H b/src/postProcessing/functionObjects/field/processorField/processorField.H
index 6d45e32acbc71c49f9333617f30dd63a808e111a..560c302e92cc4e355881bb68a45205a631e1f101 100644
--- a/src/postProcessing/functionObjects/field/processorField/processorField.H
+++ b/src/postProcessing/functionObjects/field/processorField/processorField.H
@@ -45,6 +45,7 @@ Description
     \table
         Property     | Description             | Required    | Default value
         type         | type name: processorField | yes       |
+        log          | Log to standard output  | no          | yes
     \endtable
 
 SeeAlso
@@ -95,6 +96,12 @@ protected:
         //- on/off switch
         bool active_;
 
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Protected Member Functions
 
diff --git a/src/postProcessing/functionObjects/field/readFields/readFields.C b/src/postProcessing/functionObjects/field/readFields/readFields.C
index 869f46beb013da8a1b89a0b2f4e638e516fd97a6..6bac8da6d49f2baf2ec3a9e73eb9a524339eb544 100644
--- a/src/postProcessing/functionObjects/field/readFields/readFields.C
+++ b/src/postProcessing/functionObjects/field/readFields/readFields.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -47,7 +47,8 @@ Foam::readFields::readFields
     name_(name),
     obr_(obr),
     active_(true),
-    fieldSet_()
+    fieldSet_(),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
     if (isA<fvMesh>(obr_))
@@ -84,6 +85,7 @@ void Foam::readFields::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
         dict.lookup("fields") >> fieldSet_;
     }
 }
@@ -93,29 +95,16 @@ void Foam::readFields::execute()
 {
     if (active_)
     {
-        // Clear out any previously loaded fields
-        vsf_.clear();
-        vvf_.clear();
-        vSpheretf_.clear();
-        vSymmtf_.clear();
-        vtf_.clear();
-
-        ssf_.clear();
-        svf_.clear();
-        sSpheretf_.clear();
-        sSymmtf_.clear();
-        stf_.clear();
-
         forAll(fieldSet_, fieldI)
         {
             const word& fieldName = fieldSet_[fieldI];
 
             // If necessary load field
-            loadField<scalar>(fieldName, vsf_, ssf_);
-            loadField<vector>(fieldName, vvf_, svf_);
-            loadField<sphericalTensor>(fieldName, vSpheretf_, sSpheretf_);
-            loadField<symmTensor>(fieldName, vSymmtf_, sSymmtf_);
-            loadField<tensor>(fieldName, vtf_, stf_);
+            loadField<scalar>(fieldName);
+            loadField<vector>(fieldName);
+            loadField<sphericalTensor>(fieldName);
+            loadField<symmTensor>(fieldName);
+            loadField<tensor>(fieldName);
         }
     }
 }
diff --git a/src/postProcessing/functionObjects/field/readFields/readFields.H b/src/postProcessing/functionObjects/field/readFields/readFields.H
index bf13dac4e4fb388167c06c342b99ed5b973c134e..be1d012783d42ec3cdafa81dbc1b344e0b7cd0a6 100644
--- a/src/postProcessing/functionObjects/field/readFields/readFields.H
+++ b/src/postProcessing/functionObjects/field/readFields/readFields.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,8 +28,8 @@ Group
     grpFieldFunctionObjects
 
 Description
-    This function object reads fields from the time directories and adds them to
-    the mesh database for further post-processing.
+    This function object reads fields from the time directories and adds them
+    to the mesh database for further post-processing.
 
     Example of function object specification:
     \verbatim
@@ -38,11 +38,7 @@ Description
         type        readFields;
         functionObjectLibs ("libfieldFunctionObjects.so");
         ...
-        fields
-        (
-            U
-            p
-        );
+        fields      (U p);
     }
     \endverbatim
 
@@ -51,6 +47,7 @@ Description
         Property     | Description             | Required    | Default value
         type         | type name: readFields   | yes         |
         fields       | list of fields to read  |  no         |
+        log          | Log to standard output  | no          | yes
     \endtable
 
 SeeAlso
@@ -102,18 +99,8 @@ protected:
         //- Fields to load
         wordList fieldSet_;
 
-        //- Loaded fields
-        PtrList<volScalarField> vsf_;
-        PtrList<volVectorField> vvf_;
-        PtrList<volSphericalTensorField> vSpheretf_;
-        PtrList<volSymmTensorField> vSymmtf_;
-        PtrList<volTensorField> vtf_;
-
-        PtrList<surfaceScalarField> ssf_;
-        PtrList<surfaceVectorField> svf_;
-        PtrList<surfaceSphericalTensorField> sSpheretf_;
-        PtrList<surfaceSymmTensorField> sSymmtf_;
-        PtrList<surfaceTensorField> stf_;
+        //- Switch to send output to Info as well as to file
+        Switch log_;
 
 
     // Protected Member Functions
@@ -125,12 +112,7 @@ protected:
         void operator=(const readFields&);
 
         template<class Type>
-        void loadField
-        (
-            const word&,
-            PtrList<GeometricField<Type, fvPatchField, volMesh> >&,
-            PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >&
-        ) const;
+        void loadField(const word&) const;
 
 
 public:
diff --git a/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C b/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C
index 0d7a89bc003f767c358dd152ed482f4bf8379037..57973a1da62a635ef3a4c9a7f09573d0fe7c015c 100644
--- a/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C
+++ b/src/postProcessing/functionObjects/field/readFields/readFieldsTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,12 +31,7 @@ License
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::readFields::loadField
-(
-    const word& fieldName,
-    PtrList<GeometricField<Type, fvPatchField, volMesh> >& vflds,
-    PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& sflds
-) const
+void Foam::readFields::loadField(const word& fieldName) const
 {
     typedef GeometricField<Type, fvPatchField, volMesh> vfType;
     typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfType;
@@ -45,7 +40,8 @@ void Foam::readFields::loadField
     {
         if (debug)
         {
-            Info<< "readFields : Field " << fieldName << " already in database"
+            Info<< "readFields: " << vfType::typeName << " "
+                << fieldName << " already exists in database"
                 << endl;
         }
     }
@@ -53,7 +49,8 @@ void Foam::readFields::loadField
     {
         if (debug)
         {
-            Info<< "readFields : Field " << fieldName << " already in database"
+            Info<< "readFields: " << sfType::typeName << " "
+                << fieldName << " already exists in database"
                 << endl;
         }
     }
@@ -76,11 +73,10 @@ void Foam::readFields::loadField
          && fieldHeader.headerClassName() == vfType::typeName
         )
         {
-            // store field locally
-            Info<< "    Reading " << fieldName << endl;
-            label sz = vflds.size();
-            vflds.setSize(sz+1);
-            vflds.set(sz, new vfType(fieldHeader, mesh));
+            // Store field on mesh database
+            if (log_) Info<< "    Reading " << fieldName << endl;
+            vfType* vfPtr = new vfType(fieldHeader, mesh);
+            mesh.objectRegistry::store(vfPtr);
         }
         else if
         (
@@ -88,11 +84,10 @@ void Foam::readFields::loadField
          && fieldHeader.headerClassName() == sfType::typeName
         )
         {
-            // store field locally
-            Info<< "    Reading " << fieldName << endl;
-            label sz = sflds.size();
-            sflds.setSize(sz+1);
-            sflds.set(sz, new sfType(fieldHeader, mesh));
+            // Store field on mesh database
+            if (log_) Info<< "    Reading " << fieldName << endl;
+            sfType* sfPtr = new sfType(fieldHeader, mesh);
+            mesh.objectRegistry::store(sfPtr);
         }
     }
 }
diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
index 809d1d35b225f94a35024e3d8826c7d90d958caa..b71b0b44abd97e8cedd3009f2853231f65458590 100644
--- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
+++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
@@ -72,11 +72,9 @@ void Foam::regionSizeDistribution::writeGraph
 
     OFstream str(outputPath/formatterPtr_().getFileName(coords, valNames));
 
-    if (log_)
-    {
-        Info<< "Writing distribution of " << valueName << " to " << str.name()
-            << endl;
-    }
+    if (log_) Info
+        << "Writing distribution of " << valueName << " to " << str.name()
+        << endl;
 
     List<const scalarField*> valPtrs(1);
     valPtrs[0] = &values;
@@ -162,16 +160,12 @@ void Foam::regionSizeDistribution::writeAlphaFields
             << endl;
     }
 
-    if (log_)
-    {
-        Info<< "Writing liquid-core field to " << liquidCore.name() << endl;
-    }
+    if (log_) Info
+        << "Writing liquid-core field to " << liquidCore.name() << endl;
     liquidCore.write();
 
-    if (log_)
-    {
-        Info<< "Writing background field to " << backgroundAlpha.name() << endl;
-    }
+    if (log_) Info
+        << "Writing background field to " << backgroundAlpha.name() << endl;
     backgroundAlpha.write();
 }
 
@@ -398,11 +392,9 @@ void Foam::regionSizeDistribution::read(const dictionary& dict)
         {
             coordSysPtr_.reset(new coordinateSystem(obr_, dict));
 
-            if (log_)
-            {
-                Info<< "Transforming all vectorFields with coordinate system "
-                    << coordSysPtr_().name() << endl;
-            }
+            if (log_) Info
+                << "Transforming all vectorFields with coordinate system "
+                << coordSysPtr_().name() << endl;
         }
     }
 }
@@ -467,24 +459,20 @@ void Foam::regionSizeDistribution::write()
            : obr_.lookupObject<volScalarField>(alphaName_)
         );
 
-        if (log_)
-        {
-            Info<< "    Volume of alpha          = "
-                << fvc::domainIntegrate(alpha).value()
-                << endl;
-        }
+        if (log_) Info
+            << "    Volume of alpha          = "
+            << fvc::domainIntegrate(alpha).value()
+            << endl;
 
         const scalar meshVol = gSum(mesh.V());
         const scalar maxDropletVol = 1.0/6.0*pow(maxDiam_, 3);
         const scalar delta = (maxDiam_-minDiam_)/nBins_;
 
-        if (log_)
-        {
-            Info<< "    Mesh volume              = " << meshVol << nl
-                << "    Maximum droplet diameter = " << maxDiam_ << nl
-                << "    Maximum droplet volume   = " << maxDropletVol
-                << endl;
-        }
+        if (log_) Info
+            << "    Mesh volume              = " << meshVol << nl
+            << "    Maximum droplet diameter = " << maxDiam_ << nl
+            << "    Maximum droplet volume   = " << maxDropletVol
+            << endl;
 
 
         // Determine blocked faces
@@ -543,11 +531,9 @@ void Foam::regionSizeDistribution::write()
 
         regionSplit regions(mesh, blockedFace);
 
-        if (log_)
-        {
-            Info<< "    Determined " << regions.nRegions()
-                << " disconnected regions" << endl;
-        }
+        if (log_) Info
+            << "    Determined " << regions.nRegions()
+            << " disconnected regions" << endl;
 
 
         if (debug)
@@ -566,12 +552,9 @@ void Foam::regionSizeDistribution::write()
                 dimensionedScalar("zero", dimless, 0)
             );
 
-            if (log_)
-            {
-                Info<< "    Dumping region as " << volScalarField::typeName
-                    << " to " << region.name()
-                    << endl;
-            }
+            if (log_) Info
+                << "    Dumping region as " << volScalarField::typeName
+                << " to " << region.name() << endl;
 
             forAll(regions, cellI)
             {
@@ -602,14 +585,12 @@ void Foam::regionSizeDistribution::write()
 
         if (debug)
         {
-            if (log_)
-            {
-                Info<< "    " << token::TAB << "Region"
-                    << token::TAB << "Volume(mesh)"
-                    << token::TAB << "Volume(" << alpha.name() << "):"
-                    << token::TAB << "nCells"
-                    << endl;
-            }
+            if (log_) Info
+                << "    " << token::TAB << "Region"
+                << token::TAB << "Volume(mesh)"
+                << token::TAB << "Volume(" << alpha.name() << "):"
+                << token::TAB << "nCells"
+                << endl;
 
             scalar meshSumVol = 0.0;
             scalar alphaSumVol = 0.0;
@@ -626,28 +607,24 @@ void Foam::regionSizeDistribution::write()
                 ++vIter, ++aIter, ++numIter
             )
             {
-                if (log_)
-                {
-                    Info<< "    " << token::TAB << vIter.key()
-                        << token::TAB << vIter()
-                        << token::TAB << aIter()
-                        << token::TAB << numIter()
-                        << endl;
-                }
+                if (log_) Info
+                    << "    " << token::TAB << vIter.key()
+                    << token::TAB << vIter()
+                    << token::TAB << aIter()
+                    << token::TAB << numIter()
+                    << endl;
 
                 meshSumVol += vIter();
                 alphaSumVol += aIter();
                 nCells += numIter();
             }
 
-            if (log_)
-            {
-                Info<< "    " << token::TAB << "Total:"
-                    << token::TAB << meshSumVol
-                    << token::TAB << alphaSumVol
-                    << token::TAB << nCells
-                    << nl << endl;
-            }
+            if (log_) Info
+                << "    " << token::TAB << "Total:"
+                << token::TAB << meshSumVol
+                << token::TAB << alphaSumVol
+                << token::TAB << nCells
+                << nl << endl;
         }
 
 
@@ -876,13 +853,10 @@ void Foam::regionSizeDistribution::write()
 
                     if (coordSysPtr_.valid())
                     {
-                        if (log_)
-                        {
-                            Info<< "Transforming vector field " << fldName
-                                << " with coordinate system "
-                                << coordSysPtr_().name()
-                                << endl;
-                        }
+                        if (log_) Info
+                            << "Transforming vector field " << fldName
+                            << " with coordinate system "
+                            << coordSysPtr_().name() << endl;
 
                         fld = coordSysPtr_().localVector(fld);
                     }
diff --git a/src/postProcessing/functionObjects/field/streamLine/controlDict b/src/postProcessing/functionObjects/field/streamLine/controlDict
index 4f4ccd80551ad503b844c0e30666e2b0a10179f1..1b6f1c829fe11fe97506191f8034cd3c2a501bc8 100644
--- a/src/postProcessing/functionObjects/field/streamLine/controlDict
+++ b/src/postProcessing/functionObjects/field/streamLine/controlDict
@@ -84,6 +84,10 @@ functions
             // subcycling.
             nSubCycle 5;
 
+
+        // Optional clipping
+        //bounds  (0.2 -10 -10)(0.22 10 10);
+
         // Cloud name to use
         cloudName       particleTracks;
 
diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLine.C b/src/postProcessing/functionObjects/field/streamLine/streamLine.C
index bd360cada69fcbfe606136d4ad010f3f8a4b3e9f..1015b61887e8eeeaefc60fadecbfeb695d9e7088 100644
--- a/src/postProcessing/functionObjects/field/streamLine/streamLine.C
+++ b/src/postProcessing/functionObjects/field/streamLine/streamLine.C
@@ -23,18 +23,10 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "Pstream.H"
-#include "functionObjectList.H"
 #include "streamLine.H"
 #include "fvMesh.H"
 #include "streamLineParticleCloud.H"
-#include "ReadFields.H"
-#include "meshSearch.H"
 #include "sampledSet.H"
-#include "globalIndex.H"
-#include "mapDistribute.H"
-#include "interpolationCellPoint.H"
-#include "PatchTools.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -46,60 +38,8 @@ defineTypeNameAndDebug(streamLine, 0);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::autoPtr<Foam::indirectPrimitivePatch>
-Foam::streamLine::wallPatch() const
-{
-    const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    label nFaces = 0;
-
-    forAll(patches, patchI)
-    {
-        //if (!polyPatch::constraintType(patches[patchI].type()))
-        if (isA<wallPolyPatch>(patches[patchI]))
-        {
-            nFaces += patches[patchI].size();
-        }
-    }
-
-    labelList addressing(nFaces);
-
-    nFaces = 0;
-
-    forAll(patches, patchI)
-    {
-        //if (!polyPatch::constraintType(patches[patchI].type()))
-        if (isA<wallPolyPatch>(patches[patchI]))
-        {
-            const polyPatch& pp = patches[patchI];
-
-            forAll(pp, i)
-            {
-                addressing[nFaces++] = pp.start()+i;
-            }
-        }
-    }
-
-    return autoPtr<indirectPrimitivePatch>
-    (
-        new indirectPrimitivePatch
-        (
-            IndirectList<face>
-            (
-                mesh.faces(),
-                addressing
-            ),
-            mesh.points()
-        )
-    );
-}
-
-
 void Foam::streamLine::track()
 {
-    const Time& runTime = obr_.time();
     const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
 
     IDLList<streamLineParticle> initialParticles;
@@ -128,173 +68,26 @@ void Foam::streamLine::track()
 
     label nSeeds = returnReduce(particles.size(), sumOp<label>());
 
-    Info << "    seeded " << nSeeds << " particles" << endl;
+    if (log_) Info<< "    seeded " << nSeeds << " particles" << endl;
 
     // Read or lookup fields
     PtrList<volScalarField> vsFlds;
     PtrList<interpolation<scalar> > vsInterp;
     PtrList<volVectorField> vvFlds;
     PtrList<interpolation<vector> > vvInterp;
-
     label UIndex = -1;
 
-    if (loadFromFiles_)
-    {
-        IOobjectList allObjects(mesh, runTime.timeName());
-
-        IOobjectList objects(2*fields_.size());
-        forAll(fields_, i)
-        {
-            objects.add(*allObjects[fields_[i]]);
-        }
-
-        ReadFields(mesh, objects, vsFlds);
-        vsInterp.setSize(vsFlds.size());
-        forAll(vsFlds, i)
-        {
-            vsInterp.set
-            (
-                i,
-                interpolation<scalar>::New
-                (
-                    interpolationScheme_,
-                    vsFlds[i]
-                )
-            );
-        }
-        ReadFields(mesh, objects, vvFlds);
-        vvInterp.setSize(vvFlds.size());
-        forAll(vvFlds, i)
-        {
-            vvInterp.set
-            (
-                i,
-                interpolation<vector>::New
-                (
-                    interpolationScheme_,
-                    vvFlds[i]
-                )
-            );
-        }
-    }
-    else
-    {
-        label nScalar = 0;
-        label nVector = 0;
-
-        forAll(fields_, i)
-        {
-            if (mesh.foundObject<volScalarField>(fields_[i]))
-            {
-                nScalar++;
-            }
-            else if (mesh.foundObject<volVectorField>(fields_[i]))
-            {
-                nVector++;
-            }
-            else
-            {
-                FatalErrorIn("streamLine::track()")
-                    << "Cannot find field " << fields_[i] << nl
-                    << "Valid scalar fields are:"
-                    << mesh.names(volScalarField::typeName) << nl
-                    << "Valid vector fields are:"
-                    << mesh.names(volVectorField::typeName)
-                    << exit(FatalError);
-            }
-        }
-        vsInterp.setSize(nScalar);
-        nScalar = 0;
-        vvInterp.setSize(nVector);
-        nVector = 0;
-
-        forAll(fields_, i)
-        {
-            if (mesh.foundObject<volScalarField>(fields_[i]))
-            {
-                const volScalarField& f = mesh.lookupObject<volScalarField>
-                (
-                    fields_[i]
-                );
-                vsInterp.set
-                (
-                    nScalar++,
-                    interpolation<scalar>::New
-                    (
-                        interpolationScheme_,
-                        f
-                    )
-                );
-            }
-            else if (mesh.foundObject<volVectorField>(fields_[i]))
-            {
-                const volVectorField& f = mesh.lookupObject<volVectorField>
-                (
-                    fields_[i]
-                );
-
-                if (f.name() == UName_)
-                {
-                    UIndex = nVector;
-                }
-
-                vvInterp.set
-                (
-                    nVector++,
-                    interpolation<vector>::New
-                    (
-                        interpolationScheme_,
-                        f
-                    )
-                );
-            }
-        }
-    }
-
-    // Store the names
-    scalarNames_.setSize(vsInterp.size());
-    forAll(vsInterp, i)
-    {
-        scalarNames_[i] = vsInterp[i].psi().name();
-    }
-    vectorNames_.setSize(vvInterp.size());
-    forAll(vvInterp, i)
-    {
-        vectorNames_[i] = vvInterp[i].psi().name();
-    }
-
-    // Check that we know the index of U in the interpolators.
-
-    if (UIndex == -1)
-    {
-        FatalErrorIn("streamLine::track()")
-            << "Cannot find field to move particles with : " << UName_ << nl
-            << "This field has to be present in the sampled fields " << fields_
-            << " and in the objectRegistry."
-            << exit(FatalError);
-    }
-
-    // Sampled data
-    // ~~~~~~~~~~~~
-
-    // Size to maximum expected sizes.
-    allTracks_.clear();
-    allTracks_.setCapacity(nSeeds);
-    allScalars_.setSize(vsInterp.size());
-    forAll(allScalars_, i)
-    {
-        allScalars_[i].clear();
-        allScalars_[i].setCapacity(nSeeds);
-    }
-    allVectors_.setSize(vvInterp.size());
-    forAll(allVectors_, i)
-    {
-        allVectors_[i].clear();
-        allVectors_[i].setCapacity(nSeeds);
-    }
-
+    initInterpolations
+    (
+        nSeeds,
+        UIndex,
+        vsFlds,
+        vsInterp,
+        vvFlds,
+        vvInterp
+    );
 
-    // additional particle info
+    // Additional particle info
     streamLineParticle::trackingData td
     (
         particles,
@@ -330,33 +123,13 @@ Foam::streamLine::streamLine
     const bool loadFromFiles
 )
 :
-    dict_(dict),
-    name_(name),
-    obr_(obr),
-    loadFromFiles_(loadFromFiles),
-    active_(true),
-    nSubCycle_(0)
+    streamLineBase(name, obr, dict, loadFromFiles)
 {
-    // Only active if a fvMesh is available
-    if (isA<fvMesh>(obr_))
+    // Check if the available mesh is an fvMesh otherise deactivate
+    if (setActive<fvMesh>())
     {
         read(dict_);
     }
-    else
-    {
-        active_ = false;
-        WarningIn
-        (
-            "streamLine::streamLine\n"
-            "(\n"
-                "const word&,\n"
-                "const objectRegistry&,\n"
-                "const dictionary&,\n"
-                "const bool\n"
-            ")"
-        )   << "No fvMesh available, deactivating."
-            << nl << endl;
-    }
 }
 
 
@@ -372,45 +145,7 @@ void Foam::streamLine::read(const dictionary& dict)
 {
     if (active_)
     {
-        Info<< type() << " " << name_ << ":" << nl;
-
-        //dict_ = dict;
-        dict.lookup("fields") >> fields_;
-        if (dict.found("UName"))
-        {
-            dict.lookup("UName") >> UName_;
-        }
-        else
-        {
-            UName_ = "U";
-            if (dict.found("U"))
-            {
-                IOWarningIn("streamLine::read(const dictionary&)", dict)
-                    << "Using deprecated entry \"U\"."
-                    << " Please use \"UName\" instead."
-                    << endl;
-                dict.lookup("U") >> UName_;
-            }
-        }
-
-        if (findIndex(fields_, UName_) == -1)
-        {
-            FatalIOErrorIn("streamLine::read(const dictionary&)", dict)
-                << "Velocity field for tracking " << UName_
-                << " should be present in the list of fields " << fields_
-                << exit(FatalIOError);
-        }
-
-
-        dict.lookup("trackForward") >> trackForward_;
-        dict.lookup("lifeTime") >> lifeTime_;
-        if (lifeTime_ < 1)
-        {
-            FatalErrorIn(":streamLine::read(const dictionary&)")
-                << "Illegal value " << lifeTime_ << " for lifeTime"
-                << exit(FatalError);
-        }
-
+        streamLineBase::read(dict);
 
         bool subCycling = dict.found("nSubCycle");
         bool fixedLength = dict.found("trackLength");
@@ -424,7 +159,6 @@ void Foam::streamLine::read(const dictionary& dict)
                 << exit(FatalIOError);
         }
 
-
         nSubCycle_ = 1;
         if (dict.readIfPresent("nSubCycle", nSubCycle_))
         {
@@ -433,361 +167,14 @@ void Foam::streamLine::read(const dictionary& dict)
             {
                 nSubCycle_ = 1;
             }
-            Info<< "    automatic track length specified through"
-                << " number of sub cycles : " << nSubCycle_ << nl << endl;
-        }
-        else
-        {
-            dict.lookup("trackLength") >> trackLength_;
 
-            Info<< "    fixed track length specified : "
-                << trackLength_ << nl << endl;
+            if (log_) Info
+                << "    automatic track length specified through"
+                << " number of sub cycles : " << nSubCycle_ << nl
+                << endl;
         }
-
-
-        interpolationScheme_ = dict.lookupOrDefault
-        (
-            "interpolationScheme",
-            interpolationCellPoint<scalar>::typeName
-        );
-
-        //Info<< "    using interpolation " << interpolationScheme_
-        //    << endl;
-
-        cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
-        dict.lookup("seedSampleSet") >> seedSet_;
-
-        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-        meshSearchPtr_.reset(new meshSearch(mesh));
-
-        const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
-        sampledSetPtr_ = sampledSet::New
-        (
-            seedSet_,
-            mesh,
-            meshSearchPtr_(),
-            coeffsDict
-        );
-        coeffsDict.lookup("axis") >> sampledSetAxis_;
-
-        scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat"));
-        vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat"));
     }
 }
 
 
-void Foam::streamLine::execute()
-{
-//    const Time& runTime = obr_.time();
-//    Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
-//
-//    bool isOutputTime = false;
-//
-//    const functionObjectList& fobs = runTime.functionObjects();
-//
-//    forAll(fobs, i)
-//    {
-//        if (isA<streamLineFunctionObject>(fobs[i]))
-//        {
-//            const streamLineFunctionObject& fo =
-//                dynamic_cast<const streamLineFunctionObject&>(fobs[i]);
-//
-//            if (fo.name() == name_)
-//            {
-//                Pout<< "found me:" << i << endl;
-//                if (fo.outputControl().output())
-//                {
-//                    isOutputTime = true;
-//                    break;
-//                }
-//            }
-//        }
-//    }
-//
-//
-//    if (active_ && isOutputTime)
-//    {
-//        track();
-//    }
-}
-
-
-void Foam::streamLine::end()
-{}
-
-
-void Foam::streamLine::timeSet()
-{}
-
-
-void Foam::streamLine::write()
-{
-    if (active_)
-    {
-        Info<< type() << " " << name_ << " output:" << nl;
-
-        const Time& runTime = obr_.time();
-        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-
-        // Do all injection and tracking
-        track();
-
-
-        if (Pstream::parRun())
-        {
-            // Append slave tracks to master ones
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            globalIndex globalTrackIDs(allTracks_.size());
-
-            // Construct a distribution map to pull all to the master.
-            labelListList sendMap(Pstream::nProcs());
-            labelListList recvMap(Pstream::nProcs());
-
-            if (Pstream::master())
-            {
-                // Master: receive all. My own first, then consecutive
-                // processors.
-                label trackI = 0;
-
-                forAll(recvMap, procI)
-                {
-                    labelList& fromProc = recvMap[procI];
-                    fromProc.setSize(globalTrackIDs.localSize(procI));
-                    forAll(fromProc, i)
-                    {
-                        fromProc[i] = trackI++;
-                    }
-                }
-            }
-
-            labelList& toMaster = sendMap[0];
-            toMaster.setSize(globalTrackIDs.localSize());
-            forAll(toMaster, i)
-            {
-                toMaster[i] = i;
-            }
-
-            const mapDistribute distMap
-            (
-                globalTrackIDs.size(),
-                sendMap.xfer(),
-                recvMap.xfer()
-            );
-
-
-            // Distribute the track positions. Note: use scheduled comms
-            // to prevent buffering.
-            allTracks_.shrink();
-            mapDistributeBase::distribute
-            (
-                Pstream::scheduled,
-                distMap.schedule(),
-                distMap.constructSize(),
-                distMap.subMap(),
-                false,
-                distMap.constructMap(),
-                false,
-                allTracks_,
-                flipOp()
-            );
-
-            // Distribute the scalars
-            forAll(allScalars_, scalarI)
-            {
-                allScalars_[scalarI].shrink();
-                mapDistributeBase::distribute
-                (
-                    Pstream::scheduled,
-                    distMap.schedule(),
-                    distMap.constructSize(),
-                    distMap.subMap(),
-                    false,
-                    distMap.constructMap(),
-                    false,
-                    allScalars_[scalarI],
-                    flipOp()
-                );
-                allScalars_[scalarI].setCapacity(allScalars_[scalarI].size());
-            }
-            // Distribute the vectors
-            forAll(allVectors_, vectorI)
-            {
-                allVectors_[vectorI].shrink();
-                mapDistributeBase::distribute
-                (
-                    Pstream::scheduled,
-                    distMap.schedule(),
-                    distMap.constructSize(),
-                    distMap.subMap(),
-                    false,
-                    distMap.constructMap(),
-                    false,
-                    allVectors_[vectorI],
-                    flipOp()
-                );
-                allVectors_[vectorI].setCapacity(allVectors_[vectorI].size());
-            }
-        }
-
-
-        label n = 0;
-        forAll(allTracks_, trackI)
-        {
-            n += allTracks_[trackI].size();
-        }
-
-        Info<< "    Tracks:" << allTracks_.size() << nl
-            << "    Total samples:" << n
-            << endl;
-
-
-        // Massage into form suitable for writers
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        if (Pstream::master() && allTracks_.size())
-        {
-            // Make output directory
-
-            fileName vtkPath
-            (
-                Pstream::parRun()
-              ? runTime.path()/".."/"postProcessing"/"sets"/name()
-              : runTime.path()/"postProcessing"/"sets"/name()
-            );
-            if (mesh.name() != fvMesh::defaultRegion)
-            {
-                vtkPath = vtkPath/mesh.name();
-            }
-            vtkPath = vtkPath/mesh.time().timeName();
-
-            mkDir(vtkPath);
-
-            // Convert track positions
-
-            PtrList<coordSet> tracks(allTracks_.size());
-            forAll(allTracks_, trackI)
-            {
-                tracks.set
-                (
-                    trackI,
-                    new coordSet
-                    (
-                        "track" + Foam::name(trackI),
-                        sampledSetAxis_                 //"xyz"
-                    )
-                );
-                tracks[trackI].transfer(allTracks_[trackI]);
-            }
-
-            // Convert scalar values
-
-            if (allScalars_.size() > 0)
-            {
-                List<List<scalarField> > scalarValues(allScalars_.size());
-
-                forAll(allScalars_, scalarI)
-                {
-                    DynamicList<scalarList>& allTrackVals =
-                        allScalars_[scalarI];
-                    scalarValues[scalarI].setSize(allTrackVals.size());
-
-                    forAll(allTrackVals, trackI)
-                    {
-                        scalarList& trackVals = allTrackVals[trackI];
-                        scalarValues[scalarI][trackI].transfer(trackVals);
-                    }
-                }
-
-                fileName vtkFile
-                (
-                    vtkPath
-                  / scalarFormatterPtr_().getFileName
-                    (
-                        tracks[0],
-                        scalarNames_
-                    )
-                );
-
-                Info<< "    Writing data to " << vtkFile.path() << endl;
-
-                scalarFormatterPtr_().write
-                (
-                    true,           // writeTracks
-                    tracks,
-                    scalarNames_,
-                    scalarValues,
-                    OFstream(vtkFile)()
-                );
-            }
-
-            // Convert vector values
-
-            if (allVectors_.size() > 0)
-            {
-                List<List<vectorField> > vectorValues(allVectors_.size());
-
-                forAll(allVectors_, vectorI)
-                {
-                    DynamicList<vectorList>& allTrackVals =
-                        allVectors_[vectorI];
-                    vectorValues[vectorI].setSize(allTrackVals.size());
-
-                    forAll(allTrackVals, trackI)
-                    {
-                        vectorList& trackVals = allTrackVals[trackI];
-                        vectorValues[vectorI][trackI].transfer(trackVals);
-                    }
-                }
-
-                fileName vtkFile
-                (
-                    vtkPath
-                  / vectorFormatterPtr_().getFileName
-                    (
-                        tracks[0],
-                        vectorNames_
-                    )
-                );
-
-                //Info<< "    Writing vector data to " << vtkFile << endl;
-
-                vectorFormatterPtr_().write
-                (
-                    true,           // writeTracks
-                    tracks,
-                    vectorNames_,
-                    vectorValues,
-                    OFstream(vtkFile)()
-                );
-            }
-        }
-    }
-}
-
-
-void Foam::streamLine::updateMesh(const mapPolyMesh&)
-{
-    read(dict_);
-}
-
-
-void Foam::streamLine::movePoints(const polyMesh&)
-{
-    // Moving mesh affects the search tree
-    read(dict_);
-}
-
-
-//void Foam::streamLine::readUpdate(const polyMesh::readUpdateState state)
-//{
-//    if (state != UNCHANGED)
-//    {
-//        read(dict_);
-//    }
-//}
-
-
 // ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLine.H b/src/postProcessing/functionObjects/field/streamLine/streamLine.H
index 59d9d9026e0e8e90d94abda60171904661af8611..d1f319b490b7850b9ef225643f07d2a1403f1e7f 100644
--- a/src/postProcessing/functionObjects/field/streamLine/streamLine.H
+++ b/src/postProcessing/functionObjects/field/streamLine/streamLine.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,6 +50,7 @@ Description
         lifeTime        10000;
         trackLength     1e-3;
         nSubCycle       5;
+        bounds          (0.2 -10 -10)(0.22 10 10);
         cloudName       particleTracks;
         seedSampleSet   uniform;
         uniformCoeffs
@@ -74,6 +75,8 @@ Description
         trackLength  | tracking segment length | no          |
         nSubCycle    | number of tracking steps per cell | no|
         cloudName    | cloud name to use       | yes         |
+        log          | Log to standard output  | no          | yes
+        bounds       | Bounding box to trim tracks | no | greatBox
         seedSampleSet| seeding method (see below)| yes       |
     \endtable
 
@@ -94,6 +97,7 @@ SeeAlso
     Foam::OutputFilterFunctionObject
     Foam::sampledSet
     Foam::wallBoundedStreamLine
+    Foam::streamLineBase
 
 SourceFiles
     streamLine.C
@@ -103,15 +107,7 @@ SourceFiles
 #ifndef streamLine_H
 #define streamLine_H
 
-#include "volFieldsFwd.H"
-#include "pointFieldFwd.H"
-#include "Switch.H"
-#include "DynamicList.H"
-#include "scalarList.H"
-#include "vectorList.H"
-#include "polyMesh.H"
-#include "writer.H"
-#include "indirectPrimitivePatch.H"
+#include "streamLineBase.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -121,103 +117,22 @@ namespace Foam
 // Forward declaration of classes
 class objectRegistry;
 class dictionary;
-class mapPolyMesh;
-class meshSearch;
-class sampledSet;
 
 /*---------------------------------------------------------------------------*\
                          Class streamLine Declaration
 \*---------------------------------------------------------------------------*/
 
 class streamLine
+:
+    public streamLineBase
 {
     // Private data
 
-        //- Input dictionary
-        dictionary dict_;
-
-        //- Name of this set of field averages.
-        word name_;
-
-        //- Database this class is registered to
-        const objectRegistry& obr_;
-
-        //- Load fields from files (not from objectRegistry)
-        bool loadFromFiles_;
-
-        //- On/off switch
-        bool active_;
-
-        //- List of fields to sample
-        wordList fields_;
-
-        //- Field to transport particle with
-        word UName_;
-
-        //- Interpolation scheme to use
-        word interpolationScheme_;
-
-        //- Whether to use +u or -u
-        bool trackForward_;
-
-        //- Maximum lifetime (= number of cells) of particle
-        label lifeTime_;
-
         //- Number of subcycling steps
         label nSubCycle_;
 
-        //- Track length
-        scalar trackLength_;
-
-        //- Optional specified name of particles
-        word cloudName_;
-
-        //- Type of seed
-        word seedSet_;
-
-        //- Names of scalar fields
-        wordList scalarNames_;
-
-        //- Names of vector fields
-        wordList vectorNames_;
-
-
-
-        // Demand driven
-
-            //- Mesh searching enigne
-            autoPtr<meshSearch> meshSearchPtr_;
-
-            //- Seed set engine
-            autoPtr<sampledSet> sampledSetPtr_;
 
-            //- Axis of the sampled points to output
-            word sampledSetAxis_;
-
-            //- File writer for scalar data
-            autoPtr<writer<scalar> > scalarFormatterPtr_;
-
-            //- File writer for vector data
-            autoPtr<writer<vector> > vectorFormatterPtr_;
-
-
-        // Generated data
-
-            //- All tracks. Per particle the points it passed through
-            DynamicList<List<point> > allTracks_;
-
-            //- Per scalarField, per particle, the sampled value.
-            List<DynamicList<scalarList> > allScalars_;
-
-            //- Per scalarField, per particle, the sampled value.
-            List<DynamicList<vectorList> > allVectors_;
-
-
-        //- Construct patch out of all wall patch faces
-        autoPtr<indirectPrimitivePatch> wallPatch() const;
-
-        //- Do all seeding and tracking
-        void track();
+   // Private Member Functions
 
         //- Disallow default bitwise copy construct
         streamLine(const streamLine&);
@@ -251,35 +166,11 @@ public:
 
     // Member Functions
 
-        //- Return name of the set of field averages
-        virtual const word& name() const
-        {
-            return name_;
-        }
-
-        //- Read the field average data
+        //- Read settings
         virtual void read(const dictionary&);
 
-        //- Execute the averaging
-        virtual void execute();
-
-        //- Execute the averaging at the final time-loop, currently does nothing
-        virtual void end();
-
-        //- Called when time was set at the end of the Time::operator++
-        virtual void timeSet();
-
-        //- Calculate the field average data and write
-        virtual void write();
-
-        //- Update for changes of mesh
-        virtual void updateMesh(const mapPolyMesh&);
-
-        //- Update for mesh point-motion
-        virtual void movePoints(const polyMesh&);
-
-        ////- Update for changes of mesh due to readUpdate
-        //virtual void readUpdate(const polyMesh::readUpdateState state);
+        //- Do the actual tracking to fill the track data
+        virtual void track();
 };
 
 
diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C
new file mode 100644
index 0000000000000000000000000000000000000000..e319081bf9a84855a2260997de51feaf8a72602e
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.C
@@ -0,0 +1,977 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "streamLineBase.H"
+#include "fvMesh.H"
+#include "ReadFields.H"
+#include "sampledSet.H"
+#include "globalIndex.H"
+#include "mapDistribute.H"
+#include "interpolationCellPoint.H"
+#include "wallPolyPatch.H"
+#include "meshSearchMeshObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(streamLineBase, 0);
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::indirectPrimitivePatch>
+Foam::streamLineBase::wallPatch() const
+{
+    const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
+
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
+    label nFaces = 0;
+
+    forAll(patches, patchI)
+    {
+        //if (!polyPatch::constraintType(patches[patchI].type()))
+        if (isA<wallPolyPatch>(patches[patchI]))
+        {
+            nFaces += patches[patchI].size();
+        }
+    }
+
+    labelList addressing(nFaces);
+
+    nFaces = 0;
+
+    forAll(patches, patchI)
+    {
+        //if (!polyPatch::constraintType(patches[patchI].type()))
+        if (isA<wallPolyPatch>(patches[patchI]))
+        {
+            const polyPatch& pp = patches[patchI];
+
+            forAll(pp, i)
+            {
+                addressing[nFaces++] = pp.start()+i;
+            }
+        }
+    }
+
+    return autoPtr<indirectPrimitivePatch>
+    (
+        new indirectPrimitivePatch
+        (
+            IndirectList<face>
+            (
+                mesh.faces(),
+                addressing
+            ),
+            mesh.points()
+        )
+    );
+}
+
+
+void Foam::streamLineBase::initInterpolations
+(
+    const label nSeeds,
+    label& UIndex,
+    PtrList<volScalarField>& vsFlds,
+    PtrList<interpolation<scalar> >& vsInterp,
+    PtrList<volVectorField>& vvFlds,
+    PtrList<interpolation<vector> >& vvInterp
+)
+{
+    const Time& runTime = obr_.time();
+    const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
+
+    // Read or lookup fields
+
+    if (loadFromFiles_)
+    {
+        IOobjectList allObjects(mesh, runTime.timeName());
+
+        IOobjectList objects(2*fields_.size());
+        forAll(fields_, i)
+        {
+            objects.add(*allObjects[fields_[i]]);
+        }
+
+        ReadFields(mesh, objects, vsFlds);
+        vsInterp.setSize(vsFlds.size());
+        forAll(vsFlds, i)
+        {
+            vsInterp.set
+            (
+                i,
+                interpolation<scalar>::New
+                (
+                    interpolationScheme_,
+                    vsFlds[i]
+                )
+            );
+        }
+        ReadFields(mesh, objects, vvFlds);
+        vvInterp.setSize(vvFlds.size());
+        forAll(vvFlds, i)
+        {
+            vvInterp.set
+            (
+                i,
+                interpolation<vector>::New
+                (
+                    interpolationScheme_,
+                    vvFlds[i]
+                )
+            );
+        }
+    }
+    else
+    {
+        label nScalar = 0;
+        label nVector = 0;
+
+        forAll(fields_, i)
+        {
+            if (mesh.foundObject<volScalarField>(fields_[i]))
+            {
+                nScalar++;
+            }
+            else if (mesh.foundObject<volVectorField>(fields_[i]))
+            {
+                nVector++;
+            }
+            else
+            {
+                FatalErrorIn("streamLineBase::track()")
+                    << "Cannot find field " << fields_[i] << nl
+                    << "Valid scalar fields are:"
+                    << mesh.names(volScalarField::typeName) << nl
+                    << "Valid vector fields are:"
+                    << mesh.names(volVectorField::typeName)
+                    << exit(FatalError);
+            }
+        }
+        vsInterp.setSize(nScalar);
+        nScalar = 0;
+        vvInterp.setSize(nVector);
+        nVector = 0;
+
+        forAll(fields_, i)
+        {
+            if (mesh.foundObject<volScalarField>(fields_[i]))
+            {
+                const volScalarField& f = mesh.lookupObject<volScalarField>
+                (
+                    fields_[i]
+                );
+                vsInterp.set
+                (
+                    nScalar++,
+                    interpolation<scalar>::New
+                    (
+                        interpolationScheme_,
+                        f
+                    )
+                );
+            }
+            else if (mesh.foundObject<volVectorField>(fields_[i]))
+            {
+                const volVectorField& f = mesh.lookupObject<volVectorField>
+                (
+                    fields_[i]
+                );
+
+                if (f.name() == UName_)
+                {
+                    UIndex = nVector;
+                }
+
+                vvInterp.set
+                (
+                    nVector++,
+                    interpolation<vector>::New
+                    (
+                        interpolationScheme_,
+                        f
+                    )
+                );
+            }
+        }
+    }
+
+    // Store the names
+    scalarNames_.setSize(vsInterp.size());
+    forAll(vsInterp, i)
+    {
+        scalarNames_[i] = vsInterp[i].psi().name();
+    }
+    vectorNames_.setSize(vvInterp.size());
+    forAll(vvInterp, i)
+    {
+        vectorNames_[i] = vvInterp[i].psi().name();
+    }
+
+    // Check that we know the index of U in the interpolators.
+
+    if (UIndex == -1)
+    {
+        FatalErrorIn("streamLineBase::track()")
+            << "Cannot find field to move particles with : " << UName_ << nl
+            << "This field has to be present in the sampled fields " << fields_
+            << " and in the objectRegistry."
+            << exit(FatalError);
+    }
+
+    // Sampled data
+    // ~~~~~~~~~~~~
+
+    // Size to maximum expected sizes.
+    allTracks_.clear();
+    allTracks_.setCapacity(nSeeds);
+    allScalars_.setSize(vsInterp.size());
+    forAll(allScalars_, i)
+    {
+        allScalars_[i].clear();
+        allScalars_[i].setCapacity(nSeeds);
+    }
+    allVectors_.setSize(vvInterp.size());
+    forAll(allVectors_, i)
+    {
+        allVectors_[i].clear();
+        allVectors_[i].setCapacity(nSeeds);
+    }
+}
+
+
+void Foam::streamLineBase::storePoint
+(
+    const label trackI,
+
+    const scalar w,
+    const label leftI,
+    const label rightI,
+
+    DynamicList<point>& newTrack,
+    DynamicList<scalarList>& newScalars,
+    DynamicList<vectorList>& newVectors
+) const
+{
+    label sz = newTrack.size();
+
+    const List<point>& track = allTracks_[trackI];
+
+    newTrack.append((1.0-w)*track[leftI] + w*track[rightI]);
+
+    // Scalars
+    {
+        newScalars.append(scalarList(allScalars_.size()));
+        scalarList& newVals = newScalars[sz];
+
+        forAll(allScalars_, scalarI)
+        {
+            const scalarList& trackVals = allScalars_[scalarI][trackI];
+            newVals[scalarI] = (1.0-w)*trackVals[leftI] + w*trackVals[rightI];
+        }
+    }
+
+    // Vectors
+    {
+        newVectors.append(vectorList(allVectors_.size()));
+        vectorList& newVals = newVectors[sz];
+
+        forAll(allVectors_, vectorI)
+        {
+            const vectorList& trackVals = allVectors_[vectorI][trackI];
+            newVals[vectorI] = (1.0-w)*trackVals[leftI] + w*trackVals[rightI];
+        }
+    }
+}
+
+
+// Can split a track into multiple tracks
+void Foam::streamLineBase::trimToBox
+(
+    const treeBoundBox& bb,
+    const label trackI,
+    PtrList<DynamicList<point> >& newTracks,
+    PtrList<DynamicList<scalarList> >& newScalars,
+    PtrList<DynamicList<vectorList> >& newVectors
+) const
+{
+    const List<point>& track = allTracks_[trackI];
+    if (track.size())
+    {
+        for
+        (
+            label segmentI = 1;
+            segmentI < track.size();
+            segmentI++
+        )
+        {
+            const point& startPt = track[segmentI-1];
+            const point& endPt = track[segmentI];
+
+            const vector d(endPt-startPt);
+            scalar magD = mag(d);
+            if (magD > ROOTVSMALL)
+            {
+                if (bb.contains(startPt))
+                {
+                    // Store 1.0*track[segmentI-1]+0*track[segmentI]
+                    storePoint
+                    (
+                        trackI,
+
+                        0.0,
+                        segmentI-1,
+                        segmentI,
+
+                        newTracks.last(),
+                        newScalars.last(),
+                        newVectors.last()
+                    );
+
+                    if (!bb.contains(endPt))
+                    {
+                        point clipPt;
+                        if (bb.intersects(endPt, startPt, clipPt))
+                        {
+                            // End of track. Store point and interpolated
+                            // values
+                            storePoint
+                            (
+                                trackI,
+
+                                mag(clipPt-startPt)/magD,
+                                segmentI-1,
+                                segmentI,
+
+                                newTracks.last(),
+                                newScalars.last(),
+                                newVectors.last()
+                            );
+
+                            newTracks.last().shrink();
+                            newScalars.last().shrink();
+                            newVectors.last().shrink();
+                        }
+                    }
+                }
+                else
+                {
+                    // startPt outside box. New track. Get starting point
+
+                    point clipPt;
+                    if (bb.intersects(startPt, endPt, clipPt))
+                    {
+                        // New track
+                        newTracks.append
+                        (
+                            new DynamicList<point>(track.size()/10)
+                        );
+                        newScalars.append
+                        (
+                            new DynamicList<scalarList>(track.size()/10)
+                        );
+                        newVectors.append
+                        (
+                            new DynamicList<vectorList>(track.size()/10)
+                        );
+
+                        // Store point and interpolated values
+                        storePoint
+                        (
+                            trackI,
+
+                            mag(clipPt-startPt)/magD,
+                            segmentI-1,
+                            segmentI,
+
+                            newTracks.last(),
+                            newScalars.last(),
+                            newVectors.last()
+                        );
+
+                        if (!bb.contains(endPt))
+                        {
+                            bb.intersects
+                            (
+                                endPt,
+                                point(clipPt),
+                                clipPt
+                            );
+
+                            // Store point and interpolated values
+                            storePoint
+                            (
+                                trackI,
+
+                                mag(clipPt-startPt)/magD,
+                                segmentI-1,
+                                segmentI,
+
+                                newTracks.last(),
+                                newScalars.last(),
+                                newVectors.last()
+                            );
+
+                            newTracks.last().shrink();
+                            newScalars.last().shrink();
+                            newVectors.last().shrink();
+                        }
+                    }
+                }
+            }
+        }
+
+        // Last point
+        if (bb.contains(track.last()))
+        {
+            storePoint
+            (
+                trackI,
+
+                1.0,
+                track.size()-2,
+                track.size()-1,
+
+                newTracks.last(),
+                newScalars.last(),
+                newVectors.last()
+            );
+        }
+    }
+}
+
+
+void Foam::streamLineBase::trimToBox(const treeBoundBox& bb)
+{
+    // Storage for new tracks. Per track, per sample the coordinate (newTracks)
+    // or values for all the sampled fields (newScalars, newVectors)
+    PtrList<DynamicList<point> > newTracks;
+    PtrList<DynamicList<scalarList> > newScalars;
+    PtrList<DynamicList<vectorList> > newVectors;
+
+    forAll(allTracks_, trackI)
+    {
+        const List<point>& track = allTracks_[trackI];
+
+        if (track.size())
+        {
+            // New track. Assume it consists of the whole track
+            newTracks.append(new DynamicList<point>(track.size()));
+            newScalars.append(new DynamicList<scalarList>(track.size()));
+            newVectors.append(new DynamicList<vectorList>(track.size()));
+
+            // Trim, split and append to newTracks
+            trimToBox(bb, trackI, newTracks, newScalars, newVectors);
+        }
+    }
+
+    // Transfer newTracks to allTracks_
+    allTracks_.setSize(newTracks.size());
+    forAll(allTracks_, trackI)
+    {
+        allTracks_[trackI].transfer(newTracks[trackI]);
+    }
+    // Replace track scalars
+    forAll(allScalars_, scalarI)
+    {
+        DynamicList<scalarList>& fieldVals = allScalars_[scalarI];
+        fieldVals.setSize(newTracks.size());
+
+        forAll(fieldVals, trackI)
+        {
+            scalarList& trackVals = allScalars_[scalarI][trackI];
+            trackVals.setSize(newScalars[trackI].size());
+            forAll(trackVals, sampleI)
+            {
+                trackVals[sampleI] = newScalars[trackI][sampleI][scalarI];
+            }
+        }
+    }
+    // Replace track vectors
+    forAll(allVectors_, vectorI)
+    {
+        DynamicList<vectorList>& fieldVals = allVectors_[vectorI];
+        fieldVals.setSize(newTracks.size());
+        forAll(fieldVals, trackI)
+        {
+            vectorList& trackVals = allVectors_[vectorI][trackI];
+            trackVals.setSize(newVectors[trackI].size());
+            forAll(trackVals, sampleI)
+            {
+                trackVals[sampleI] = newVectors[trackI][sampleI][vectorI];
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::streamLineBase::streamLineBase
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool loadFromFiles
+)
+:
+    functionObjectState(obr, name),
+    dict_(dict),
+    obr_(obr),
+    loadFromFiles_(loadFromFiles),
+    log_(true)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::streamLineBase::~streamLineBase()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::streamLineBase::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        log_.readIfPresent("log", dict);
+
+        if (log_) Info<< type() << " " << name_ << ":" << nl;
+
+        dict.lookup("fields") >> fields_;
+        if (dict.found("UName"))
+        {
+            dict.lookup("UName") >> UName_;
+        }
+        else
+        {
+            UName_ = "U";
+            if (dict.found("U"))
+            {
+                IOWarningIn("streamLineBase::read(const dictionary&)", dict)
+                    << "Using deprecated entry \"U\"."
+                    << " Please use \"UName\" instead."
+                    << endl;
+                dict.lookup("U") >> UName_;
+            }
+        }
+
+        if (findIndex(fields_, UName_) == -1)
+        {
+            FatalIOErrorIn("streamLineBase::read(const dictionary&)", dict)
+                << "Velocity field for tracking " << UName_
+                << " should be present in the list of fields " << fields_
+                << exit(FatalIOError);
+        }
+
+
+        dict.lookup("trackForward") >> trackForward_;
+        dict.lookup("lifeTime") >> lifeTime_;
+        if (lifeTime_ < 1)
+        {
+            FatalErrorIn(":streamLineBase::read(const dictionary&)")
+                << "Illegal value " << lifeTime_ << " for lifeTime"
+                << exit(FatalError);
+        }
+
+
+        trackLength_ = VGREAT;
+        if (dict.found("trackLength"))
+        {
+            dict.lookup("trackLength") >> trackLength_;
+
+            if (log_)
+            {
+                Info<< type() << " : fixed track length specified : "
+                    << trackLength_ << nl << endl;
+            }
+        }
+
+
+        bounds_ = boundBox::greatBox;
+        if (dict.readIfPresent("bounds", bounds_))
+        {
+            if (log_) Info<< "    clipping all segments to " << bounds_ << nl << endl;
+        }
+
+
+        interpolationScheme_ = dict.lookupOrDefault
+        (
+            "interpolationScheme",
+            interpolationCellPoint<scalar>::typeName
+        );
+
+        //if (log_) Info<< "    using interpolation " << interpolationScheme_
+        //    << endl;
+
+        cloudName_ = dict.lookupOrDefault<word>("cloudName", type());
+        dict.lookup("seedSampleSet") >> seedSet_;
+
+        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
+
+        const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
+
+        sampledSetPtr_ = sampledSet::New
+        (
+            seedSet_,
+            mesh,
+            meshSearchMeshObject::New(mesh),
+            coeffsDict
+        );
+        coeffsDict.lookup("axis") >> sampledSetAxis_;
+
+        scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat"));
+        vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat"));
+    }
+}
+
+
+void Foam::streamLineBase::execute()
+{}
+
+
+void Foam::streamLineBase::end()
+{}
+
+
+void Foam::streamLineBase::timeSet()
+{}
+
+
+void Foam::streamLineBase::write()
+{
+    if (active_)
+    {
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
+
+        const Time& runTime = obr_.time();
+        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
+
+
+        // Do all injection and tracking
+        track();
+
+
+        if (Pstream::parRun())
+        {
+            // Append slave tracks to master ones
+            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+            globalIndex globalTrackIDs(allTracks_.size());
+
+            // Construct a distribution map to pull all to the master.
+            labelListList sendMap(Pstream::nProcs());
+            labelListList recvMap(Pstream::nProcs());
+
+            if (Pstream::master())
+            {
+                // Master: receive all. My own first, then consecutive
+                // processors.
+                label trackI = 0;
+
+                forAll(recvMap, procI)
+                {
+                    labelList& fromProc = recvMap[procI];
+                    fromProc.setSize(globalTrackIDs.localSize(procI));
+                    forAll(fromProc, i)
+                    {
+                        fromProc[i] = trackI++;
+                    }
+                }
+            }
+
+            labelList& toMaster = sendMap[0];
+            toMaster.setSize(globalTrackIDs.localSize());
+            forAll(toMaster, i)
+            {
+                toMaster[i] = i;
+            }
+
+            const mapDistribute distMap
+            (
+                globalTrackIDs.size(),
+                sendMap.xfer(),
+                recvMap.xfer()
+            );
+
+
+            // Distribute the track positions. Note: use scheduled comms
+            // to prevent buffering.
+            allTracks_.shrink();
+            mapDistributeBase::distribute
+            (
+                Pstream::scheduled,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                false,
+                distMap.constructMap(),
+                false,
+                allTracks_,
+                flipOp()
+            );
+            allTracks_.setCapacity(allTracks_.size());
+
+            // Distribute the scalars
+            forAll(allScalars_, scalarI)
+            {
+                allScalars_[scalarI].shrink();
+                mapDistributeBase::distribute
+                (
+                    Pstream::scheduled,
+                    distMap.schedule(),
+                    distMap.constructSize(),
+                    distMap.subMap(),
+                    false,
+                    distMap.constructMap(),
+                    false,
+                    allScalars_[scalarI],
+                    flipOp()
+                );
+                allScalars_[scalarI].setCapacity(allScalars_[scalarI].size());
+            }
+            // Distribute the vectors
+            forAll(allVectors_, vectorI)
+            {
+                allVectors_[vectorI].shrink();
+                mapDistributeBase::distribute
+                (
+                    Pstream::scheduled,
+                    distMap.schedule(),
+                    distMap.constructSize(),
+                    distMap.subMap(),
+                    false,
+                    distMap.constructMap(),
+                    false,
+                    allVectors_[vectorI],
+                    flipOp()
+                );
+                allVectors_[vectorI].setCapacity(allVectors_[vectorI].size());
+            }
+        }
+
+
+        if (Pstream::master())
+        {
+            if (bounds_ != boundBox::greatBox)
+            {
+                // Clip to bounding box
+                trimToBox(treeBoundBox(bounds_));
+            }
+
+
+            label nTracks = 0;
+            label n = 0;
+            forAll(allTracks_, trackI)
+            {
+                if (allTracks_[trackI].size())
+                {
+                    nTracks++;
+                    n += allTracks_[trackI].size();
+                }
+            }
+
+            if (log_)
+            {
+                Info<< "    Tracks:" << nTracks << nl
+                    << "    Total samples:" << n
+                    << endl;
+            }
+
+
+            // Massage into form suitable for writers
+            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+            // Make output directory
+
+            fileName vtkPath
+            (
+                Pstream::parRun()
+              ? runTime.path()/".."/"postProcessing"/"sets"/name()
+              : runTime.path()/"postProcessing"/"sets"/name()
+            );
+            if (mesh.name() != fvMesh::defaultRegion)
+            {
+                vtkPath = vtkPath/mesh.name();
+            }
+            vtkPath = vtkPath/mesh.time().timeName();
+
+            mkDir(vtkPath);
+
+            // Convert track positions (and compact out empty tracks)
+
+            PtrList<coordSet> tracks(nTracks);
+            nTracks = 0;
+            labelList oldToNewTrack(allTracks_.size(), -1);
+
+            forAll(allTracks_, trackI)
+            {
+                if (allTracks_[trackI].size())
+                {
+                    tracks.set
+                    (
+                        nTracks,
+                        new coordSet
+                        (
+                            "track" + Foam::name(nTracks),
+                            sampledSetAxis_                 //"xyz"
+                        )
+                    );
+                    oldToNewTrack[trackI] = nTracks;
+                    tracks[nTracks].transfer(allTracks_[trackI]);
+                    nTracks++;
+                }
+            }
+
+            // Convert scalar values
+
+            if (allScalars_.size() > 0)
+            {
+                List<List<scalarField> > scalarValues(allScalars_.size());
+
+                forAll(allScalars_, scalarI)
+                {
+                    DynamicList<scalarList>& allTrackVals =
+                        allScalars_[scalarI];
+                    scalarValues[scalarI].setSize(nTracks);
+
+                    forAll(allTrackVals, trackI)
+                    {
+                        scalarList& vals = allTrackVals[trackI];
+                        if (vals.size())
+                        {
+                            label newTrackI = oldToNewTrack[trackI];
+                            scalarValues[scalarI][newTrackI].transfer(vals);
+                        }
+                    }
+                }
+
+                fileName vtkFile
+                (
+                    vtkPath
+                  / scalarFormatterPtr_().getFileName
+                    (
+                        tracks[0],
+                        scalarNames_
+                    )
+                );
+
+                if (log_) Info
+                    << "    Writing data to " << vtkFile.path() << endl;
+
+                scalarFormatterPtr_().write
+                (
+                    true,           // writeTracks
+                    tracks,
+                    scalarNames_,
+                    scalarValues,
+                    OFstream(vtkFile)()
+                );
+
+                forAll(scalarNames_, nameI)
+                {
+                    dictionary propsDict;
+                    propsDict.add("file", vtkFile);
+                    const word& fieldName = scalarNames_[nameI];
+                    setProperty(fieldName, propsDict);
+                }
+            }
+
+            // Convert vector values
+
+            if (allVectors_.size() > 0)
+            {
+                List<List<vectorField> > vectorValues(allVectors_.size());
+
+                forAll(allVectors_, vectorI)
+                {
+                    DynamicList<vectorList>& allTrackVals =
+                        allVectors_[vectorI];
+                    vectorValues[vectorI].setSize(nTracks);
+
+                    forAll(allTrackVals, trackI)
+                    {
+                        vectorList& vals = allTrackVals[trackI];
+                        if (vals.size())
+                        {
+                            label newTrackI = oldToNewTrack[trackI];
+                            vectorValues[vectorI][newTrackI].transfer(vals);
+                        }
+                    }
+                }
+
+                fileName vtkFile
+                (
+                    vtkPath
+                  / vectorFormatterPtr_().getFileName
+                    (
+                        tracks[0],
+                        vectorNames_
+                    )
+                );
+
+                //if (log_) Info<< "    Writing vector data to " << vtkFile << endl;
+
+                vectorFormatterPtr_().write
+                (
+                    true,           // writeTracks
+                    tracks,
+                    vectorNames_,
+                    vectorValues,
+                    OFstream(vtkFile)()
+                );
+
+                forAll(vectorNames_, nameI)
+                {
+                    dictionary propsDict;
+                    propsDict.add("file", vtkFile);
+                    const word& fieldName = vectorNames_[nameI];
+                    setProperty(fieldName, propsDict);
+                }
+            }
+        }
+    }
+}
+
+
+void Foam::streamLineBase::updateMesh(const mapPolyMesh&)
+{
+    read(dict_);
+}
+
+
+void Foam::streamLineBase::movePoints(const polyMesh&)
+{
+    // Moving mesh affects the search tree
+    read(dict_);
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H
new file mode 100644
index 0000000000000000000000000000000000000000..cc4346b98bb58e36339d710e0b45cbf3795277e8
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/streamLine/streamLineBase.H
@@ -0,0 +1,246 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::streamLineBase
+
+SeeAlso
+    Foam::streamLine
+    Foam::wallBoundedStreamLine
+
+SourceFiles
+    streamLineBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef streamLineBase_H
+#define streamLineBase_H
+
+#include "functionObjectState.H"
+#include "DynamicList.H"
+#include "scalarList.H"
+#include "vectorList.H"
+#include "writer.H"
+#include "indirectPrimitivePatch.H"
+#include "interpolation.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class mapPolyMesh;
+class meshSearch;
+class sampledSet;
+
+/*---------------------------------------------------------------------------*\
+                         Class streamLineBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class streamLineBase
+:
+    public functionObjectState
+{
+protected:
+
+        //- Input dictionary
+        dictionary dict_;
+
+        //- Database this class is registered to
+        const objectRegistry& obr_;
+
+        //- Load fields from files (not from objectRegistry)
+        bool loadFromFiles_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
+        //- List of fields to sample
+        wordList fields_;
+
+        //- Field to transport particle with
+        word UName_;
+
+        //- Interpolation scheme to use
+        word interpolationScheme_;
+
+        //- Whether to use +u or -u
+        bool trackForward_;
+
+        //- Maximum lifetime (= number of cells) of particle
+        label lifeTime_;
+
+        //- Track length
+        scalar trackLength_;
+
+        //- Optional trimming of tracks
+        boundBox bounds_;
+
+        //- Optional specified name of particles
+        word cloudName_;
+
+        //- Type of seed
+        word seedSet_;
+
+        //- Names of scalar fields
+        wordList scalarNames_;
+
+        //- Names of vector fields
+        wordList vectorNames_;
+
+
+        // Demand driven
+
+            //- Mesh searching enigne
+            autoPtr<meshSearch> meshSearchPtr_;
+
+            //- Seed set engine
+            autoPtr<sampledSet> sampledSetPtr_;
+
+            //- Axis of the sampled points to output
+            word sampledSetAxis_;
+
+            //- File writer for scalar data
+            autoPtr<writer<scalar> > scalarFormatterPtr_;
+
+            //- File writer for vector data
+            autoPtr<writer<vector> > vectorFormatterPtr_;
+
+
+        // Generated data
+
+            //- All tracks. Per track the points it passed through
+            DynamicList<List<point> > allTracks_;
+
+            //- Per scalarField, per track, the sampled values
+            List<DynamicList<scalarList> > allScalars_;
+
+            //- Per vectorField, per track, the sampled values
+            List<DynamicList<vectorList> > allVectors_;
+
+
+        //- Construct patch out of all wall patch faces
+        autoPtr<indirectPrimitivePatch> wallPatch() const;
+
+        //- Initialise fields, interpolators and track storage
+        void initInterpolations
+        (
+            const label nSeeds,
+            label& UIndex,
+            PtrList<volScalarField>& vsFlds,
+            PtrList<interpolation<scalar> >& vsInterp,
+            PtrList<volVectorField>& vvFlds,
+            PtrList<interpolation<vector> >& vvInterp
+        );
+
+        //- Generate point and values by interpolating from existing values
+        void storePoint
+        (
+            const label trackI,
+
+            const scalar w,
+            const label leftI,
+            const label rightI,
+
+            DynamicList<point>& newTrack,
+            DynamicList<List<scalar> >& newScalars,
+            DynamicList<List<vector> >& newVectors
+        ) const;
+
+        //- Trim and possibly split a track
+        void trimToBox
+        (
+            const treeBoundBox& bb,
+            const label trackI,
+            PtrList<DynamicList<point> >& newTracks,
+            PtrList<DynamicList<scalarList> >& newScalars,
+            PtrList<DynamicList<vectorList> >& newVectors
+        ) const;
+
+        //- Trim tracks to bounding box
+        void trimToBox(const treeBoundBox& bb);
+
+        //- Do the actual tracking to fill the track data
+        virtual void track() = 0;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("streamLineBase");
+
+
+    // Constructors
+
+        //- Construct for given objectRegistry and dictionary.
+        //  Allow the possibility to load fields from files
+        streamLineBase
+        (
+            const word& name,
+            const objectRegistry&,
+            const dictionary&,
+            const bool loadFromFiles = false
+        );
+
+
+    //- Destructor
+    virtual ~streamLineBase();
+
+
+    // Member Functions
+
+        //- Read the field average data
+        virtual void read(const dictionary&);
+
+        //- Execute the averaging
+        virtual void execute();
+
+        //- Execute the averaging at the final time-loop, currently does nothing
+        virtual void end();
+
+        //- Called when time was set at the end of the Time::operator++
+        virtual void timeSet();
+
+        //- Track and write
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&);
+
+        //- Update for mesh point-motion
+        virtual void movePoints(const polyMesh&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C
index 0048f0d15abef09ff1bbcd30ceb2ddbe65698a0d..f877a6d0868729b982ddee904c007dbf74733a33 100644
--- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C
+++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,7 +46,8 @@ Foam::surfaceInterpolateFields::surfaceInterpolateFields
     name_(name),
     obr_(obr),
     active_(true),
-    fieldSet_()
+    fieldSet_(),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
     if (isA<fvMesh>(obr_))
@@ -83,6 +84,7 @@ void Foam::surfaceInterpolateFields::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
         dict.lookup("fields") >> fieldSet_;
     }
 }
@@ -92,7 +94,7 @@ void Foam::surfaceInterpolateFields::execute()
 {
     if (active_)
     {
-        Info<< type() << " " << name_ << " output:" << nl;
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
 
         // Clear out any previously loaded fields
         ssf_.clear();
@@ -107,7 +109,7 @@ void Foam::surfaceInterpolateFields::execute()
         interpolateFields<symmTensor>(sSymmtf_);
         interpolateFields<tensor>(stf_);
 
-        Info<< endl;
+        if (log_) Info<< endl;
     }
 }
 
@@ -131,9 +133,9 @@ void Foam::surfaceInterpolateFields::write()
 {
     if (active_)
     {
-        Info<< type() << " " << name_ << " output:" << nl;
-
-        Info<< "    Writing interpolated surface fields to "
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    Writing interpolated surface fields to "
             << obr_.time().timeName() << endl;
 
         forAll(ssf_, i)
diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H
index 1a5d38a0759cd6d009c52aa91b8398351eaf30ae..b71503f3936970ce88c651a86e4f62810f8e96e3 100644
--- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H
+++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFields.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -54,6 +54,7 @@ Description
         Property | Description               | Required    | Default value
         type     | type name: nearWallFields | yes         |
         fields   | list of fields with correspoding output field names | yes |
+        log      | Log to standard output    | no          | yes
     \endtable
 
 
@@ -103,9 +104,11 @@ protected:
         bool active_;
 
         //- Fields to process
-        //wordList fieldSet_;
         List<Tuple2<word, word> > fieldSet_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
         //- Locally constructed fields
         PtrList<surfaceScalarField> ssf_;
         PtrList<surfaceVectorField> svf_;
diff --git a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C
index f302ae1f2cbb731ea6d91fd6174da471be1bbf58..ad89ee2716b0b47adbb18779564f5184e65d4990 100644
--- a/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C
+++ b/src/postProcessing/functionObjects/field/surfaceInterpolateFields/surfaceInterpolateFieldsTemplates.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -59,7 +59,8 @@ void Foam::surfaceInterpolateFields::interpolateFields
 
             if (obr_.found(sName))
             {
-                Info<< "        surface field " << sName << " already exists"
+                if (log_) Info
+                    << "        surface field " << sName << " already exists"
                     << endl;
             }
             else
@@ -68,7 +69,8 @@ void Foam::surfaceInterpolateFields::interpolateFields
                 sflds.setSize(sz+1);
                 sflds.set(sz, new sfType(sName, linearInterpolate(fld)));
 
-                Info<< "        interpolated " << fld.name() << " to create "
+                if (log_) Info
+                    << "        interpolated " << fld.name() << " to create "
                     << sflds[sz].name() << endl;
             }
         }
diff --git a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H b/src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H
similarity index 74%
rename from applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H
rename to src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H
index 0c1391f80a13b78181c78a65ea01ee8ab3194c8a..d6d58060b9b070f2fe7db6f8205d00dfec6fe8c2 100644
--- a/applications/utilities/preProcessing/createExternalCoupledPatchGeometry/createExternalCoupledPatchGeometryTemplates.H
+++ b/src/postProcessing/functionObjects/field/valueAverage/IOvalueAverage.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,29 +21,29 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
+Typedef
+    Foam::IOvalueAverage
+
+Description
+    Instance of the generic IOOutputFilter for valueAverage.
+
 \*---------------------------------------------------------------------------*/
 
-#ifndef createExternalCoupledPatchGeometryTemplates_H
-#define createExternalCoupledPatchGeometryTemplates_H
+#ifndef IOvalueAverage_H
+#define IOvalueAverage_H
 
-#include "word.H"
+#include "valueAverage.H"
+#include "IOOutputFilter.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    template<class Type>
-    void processField(bool& processed, const word& fieldName);
+    typedef IOOutputFilter<valueAverage> IOvalueAverage;
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#ifdef NoRepository
-    #include "createExternalCoupledPatchGeometryTemplates.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C
new file mode 100644
index 0000000000000000000000000000000000000000..a8e0a8d51e5695acedc895edeb784e3323d386a9
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.C
@@ -0,0 +1,202 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "valueAverage.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(valueAverage, 0);
+}
+
+
+// * * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * //
+
+void Foam::valueAverage::writeFileHeader(Ostream& os) const
+{
+    writeHeader(os, "Value averages");
+    writeCommented(os, "Time");
+    forAll(fieldNames_, fieldI)
+    {
+        writeTabbed(os, fieldNames_[fieldI]);
+    }
+    os  << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::valueAverage::valueAverage
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool loadFromFiles
+)
+:
+    functionObjectState(obr, name),
+    functionObjectFile(obr, name, typeName, dict),
+    obr_(obr),
+    functionObjectName_(dict.lookup("functionObjectName")),
+    fieldNames_(dict.lookup("fields")),
+    window_(dict.lookupOrDefault<scalar>("window", -1)),
+    totalTime_(fieldNames_.size(), obr_.time().deltaTValue()),
+    resetOnRestart_(false),
+    log_(true)
+{
+    if (resetOnRestart_)
+    {
+        forAll(fieldNames_, fieldI)
+        {
+            const word& fieldName = fieldNames_[fieldI];
+
+            if (dict.found(fieldName))
+            {
+                const dictionary& valueDict = dict.subDict(fieldName);
+                totalTime_[fieldI] = readScalar(valueDict.lookup("totalTime"));
+            }
+        }
+    }
+
+    writeFileHeader(file());
+}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::valueAverage::~valueAverage()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+void Foam::valueAverage::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        functionObjectFile::read(dict);
+
+        log_ = dict.lookupOrDefault<Switch>("log", true);
+    }
+}
+
+
+void Foam::valueAverage::execute()
+{
+    if (!active_)
+    {
+        return;
+    }
+
+    scalar dt = obr_.time().deltaTValue();
+
+    if (log_) Info<< type() << ": " << name_ << " averages:" << nl;
+
+    file() << obr_.time().timeName();
+
+    DynamicList<label> unprocessedFields(fieldNames_.size());
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName(fieldNames_[fieldI]);
+        const word meanName(fieldName + "Mean");
+
+        scalar Dt = totalTime_[fieldI];
+        scalar alpha = (Dt - dt)/Dt;
+        scalar beta = dt/Dt;
+
+        if (window_ > 0)
+        {
+            if (Dt - dt >= window_)
+            {
+                alpha = (window_ - dt)/window_;
+                beta = dt/window_;
+            }
+        }
+
+        bool processed = false;
+        calc<scalar>(fieldName, meanName, alpha, beta, processed);
+        calc<vector>(fieldName, meanName, alpha, beta, processed);
+        calc<sphericalTensor>(fieldName, meanName, alpha, beta, processed);
+        calc<symmTensor>(fieldName, meanName, alpha, beta, processed);
+        calc<tensor>(fieldName, meanName, alpha, beta, processed);
+
+        if (!processed)
+        {
+            unprocessedFields.append(fieldI);
+
+            if (writeToFile())
+            {
+                file() << tab << "n/a";
+            }
+        }
+
+        totalTime_[fieldI] += dt;
+    }
+
+    file()<< endl;
+
+    if (unprocessedFields.size())
+    {
+        WarningIn("bool Foam::valueAverage::execute()")
+            << "From function object: " << functionObjectName_ << nl
+            << "Unprocessed fields:" << nl;
+
+        forAll(unprocessedFields, i)
+        {
+            label fieldI = unprocessedFields[i];
+            Info<< "        " << fieldNames_[fieldI] << nl;
+        }
+        Info<< endl;
+    }
+
+    if (log_) Info<< endl;
+}
+
+
+void Foam::valueAverage::end()
+{
+    if (active_)
+    {
+        execute();
+    }
+}
+
+
+void Foam::valueAverage::timeSet()
+{
+    // Do nothing
+}
+
+
+void Foam::valueAverage::write()
+{
+    // Do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H
new file mode 100644
index 0000000000000000000000000000000000000000..584e1481066ab172f3ba05c55e97117af1dd429b
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverage.H
@@ -0,0 +1,209 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::valueAverage
+
+Group
+    grpFieldFunctionObjects
+
+Description
+    This function object calculates the average value from the output of
+    function objects that generate singular values.
+
+    Example of function object specification:
+    \verbatim
+    valueAverage1
+    {
+        type        valueAverage;
+        functionObjectLibs ("libfieldFunctionObjects.so");
+        ...
+        writeToFile yes;
+        log         yes;
+        functionObjectName forceCoeffs1;
+        fields      (Cm Cd Cl);
+        window      0.5;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | type name: valueAverage | yes         |
+        writeToFile  | write average data to file |  no      | yes
+        log          | write average data to standard output | no | yes
+        fields       | list of fields to process | yes       |
+    \endtable
+
+    Output data is written to the file \<timeDir\>/valueAverage.dat
+
+SeeAlso
+    Foam::functionObject
+    Foam::functionObjectFile
+    Foam::functionObjectState
+    Foam::OutputFilterFunctionObject
+
+SourceFiles
+    valueAverage.C
+    valueAverageTemplates.C
+    IOvalueAverage.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef valueAverage_H
+#define valueAverage_H
+
+#include "functionObjectState.H"
+#include "functionObjectFile.H"
+#include "Switch.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class polyMesh;
+class mapPolyMesh;
+
+/*---------------------------------------------------------------------------*\
+                        Class valueAverage Declaration
+\*---------------------------------------------------------------------------*/
+
+class valueAverage
+:
+    public functionObjectState,
+    public functionObjectFile
+{
+protected:
+
+    // Protected data
+
+        //- Reference to the database
+        const objectRegistry& obr_;
+
+        //- Name of function object to retrueve data from
+        word functionObjectName_;
+
+        //- List of fields on which to operate
+        wordList fieldNames_;
+
+        //- Averaging window
+        const scalar window_;
+
+        //- Average time per field
+        List<scalar> totalTime_;
+
+        //- Reset the averaging process on restart flag
+        Switch resetOnRestart_;
+
+        //- Switch to send output to Info as well
+        Switch log_;
+
+
+    // Protected Member Functions
+
+        //- Templated function to calculate the average
+        template<class Type>
+        void calc
+        (
+            const word& fieldName,
+            const word& meanName,
+            const scalar alpha,
+            const scalar beta,
+            bool& processed
+        );
+
+        //- Output file header information
+        virtual void writeFileHeader(Ostream& os) const;
+
+        //- Disallow default bitwise copy construct
+        valueAverage(const valueAverage&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const valueAverage&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("valueAverage");
+
+    //- Constructor
+    valueAverage
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+       const bool loadFromFiles = false
+    );
+
+    //- Destructor
+    virtual ~valueAverage();
+
+
+    // Public Member Functions
+
+        //- Read the field min/max data
+        virtual void read(const dictionary&);
+
+        //- Execute, currently does nothing
+        virtual void execute();
+
+        //- Execute at the final time-loop, currently does nothing
+        virtual void end();
+
+        //- Called when time was set at the end of the Time::operator++
+        virtual void timeSet();
+
+        //- Write the fieldMinMax
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&)
+        {}
+
+        //- Update for changes of mesh
+        virtual void movePoints(const polyMesh&)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "valueAverageTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..347cc28b52c115449bc613277b00acbad7d3bcb3
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.C
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "valueAverageFunctionObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineNamedTemplateTypeNameAndDebug(valueAverageFunctionObject, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        valueAverageFunctionObject,
+        dictionary
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..0845bc655cc11a11b6e478fc0b0dfdb7e1e8abf9
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageFunctionObject.H
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::valueAverageFunctionObject
+
+Description
+    FunctionObject wrapper around valueAverageFunctionObject to allow them
+    to be created via the functions entry within controlDict.
+
+SourceFiles
+    fieldMinMaxFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef valueAverageFunctionObject_H
+#define valueAverageFunctionObject_H
+
+#include "valueAverage.H"
+#include "OutputFilterFunctionObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef OutputFilterFunctionObject<valueAverage>
+        valueAverageFunctionObject;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C b/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..10bff887799ac235a1ff04cec6638b15a99b4ced
--- /dev/null
+++ b/src/postProcessing/functionObjects/field/valueAverage/valueAverageTemplates.C
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+template<class Type>
+void Foam::valueAverage::calc
+(
+    const word& fieldName,
+    const word& meanName,
+    const scalar alpha,
+    const scalar beta,
+    bool& processed
+)
+{
+    const word valueType = objectResultType(functionObjectName_, fieldName);
+
+    if (pTraits<Type>::typeName != valueType)
+    {
+        return;
+    }
+
+    Type currentValue = getObjectResult<Type>(functionObjectName_, fieldName);
+
+    Type meanValue = getResult<Type>(meanName);
+    meanValue = alpha*meanValue + beta*currentValue;
+
+    setResult(meanName, meanValue);
+
+    file() << tab << meanValue;
+
+    if (log_) Info<< "    " << meanName << ": " << meanValue << nl;
+
+    processed = true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict
index 3cf1f74d8856e146e279639e2f9479e04f5d8d82..deb3199c2934958617387394eb5106c4e3fe2815 100644
--- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict
+++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict
@@ -112,6 +112,9 @@ functions
         // Size of single track segment [m]
         //trackLength 1e-3;
 
+        // Optional clipping
+        //bounds  (0.2 -10 -10)(0.22 10 10);
+
         // Cloud name to use
         cloudName       particleTracks;
 
diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C
index f9d1407c1e051ae83ebfffab642dcdc01034eb08..52ca5a7d6279988af8447d133be4f4ca2690cbc2 100644
--- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C
+++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.C
@@ -190,9 +190,7 @@ Foam::scalar Foam::wallBoundedParticle::trackFaceTri
         currentE = currentEdge();
     }
 
-    // Determine path along line position+s*d to see where intersections
-    // are.
-
+    // Determine path along line position+s*d to see where intersections are.
     forAll(tri, i)
     {
         label j = tri.fcIndex(i);
@@ -259,23 +257,20 @@ bool Foam::wallBoundedParticle::isTriAlongTrack
     const triFace triVerts(currentTetIndices().faceTriIs(mesh_));
     const edge currentE = currentEdge();
 
-    //if (debug)
+    if
+    (
+        currentE[0] == currentE[1]
+     || findIndex(triVerts, currentE[0]) == -1
+     || findIndex(triVerts, currentE[1]) == -1
+    )
     {
-        if
+        FatalErrorIn
         (
-            currentE[0] == currentE[1]
-         || findIndex(triVerts, currentE[0]) == -1
-         || findIndex(triVerts, currentE[1]) == -1
-        )
-        {
-            FatalErrorIn
-            (
-                "wallBoundedParticle::isTriAlongTrack"
-                "(const point&)"
-            )   << "Edge " << currentE << " not on triangle " << triVerts
-                << info()
-                << abort(FatalError);
-        }
+            "wallBoundedParticle::isTriAlongTrack"
+            "(const point&)"
+        )   << "Edge " << currentE << " not on triangle " << triVerts
+            << info()
+            << abort(FatalError);
     }
 
 
@@ -344,12 +339,7 @@ Foam::wallBoundedParticle::wallBoundedParticle
         }
         else
         {
-            is.read
-            (
-                reinterpret_cast<char*>(&meshEdgeStart_),
-                sizeof(meshEdgeStart_)
-              + sizeof(diagEdge_)
-            );
+            is.read(reinterpret_cast<char*>(&meshEdgeStart_), sizeofFields_);
         }
     }
 
diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
index 0054ec2bb956545c18f44c42802b181de79ef3d4..2be575b54e489135017c2914fc976ea2fd7d36a6 100644
--- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
+++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
@@ -115,15 +115,6 @@ protected:
         //- Construct current edge
         edge currentEdge() const;
 
-        //- Check if inside current tet
-        //void checkInside() const;
-
-        //- Check if on current edge
-        //void checkOnEdge() const;
-
-        //- Check if point on triangle
-        //void checkOnTriangle(const point&) const;
-
         //- Cross mesh edge into different face on same cell
         void crossEdgeConnectedFace(const edge& meshEdge);
 
diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
index 6b6823121e06eaca74a9d0ea77d853a6daa6eb6d..03a37bc518f4654f7846b50b08f41f143c050da0 100644
--- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
+++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
      \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -23,82 +23,22 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "Pstream.H"
-#include "functionObjectList.H"
 #include "wallBoundedStreamLine.H"
 #include "fvMesh.H"
 #include "wallBoundedStreamLineParticleCloud.H"
-#include "ReadFields.H"
-#include "meshSearch.H"
 #include "sampledSet.H"
-#include "globalIndex.H"
-#include "mapDistribute.H"
-#include "interpolationCellPoint.H"
-#include "PatchTools.H"
-#include "meshSearchMeshObject.H"
 #include "faceSet.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
-defineTypeNameAndDebug(wallBoundedStreamLine, 0);
+    defineTypeNameAndDebug(wallBoundedStreamLine, 0);
 }
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::autoPtr<Foam::indirectPrimitivePatch>
-Foam::wallBoundedStreamLine::wallPatch() const
-{
-    const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    label nFaces = 0;
-
-    forAll(patches, patchI)
-    {
-        //if (!polyPatch::constraintType(patches[patchI].type()))
-        if (isA<wallPolyPatch>(patches[patchI]))
-        {
-            nFaces += patches[patchI].size();
-        }
-    }
-
-    labelList addressing(nFaces);
-
-    nFaces = 0;
-
-    forAll(patches, patchI)
-    {
-        //if (!polyPatch::constraintType(patches[patchI].type()))
-        if (isA<wallPolyPatch>(patches[patchI]))
-        {
-            const polyPatch& pp = patches[patchI];
-
-            forAll(pp, i)
-            {
-                addressing[nFaces++] = pp.start()+i;
-            }
-        }
-    }
-
-    return autoPtr<indirectPrimitivePatch>
-    (
-        new indirectPrimitivePatch
-        (
-            IndirectList<face>
-            (
-                mesh.faces(),
-                addressing
-            ),
-            mesh.points()
-        )
-    );
-}
-
-
 Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet
 (
     const PackedBoolList& isWallPatch,
@@ -158,7 +98,7 @@ Foam::tetIndices Foam::wallBoundedStreamLine::findNearestTet
 
 void Foam::wallBoundedStreamLine::track()
 {
-    const Time& runTime = obr_.time();
+    //const Time& runTime = obr_.time();
     const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
 
 
@@ -227,14 +167,14 @@ void Foam::wallBoundedStreamLine::track()
             else
             {
                 Pout<< type() << " : ignoring seed " << seedPt
-                    << " since not in wall cell." << endl;
+                    << " since not in wall cell" << endl;
             }
         }
     }
 
     label nSeeds = returnReduce(particles.size(), sumOp<label>());
 
-    Info<< type() << " : seeded " << nSeeds << " particles." << endl;
+    if (log_) Info<< type() << " : seeded " << nSeeds << " particles" << endl;
 
 
 
@@ -243,168 +183,19 @@ void Foam::wallBoundedStreamLine::track()
     PtrList<interpolation<scalar> > vsInterp;
     PtrList<volVectorField> vvFlds;
     PtrList<interpolation<vector> > vvInterp;
-
     label UIndex = -1;
 
-    if (loadFromFiles_)
-    {
-        IOobjectList allObjects(mesh, runTime.timeName());
-
-        IOobjectList objects(2*fields_.size());
-        forAll(fields_, i)
-        {
-            objects.add(*allObjects[fields_[i]]);
-        }
-
-        ReadFields(mesh, objects, vsFlds);
-        vsInterp.setSize(vsFlds.size());
-        forAll(vsFlds, i)
-        {
-            vsInterp.set
-            (
-                i,
-                interpolation<scalar>::New
-                (
-                    interpolationScheme_,
-                    vsFlds[i]
-                )
-            );
-        }
-        ReadFields(mesh, objects, vvFlds);
-        vvInterp.setSize(vvFlds.size());
-        forAll(vvFlds, i)
-        {
-            vvInterp.set
-            (
-                i,
-                interpolation<vector>::New
-                (
-                    interpolationScheme_,
-                    vvFlds[i]
-                )
-            );
-        }
-    }
-    else
-    {
-        label nScalar = 0;
-        label nVector = 0;
-
-        forAll(fields_, i)
-        {
-            if (mesh.foundObject<volScalarField>(fields_[i]))
-            {
-                nScalar++;
-            }
-            else if (mesh.foundObject<volVectorField>(fields_[i]))
-            {
-                nVector++;
-            }
-            else
-            {
-                FatalErrorIn("wallBoundedStreamLine::execute()")
-                    << "Cannot find field " << fields_[i] << endl
-                    << "Valid scalar fields are:"
-                    << mesh.names(volScalarField::typeName) << endl
-                    << "Valid vector fields are:"
-                    << mesh.names(volVectorField::typeName)
-                    << exit(FatalError);
-            }
-        }
-        vsInterp.setSize(nScalar);
-        nScalar = 0;
-        vvInterp.setSize(nVector);
-        nVector = 0;
-
-        forAll(fields_, i)
-        {
-            if (mesh.foundObject<volScalarField>(fields_[i]))
-            {
-                const volScalarField& f = mesh.lookupObject<volScalarField>
-                (
-                    fields_[i]
-                );
-                vsInterp.set
-                (
-                    nScalar++,
-                    interpolation<scalar>::New
-                    (
-                        interpolationScheme_,
-                        f
-                    )
-                );
-            }
-            else if (mesh.foundObject<volVectorField>(fields_[i]))
-            {
-                const volVectorField& f = mesh.lookupObject<volVectorField>
-                (
-                    fields_[i]
-                );
-
-                if (f.name() == UName_)
-                {
-                    UIndex = nVector;
-                }
-
-                vvInterp.set
-                (
-                    nVector++,
-                    interpolation<vector>::New
-                    (
-                        interpolationScheme_,
-                        f
-                    )
-                );
-            }
-        }
-    }
-
-    // Store the names
-    scalarNames_.setSize(vsInterp.size());
-    forAll(vsInterp, i)
-    {
-        scalarNames_[i] = vsInterp[i].psi().name();
-    }
-    vectorNames_.setSize(vvInterp.size());
-    forAll(vvInterp, i)
-    {
-        vectorNames_[i] = vvInterp[i].psi().name();
-    }
-
-    // Check that we know the index of U in the interpolators.
-
-    if (UIndex == -1)
-    {
-        FatalErrorIn("wallBoundedStreamLine::execute()")
-            << "Cannot find field to move particles with : " << UName_
-            << endl
-            << "This field has to be present in the sampled fields "
-            << fields_
-            << " and in the objectRegistry." << endl
-            << exit(FatalError);
-    }
-
-    // Sampled data
-    // ~~~~~~~~~~~~
-
-    // Size to maximum expected sizes.
-    allTracks_.clear();
-    allTracks_.setCapacity(nSeeds);
-    allScalars_.setSize(vsInterp.size());
-    forAll(allScalars_, i)
-    {
-        allScalars_[i].clear();
-        allScalars_[i].setCapacity(nSeeds);
-    }
-    allVectors_.setSize(vvInterp.size());
-    forAll(allVectors_, i)
-    {
-        allVectors_[i].clear();
-        allVectors_[i].setCapacity(nSeeds);
-    }
-
+    initInterpolations
+    (
+        nSeeds,
+        UIndex,
+        vsFlds,
+        vsInterp,
+        vvFlds,
+        vvInterp
+    );
 
-    // additional particle info
+    // Additional particle info
     wallBoundedStreamLineParticle::trackingData td
     (
         particles,
@@ -440,32 +231,13 @@ Foam::wallBoundedStreamLine::wallBoundedStreamLine
     const bool loadFromFiles
 )
 :
-    dict_(dict),
-    name_(name),
-    obr_(obr),
-    loadFromFiles_(loadFromFiles),
-    active_(true)
+    streamLineBase(name, obr, dict, loadFromFiles)
 {
-    // Only active if a fvMesh is available
-    if (isA<fvMesh>(obr_))
+    // Check if the available mesh is an fvMesh otherise deactivate
+    if (setActive<fvMesh>())
     {
         read(dict_);
     }
-    else
-    {
-        active_ = false;
-        WarningIn
-        (
-            "wallBoundedStreamLine::wallBoundedStreamLine\n"
-            "("
-                "const word&, "
-                "const objectRegistry&, "
-                "const dictionary&, "
-                "const bool "
-            ")"
-        )   << "No fvMesh available, deactivating " << name_
-            << nl << endl;
-    }
 }
 
 
@@ -481,94 +253,13 @@ void Foam::wallBoundedStreamLine::read(const dictionary& dict)
 {
     if (active_)
     {
-        //dict_ = dict;
-        dict.lookup("fields") >> fields_;
-        if (dict.found("UName"))
-        {
-            dict.lookup("UName") >> UName_;
-        }
-        else
-        {
-            UName_ = "U";
-            if (dict.found("U"))
-            {
-                IOWarningIn
-                (
-                    "wallBoundedStreamLine::read(const dictionary&)",
-                    dict
-                )   << "Using deprecated entry \"U\"."
-                    << " Please use \"UName\" instead."
-                    << endl;
-                dict.lookup("U") >> UName_;
-            }
-        }
-
-        if (findIndex(fields_, UName_) == -1)
-        {
-            FatalIOErrorIn
-            (
-                "wallBoundedStreamLine::read(const dictionary&)",
-                dict
-            )   << "Velocity field for tracking " << UName_
-                << " should be present in the list of fields " << fields_
-                << exit(FatalIOError);
-        }
-
-
-        dict.lookup("trackForward") >> trackForward_;
-        dict.lookup("lifeTime") >> lifeTime_;
-        if (lifeTime_ < 1)
-        {
-            FatalErrorIn(":wallBoundedStreamLine::read(const dictionary&)")
-                << "Illegal value " << lifeTime_ << " for lifeTime"
-                << exit(FatalError);
-        }
-        trackLength_ = VGREAT;
-        if (dict.found("trackLength"))
-        {
-            dict.lookup("trackLength") >> trackLength_;
-
-            Info<< type() << " : fixed track length specified : "
-                << trackLength_ << nl << endl;
-        }
-
-
-        interpolationScheme_ = dict.lookupOrDefault
-        (
-            "interpolationScheme",
-            interpolationCellPoint<scalar>::typeName
-        );
-
-        //Info<< typeName << " using interpolation " << interpolationScheme_
-        //    << endl;
-
-        cloudName_ = dict.lookupOrDefault<word>
-        (
-            "cloudName",
-            "wallBoundedStreamLine"
-        );
-        dict.lookup("seedSampleSet") >> seedSet_;
-
-        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-        const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
-
-        sampledSetPtr_ = sampledSet::New
-        (
-            seedSet_,
-            mesh,
-            meshSearchMeshObject::New(mesh),
-            coeffsDict
-        );
-        coeffsDict.lookup("axis") >> sampledSetAxis_;
-
-        scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat"));
-        vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat"));
-
+        streamLineBase::read(dict);
 
         // Make sure that the mesh is trackable
         if (debug)
         {
+            const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
+
             // 1. positive volume decomposition tets
             faceSet faces(mesh, "lowQualityTetFaces", mesh.nFaces()/100+1);
             if
@@ -636,283 +327,4 @@ void Foam::wallBoundedStreamLine::read(const dictionary& dict)
 }
 
 
-void Foam::wallBoundedStreamLine::execute()
-{}
-
-
-void Foam::wallBoundedStreamLine::end()
-{}
-
-
-void Foam::wallBoundedStreamLine::timeSet()
-{}
-
-
-void Foam::wallBoundedStreamLine::write()
-{
-    if (active_)
-    {
-        const Time& runTime = obr_.time();
-        const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
-
-
-        // Do all injection and tracking
-        track();
-
-
-        if (Pstream::parRun())
-        {
-            // Append slave tracks to master ones
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            globalIndex globalTrackIDs(allTracks_.size());
-
-            // Construct a distribution map to pull all to the master.
-            labelListList sendMap(Pstream::nProcs());
-            labelListList recvMap(Pstream::nProcs());
-
-            if (Pstream::master())
-            {
-                // Master: receive all. My own first, then consecutive
-                // processors.
-                label trackI = 0;
-
-                forAll(recvMap, procI)
-                {
-                    labelList& fromProc = recvMap[procI];
-                    fromProc.setSize(globalTrackIDs.localSize(procI));
-                    forAll(fromProc, i)
-                    {
-                        fromProc[i] = trackI++;
-                    }
-                }
-            }
-
-            labelList& toMaster = sendMap[0];
-            toMaster.setSize(globalTrackIDs.localSize());
-            forAll(toMaster, i)
-            {
-                toMaster[i] = i;
-            }
-
-            const mapDistribute distMap
-            (
-                globalTrackIDs.size(),
-                sendMap.xfer(),
-                recvMap.xfer()
-            );
-
-
-            // Distribute the track positions. Note: use scheduled comms
-            // to prevent buffering.
-            allTracks_.shrink();
-            mapDistributeBase::distribute
-            (
-                Pstream::scheduled,
-                distMap.schedule(),
-                distMap.constructSize(),
-                distMap.subMap(),
-                false,
-                distMap.constructMap(),
-                false,
-                allTracks_,
-                flipOp()
-            );
-
-            // Distribute the scalars
-            forAll(allScalars_, scalarI)
-            {
-                allScalars_[scalarI].shrink();
-                mapDistributeBase::distribute
-                (
-                    Pstream::scheduled,
-                    distMap.schedule(),
-                    distMap.constructSize(),
-                    distMap.subMap(),
-                    false,
-                    distMap.constructMap(),
-                    false,
-                    allScalars_[scalarI],
-                    flipOp()
-                );
-                allScalars_[scalarI].setCapacity(allScalars_[scalarI].size());
-            }
-            // Distribute the vectors
-            forAll(allVectors_, vectorI)
-            {
-                allVectors_[vectorI].shrink();
-                mapDistributeBase::distribute
-                (
-                    Pstream::scheduled,
-                    distMap.schedule(),
-                    distMap.constructSize(),
-                    distMap.subMap(),
-                    false,
-                    distMap.constructMap(),
-                    false,
-                    allVectors_[vectorI],
-                    flipOp()
-                );
-                allVectors_[vectorI].setCapacity(allVectors_[vectorI].size());
-            }
-        }
-
-
-        label n = 0;
-        forAll(allTracks_, trackI)
-        {
-            n += allTracks_[trackI].size();
-        }
-
-        Info<< "    Tracks:" << allTracks_.size() << nl
-            << "    Total samples:" << n << endl;
-
-
-        // Massage into form suitable for writers
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        if (Pstream::master() && allTracks_.size())
-        {
-            // Make output directory
-
-            fileName vtkPath
-            (
-                Pstream::parRun()
-              ? runTime.path()/".."/"postProcessing"/"sets"/name()
-              : runTime.path()/"postProcessing"/"sets"/name()
-            );
-            if (mesh.name() != fvMesh::defaultRegion)
-            {
-                vtkPath = vtkPath/mesh.name();
-            }
-            vtkPath = vtkPath/mesh.time().timeName();
-
-            mkDir(vtkPath);
-
-            // Convert track positions
-
-            PtrList<coordSet> tracks(allTracks_.size());
-            forAll(allTracks_, trackI)
-            {
-                tracks.set
-                (
-                    trackI,
-                    new coordSet
-                    (
-                        "track" + Foam::name(trackI),
-                        sampledSetAxis_                 //"xyz"
-                    )
-                );
-                tracks[trackI].transfer(allTracks_[trackI]);
-            }
-
-            // Convert scalar values
-
-            if (allScalars_.size() > 0)
-            {
-                List<List<scalarField> > scalarValues(allScalars_.size());
-
-                forAll(allScalars_, scalarI)
-                {
-                    DynamicList<scalarList>& allTrackVals =
-                        allScalars_[scalarI];
-                    scalarValues[scalarI].setSize(allTrackVals.size());
-
-                    forAll(allTrackVals, trackI)
-                    {
-                        scalarList& trackVals = allTrackVals[trackI];
-                        scalarValues[scalarI][trackI].transfer(trackVals);
-                    }
-                }
-
-                fileName vtkFile
-                (
-                    vtkPath
-                  / scalarFormatterPtr_().getFileName
-                    (
-                        tracks[0],
-                        scalarNames_
-                    )
-                );
-
-                Info<< "Writing data to " << vtkFile.path() << endl;
-
-                scalarFormatterPtr_().write
-                (
-                    true,           // writeTracks
-                    tracks,
-                    scalarNames_,
-                    scalarValues,
-                    OFstream(vtkFile)()
-                );
-            }
-
-            // Convert vector values
-
-            if (allVectors_.size() > 0)
-            {
-                List<List<vectorField> > vectorValues(allVectors_.size());
-
-                forAll(allVectors_, vectorI)
-                {
-                    DynamicList<vectorList>& allTrackVals =
-                        allVectors_[vectorI];
-                    vectorValues[vectorI].setSize(allTrackVals.size());
-
-                    forAll(allTrackVals, trackI)
-                    {
-                        vectorList& trackVals = allTrackVals[trackI];
-                        vectorValues[vectorI][trackI].transfer(trackVals);
-                    }
-                }
-
-                fileName vtkFile
-                (
-                    vtkPath
-                  / vectorFormatterPtr_().getFileName
-                    (
-                        tracks[0],
-                        vectorNames_
-                    )
-                );
-
-                //Info<< "Writing vector data to " << vtkFile << endl;
-
-                vectorFormatterPtr_().write
-                (
-                    true,           // writeTracks
-                    tracks,
-                    vectorNames_,
-                    vectorValues,
-                    OFstream(vtkFile)()
-                );
-            }
-        }
-    }
-}
-
-
-void Foam::wallBoundedStreamLine::updateMesh(const mapPolyMesh&)
-{
-    read(dict_);
-}
-
-
-void Foam::wallBoundedStreamLine::movePoints(const polyMesh&)
-{
-    // Moving mesh affects the search tree
-    read(dict_);
-}
-
-
-//void Foam::wallBoundedStreamLine::readUpdate
-//(const polyMesh::readUpdateState state)
-//{
-//    if (state != UNCHANGED)
-//    {
-//        read(dict_);
-//    }
-//}
-
-
 // ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
index 98956ba9caa2111e22aa5c53c6ae791887d18652..fe7d3366ac01c004c85acd91e1ffeb87a5991864 100644
--- a/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
+++ b/src/postProcessing/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,7 +49,7 @@ Description
         );
         lifeTime        10000;
         trackLength     1e-3;
-        nSubCycle       5;
+        bounds          (0.2 -10 -10)(0.22 10 10);
         cloudName       particleTracks;
         seedSampleSet   patchSeed;
         patchSeedCoeffs
@@ -71,8 +71,9 @@ Description
         fields       | fields to sample        | yes         |
         lifetime     | maximum number of particle tracking steps | yes |
         trackLength  | tracking segment length | no          |
-        nSubCycle    | number of tracking steps per cell | no|
         cloudName    | cloud name to use       | yes         |
+        log          | Log to standard output  | no          | yes
+        bounds       | Bounding box to trim tracks | no | greatBox
         seedSampleSet| seeding method (see below)| yes       |
     \endtable
 
@@ -85,14 +86,11 @@ Description
         triSurfaceMeshPointSet | points according to a tri-surface mesh
     \endplaintable
 
-Note
-    When specifying the track resolution, the \c trackLength OR \c nSubCycle
-    option should be used
-
 SeeAlso
     Foam::functionObject
     Foam::OutputFilterFunctionObject
     Foam::sampledSet
+    Foam::streamLineBase
     Foam::streamLine
 
 SourceFiles
@@ -103,16 +101,7 @@ SourceFiles
 #ifndef wallBoundedStreamLine_H
 #define wallBoundedStreamLine_H
 
-#include "volFieldsFwd.H"
-#include "pointFieldFwd.H"
-#include "Switch.H"
-#include "DynamicList.H"
-#include "scalarList.H"
-#include "vectorList.H"
-#include "polyMesh.H"
-#include "writer.H"
-#include "indirectPrimitivePatch.H"
-#include "tetIndices.H"
+#include "streamLineBase.H"
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -120,99 +109,15 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of classes
-class objectRegistry;
-class dictionary;
-class mapPolyMesh;
-class meshSearch;
-class sampledSet;
-
 /*---------------------------------------------------------------------------*\
                     Class wallBoundedStreamLine Declaration
 \*---------------------------------------------------------------------------*/
 
 class wallBoundedStreamLine
+:
+    public streamLineBase
 {
-    // Private data
-
-        //- Input dictionary
-        dictionary dict_;
-
-        //- Name of this set of field averages.
-        word name_;
-
-        //- Database this class is registered to
-        const objectRegistry& obr_;
-
-        //- Load fields from files (not from objectRegistry)
-        bool loadFromFiles_;
-
-        //- On/off switch
-        bool active_;
-
-
-        //- List of fields to sample
-        wordList fields_;
-
-        //- Field to transport particle with
-        word UName_;
-
-        //- Interpolation scheme to use
-        word interpolationScheme_;
-
-        //- Whether to use +u or -u
-        bool trackForward_;
-
-        //- Maximum lifetime (= number of cells) of particle
-        label lifeTime_;
-
-        //- Track length
-        scalar trackLength_;
-
-        //- Optional specified name of particles
-        word cloudName_;
-
-        //- Type of seed
-        word seedSet_;
-
-        //- Names of scalar fields
-        wordList scalarNames_;
-
-        //- Names of vector fields
-        wordList vectorNames_;
-
-
-        // Demand driven
-
-            //- Mesh searching enigne
-            autoPtr<meshSearch> meshSearchPtr_;
-
-            //- Seed set engine
-            autoPtr<sampledSet> sampledSetPtr_;
-
-            //- Axis of the sampled points to output
-            word sampledSetAxis_;
-
-            //- File output writer
-            autoPtr<writer<scalar> > scalarFormatterPtr_;
-
-            autoPtr<writer<vector> > vectorFormatterPtr_;
-
-
-        // Generated data
-
-            //- All tracks. Per particle the points it passed through
-            DynamicList<List<point> > allTracks_;
-
-            //- Per scalarField, per particle, the sampled value.
-            List<DynamicList<scalarList> > allScalars_;
-
-            //- Per scalarField, per particle, the sampled value.
-            List<DynamicList<vectorList> > allVectors_;
-
-
-        //- Construct patch out of all wall patch faces
-        autoPtr<indirectPrimitivePatch> wallPatch() const;
+   // Private Member Functions
 
         //- Find wall tet on cell
         tetIndices findNearestTet
@@ -222,9 +127,6 @@ class wallBoundedStreamLine
             const label cellI
         ) const;
 
-        //- Do all seeding and tracking
-        void track();
-
         //- Disallow default bitwise copy construct
         wallBoundedStreamLine(const wallBoundedStreamLine&);
 
@@ -257,35 +159,11 @@ public:
 
     // Member Functions
 
-        //- Return name of the set of field averages
-        virtual const word& name() const
-        {
-            return name_;
-        }
-
-        //- Read the field average data
+        //- Read settings
         virtual void read(const dictionary&);
 
-        //- Execute the averaging
-        virtual void execute();
-
-        //- Execute the averaging at the final time-loop, currently does nothing
-        virtual void end();
-
-        //- Called when time was set at the end of the Time::operator++
-        virtual void timeSet();
-
-        //- Calculate the field average data and write
-        virtual void write();
-
-        //- Update for changes of mesh
-        virtual void updateMesh(const mapPolyMesh&);
-
-        //- Update for mesh point-motion
-        virtual void movePoints(const polyMesh&);
-
-        ////- Update for changes of mesh due to readUpdate
-        //virtual void readUpdate(const polyMesh::readUpdateState state);
+        //- Do the actual tracking to fill the track data
+        virtual void track();
 };
 
 
diff --git a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C
index da2f58847274c4dbb3ea877dc935a756fadf1359..e3417e26f82f5fab44fd3e103b4f03f26019e14b 100644
--- a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C
+++ b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C
@@ -343,20 +343,18 @@ void Foam::forceCoeffs::execute()
     scalar ClfTot = ClTot/2.0 + CmTot;
     scalar ClrTot = ClTot/2.0 - CmTot;
 
-    if (log_)
-    {
-        Info<< type() << " " << name_ << " output:" << nl
-            << "    Coefficients" << nl;
-    }
+    if (log_) Info
+        << type() << " " << name_ << " output:" << nl
+        << "    Coefficients" << nl;
+
     writeIntegratedData("Cm", momentCoeffs);
     writeIntegratedData("Cd", dragCoeffs);
     writeIntegratedData("Cl", liftCoeffs);
-    if (log_)
-    {
-        Info<< "        Cl(f)    : " << ClfTot << nl
-            << "        Cl(r)    : " << ClrTot << nl
-            << endl;
-    }
+
+    if (log_) Info
+        << "        Cl(f)    : " << ClfTot << nl
+        << "        Cl(r)    : " << ClrTot << nl
+        << endl;
 
     if (writeToFile())
     {
diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C
index 8c951de8ecfe0a73440c5e48d4b7d2c7251d7bab..9c5e5873288d686d3fa6dd0df2908b671e26d24e 100644
--- a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C
+++ b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -88,7 +88,8 @@ Foam::calcFvcDiv::calcFvcDiv
     obr_(obr),
     active_(true),
     fieldName_("undefined-fieldName"),
-    resultName_("undefined-resultName")
+    resultName_(word::null),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -123,10 +124,12 @@ void Foam::calcFvcDiv::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
+
         dict.lookup("fieldName") >> fieldName_;
-        dict.lookup("resultName") >> resultName_;
+        dict.readIfPresent("resultName", resultName_);
 
-        if (resultName_ == "none")
+        if (resultName_ == word::null)
         {
             resultName_ = "fvc::div(" + fieldName_ + ")";
         }
@@ -176,7 +179,8 @@ void Foam::calcFvcDiv::write()
             const regIOobject& field =
                 obr_.lookupObject<regIOobject>(resultName_);
 
-            Info<< type() << " " << name_ << " output:" << nl
+            if (log_) Info
+                << type() << " " << name_ << " output:" << nl
                 << "    writing field " << field.name() << nl << endl;
 
             field.write();
diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H
index 447b00c92c8b36168ed5d42061964247700de7a5..bc498be4ec8140c723c8dbd21ad2a6d43b58a5e2 100644
--- a/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H
+++ b/src/postProcessing/functionObjects/fvTools/calcFvcDiv/calcFvcDiv.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2012-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2012-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,9 +28,29 @@ Group
     grpFVFunctionObjects
 
 Description
-    This function object calculates the divergence of a field.  The operation is
-    limited to surfaceScalarFields and volumeVector fields, and the output is a
-    volume scalar field.
+    This function object calculates the divergence of a field.  The operation
+    is limited to surfaceScalarFields and volumeVector fields, and the output
+    is a volume scalar field.
+
+    Example of function object specification:
+    \verbatim
+    calcFvcDiv1
+    {
+        type        calcFvcDiv;
+        functionObjectLibs ("libFVFunctionObjects.so");
+        ...
+        fieldName   U;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property | Description                | Required  | Default value
+        type     | type name: calcFvcDiv      | yes       |
+        fieldName | Name of field to process  | yes       |
+        resultName | Name of divergence field | no        | fvc::div(fieldName)
+        log      | Log to standard output     | no        | yes
+    \endtable
 
 SourceFiles
     calcFvcDiv.C
@@ -82,6 +102,9 @@ class calcFvcDiv
         //- Name of result field
         word resultName_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C
index c0642ecf01baeb6edce31cf09e2ca6cdd1a228ef..ff97fa0f3ffa730639124b3e50d8e1671414d27f 100644
--- a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C
+++ b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,7 +50,8 @@ Foam::calcFvcGrad::calcFvcGrad
     obr_(obr),
     active_(true),
     fieldName_("undefined-fieldName"),
-    resultName_("undefined-resultName")
+    resultName_(word::null),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -85,10 +86,12 @@ void Foam::calcFvcGrad::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
+
         dict.lookup("fieldName") >> fieldName_;
-        dict.lookup("resultName") >> resultName_;
+        dict.readIfPresent("resultName", resultName_);
 
-        if (resultName_ == "none")
+        if (resultName_ == word::null)
         {
             resultName_ = "fvc::grad(" + fieldName_ + ")";
         }
@@ -138,7 +141,8 @@ void Foam::calcFvcGrad::write()
             const regIOobject& field =
                 obr_.lookupObject<regIOobject>(resultName_);
 
-            Info<< type() << " " << name_ << " output:" << nl
+            if (log_) Info
+                << type() << " " << name_ << " output:" << nl
                 << "    writing field " << field.name() << nl << endl;
 
             field.write();
diff --git a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H
index bdaf5383ed5b7aa90f1e51063e5d7587dea5b1d9..45b6d9c7277bca4f1a144df257c4d9aaa29dbe04 100644
--- a/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H
+++ b/src/postProcessing/functionObjects/fvTools/calcFvcGrad/calcFvcGrad.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2012-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2012-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,9 +28,29 @@ Group
     grpFVFunctionObjects
 
 Description
-    This function object calculates the gradient of a field.  The operation is
-    limited to scalar and vector volume or surface fields, and the output is a
-    volume vector or tensor field.
+    This function object calculates the gradient of a field.  The operation
+    is limited to scalar and vector volume or surface fields, and the output
+    is a volume vector or tensor field.
+
+    Example of function object specification:
+    \verbatim
+    calcFvcGrad1
+    {
+        type        calcFvcGrad;
+        functionObjectLibs ("libFVFunctionObjects.so");
+        ...
+        fieldName   U;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property | Description                | Required  | Default value
+        type     | type name: calcFvcGrad     | yes       |
+        fieldName | Name of field to process  | yes       |
+        resultName | Name of gradient field   | no        | fvc::grad(fieldName)
+        log      | Log to standard output     | no        | yes
+    \endtable
 
 SourceFiles
     calcFvcGrad.C
@@ -82,6 +102,9 @@ class calcFvcGrad
         //- Name of result field
         word resultName_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C
index d853aaf00dca833f0b4d60ff51c43daf7c0abde5..ea11e28b4c60ba91d95adc548b87bdc6d102d9ed 100644
--- a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C
+++ b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,7 +50,8 @@ Foam::calcMag::calcMag
     obr_(obr),
     active_(true),
     fieldName_("undefined-fieldName"),
-    resultName_("undefined-resultName")
+    resultName_(word::null),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -85,10 +86,12 @@ void Foam::calcMag::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
+
         dict.lookup("fieldName") >> fieldName_;
-        dict.lookup("resultName") >> resultName_;
+        dict.readIfPresent("resultName", resultName_);
 
-        if (resultName_ == "none")
+        if (resultName_ == word::null)
         {
             resultName_ = "mag(" + fieldName_ + ")";
         }
@@ -141,7 +144,8 @@ void Foam::calcMag::write()
             const regIOobject& field =
                 obr_.lookupObject<regIOobject>(resultName_);
 
-            Info<< type() << " " << name_ << " output:" << nl
+            if (log_) Info
+                << type() << " " << name_ << " output:" << nl
                 << "    writing field " << field.name() << nl << endl;
 
             field.write();
diff --git a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H
index 76f10721117618a00c503b554b219c8e91c69fc7..1df80da3aa1ac0bc5f453aa7d6437fc088877bb6 100644
--- a/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H
+++ b/src/postProcessing/functionObjects/fvTools/calcMag/calcMag.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2012-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2012-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -32,6 +32,25 @@ Description
     can be applied to any volume or surface fieldsm and the output is a
     volume or surface scalar field.
 
+    Example of function object specification:
+    \verbatim
+    calcMag1
+    {
+        type        calcMag;
+        functionObjectLibs ("libFVFunctionObjects.so");
+        ...
+        fieldName   U;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property | Description                | Required  | Default value
+        type     | type name: calcMag         | yes       |
+        fieldName | Name of field to process  | yes       |
+        resultName | Name of magnitude field  | no        | mag(fieldName)
+        log      | Log to standard output     | no        | yes
+    \endtable
 SourceFiles
     calcMag.C
     IOcalcMag.H
@@ -82,6 +101,9 @@ class calcMag
         //- Name of result field
         word resultName_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H b/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H
new file mode 100644
index 0000000000000000000000000000000000000000..9839333c7687a84fbe94a9590954ccea5dcdf2b0
--- /dev/null
+++ b/src/postProcessing/functionObjects/graphics/doc/graphicsFunctionObjectsDoc.H
@@ -0,0 +1,30 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 3 of the License, or (at your option)
+    any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+    details.
+
+    You should have received a copy of the GNU General Public License along with
+    OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\defgroup grpGraphicsFunctionObjects Graphics function objects
+@{
+    \ingroup grpFunctionObjects
+    This group contains graphics-based function objects
+@}
+
+\*---------------------------------------------------------------------------*/
diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H
index 087942b92d5627cbc3aea430a7fd715f2c9eb564..d386aae369fe4a0f7a53fb6d5e1f9b516b423647 100644
--- a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H
+++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,9 @@ License
 Class
     Foam::runTimePostProcessing
 
+Group
+    grpGraphicsFunctionObjects
+
 Description
     Function object to generate images during run-time.
 
diff --git a/src/postProcessing/functionObjects/jobControl/Make/files b/src/postProcessing/functionObjects/jobControl/Make/files
index c86cc727f689b657f05d9f02987279385353246e..9d4ebe3aebe70c86c331b466dc679ddf3075506f 100644
--- a/src/postProcessing/functionObjects/jobControl/Make/files
+++ b/src/postProcessing/functionObjects/jobControl/Make/files
@@ -1,4 +1,20 @@
 abortCalculation/abortCalculation.C
 abortCalculation/abortCalculationFunctionObject.C
 
+runTimeControl/runTimeControl.C
+runTimeControl/runTimeControlFunctionObject.C
+runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C
+runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C
+runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C
+runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C
+runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C
+runTimeControl/runTimeCondition/averageCondition/averageCondition.C
+runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C
+
+externalCoupled = externalCoupled
+$(externalCoupled)/externalCoupledFunctionObject.C
+$(externalCoupled)/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
+$(externalCoupled)/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
+
+
 LIB = $(FOAM_LIBBIN)/libjobControl
diff --git a/src/postProcessing/functionObjects/jobControl/Make/options b/src/postProcessing/functionObjects/jobControl/Make/options
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c6867bf0d19075542c973348e71a4ce1f971e0e4 100644
--- a/src/postProcessing/functionObjects/jobControl/Make/options
+++ b/src/postProcessing/functionObjects/jobControl/Make/options
@@ -0,0 +1,10 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
+    -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
+    -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
+    -I$(LIB_SRC)/transportModels/compressible/lnInclude
+
+LIB_LIBS = \
+    -lfiniteVolume \
+    -lcompressibleTurbulenceModels
diff --git a/src/postProcessing/functionObjects/jobControl/jobControlFunctionObjectsDoc.H b/src/postProcessing/functionObjects/jobControl/doc/jobControlFunctionObjectsDoc.H
similarity index 100%
rename from src/postProcessing/functionObjects/jobControl/jobControlFunctionObjectsDoc.H
rename to src/postProcessing/functionObjects/jobControl/doc/jobControlFunctionObjectsDoc.H
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..ca7e2d3951d40e63de4a97b2e1f2c668ce05ed77
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C
@@ -0,0 +1,947 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "externalCoupledFunctionObject.H"
+#include "addToRunTimeSelectionTable.H"
+#include "OSspecific.H"
+#include "IFstream.H"
+#include "OFstream.H"
+#include "volFields.H"
+#include "globalIndex.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(externalCoupledFunctionObject, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        externalCoupledFunctionObject,
+        dictionary
+    );
+}
+
+Foam::word Foam::externalCoupledFunctionObject::lockName = "OpenFOAM";
+
+Foam::string Foam::externalCoupledFunctionObject::patchKey = "# Patch: ";
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::fileName Foam::externalCoupledFunctionObject::baseDir() const
+{
+    fileName result(commsDir_);
+    result.clean();
+
+    return result;
+}
+
+
+Foam::fileName Foam::externalCoupledFunctionObject::groupDir
+(
+    const fileName& commsDir,
+    const word& regionName,
+    const wordRe& groupName
+)
+{
+    fileName result(commsDir/regionName/string::validate<fileName>(groupName));
+    result.clean();
+
+    return result;
+}
+
+
+Foam::fileName Foam::externalCoupledFunctionObject::lockFile() const
+{
+    return fileName(baseDir()/(lockName + ".lock"));
+}
+
+
+void Foam::externalCoupledFunctionObject::createLockFile() const
+{
+    if (!Pstream::master())
+    {
+        return;
+    }
+
+    const fileName fName(lockFile());
+    IFstream is(fName);
+
+    // Only create lock file if it doesn't already exist
+    if (!is.good())
+    {
+        if (log_) Info<< type() << ": creating lock file" << endl;
+
+        OFstream os(fName);
+        os  << "lock file";
+        os.flush();
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::removeLockFile() const
+{
+    if (!Pstream::master())
+    {
+        return;
+    }
+
+    if (log_) Info<< type() << ": removing lock file" << endl;
+
+    rm(lockFile());
+}
+
+
+void Foam::externalCoupledFunctionObject::removeReadFiles() const
+{
+    if (!Pstream::master())
+    {
+        return;
+    }
+
+    if (log_) Info<< type() << ": removing all read files" << endl;
+
+    forAll(regionNames_, regionI)
+    {
+        const word& regionName = regionNames_[regionI];
+        const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+        const labelList& groups = regionToGroups_[regionName];
+        forAll(groups, i)
+        {
+            label groupI = groups[i];
+            const wordRe& groupName = groupNames_[groupI];
+
+            forAll(groupReadFields_[groupI], fieldI)
+            {
+                const word& fieldName = groupReadFields_[groupI][fieldI];
+                rm
+                (
+                    groupDir(commsDir_, mesh.dbDir(), groupName)
+                  / fieldName + ".in"
+                );
+            }
+        }
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::removeWriteFiles() const
+{
+    if (!Pstream::master())
+    {
+        return;
+    }
+
+    if (log_) Info<< type() << ": removing all write files" << endl;
+
+    forAll(regionNames_, regionI)
+    {
+        const word& regionName = regionNames_[regionI];
+        const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+        const labelList& groups = regionToGroups_[regionName];
+        forAll(groups, i)
+        {
+            label groupI = groups[i];
+            const wordRe& groupName = groupNames_[groupI];
+
+            forAll(groupWriteFields_[groupI], fieldI)
+            {
+                const word& fieldName = groupWriteFields_[groupI][fieldI];
+                rm
+                (
+                    groupDir(commsDir_, mesh.dbDir(), groupName)
+                  / fieldName + ".out"
+                );
+            }
+        }
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::wait() const
+{
+    const fileName fName(lockFile());
+    label found = 0;
+    label totalTime = 0;
+
+    if (log_) Info<< type() << ": beginning wait for lock file " << fName << nl;
+
+    while (found == 0)
+    {
+        if (Pstream::master())
+        {
+            if (totalTime > timeOut_)
+            {
+                FatalErrorIn
+                (
+                    "void "
+                    "Foam::externalCoupledFunctionObject::wait() "
+                    "const"
+                )
+                    << "Wait time exceeded time out time of " << timeOut_
+                    << " s" << abort(FatalError);
+            }
+
+            IFstream is(fName);
+
+            if (is.good())
+            {
+                found++;
+
+                if (log_)
+                {
+                    Info<< type() << ": found lock file " << fName << endl;
+                }
+            }
+            else
+            {
+                sleep(waitInterval_);
+                totalTime += waitInterval_;
+
+                if (log_)
+                {
+                    Info<< type() << ": wait time = " << totalTime << endl;
+                }
+            }
+        }
+
+        // prevent other procs from racing ahead
+        reduce(found, sumOp<label>());
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::readColumns
+(
+    const label nRows,
+    const label nColumns,
+    autoPtr<IFstream>& masterFilePtr,
+    List<scalarField>& data
+) const
+{
+    // Get sizes for all processors
+    const globalIndex globalFaces(nRows);
+
+    PstreamBuffers pBufs(Pstream::nonBlocking);
+    if (Pstream::master())
+    {
+        string line;
+
+        // Read data from file and send to destination processor
+
+        for (label procI = 0; procI < Pstream::nProcs(); procI++)
+        {
+            // Temporary storage
+            List<scalarField> values(nColumns);
+
+            // Number of rows to read for processor procI
+            label procNRows = globalFaces.localSize(procI);
+
+            forAll(values, columnI)
+            {
+                values[columnI].setSize(procNRows);
+            }
+
+            for (label rowI = 0; rowI < procNRows; rowI++)
+            {
+                // Get a line
+                do
+                {
+                    if (!masterFilePtr().good())
+                    {
+                        FatalIOErrorIn
+                        (
+                            "externalCoupledFunctionObject::readColumns()",
+                            masterFilePtr()
+                        )   << "Trying to read data for processor " << procI
+                            << " row " << rowI
+                            << ". Does your file have as many rows as there are"
+                            << " patch faces (" << globalFaces.size()
+                            << ") ?" << exit(FatalIOError);
+                    }
+
+                    masterFilePtr().getLine(line);
+                } while (line.empty() || line[0] == '#');
+
+                IStringStream lineStr(line);
+
+                for (label columnI = 0; columnI < nColumns; columnI++)
+                {
+                    lineStr >> values[columnI][rowI];
+                }
+            }
+
+            // Send to procI
+            UOPstream str(procI, pBufs);
+            str << values;
+        }
+    }
+    pBufs.finishedSends();
+
+    // Read from PstreamBuffers
+    UIPstream str(Pstream::masterNo(), pBufs);
+    str >> data;
+}
+
+
+void Foam::externalCoupledFunctionObject::readLines
+(
+    const label nRows,
+    autoPtr<IFstream>& masterFilePtr,
+    OStringStream& lines
+) const
+{
+    // Get sizes for all processors
+    const globalIndex globalFaces(nRows);
+
+    PstreamBuffers pBufs(Pstream::nonBlocking);
+
+    if (Pstream::master())
+    {
+        string line;
+
+        // Read line from file and send to destination processor
+
+        for (label procI = 0; procI < Pstream::nProcs(); procI++)
+        {
+            // Number of rows to read for processor procI
+            label procNRows = globalFaces.localSize(procI);
+
+            UOPstream toProc(procI, pBufs);
+
+            for (label rowI = 0; rowI < procNRows; rowI++)
+            {
+                // Get a line
+                do
+                {
+                    if (!masterFilePtr().good())
+                    {
+                        FatalIOErrorIn
+                        (
+                            "externalCoupledFunctionObject::readColumns()",
+                            masterFilePtr()
+                        )   << "Trying to read data for processor " << procI
+                            << " row " << rowI
+                            << ". Does your file have as many rows as there are"
+                            << " patch faces (" << globalFaces.size()
+                            << ") ?" << exit(FatalIOError);
+                    }
+
+                    masterFilePtr().getLine(line);
+                } while (line.empty() || line[0] == '#');
+
+                // Send line to the destination processor
+                toProc << line;
+            }
+        }
+    }
+
+
+    pBufs.finishedSends();
+
+    // Read lines from PstreamBuffers
+    UIPstream str(Pstream::masterNo(), pBufs);
+    for (label rowI = 0; rowI < nRows; rowI++)
+    {
+        string line(str);
+        lines << line.c_str() << nl;
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::writeGeometry
+(
+    const fvMesh& mesh,
+    const fileName& commsDir,
+    const wordRe& groupName
+)
+{
+    fileName dir(groupDir(commsDir, mesh.dbDir(), groupName));
+
+    //if (log_)
+    {
+        Info<< typeName << ": writing geometry to " << dir << endl;
+    }
+
+    autoPtr<OFstream> osPointsPtr;
+    autoPtr<OFstream> osFacesPtr;
+    if (Pstream::master())
+    {
+        mkDir(dir);
+        osPointsPtr.reset(new OFstream(dir/"patchPoints"));
+        osFacesPtr.reset(new OFstream(dir/"patchFaces"));
+    }
+
+    const labelList patchIDs
+    (
+        mesh.boundaryMesh().patchSet
+        (
+            List<wordRe>(1, groupName)
+        ).sortedToc()
+    );
+
+    forAll(patchIDs, i)
+    {
+        label patchI = patchIDs[i];
+
+        const polyPatch& p = mesh.boundaryMesh()[patchI];
+
+        labelList pointToGlobal;
+        labelList uniquePointIDs;
+        mesh.globalData().mergePoints
+        (
+            p.meshPoints(),
+            p.meshPointMap(),
+            pointToGlobal,
+            uniquePointIDs
+        );
+
+        label procI = Pstream::myProcNo();
+
+        List<pointField> allPoints(Pstream::nProcs());
+        allPoints[procI] = pointField(mesh.points(), uniquePointIDs);
+        Pstream::gatherList(allPoints);
+
+        List<faceList> allFaces(Pstream::nProcs());
+        faceList& patchFaces = allFaces[procI];
+        patchFaces = p.localFaces();
+        forAll(patchFaces, faceI)
+        {
+            inplaceRenumber(pointToGlobal, patchFaces[faceI]);
+        }
+        Pstream::gatherList(allFaces);
+
+        if (Pstream::master())
+        {
+            pointField pts
+            (
+                ListListOps::combine<pointField>
+                (
+                    allPoints,
+                    accessOp<pointField>()
+                )
+            );
+
+            //if (log_)
+            {
+                Info<< typeName << ": for patch " << p.name()
+                    << " writing " << pts.size() << " points to "
+                    << osPointsPtr().name() << endl;
+            }
+
+            // Write points
+            osPointsPtr() << patchKey.c_str() << p.name() << pts << endl;
+
+            faceList fcs
+            (
+                ListListOps::combine<faceList>(allFaces, accessOp<faceList>())
+            );
+
+            //if (log_)
+            {
+                Info<< typeName << ": for patch " << p.name()
+                    << " writing " << fcs.size() << " faces to "
+                    << osFacesPtr().name() << endl;
+            }
+
+            // Write faces
+            osFacesPtr() << patchKey.c_str() << p.name() << fcs << endl;
+        }
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::readData()
+{
+    forAll(regionNames_, regionI)
+    {
+        const word& regionName = regionNames_[regionI];
+        const labelList& groups = regionToGroups_[regionName];
+
+        const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+
+        forAll(groups, i)
+        {
+            label groupI = groups[i];
+            const wordRe& groupName = groupNames_[groupI];
+            const labelList& patchIDs = groupPatchIDs_[groupI];
+            const wordList& fieldNames = groupReadFields_[groupI];
+
+            forAll(fieldNames, fieldI)
+            {
+                const word& fieldName = fieldNames[fieldI];
+
+                bool ok = readData<scalar>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || readData<vector>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || readData<sphericalTensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || readData<symmTensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || readData<tensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+
+                if (!ok)
+                {
+                    WarningIn
+                    (
+                        "void Foam::externalCoupledFunctionObject::readData()"
+                    )
+                        << "Field " << fieldName << " in region " << mesh.name()
+                        << " was not found." << endl;
+                }
+            }
+        }
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::writeData() const
+{
+    forAll(regionNames_, regionI)
+    {
+        const word& regionName = regionNames_[regionI];
+        const labelList& groups = regionToGroups_[regionName];
+
+        const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+
+        forAll(groups, i)
+        {
+            label groupI = groups[i];
+            const wordRe& groupName = groupNames_[groupI];
+            const labelList& patchIDs = groupPatchIDs_[groupI];
+            const wordList& fieldNames = groupWriteFields_[groupI];
+
+            forAll(fieldNames, fieldI)
+            {
+                const word& fieldName = fieldNames[fieldI];
+                bool ok = writeData<scalar>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || writeData<vector>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || writeData<sphericalTensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || writeData<symmTensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+                ok = ok || writeData<tensor>
+                (
+                    mesh,
+                    groupName,
+                    patchIDs,
+                    fieldName
+                );
+
+                if (!ok)
+                {
+                    WarningIn
+                    (
+                        "void Foam::externalCoupledFunctionObject::writeData()"
+                    )
+                        << "Field " << fieldName << " in region " << mesh.name()
+                        << " was not found." << endl;
+                }
+            }
+        }
+    }
+}
+
+
+void Foam::externalCoupledFunctionObject::initialise()
+{
+    if (initialised_)
+    {
+        return;
+    }
+
+    // Write the geometry if not already there
+    forAll(regionNames_, regionI)
+    {
+        const word& regionName = regionNames_[regionI];
+        const labelList& groups = regionToGroups_[regionName];
+
+        const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+
+        forAll(groups, i)
+        {
+            label groupI = groups[i];
+            const wordRe& groupName = groupNames_[groupI];
+
+            bool exists = false;
+            if (Pstream::master())
+            {
+                fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName));
+
+                exists = isFile(dir/"patchPoints") || isFile(dir/"patchFaces");
+            }
+
+            if (!returnReduce(exists, orOp<bool>()))
+            {
+                writeGeometry(mesh, commsDir_, groupName);
+            }
+        }
+    }
+
+    if (initByExternal_)
+    {
+        // Wait for initial data to be made available
+        wait();
+
+        // Eead data passed back from external source
+        readData();
+    }
+
+    initialised_ = true;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::externalCoupledFunctionObject::externalCoupledFunctionObject
+(
+    const word& name,
+    const Time& runTime,
+    const dictionary& dict
+)
+:
+    functionObject(name),
+    time_(runTime),
+    enabled_(true),
+    initialised_(false)
+{
+    read(dict);
+
+    if (Pstream::master())
+    {
+        mkDir(baseDir());
+    }
+
+    if (!initByExternal_)
+    {
+        createLockFile();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::externalCoupledFunctionObject::~externalCoupledFunctionObject()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::externalCoupledFunctionObject::on()
+{
+    enabled_ = true;
+}
+
+
+void Foam::externalCoupledFunctionObject::off()
+{
+    enabled_ = false;
+}
+
+
+bool Foam::externalCoupledFunctionObject::start()
+{
+    return true;
+}
+
+
+bool Foam::externalCoupledFunctionObject::execute(const bool forceWrite)
+{
+    if
+    (
+        enabled()
+     && (!initialised_ || time_.timeIndex() % calcFrequency_ == 0)
+    )
+    {
+        // Initialise the coupling
+        initialise();
+
+        // Write data for external source
+        writeData();
+
+        // remove lock file, signalling external source to execute
+        removeLockFile();
+
+        // Wait for response
+        wait();
+
+        // Remove old data files from OpenFOAM
+        removeWriteFiles();
+
+        // Read data passed back from external source
+        readData();
+
+        // create lock file for external source
+        createLockFile();
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+bool Foam::externalCoupledFunctionObject::end()
+{
+    if (enabled())
+    {
+        // Remove old data files
+        removeReadFiles();
+        removeWriteFiles();
+        removeLockFile();
+    }
+
+    return true;
+}
+
+
+bool Foam::externalCoupledFunctionObject::timeSet()
+{
+    // Do nothing - only valid on execute
+    return true;
+}
+
+
+bool Foam::externalCoupledFunctionObject::adjustTimeStep()
+{
+    return true;
+}
+
+
+bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
+{
+    dict.readIfPresent("enabled", enabled_);
+
+    if (!enabled_)
+    {
+        return true;
+    }
+
+    dict.lookup("commsDir") >> commsDir_;
+    commsDir_.expand();
+
+    waitInterval_ = dict.lookupOrDefault("waitInterval", 1);
+    timeOut_ = dict.lookupOrDefault("timeOut", 100*waitInterval_);
+    calcFrequency_ = dict.lookupOrDefault("calcFrequency", 1);
+    initByExternal_ = readBool(dict.lookup("initByExternal"));
+    log_ = dict.lookupOrDefault("log", false);
+
+    const dictionary& allRegionsDict = dict.subDict("regions");
+
+    forAllConstIter(dictionary, allRegionsDict, iter)
+    {
+        if (!iter().isDict())
+        {
+            FatalIOErrorIn
+            (
+                "void Foam::externalCoupledFunctionObject::read"
+                "(const dictionary&)",
+                allRegionsDict
+            )
+                << "Regions must be specified in dictionary format"
+                << exit(FatalIOError);
+        }
+
+        const word& regionName = iter().keyword();
+        const dictionary& regionDict = iter().dict();
+        regionNames_.append(regionName);
+
+        forAllConstIter(dictionary, regionDict, regionIter)
+        {
+            if (!regionIter().isDict())
+            {
+                FatalIOErrorIn
+                (
+                    "void Foam::externalCoupledFunctionObject::read"
+                    "(const dictionary&)",
+                    regionDict
+                )
+                    << "Regions must be specified in dictionary format"
+                    << exit(FatalIOError);
+            }
+            const wordRe groupName(regionIter().keyword());
+            const dictionary& groupDict = regionIter().dict();
+
+            label nGroups = groupNames_.size();
+            const wordList readFields(groupDict.lookup("readFields"));
+            const wordList writeFields(groupDict.lookup("writeFields"));
+
+            HashTable<labelList>::iterator fnd = regionToGroups_.find
+            (
+                regionName
+            );
+            if (fnd != regionToGroups_.end())
+            {
+                fnd().append(nGroups);
+            }
+            else
+            {
+                regionToGroups_.insert(regionName, labelList(1, nGroups));
+            }
+            groupNames_.append(groupName);
+            groupReadFields_.append(readFields);
+            groupWriteFields_.append(writeFields);
+
+            // Pre-calculate the patchIDs
+            const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+            groupPatchIDs_.append
+            (
+                mesh.boundaryMesh().patchSet
+                (
+                    List<wordRe>(1, groupName)
+                ).sortedToc()
+            );
+        }
+    }
+
+
+    // Print a bit
+    if (log_)
+    {
+        Info<< type() << ": Communicating with regions:" << endl;
+        forAll(regionNames_, regionI)
+        {
+            const word& regionName = regionNames_[regionI];
+            const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+
+            Info<< "Region: " << mesh.name() << endl << incrIndent;
+            const labelList& groups = regionToGroups_[regionName];
+            forAll(groups, i)
+            {
+                label groupI = groups[i];
+                const wordRe& groupName = groupNames_[groupI];
+                const labelList& patchIDs = groupPatchIDs_[groupI];
+
+                Info<< indent << "Group: " << groupName << "\t"
+                    << " patches: " << patchIDs << endl
+                    << incrIndent
+                    << indent << "Reading fields: " << groupReadFields_[groupI]
+                    << endl
+                    << indent << "Writing fields: " << groupWriteFields_[groupI]
+                    << endl
+                    << decrIndent;
+            }
+            Info<< decrIndent;
+        }
+        Info<< endl;
+    }
+
+
+    // Note: we should not have to make directories since the geometry
+    //       should already be written - but just make sure
+    if (Pstream::master())
+    {
+        forAll(regionNames_, regionI)
+        {
+            const word& regionName = regionNames_[regionI];
+            const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
+            const labelList& groups = regionToGroups_[regionName];
+            forAll(groups, i)
+            {
+                label groupI = groups[i];
+                const wordRe& groupName = groupNames_[groupI];
+
+                fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName));
+                if (!isDir(dir))
+                {
+                    if (log_)
+                    {
+                        Info<< type() << ": creating communications directory "
+                        << dir << endl;
+                    }
+
+                    mkDir(dir);
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+
+void Foam::externalCoupledFunctionObject::updateMesh(const mapPolyMesh& mpm)
+{}
+
+
+void Foam::externalCoupledFunctionObject::movePoints(const polyMesh& mesh)
+{}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..7806e64d64aa89bfeef74a957bf6fc55f3244fe6
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H
@@ -0,0 +1,383 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify i
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::externalCoupledFunctionObject
+
+Group
+    grpJobControlFunctionObjects
+
+Description
+    This functionObject provides a simple interface for explicit coupling with
+    an external application. The coupling is through plain text files
+    where OpenFOAM boundary data is read/written as one line per face
+    (data from all processors collated):
+
+        # Patch: <patch name>
+        <fld1> <fld2> .. <fldn>             //face0
+        <fld1> <fld2> .. <fldn>             //face1
+        ..
+        <fld1> <fld2> .. <fldn>             //faceN
+
+    where the actual entries depend on the bc type:
+    - mixed: value, snGrad, refValue, refGrad, valueFraction
+    - externalCoupledMixed: output of writeData
+    - other: value, snGrad
+
+    These text files are located in a user specified communications directory
+    which gets read/written on the master processor only. In the
+    communications directory the structure will be
+
+        <regionName>/<patchGroup>/<fieldName>.[in|out]
+
+    At start-up, the boundary creates a lock file, i.e..
+
+        OpenFOAM.lock
+
+    ... to signal the external source to wait. During the functionObject
+    execution the boundary values are written to files (one per region,
+    per patch(group), per field), e.g.
+
+        <regionName>/<patchGroup>/<fieldName>.out
+
+    The lock file is then removed, instructing the external source to take
+    control of the program execution. When ready, the external program
+    should create the return values, e.g. to files
+
+        <regionName>/<patchGroup>/<fieldName>.in
+
+    ... and then re-instate the lock file. The functionObject will then
+    read these values, apply them to the boundary conditions and pass
+    program execution back to OpenFOAM.
+
+    Example of function object specification:
+    \verbatim
+    externalCoupled
+    {
+        type            externalCoupled;
+        ...
+        log             yes;
+        commsDir        "${FOAM_CASE}/comms";
+        initByExternal  yes;
+
+        regions
+        {
+            region0
+            {
+                TPatchGroup             // Name of patch(group)
+                {
+                    readFields  (p);    // List of fields to read
+                    writeFields (T);    // List of fields to write
+                }
+            }
+        }
+    }
+    \endverbatim
+
+    This reads/writes (on the master processor) the directory:
+        comms/region0/TPatchGroup/
+    with contents:
+        patchPoints     (collected points)
+        patchFaces      (collected faces)
+        p.in            (input file of p, written by external application)
+        T.out           (output file of T, written by OpenFOAM)
+
+    The patchPoints/patchFaces files denote the (collated) geometry
+    which will be written if it does not exist yet or can be written as
+    a preprocessing step using the createExternalCoupledPatchGeometry
+    application.
+
+SourceFiles
+    externalCoupledFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef externalCoupledFunctionObject_H
+#define externalCoupledFunctionObject_H
+
+#include "functionObject.H"
+#include "DynamicList.H"
+#include "wordReList.H"
+#include "scalarField.H"
+#include "Switch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class dictionary;
+class polyMesh;
+class mapPolyMesh;
+class IFstream;
+class fvMesh;
+
+/*---------------------------------------------------------------------------*\
+                Class externalCoupledFunctionObject Declaration
+\*---------------------------------------------------------------------------*/
+
+class externalCoupledFunctionObject
+:
+    public functionObject
+{
+    // Private data
+
+        //- Reference to the time database
+        const Time& time_;
+
+        //- Switch for the execution - defaults to 'yes/on'
+        Switch enabled_;
+
+        //- Path to communications directory
+        fileName commsDir_;
+
+        //- Interval time between checking for return data [s]
+        label waitInterval_;
+
+        //- Time out time [s]
+        label timeOut_;
+
+        //- Calculation frequency
+        label calcFrequency_;
+
+        //- Flag to indicate values are initialised by external application
+        bool initByExternal_;
+
+        //- Log flag
+        bool log_;
+
+        //- Names of regions
+        DynamicList<word> regionNames_;
+
+        // Per region the indices of the group information
+        HashTable<labelList> regionToGroups_;
+
+        // Per group the names of the patches/patchGroups
+        DynamicList<wordRe> groupNames_;
+
+        // Per group the indices of the patches
+        DynamicList<labelList> groupPatchIDs_;
+
+        // Per group the names of the fields to read
+        DynamicList<wordList> groupReadFields_;
+
+        // Per group the names of the fields to write
+        DynamicList<wordList> groupWriteFields_;
+
+        //- Initialised flag
+        bool initialised_;
+
+
+    // Private Member Functions
+
+        //- Return the file path to the communications directory for the region
+        static fileName groupDir
+        (
+            const fileName& commsDir,
+            const word& regionName,
+            const wordRe& groupName
+        );
+
+        //- Return the file path to the base communications directory
+        fileName baseDir() const;
+
+        //- Return the file path to the lock file
+        fileName lockFile() const;
+
+        //- Create lock file
+        void createLockFile() const;
+
+        //- Remove lock file
+        void removeLockFile() const;
+
+        //- Remove files written by OpenFOAM
+        void removeWriteFiles() const;
+
+        //- Remove files written by external code
+        void removeReadFiles() const;
+
+        //- Wait for response from external source
+        void wait() const;
+
+
+        //- Read data for a single region, single field
+        template<class Type>
+        bool readData
+        (
+            const fvMesh& mesh,
+            const wordRe& groupName,
+            const labelList& patchIDs,
+            const word& fieldName
+        );
+        //- Read data for all regions, all fields
+        void readData();
+
+        //- Write data for a single region, single field
+        template<class Type>
+        bool writeData
+        (
+            const fvMesh& mesh,
+            const wordRe& groupName,
+            const labelList& patchIDs,
+            const word& fieldName
+        ) const;
+
+        //- Write data for all regions, all fields
+        void writeData() const;
+
+        void initialise();
+
+        //- Read (and distribute) scalar columns from stream. Every processor
+        //  gets nRows (= patch size) of these. Note: could make its argument
+        //  ISstream& but then would need additional logic to construct valid
+        //  stream on all processors.
+        void readColumns
+        (
+            const label nRows,
+            const label nColumns,
+            autoPtr<IFstream>& masterFilePtr,
+            List<scalarField>& data
+        ) const;
+
+        //- Read (and distribute) lines from stream. Every processor
+        //  gets nRows (= patch size) of these. Data kept as stream (instead
+        //  of strings) for ease of interfacing to readData routines that take
+        //  an Istream.
+        void readLines
+        (
+            const label nRows,
+            autoPtr<IFstream>& masterFilePtr,
+            OStringStream& data
+        ) const;
+
+        //- Helper: append data from all processors onto master
+        template<class Type>
+        static tmp<Field<Type> > gatherAndCombine(const Field<Type>& fld);
+
+
+        //- Disallow default bitwise copy construc
+        externalCoupledFunctionObject(const externalCoupledFunctionObject&);
+
+        //- Disallow default bitwise assignmen
+        void operator=(const externalCoupledFunctionObject&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("externalCoupled");
+
+    //- Name of lock file
+    static word lockName;
+
+    //- Name of patch key, e.g. '# Patch:' when looking for start of patch data
+    static string patchKey;
+
+
+    // Constructors
+
+        //- Construct given time and dictionary
+        externalCoupledFunctionObject
+        (
+            const word& name,
+            const Time& runTime,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~externalCoupledFunctionObject();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Return the enabled flag
+            virtual bool enabled() const
+            {
+                return enabled_;
+            }
+
+
+        // Function object control
+
+            //- Switch the function object on
+            virtual void on();
+
+            //- Switch the function object off
+            virtual void off();
+
+            //- Called at the start of the time-loop
+            virtual bool start();
+
+            //- Called at each ++ or += of the time-loop
+            virtual bool execute(const bool forceWrite);
+
+            //- Called when Time::run() determines that the time-loop exits
+            virtual bool end();
+
+            //- Called when time was set at the end of the Time::operator++
+            virtual bool timeSet();
+
+            //- Called at the end of Time::adjustDeltaT() if adjustTime is true
+            virtual bool adjustTimeStep();
+
+            //- Read and set the function object if its data have changed
+            virtual bool read(const dictionary&);
+
+            //- Update for changes of mesh
+            virtual void updateMesh(const mapPolyMesh& mpm);
+
+            //- Update for changes of mesh
+            virtual void movePoints(const polyMesh& mesh);
+
+
+        // Other
+
+            //- Write geometry for the group/patch
+            static void writeGeometry
+            (
+                const fvMesh& mesh,
+                const fileName& commsDir,
+                const wordRe& groupName
+            );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "externalCoupledFunctionObjectTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..88477c5bb64ba253d3f26a24a9d03dfd90cd9def
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObjectTemplates.C
@@ -0,0 +1,459 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify i
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "externalCoupledFunctionObject.H"
+#include "OSspecific.H"
+#include "IFstream.H"
+#include "OFstream.H"
+#include "volFields.H"
+#include "externalCoupledMixedFvPatchFields.H"
+#include "mixedFvPatchFields.H"
+#include "fixedGradientFvPatchFields.H"
+#include "fixedValueFvPatchFields.H"
+#include "OStringStream.H"
+#include "globalIndex.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::externalCoupledFunctionObject::readData
+(
+    const fvMesh& mesh,
+    const wordRe& groupName,
+    const labelList& patchIDs,
+    const word& fieldName
+)
+{
+    typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+    typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
+
+    if (!mesh.foundObject<volFieldType>(fieldName))
+    {
+        return false;
+    }
+
+    const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
+    const typename volFieldType::GeometricBoundaryField& bf =
+        cvf.boundaryField();
+
+
+    // File only opened on master; contains data for all processors, for all
+    // patchIDs.
+    autoPtr<IFstream> masterFilePtr;
+    if (Pstream::master())
+    {
+        const fileName transferFile
+        (
+            groupDir(commsDir_, mesh.dbDir(), groupName)
+          / fieldName + ".in"
+        );
+
+        if (log_)
+        {
+            Info<< type() << ": reading data from " << transferFile << endl;
+        }
+        masterFilePtr.reset(new IFstream(transferFile));
+
+        if (!masterFilePtr().good())
+        {
+            FatalIOErrorIn
+            (
+                "void externalCoupledFunctionObject::readData"
+                "("
+                    "const fvMesh&, "
+                    "const wordRe&, "
+                    "const labelList&, "
+                    "const word&"
+               ")",
+                masterFilePtr()
+            )   << "Cannot open file for region " << mesh.name()
+                << ", field " << fieldName << ", patches " << patchIDs
+                << exit(FatalIOError);
+        }
+    }
+
+    // Handle column-wise reading of patch data. Supports most easy types
+    forAll(patchIDs, i)
+    {
+        label patchI = patchIDs[i];
+
+        if (isA<patchFieldType>(bf[patchI]))
+        {
+            // Explicit handling of externalCoupledObjectMixed bcs - they have
+            // specialised reading routines.
+
+            patchFieldType& pf = const_cast<patchFieldType&>
+            (
+                refCast<const patchFieldType>
+                (
+                    bf[patchI]
+                )
+            );
+
+            // Read from master into local stream
+            OStringStream os;
+            readLines
+            (
+                bf[patchI].size(),      // number of lines to read
+                masterFilePtr,
+                os
+            );
+
+            // Pass responsability for all reading over to bc
+            pf.readData(IStringStream(os.str())());
+
+            // Update the value from the read coefficicient. Bypass any
+            // additional processing by derived type.
+            pf.patchFieldType::evaluate();
+        }
+        else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
+        {
+            // Read columns from file for
+            // value, snGrad, refValue, refGrad, valueFraction
+            List<scalarField> data;
+            readColumns
+            (
+                bf[patchI].size(),              // number of lines to read
+                4*pTraits<Type>::nComponents+1, // nColumns: 4*Type + 1*scalar
+                masterFilePtr,
+                data
+            );
+
+            mixedFvPatchField<Type>& pf = const_cast<mixedFvPatchField<Type>&>
+            (
+                refCast<const mixedFvPatchField<Type> >
+                (
+                    bf[patchI]
+                )
+            );
+
+            // Transfer read data to bc.
+            // Skip value, snGrad
+            direction columnI = 2*pTraits<Type>::nComponents;
+
+            Field<Type>& refValue = pf.refValue();
+            for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
+            {
+                refValue.replace(cmpt, data[columnI++]);
+            }
+            Field<Type>& refGrad = pf.refGrad();
+            for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
+            {
+                refGrad.replace(cmpt, data[columnI++]);
+            }
+            pf.valueFraction() = data[columnI];
+
+            // Update the value from the read coefficicient. Bypass any
+            // additional processing by derived type.
+            pf.mixedFvPatchField<Type>::evaluate();
+        }
+        else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI]))
+        {
+            // Read columns for value and gradient
+            List<scalarField> data;
+            readColumns
+            (
+                bf[patchI].size(),              // number of lines to read
+                2*pTraits<Type>::nComponents,   // nColumns: Type
+                masterFilePtr,
+                data
+            );
+
+            fixedGradientFvPatchField<Type>& pf =
+            const_cast<fixedGradientFvPatchField<Type>&>
+            (
+                refCast<const fixedGradientFvPatchField<Type> >
+                (
+                    bf[patchI]
+                )
+            );
+
+            // Transfer gradient to bc
+            Field<Type>& gradient = pf.gradient();
+            for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
+            {
+                gradient.replace(cmpt, data[pTraits<Type>::nComponents+cmpt]);
+            }
+
+            // Update the value from the read coefficicient. Bypass any
+            // additional processing by derived type.
+            pf.fixedGradientFvPatchField<Type>::evaluate();
+        }
+        else if (isA<fixedValueFvPatchField<Type> >(bf[patchI]))
+        {
+            // Read columns for value only
+            List<scalarField> data;
+            readColumns
+            (
+                bf[patchI].size(),              // number of lines to read
+                pTraits<Type>::nComponents,     // number of columns to read
+                masterFilePtr,
+                data
+            );
+
+            // Transfer read value to bc
+            Field<Type> value(bf[patchI].size());
+            for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
+            {
+                value.replace(cmpt, data[cmpt]);
+            }
+
+            fixedValueFvPatchField<Type>& pf =
+            const_cast<fixedValueFvPatchField<Type>&>
+            (
+                refCast<const fixedValueFvPatchField<Type> >
+                (
+                    bf[patchI]
+                )
+            );
+
+            pf == value;
+
+            // Update the value from the read coefficicient. Bypass any
+            // additional processing by derived type.
+            pf.fixedValueFvPatchField<Type>::evaluate();
+        }
+        else
+        {
+            FatalErrorIn
+            (
+                "void externalCoupledFunctionObject::readData"
+                "("
+                    "const fvMesh&, "
+                    "const wordRe&, "
+                    "const labelList&, "
+                    "const word&"
+               ")"
+            )
+                << "Unsupported boundary condition " << bf[patchI].type()
+                << " for patch " << bf[patchI].patch().name()
+                << " in region " << mesh.name()
+                << exit(FatalError);
+        }
+
+        initialised_ = true;
+    }
+
+    return true;
+}
+
+
+template<class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::externalCoupledFunctionObject::gatherAndCombine
+(
+    const Field<Type>& fld
+)
+{
+    // Collect values from all processors
+    List<Field<Type> > gatheredValues(Pstream::nProcs());
+    gatheredValues[Pstream::myProcNo()] = fld;
+    Pstream::gatherList(gatheredValues);
+
+
+    tmp<Field<Type> > tresult(new Field<Type>(0));
+    Field<Type>& result = tresult();
+
+    if (Pstream::master())
+    {
+        // Combine values into single field
+        label globalElemI = 0;
+
+        forAll(gatheredValues, lstI)
+        {
+            globalElemI += gatheredValues[lstI].size();
+        }
+
+        result.setSize(globalElemI);
+
+        globalElemI = 0;
+
+        forAll(gatheredValues, lstI)
+        {
+            const Field<Type>& sub = gatheredValues[lstI];
+
+            forAll(sub, elemI)
+            {
+                result[globalElemI++] = sub[elemI];
+            }
+        }
+    }
+
+    return tresult;
+}
+
+
+template<class Type>
+bool Foam::externalCoupledFunctionObject::writeData
+(
+    const fvMesh& mesh,
+    const wordRe& groupName,
+    const labelList& patchIDs,
+    const word& fieldName
+) const
+{
+    typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+    typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
+
+    if (!mesh.foundObject<volFieldType>(fieldName))
+    {
+        return false;
+    }
+
+    const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
+    const typename volFieldType::GeometricBoundaryField& bf =
+        cvf.boundaryField();
+
+
+    // File only opened on master; contains data for all processors, for all
+    // patchIDs
+    autoPtr<OFstream> masterFilePtr;
+    if (Pstream::master())
+    {
+        const fileName transferFile
+        (
+            groupDir(commsDir_, mesh.dbDir(), groupName)
+          / fieldName + ".out"
+        );
+
+        if (log_)
+        {
+            Info<< type() << ": writing data to " << transferFile << endl;
+        }
+        masterFilePtr.reset(new OFstream(transferFile));
+
+        if (!masterFilePtr().good())
+        {
+            FatalIOErrorIn
+            (
+                "externalCoupledFunctionObject::writeData"
+                "("
+                    "const fvMesh&, "
+                    "const wordRe&, "
+                    "const labelList&, "
+                    "const word&"
+                ") const",
+                masterFilePtr()
+            )   << "Cannot open file for region " << mesh.name()
+                << ", field " << fieldName << ", patches " << patchIDs
+                << exit(FatalIOError);
+        }
+    }
+
+
+    bool headerDone = false;
+
+    // Handle column-wise writing of patch data. Supports most easy types
+    forAll(patchIDs, i)
+    {
+        label patchI = patchIDs[i];
+
+        const globalIndex globalFaces(bf[patchI].size());
+
+        if (isA<patchFieldType>(bf[patchI]))
+        {
+            // Explicit handling of externalCoupledObjectMixed bcs - they have
+            // specialised writing routines
+
+            const patchFieldType& pf = refCast<const patchFieldType>
+            (
+                bf[patchI]
+            );
+            OStringStream os;
+
+            // Pass responsibility for all writing over to bc
+            pf.writeData(os);
+
+            // Collect contributions from all processors and output them on
+            // master
+            if (Pstream::master())
+            {
+                // Output master data first
+                if (!headerDone)
+                {
+                    pf.writeHeader(masterFilePtr());
+                    headerDone = true;
+                }
+                masterFilePtr() << os.str().c_str();
+
+                for (label procI = 1; procI < Pstream::nProcs(); procI++)
+                {
+                    IPstream fromSlave(Pstream::scheduled, procI);
+                    string str(fromSlave);
+                    masterFilePtr() << str.c_str();
+                }
+            }
+            else
+            {
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+                toMaster << os.str();
+            }
+        }
+        else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
+        {
+            const mixedFvPatchField<Type>& pf =
+                refCast<const mixedFvPatchField<Type> >(bf[patchI]);
+
+            Field<Type> value(gatherAndCombine(pf));
+            Field<Type> snGrad(gatherAndCombine(pf.snGrad()()));
+            Field<Type> refValue(gatherAndCombine(pf.refValue()));
+            Field<Type> refGrad(gatherAndCombine(pf.refGrad()));
+            scalarField valueFraction(gatherAndCombine(pf.valueFraction()));
+
+            if (Pstream::master())
+            {
+                forAll(refValue, faceI)
+                {
+                    masterFilePtr()
+                        << value[faceI] << token::SPACE
+                        << snGrad[faceI] << token::SPACE
+                        << refValue[faceI] << token::SPACE
+                        << refGrad[faceI] << token::SPACE
+                        << valueFraction[faceI] << nl;
+                }
+            }
+        }
+        else
+        {
+            // Output the value and snGrad
+            Field<Type> value(gatherAndCombine(bf[patchI]));
+            Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()()));
+            if (Pstream::master())
+            {
+                forAll(value, faceI)
+                {
+                    masterFilePtr()
+                        << value[faceI] << token::SPACE
+                        << snGrad[faceI] << nl;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C
new file mode 100644
index 0000000000000000000000000000000000000000..c99e3cc1e5a044308357dd30e18e402f1b542412
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.C
@@ -0,0 +1,168 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "externalCoupledMixedFvPatchField.H"
+#include "fvPatchFieldMapper.H"
+#include "ISstream.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+externalCoupledMixedFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF
+)
+:
+    mixedFvPatchField<Type>(p, iF)
+{
+    this->refValue() = pTraits<Type>::zero;
+    this->refGrad() = pTraits<Type>::zero;
+    this->valueFraction() = 0.0;
+}
+
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+externalCoupledMixedFvPatchField
+(
+    const externalCoupledMixedFvPatchField& ptf,
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    mixedFvPatchField<Type>(ptf, p, iF, mapper)
+{}
+
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+externalCoupledMixedFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    mixedFvPatchField<Type>(p, iF, dict)
+{}
+
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+externalCoupledMixedFvPatchField
+(
+    const externalCoupledMixedFvPatchField& ecmpf
+)
+:
+    mixedFvPatchField<Type>(ecmpf)
+{}
+
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+externalCoupledMixedFvPatchField
+(
+    const externalCoupledMixedFvPatchField& ecmpf,
+    const DimensionedField<Type, volMesh>& iF
+)
+:
+    mixedFvPatchField<Type>(ecmpf, iF)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+template<class Type>
+Foam::externalCoupledMixedFvPatchField<Type>::
+~externalCoupledMixedFvPatchField()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type>
+void Foam::externalCoupledMixedFvPatchField<Type>::writeHeader
+(
+    Ostream& os
+) const
+{
+    os  << "# Values: value snGrad refValue refGrad valueFraction" << endl;
+}
+
+
+template<class Type>
+void Foam::externalCoupledMixedFvPatchField<Type>::writeData
+(
+    Ostream& os
+) const
+{
+    const Field<Type> snGrad(this->snGrad());
+    const Field<Type>& refValue(this->refValue());
+    const Field<Type>& refGrad(this->refGrad());
+    const scalarField& valueFraction(this->valueFraction());
+
+    forAll(refValue, faceI)
+    {
+        os  << this->operator[](faceI) << token::SPACE
+            << snGrad[faceI] << token::SPACE
+            << refValue[faceI] << token::SPACE
+            << refGrad[faceI] << token::SPACE
+            << valueFraction[faceI] << nl;
+    }
+}
+
+
+template<class Type>
+void Foam::externalCoupledMixedFvPatchField<Type>::readData(Istream& is)
+{
+    // Assume generic input stream so we can do line-based format and skip
+    // unused columns
+    ISstream& iss = dynamic_cast<ISstream&>(is);
+
+    string line;
+
+    forAll(*this, faceI)
+    {
+        iss.getLine(line);
+        IStringStream lineStr(line);
+
+        // For symmetry with writing ignore value, snGrad columns
+
+        Type value, snGrad;
+
+        lineStr
+            >> value
+            >> snGrad
+            >> this->refValue()[faceI]
+            >> this->refGrad()[faceI]
+            >> this->valueFraction()[faceI];
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H
new file mode 100644
index 0000000000000000000000000000000000000000..2d700207d19e9987471585aa76ceb7e51c543473
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchField.H
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::externalCoupledMixedFvPatchField
+
+Group
+    grpGenericBoundaryConditions grpCoupledBoundaryConditions
+
+Description
+    This boundary condition extends the mixed boundary condition with
+    serialisation through
+    - writeHeader
+    - writeData
+    - readData
+    functions. It is used for coupling to external applications in combination
+    with the externalCoupled functionObject. The default output is one
+    line per face, with columns
+    <value> <snGrad> <refValue> <refGrad> <valueFraction>
+
+Notes
+    readData,writeData are not callbacks for regIOobject (since fvPatchField
+    not derived from it). They do however do exactly the same - streaming of
+    data.
+
+SeeAlso
+    mixedFvPatchField
+    externalCoupledFunctionObject
+
+SourceFiles
+    externalCoupledMixedFvPatchField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef externalCoupledMixedFvPatchField_H
+#define externalCoupledMixedFvPatchField_H
+
+#include "mixedFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+              Class externalCoupledMixedFvPatchField Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Type>
+class externalCoupledMixedFvPatchField
+:
+    public mixedFvPatchField<Type>
+{
+
+public:
+
+    //- Runtime type information
+    TypeName("externalCoupled");
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        externalCoupledMixedFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        externalCoupledMixedFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given externalCoupledMixedFvPatchField
+        //  onto a new patch
+        externalCoupledMixedFvPatchField
+        (
+            const externalCoupledMixedFvPatchField<Type>&,
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        externalCoupledMixedFvPatchField
+        (
+            const externalCoupledMixedFvPatchField&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchField<Type> > clone() const
+        {
+            return tmp<fvPatchField<Type> >
+            (
+                new externalCoupledMixedFvPatchField<Type>(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        externalCoupledMixedFvPatchField
+        (
+            const externalCoupledMixedFvPatchField&,
+            const DimensionedField<Type, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchField<Type> > clone
+        (
+            const DimensionedField<Type, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchField<Type> >
+            (
+                new externalCoupledMixedFvPatchField<Type>(*this, iF)
+            );
+        }
+
+
+    //- Destructor
+    virtual ~externalCoupledMixedFvPatchField();
+
+
+    // Member functions
+
+        //- Write header
+        virtual void writeHeader(Ostream&) const;
+
+        //- Write data
+        virtual void writeData(Ostream&) const;
+
+        //- Read data
+        virtual void readData(Istream&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "externalCoupledMixedFvPatchField.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
similarity index 95%
rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
index 42ab10636d5cf304bfadc234540066b8e5d62a85..3a5bce74c4f5e1d3ef409b72c10be15d6ce44306 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H
similarity index 95%
rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H
rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H
index 36d457004b0a9992f7fa24ba7048fcef6327a3e8..72b563638ba0423166ab5b900fb08764bc699fb1 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFields.H
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFields.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H
similarity index 95%
rename from src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H
rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H
index 7aae5c7b502ea25242f635c936398f08d5873d9f..b39a8d7da5c20c91b0c7bf49a9b02fe2a17a839b 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledMixed/externalCoupledMixedFvPatchFieldsFwd.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
diff --git a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
similarity index 65%
rename from src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
index 9791087190b487ef22cbe9deb6b30f7c57071e6e..7f8e23041b7e6fb8bb8e8fea498007d7be4dfd83 100644
--- a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.C
@@ -28,16 +28,15 @@ License
 #include "addToRunTimeSelectionTable.H"
 #include "fvPatchFieldMapper.H"
 #include "volFields.H"
-#include "OFstream.H"
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeHeader
 (
-    OFstream& os
+    Ostream& os
 ) const
 {
-    os  << "# Values: magSf value qDot htc" << endl;
+    os  << "# Values: magSf T qDot htc" << endl;
 }
 
 
@@ -75,8 +74,40 @@ externalCoupledTemperatureMixedFvPatchScalarField
     const dictionary& dict
 )
 :
-    externalCoupledMixedFvPatchField<scalar>(p, iF, dict)
-{}
+    //externalCoupledMixedFvPatchField<scalar>(p, iF, dict)
+    externalCoupledMixedFvPatchField<scalar>(p, iF)
+{
+    if (dict.found("refValue"))
+    {
+        // Initialise same way as mixed
+        this->refValue() = scalarField("refValue", dict, p.size());
+        this->refGrad() = scalarField("refGradient", dict, p.size());
+        this->valueFraction() = scalarField("valueFraction", dict, p.size());
+
+        evaluate();
+    }
+    else
+    {
+        // For convenience: initialise as fixedValue with either read value
+        // or extrapolated value
+        if (dict.found("value"))
+        {
+            fvPatchField<scalar>::operator=
+            (
+                scalarField("value", dict, p.size())
+            );
+        }
+        else
+        {
+            fvPatchField<scalar>::operator=(this->patchInternalField());
+        }
+
+        // Initialise as a fixed value
+        this->refValue() = *this;
+        this->refGrad() = pTraits<scalar>::zero;
+        this->valueFraction() = 1.0;
+    }
+}
 
 
 Foam::externalCoupledTemperatureMixedFvPatchScalarField::
@@ -109,21 +140,14 @@ Foam::externalCoupledTemperatureMixedFvPatchScalarField::
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
+void Foam::externalCoupledTemperatureMixedFvPatchScalarField::writeData
 (
-    OFstream& os
+    Ostream& os
 ) const
 {
-    if (log())
-    {
-        Info<< type() << ": " << this->patch().name()
-            << ": writing data to " << os.name()
-            << endl;
-    }
-
     const label patchI = patch().index();
 
-    // heat flux [W/m2]
+    // Heat flux [W/m2]
     scalarField qDot(this->patch().size(), 0.0);
 
     typedef compressible::turbulenceModel cmpTurbModelType;
@@ -137,7 +161,7 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
         )
     );
 
-    static word thermoName(basicThermo::dictName);
+    static word thermoName("thermophysicalProperties");
 
     if (db().foundObject<cmpTurbModelType>(turbName))
     {
@@ -165,100 +189,55 @@ void Foam::externalCoupledTemperatureMixedFvPatchScalarField::transferData
             "void Foam::externalCoupledTemperatureMixedFvPatchScalarField::"
             "transferData"
             "("
-                "OFstream&"
+                "Ostream&"
             ") const"
         )   << "Condition requires either compressible turbulence and/or "
             << "thermo model to be available" << exit(FatalError);
     }
 
-    // patch temperature [K]
-    const scalarField Tp(*this);
+    // Patch temperature [K]
+    const scalarField& Tp(*this);
 
-    // near wall cell temperature [K]
+    // Near wall cell temperature [K]
     const scalarField Tc(patchInternalField());
 
-    // heat transfer coefficient [W/m2/K]
+    // Heat transfer coefficient [W/m2/K]
     const scalarField htc(qDot/(Tp - Tc + ROOTVSMALL));
 
-    if (Pstream::parRun())
-    {
-        int tag = Pstream::msgType() + 1;
+    const Field<scalar>& magSf(this->patch().magSf());
 
-        List<Field<scalar> > magSfs(Pstream::nProcs());
-        magSfs[Pstream::myProcNo()].setSize(this->patch().size());
-        magSfs[Pstream::myProcNo()] = this->patch().magSf();
-        Pstream::gatherList(magSfs, tag);
-
-        List<Field<scalar> > values(Pstream::nProcs());
-        values[Pstream::myProcNo()].setSize(this->patch().size());
-        values[Pstream::myProcNo()] = Tp;
-        Pstream::gatherList(values, tag);
-
-        List<Field<scalar> > qDots(Pstream::nProcs());
-        qDots[Pstream::myProcNo()].setSize(this->patch().size());
-        qDots[Pstream::myProcNo()] = qDot;
-        Pstream::gatherList(qDots, tag);
-
-        List<Field<scalar> > htcs(Pstream::nProcs());
-        htcs[Pstream::myProcNo()].setSize(this->patch().size());
-        htcs[Pstream::myProcNo()] = htc;
-        Pstream::gatherList(htcs, tag);
-
-        if (Pstream::master())
-        {
-            forAll(values, procI)
-            {
-                const Field<scalar>& magSf = magSfs[procI];
-                const Field<scalar>& value = values[procI];
-                const Field<scalar>& qDot = qDots[procI];
-                const Field<scalar>& htc = htcs[procI];
-
-                forAll(magSf, faceI)
-                {
-                    os  << magSf[faceI] << token::SPACE
-                        << value[faceI] << token::SPACE
-                        << qDot[faceI] << token::SPACE
-                        << htc[faceI] << token::SPACE
-                        << nl;
-                }
-            }
-
-            os.flush();
-        }
-    }
-    else
+    forAll(patch(), faceI)
     {
-        const Field<scalar>& magSf(this->patch().magSf());
-
-        forAll(patch(), faceI)
-        {
-            os  << magSf[faceI] << token::SPACE
-                << Tp[faceI] << token::SPACE
-                << qDot[faceI] << token::SPACE
-                << htc[faceI] << token::SPACE
-                << nl;
-        }
-
-        os.flush();
+        os  << magSf[faceI] << token::SPACE
+            << Tp[faceI] << token::SPACE
+            << qDot[faceI] << token::SPACE
+            << htc[faceI] << token::SPACE
+            << nl;
     }
 }
 
 
-void Foam::externalCoupledTemperatureMixedFvPatchScalarField::evaluate
+void Foam::externalCoupledTemperatureMixedFvPatchScalarField::readData
 (
-    const Pstream::commsTypes comms
+    Istream& is
 )
 {
-    externalCoupledMixedFvPatchField<scalar>::evaluate(comms);
-}
+    // Assume generic input stream so we can do line-based format and skip
+    // unused columns
+    ISstream& iss = dynamic_cast<ISstream&>(is);
 
+    string line;
 
-void Foam::externalCoupledTemperatureMixedFvPatchScalarField::write
-(
-    Ostream& os
-) const
-{
-    externalCoupledMixedFvPatchField<scalar>::write(os);
+    forAll(*this, faceI)
+    {
+        iss.getLine(line);
+        IStringStream lineStr(line);
+
+        lineStr
+            >> this->refValue()[faceI]
+            >> this->refGrad()[faceI]
+            >> this->valueFraction()[faceI];
+    }
 }
 
 
diff --git a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H
similarity index 67%
rename from src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H
rename to src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H
index 47fb9153185cd3ec0ab3ea2c7943162f2b80e7c6..23679aac309770cf3bf27f9ee8119cadef922f86 100644
--- a/src/TurbulenceModels/compressible/turbulentFluidThermoModels/derivedFvPatchFields/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledTemperatureMixed/externalCoupledTemperatureMixedFvPatchScalarField.H
@@ -29,7 +29,7 @@ Group
 
 Description
     This boundary condition provides a temperatue interface to an external
-    application.  Values are transferred as plain text files, where OpenFOAM
+    application. Values are transferred as plain text files, where OpenFOAM
     data is written as:
 
         # Patch: <patch name>
@@ -42,59 +42,16 @@ Description
     and received as the constituent pieces of the `mixed' condition, i.e.
 
         # Patch: <patch name>
-        <value1> <gradient1> <valueFracion1>
-        <value2> <gradient2> <valueFracion2>
-        <value3> <gradient3> <valueFracion3>
-        ...
-        <valueN> <gradientN> <valueFracionN>
-
-    Data is sent/received as a single file for all patches from the directory
-
-        $FOAM_CASE/<commsDir>
-
-    At start-up, the boundary creates a lock file, i.e..
-
-        OpenFOAM.lock
-
-    ... to signal the external source to wait.  During the boundary condition
-    update, boundary values are written to file, e.g.
-
-        <fileName>.out
-
-    The lock file is then removed, instructing the external source to take
-    control of the program execution.  When ready, the external program
-    should create the return values, e.g. to file
-
-        <fileName>.in
-
-    ... and then re-instate the lock file.  The boundary condition will then
-    read the return values, and pass program execution back to OpenFOAM.
-
+        <refValue1> <refGrad1> <valueFraction1>
+        <refValue2> <refGrad2> <valueFraction2>
+        <refValue3> <refGrad3> <valueFraction3>
+          ...
+        <refValueN> <refGradN> <valueFractionN>
 
-    \heading Patch usage
-
-    \table
-        Property     | Description             | Required    | Default value
-        commsDir     | communications directory   | yes         |
-        fileName     | transfer file name      | yes         |
-        waitInterval | interval [s] between file checks | no | 1
-        timeOut      | time after which error invoked [s] |no |100*waitInterval
-        calcFrequency | calculation frequency  | no          | 1
-        log          | log program control     | no          | no
-    \endtable
-
-    Example of the boundary condition specification:
-    \verbatim
-    myPatch
-    {
-        type            externalCoupledTemperature;
-        commsDir        "$FOAM_CASE/comms";
-        fileName        data;
-        calcFrequency   1;
-    }
-    \endverbatim
+    To be used in combination with the externalCoupled functionObject.
 
 SeeAlso
+    externalCoupledFunctionObject
     mixedFvPatchField
     externalCoupledMixedFvPatchField
 
@@ -113,10 +70,8 @@ SourceFiles
 namespace Foam
 {
 
-class IFstream;
-
 /*---------------------------------------------------------------------------*\
-     Class externalCoupledTemperatureMixedFvPatchScalarField Declaration
+      Class externalCoupledTemperatureMixedFvPatchScalarField Declaration
 \*---------------------------------------------------------------------------*/
 
 class externalCoupledTemperatureMixedFvPatchScalarField
@@ -124,14 +79,6 @@ class externalCoupledTemperatureMixedFvPatchScalarField
     public externalCoupledMixedFvPatchField<scalar>
 {
 
-protected:
-
-    // Protected Member Functions
-
-        //- Write header to transfer file
-        virtual void writeHeader(OFstream& os) const;
-
-
 public:
 
     //- Runtime type information
@@ -210,20 +157,14 @@ public:
 
     // Member functions
 
-        // Evaluation functions
-
-            //- Evaluate the patch field
-            virtual void evaluate
-            (
-                const Pstream::commsTypes commsType=Pstream::blocking
-            );
-
-            //- Transfer data for external source
-            virtual void transferData(OFstream& os) const;
+        //- Write header
+        virtual void writeHeader(Ostream&) const;
 
+        //- Write data
+        virtual void writeData(Ostream&) const;
 
-        //- Write
-        virtual void write(Ostream&) const;
+        //- Read data
+        virtual void readData(Istream&);
 };
 
 
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H
new file mode 100644
index 0000000000000000000000000000000000000000..da73cb5db366e6cc2223fcb7187b5d9fd6dae7dc
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/IOrunTimeControl.H
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::IOrunTimeControl
+
+Description
+    Instance of the generic IOOutputFilter for runTimeControl.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IOrunTimeControl_H
+#define IOrunTimeControl_H
+
+#include "runTimeControl.H"
+#include "IOOutputFilter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef IOOutputFilter<runTimeControl> IOrunTimeControl;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..1c47a2ea1f6500df1e040f1a6143a3c4046d6b63
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.C
@@ -0,0 +1,179 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "averageCondition.H"
+#include "addToRunTimeSelectionTable.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(averageCondition, 0);
+    addToRunTimeSelectionTable(runTimeCondition, averageCondition, dictionary);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::averageCondition::averageCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    runTimeCondition(name, obr, dict, state),
+    functionObjectName_(dict.lookup("functionObjectName")),
+    fieldNames_(dict.lookup("fields")),
+    tolerance_(readScalar(dict.lookup("tolerance"))),
+    window_(dict.lookupOrDefault<scalar>("window", -1)),
+    totalTime_(fieldNames_.size(), obr_.time().deltaTValue()),
+    resetOnRestart_(false)
+{
+    if (resetOnRestart_)
+    {
+        const dictionary& dict = conditionDict();
+
+        forAll(fieldNames_, fieldI)
+        {
+            const word& fieldName = fieldNames_[fieldI];
+
+            if (dict.found(fieldName))
+            {
+                const dictionary& valueDict = dict.subDict(fieldName);
+                totalTime_[fieldI] = readScalar(valueDict.lookup("totalTime"));
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::averageCondition::~averageCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::averageCondition::apply()
+{
+    bool satisfied = true;
+
+    if (!active_)
+    {
+        return satisfied;
+    }
+
+    scalar dt = obr_.time().deltaTValue();
+
+    if (log_) Info<< "    " << type() << ": " << name_ << " averages:" << nl;
+
+    DynamicList<label> unprocessedFields(fieldNames_.size());
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName(fieldNames_[fieldI]);
+
+        scalar Dt = totalTime_[fieldI];
+        scalar alpha = (Dt - dt)/Dt;
+        scalar beta = dt/Dt;
+
+        if (window_ > 0)
+        {
+            if (Dt - dt >= window_)
+            {
+                alpha = (window_ - dt)/window_;
+                beta = dt/window_;
+            }
+            else
+            {
+                // Ensure that averaging is performed over window time
+                // before condition can be satisfied
+                satisfied = false;
+            }
+        }
+
+        bool processed = false;
+        calc<scalar>(fieldName, alpha, beta, satisfied, processed);
+        calc<vector>(fieldName, alpha, beta, satisfied, processed);
+        calc<sphericalTensor>(fieldName, alpha, beta, satisfied, processed);
+        calc<symmTensor>(fieldName, alpha, beta, satisfied, processed);
+        calc<tensor>(fieldName, alpha, beta, satisfied, processed);
+
+        if (!processed)
+        {
+            unprocessedFields.append(fieldI);
+        }
+
+        totalTime_[fieldI] += dt;
+    }
+
+    if (unprocessedFields.size())
+    {
+        WarningIn("bool Foam::averageCondition::apply()")
+            << "From function object: " << functionObjectName_ << nl
+            << "Unprocessed fields:" << nl;
+
+        forAll(unprocessedFields, i)
+        {
+            label fieldI = unprocessedFields[i];
+            Info<< "        " << fieldNames_[fieldI] << nl;
+        }
+    }
+
+    if (log_) Info<< endl;
+
+    return satisfied;
+}
+
+
+void Foam::averageCondition::write()
+{
+    dictionary& conditionDict = this->conditionDict();
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName = fieldNames_[fieldI];
+
+        // value dictionary should be present - mean values are written there
+        if (conditionDict.found(fieldName))
+        {
+            dictionary& valueDict = conditionDict.subDict(fieldName);
+            valueDict.add("totalTime", totalTime_[fieldI], true);
+        }
+        else
+        {
+            dictionary valueDict;
+            valueDict.add("totalTime", totalTime_[fieldI], true);
+            conditionDict.add(fieldName, valueDict);
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..0734cda8fd9309f9a7abaf7b6496adbeede529f2
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageCondition.H
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::averageCondition
+
+Description
+    Average run time condition - satisfied when average does not change by
+    more than a given value.
+
+SourceFiles
+    averageCondition.H
+    averageCondition.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef averageCondition_H
+#define averageCondition_H
+
+#include "runTimeCondition.H"
+#include "Switch.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class averageCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class averageCondition
+:
+    public runTimeCondition
+{
+protected:
+
+    // Protected data
+
+        //- Name of function object to retrueve data from
+        word functionObjectName_;
+
+        //- List of fields on which to operate
+        wordList fieldNames_;
+
+        //- Satisfied when difference in mean values is less than this value
+        const scalar tolerance_;
+
+        //- Averaging window
+        const scalar window_;
+
+        //- Average time per field
+        List<scalar> totalTime_;
+
+        //- Reset the averaging process on restart flag
+        Switch resetOnRestart_;
+
+
+    // Protected Member Functions
+
+        //- Templated function to calculate the average
+        template<class Type>
+        void calc
+        (
+            const word& fieldName,
+            const scalar alpha,
+            const scalar beta,
+            bool& satisfied,
+            bool& processed
+        );
+
+
+public:
+
+    //- Runtime type information
+    TypeName("average");
+
+    //- Constructor
+    averageCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~averageCondition();
+
+
+    // Public Member Functions
+
+        //- Apply the condition
+        virtual bool apply();
+
+        //- Write
+        virtual void write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "averageConditionTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..d5d35ed61d79f155002e197d877db2e67f3c4ac4
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/averageCondition/averageConditionTemplates.C
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+template<class Type>
+void Foam::averageCondition::calc
+(
+    const word& fieldName,
+    const scalar alpha,
+    const scalar beta,
+    bool& satisfied,
+    bool& processed
+)
+{
+    const word valueType =
+        state_.objectResultType(functionObjectName_, fieldName);
+
+    if (pTraits<Type>::typeName != valueType)
+    {
+        return;
+    }
+
+    Type currentValue =
+        state_.getObjectResult<Type>(functionObjectName_, fieldName);
+
+    const word meanName(fieldName + "Mean");
+
+    Type meanValue = state_.getResult<Type>(meanName);
+    meanValue = alpha*meanValue + beta*currentValue;
+
+    scalar delta = mag(meanValue - currentValue);
+
+    if (log_)
+    {
+        Info<< "        " << meanName << ": " << meanValue
+            << ", delta: " << delta << nl;
+    }
+
+    state_.setResult(meanName, meanValue);
+
+    if (delta > tolerance_)
+    {
+        satisfied = false;
+    }
+
+    processed = true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..73de3e3f3d45f7aeee2ba27a0237755fba3bfe98
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.C
@@ -0,0 +1,222 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "equationInitialResidualCondition.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(equationInitialResidualCondition, 0);
+    addToRunTimeSelectionTable
+    (
+        runTimeCondition,
+        equationInitialResidualCondition,
+        dictionary
+    );
+
+    template<>
+    const char* Foam::NamedEnum
+    <
+        equationInitialResidualCondition::operatingMode,
+        2
+    >::names[] =
+    {
+        "minimum",
+        "maximum"
+    };
+
+    const NamedEnum<Foam::equationInitialResidualCondition::operatingMode, 2>
+        Foam::equationInitialResidualCondition::operatingModeNames;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::equationInitialResidualCondition::equationInitialResidualCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    runTimeCondition(name, obr, dict, state),
+    fieldNames_(dict.lookup("fields")),
+    value_(readScalar(dict.lookup("value"))),
+    timeStart_(dict.lookupOrDefault("timeStart", -GREAT)),
+    mode_(operatingModeNames.read(dict.lookup("mode")))
+{
+    if (!fieldNames_.size())
+    {
+        WarningIn
+        (
+            "Foam::equationInitialResidualCondition::"
+            "equationInitialResidualCondition"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "functionObjectState&"
+            ")"
+        )
+            << "No fields supplied: deactivating" << endl;
+
+        active_ = false;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::equationInitialResidualCondition::
+~equationInitialResidualCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::equationInitialResidualCondition::apply()
+{
+    bool satisfied = false;
+
+    if (!active_)
+    {
+        return true;
+    }
+
+    if ((obr_.time().timeIndex() < 3) || (obr_.time().value() < timeStart_))
+    {
+        // Do not start checking until reached start time
+        return false;
+    }
+
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+    const dictionary& solverDict = mesh.solverPerformanceDict();
+
+    List<scalar> result(fieldNames_.size(), -VGREAT);
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName = fieldNames_[fieldI];
+
+        if (solverDict.found(fieldName))
+        {
+            const List<solverPerformance> sp(solverDict.lookup(fieldName));
+            const scalar residual = sp.first().initialResidual();
+            result[fieldI] = residual;
+
+            switch (mode_)
+            {
+                case omMin:
+                {
+                    if (residual < value_)
+                    {
+                        satisfied = true;
+                    }
+                    break;
+                }
+                case omMax:
+                {
+                    if (residual > value_)
+                    {
+                        satisfied = true;
+                    }
+                    break;
+                }
+                default:
+                {
+                    FatalErrorIn
+                    (
+                        "bool Foam::equationInitialResidualCondition::apply()"
+                    )
+                        << "Unhandled enumeration "
+                        << operatingModeNames[mode_]
+                        << abort(FatalError);
+                }
+            }
+        }
+    }
+
+    bool valid = false;
+    forAll(result, i)
+    {
+        if (result[i] < 0)
+        {
+            WarningIn("bool Foam::equationInitialResidualCondition::apply()")
+                << "Initial residual data not found for field "
+                << fieldNames_[i] << endl;
+        }
+        else
+        {
+            valid = true;
+        }
+    }
+
+    if (!valid)
+    {
+        WarningIn("bool Foam::equationInitialResidualCondition::apply()")
+            << "Initial residual data not found for any fields: "
+            << "deactivating" << endl;
+
+        active_ = false;
+    }
+
+    if (satisfied && valid)
+    {
+        if (log_)
+        {
+            Info<< type() << ": " << name_
+                << ": satisfied using threshold value: " << value_ << nl;
+        }
+
+        forAll(result, resultI)
+        {
+            if (result[resultI] > 0)
+            {
+                if (log_)
+                {
+                    Info<< "    field: " << fieldNames_[resultI]
+                        << ", residual: " << result[resultI] << nl;
+                }
+            }
+        }
+        if (log_) Info<< endl;
+    }
+
+    return satisfied;
+}
+
+
+void Foam::equationInitialResidualCondition::write()
+{
+    // do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..60a2163b7db6e818b6d6c766d9b2e9ed8f4701db
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationInitialResidualCondition/equationInitialResidualCondition.H
@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::equationInitialResidualCondition
+
+Description
+    Minimum or maximum initial residual run time condition
+
+SourceFiles
+    equationInitialResidualCondition.H
+    equationInitialResidualCondition.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef equationInitialResidualCondition_H
+#define equationInitialResidualCondition_H
+
+#include "runTimeCondition.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+              Class equationInitialResidualCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class equationInitialResidualCondition
+:
+    public runTimeCondition
+{
+public:
+
+    enum operatingMode
+    {
+        omMin,
+        omMax
+    };
+
+    static const NamedEnum<operatingMode, 2> operatingModeNames;
+
+
+protected:
+
+    // Protected data
+
+        //- Field name
+        const wordList fieldNames_;
+
+        //- Value to compare
+        const scalar value_;
+
+        //- Start checking from time - always skips first iteration
+        scalar timeStart_;
+
+        //- Operating mode
+        operatingMode mode_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("equationInitialResidual");
+
+    //- Constructor
+    equationInitialResidualCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~equationInitialResidualCondition();
+
+
+    // Public Member Functions
+
+        //- Apply the condition
+        virtual bool apply();
+
+        //- Write
+        virtual void write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..ebad50629d8fc36243e1a035eed16b635f36d286
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.C
@@ -0,0 +1,183 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "equationMaxIterCondition.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(equationMaxIterCondition, 0);
+    addToRunTimeSelectionTable
+    (
+        runTimeCondition,
+        equationMaxIterCondition,
+        dictionary
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::equationMaxIterCondition::equationMaxIterCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    runTimeCondition(name, obr, dict, state),
+    fieldNames_(dict.lookup("fields")),
+    threshold_(readLabel(dict.lookup("threshold"))),
+    startIter_(dict.lookupOrDefault("startIter", 2))
+{
+    if (!fieldNames_.size())
+    {
+        WarningIn
+        (
+            "Foam::equationMaxIterCondition::"
+            "equationMaxIterCondition"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "functionObjectState&"
+            ")"
+        )
+            << "No fields supplied: deactivating" << endl;
+
+        active_ = false;
+    }
+
+    startIter_ = max(startIter_, 2);
+}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::equationMaxIterCondition::~equationMaxIterCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::equationMaxIterCondition::apply()
+{
+    bool satisfied = false;
+
+    if (!active_)
+    {
+        return true;
+    }
+
+    if (obr_.time().timeIndex() < startIter_)
+    {
+        // Do not start checking until start iter
+        return false;
+    }
+
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+    const dictionary& solverDict = mesh.solverPerformanceDict();
+
+    List<label> result(fieldNames_.size(), -1);
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName = fieldNames_[fieldI];
+
+        if (solverDict.found(fieldName))
+        {
+            const List<solverPerformance> sp(solverDict.lookup(fieldName));
+            const label nIterations = sp.first().nIterations();
+            result[fieldI] = nIterations;
+
+            if (nIterations > threshold_)
+            {
+                satisfied = true;
+            }
+        }
+    }
+
+    bool valid = false;
+    forAll(result, i)
+    {
+        if (result[i] < 0)
+        {
+            WarningIn("bool Foam::equationMaxIterCondition::apply()")
+                << "Number of iterations data not found for field "
+                << fieldNames_[i] << endl;
+        }
+        else
+        {
+            valid = true;
+        }
+    }
+
+    if (!valid)
+    {
+        WarningIn("bool Foam::equationMaxIterCondition::apply()")
+            << "Number of iterations data not found for any fields: "
+            << "deactivating" << endl;
+
+        active_ = false;
+    }
+
+    if (satisfied && valid)
+    {
+        if (log_)
+        {
+            Info<< type() << ": " << name_
+                << ": satisfied using threshold value: " << threshold_ << nl;
+        }
+
+        forAll(result, resultI)
+        {
+            if (result[resultI] != -1)
+            {
+                if (log_)
+                {
+                    Info<< "    field: " << fieldNames_[resultI]
+                        << ", iterations: " << result[resultI] << nl;
+                }
+            }
+        }
+        if (log_) Info<< endl;
+    }
+
+    return satisfied;
+}
+
+
+void Foam::equationMaxIterCondition::write()
+{
+    // do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..d77ab68366a7b640fcb046f6e4ae305231194f0f
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/equationMaxIterCondition/equationMaxIterCondition.H
@@ -0,0 +1,105 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::equationMaxIterCondition
+
+Description
+    Maximum number of equation iterations run time condition
+
+SourceFiles
+    equationMaxIterCondition.H
+    equationMaxIterCondition.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef equationMaxIterCondition_H
+#define equationMaxIterCondition_H
+
+#include "runTimeCondition.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class equationMaxIterCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class equationMaxIterCondition
+:
+    public runTimeCondition
+{
+protected:
+
+    // Protected data
+
+        //- Field name
+        const wordList fieldNames_;
+
+        //- Threshold for maximum number of iterations
+        const label threshold_;
+
+        //- Start checking from iteration - always skips first iteration
+        label startIter_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("equationMaxIter");
+
+    //- Constructor
+    equationMaxIterCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~equationMaxIterCondition();
+
+
+    // Public Member Functions
+
+        //- Apply the condition
+        virtual bool apply();
+
+        //- Write
+        virtual void write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..ba86537e0911ec48d022b004443b62970d9a59b1
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.C
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "minMaxCondition.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+template<>
+void Foam::minMaxCondition::setValue<Foam::scalar>
+(
+    const word& valueType,
+    const word& fieldName,
+    scalar& value
+) const
+{
+    state_.getObjectResult(functionObjectName_, fieldName, value);
+}
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(minMaxCondition, 0);
+    addToRunTimeSelectionTable(runTimeCondition, minMaxCondition, dictionary);
+
+    template<>
+    const char* NamedEnum<minMaxCondition::modeType, 2>::names[] =
+    {
+        "minimum",
+        "maximum"
+    };
+}
+
+const Foam::NamedEnum<Foam::minMaxCondition::modeType, 2>
+    Foam::minMaxCondition::modeTypeNames_;
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::minMaxCondition::minMaxCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    runTimeCondition(name, obr, dict, state),
+    functionObjectName_(dict.lookup("functionObjectName")),
+    mode_(modeTypeNames_.read(dict.lookup("mode"))),
+    fieldNames_(dict.lookup("fields")),
+    value_(readScalar(dict.lookup("value")))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::minMaxCondition::~minMaxCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::minMaxCondition::apply()
+{
+    bool satisfied = true;
+
+    if (!active_)
+    {
+        return satisfied;
+    }
+
+    forAll(fieldNames_, fieldI)
+    {
+        const word& fieldName = fieldNames_[fieldI];
+
+        const word valueType =
+            state_.objectResultType(functionObjectName_, fieldName);
+
+        if (valueType == word::null)
+        {
+            WarningIn("bool Foam::minMaxCondition::apply()")
+                << "Unable to find entry " << fieldName
+                << " for function object " << functionObjectName_
+                << ".  Condition will not be applied."
+                << endl;
+
+            continue;
+        }
+
+        scalar v = 0;
+        setValue<scalar>(valueType, fieldName, v);
+        setValue<vector>(valueType, fieldName, v);
+        setValue<sphericalTensor>(valueType, fieldName, v);
+        setValue<symmTensor>(valueType, fieldName, v);
+        setValue<tensor>(valueType, fieldName, v);
+
+        Switch ok = false;
+        switch (mode_)
+        {
+            case mdMin:
+            {
+                if (v < value_)
+                {
+                    ok = true;
+                }
+                break;
+            }
+            case mdMax:
+            {
+                if (v > value_)
+                {
+                    ok = true;
+                }
+                break;
+            }
+        }
+
+        if (log_)
+        {
+            Info<< "    " << type() << ": " << modeTypeNames_[mode_] << " "
+                << fieldName << ": value = " << v
+                << ", threshold value = " << value_
+                << ", satisfied = " << ok << endl;
+        }
+
+        satisfied = satisfied && ok;
+    }
+
+    return satisfied;
+}
+
+
+void Foam::minMaxCondition::write()
+{
+    // do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..7bd899d3fe9cd60aba2b35c073b2df3c2ae26b86
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxCondition.H
@@ -0,0 +1,145 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::minMaxCondition
+
+Description
+    Minimum/maximum run time conditions.  If the value type is not scalar,
+    the magnitude of the value is used in the evaluation.
+
+SourceFiles
+    minMaxCondition.H
+    minMaxCondition.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef minMaxCondition_H
+#define minMaxCondition_H
+
+#include "runTimeCondition.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class minMaxCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class minMaxCondition
+:
+    public runTimeCondition
+{
+public:
+
+    // Public enumerations
+
+        // Mode type
+        enum modeType
+        {
+            mdMin,
+            mdMax
+        };
+
+        static const NamedEnum<modeType, 2> modeTypeNames_;
+
+
+protected:
+
+    // Protected data
+
+        //- Name of function object to retrueve data from
+        word functionObjectName_;
+
+        //- Mode
+        modeType mode_;
+
+        //- Field names
+        const wordList fieldNames_;
+
+        //- Value to compare
+        const scalar value_;
+
+        //- Helper function to retrieve the value from the state dictionary
+        template<class Type>
+        void setValue
+        (
+            const word& valueType,
+            const word& fieldName,
+            scalar& value
+        ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("minMax");
+
+    //- Constructor
+    minMaxCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~minMaxCondition();
+
+
+    // Public Member Functions
+
+        //- Apply the condition
+        virtual bool apply();
+
+        //- Write
+        virtual void write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+template<>
+void minMaxCondition::setValue<Foam::scalar>
+(
+    const word& valueType,
+    const word& fieldName,
+    scalar& value
+) const;
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "minMaxConditionTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..a8befe9cda9779421e9c12e4ac65689c2cc7e581
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minMaxCondition/minMaxConditionTemplates.C
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+template<class Type>
+void Foam::minMaxCondition::setValue
+(
+    const word& valueType,
+    const word& fieldName,
+    scalar& value
+) const
+{
+    if (pTraits<Type>::typeName != valueType)
+    {
+        return;
+    }
+
+    Type v = state_.getObjectResult<Type>(functionObjectName_, fieldName);
+    value = mag(v);
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..4b91fd14dcd3c157a80c243dd06046c61fe23bd7
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.C
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "minTimeStepCondition.H"
+#include "addToRunTimeSelectionTable.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(minTimeStepCondition, 0);
+    addToRunTimeSelectionTable
+    (
+        runTimeCondition,
+        minTimeStepCondition,
+        dictionary
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::minTimeStepCondition::minTimeStepCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    runTimeCondition(name, obr, dict, state),
+    minValue_(readScalar(dict.lookup("minValue")))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::minTimeStepCondition::~minTimeStepCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::minTimeStepCondition::apply()
+{
+    bool satisfied = false;
+
+    if (!active_)
+    {
+        return true;
+    }
+
+    if (obr_.time().deltaTValue() < minValue_)
+    {
+        satisfied = true;
+    }
+
+    return satisfied;
+}
+
+
+void Foam::minTimeStepCondition::write()
+{
+    // do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..b5088a162d62cf6583ccbc2439cb9689b87d5b1c
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/minTimeStepCondition/minTimeStepCondition.H
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::minTimeStepCondition
+
+Description
+    Initial residual run time condition
+
+SourceFiles
+    minTimeStepCondition.H
+    minTimeStepCondition.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef minTimeStepCondition_H
+#define minTimeStepCondition_H
+
+#include "runTimeCondition.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                Class minTimeStepCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class minTimeStepCondition
+:
+    public runTimeCondition
+{
+protected:
+
+    // Protected data
+
+        //- Minumim time step value to compare
+        const scalar minValue_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("minTimeStep");
+
+    //- Constructor
+    minTimeStepCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~minTimeStepCondition();
+
+
+    // Public Member Functions
+
+        //- Apply the condition
+        virtual bool apply();
+
+        //- Write
+        virtual void write();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C
new file mode 100644
index 0000000000000000000000000000000000000000..16bcc6cb94090867147a81f71215be1eb04d4422
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.C
@@ -0,0 +1,110 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "runTimeCondition.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(runTimeCondition, 0);
+    defineRunTimeSelectionTable(runTimeCondition, dictionary);
+}
+
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+Foam::dictionary& Foam::runTimeCondition::setConditionDict()
+{
+    dictionary& propertyDict = state_.propertyDict();
+
+    if (!propertyDict.found(name_))
+    {
+        propertyDict.add(name_, dictionary());
+    }
+
+    return propertyDict.subDict(name_);
+}
+
+
+const Foam::dictionary& Foam::runTimeCondition::conditionDict() const
+{
+    return conditionDict_;
+}
+
+
+Foam::dictionary& Foam::runTimeCondition::conditionDict()
+{
+    return conditionDict_;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::runTimeCondition::runTimeCondition
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+:
+    name_(name),
+    obr_(obr),
+    state_(state),
+    active_(dict.lookupOrDefault<bool>("active", true)),
+    conditionDict_(setConditionDict()),
+    log_(dict.lookupOrDefault("log", true)),
+    groupID_(dict.lookupOrDefault("groupID", -1))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+Foam::runTimeCondition::~runTimeCondition()
+{}
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+const Foam::word& Foam::runTimeCondition::name() const
+{
+    return name_;
+}
+
+
+bool Foam::runTimeCondition::active() const
+{
+    return active_;
+}
+
+
+Foam::label Foam::runTimeCondition::groupID() const
+{
+    return groupID_;
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H
new file mode 100644
index 0000000000000000000000000000000000000000..752a0ad8ec525e3dd95882d9b80c187180aa1ae8
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeCondition.H
@@ -0,0 +1,167 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::runTimeCondition
+
+Description
+    Base class for run time conditions
+
+SourceFiles
+    runTimeCondition.C
+    runTimeConditionNew.C
+    runTimeCondition.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef runTimeCondition_H
+#define runTimeCondition_H
+
+#include "functionObjectState.H"
+#include "dictionary.H"
+#include "autoPtr.H"
+#include "runTimeSelectionTables.H"
+#include "Switch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class runTimeCondition Declaration
+\*---------------------------------------------------------------------------*/
+
+class runTimeCondition
+{
+
+protected:
+
+    // Protected data
+
+        //- Condition name
+        word name_;
+
+        //- Reference to the object registry
+        const objectRegistry& obr_;
+
+        //- State
+        functionObjectState& state_;
+
+        //- On/off switch
+        bool active_;
+
+        //- Reference to the condition dictionary
+        dictionary& conditionDict_;
+
+        //- Switch to send output to Info
+        Switch log_;
+
+        //- Group index - if applied, all conditions in a group must be
+        //  satisfield before condition is met
+        label groupID_;
+
+
+    // Protected Member Functions
+
+        //- Set the condition dictionary (create if necessary)
+        dictionary& setConditionDict();
+
+        //- Return const access to the conditions dictionary
+        const dictionary& conditionDict() const;
+
+        //- Return non-const access to the conditions dictionary
+        dictionary& conditionDict();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("runTimeCondition");
+
+    //- Declare runtime constructor selection table
+    declareRunTimeSelectionTable
+    (
+        autoPtr,
+        runTimeCondition,
+        dictionary,
+        (
+            const word& name,
+            const objectRegistry& obr,
+            const dictionary& dict,
+            functionObjectState& state
+        ),
+        (name, obr, dict, state)
+    );
+
+
+    //- Constructor
+    runTimeCondition
+    (
+        const word& name,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+    //- Destructor
+    virtual ~runTimeCondition();
+
+    //- Selector
+    static autoPtr<runTimeCondition> New
+    (
+        const word& conditionName,
+        const objectRegistry& obr,
+        const dictionary& dict,
+        functionObjectState& state
+    );
+
+
+    // Public Member Functions
+
+        //- Return the condition name
+        virtual const word& name() const;
+
+        //- Return the active flag
+        virtual bool active() const;
+
+        //- Return the group index
+        virtual label groupID() const;
+
+        //- Apply the condition
+        virtual bool apply() = 0;
+
+        //- Write
+        virtual void write() = 0;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C
new file mode 100644
index 0000000000000000000000000000000000000000..72c5d99ca6c42676acf61d0825cd8baae19393d3
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeCondition/runTimeCondition/runTimeConditionNew.C
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "runTimeCondition.H"
+
+// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::runTimeCondition> Foam::runTimeCondition::New
+(
+    const word& conditionName,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    functionObjectState& state
+)
+{
+    word conditionType(dict.lookup("type"));
+
+    Info<< "Selecting runTimeCondition " << conditionType << endl;
+
+    dictionaryConstructorTable::iterator cstrIter =
+        dictionaryConstructorTablePtr_->find(conditionType);
+
+    if (cstrIter == dictionaryConstructorTablePtr_->end())
+    {
+        FatalErrorIn
+        (
+            "runTimeCondition::New"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "functionObjectState&"
+            ")"
+        )   << "Unknown runTimeCondition type "
+            << conditionType << nl << nl
+            << "Valid runTimeCondition types are:" << nl
+            << dictionaryConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
+    }
+
+    return autoPtr<runTimeCondition>
+        (
+            cstrIter()(conditionName, obr, dict, state)
+        );
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C
new file mode 100644
index 0000000000000000000000000000000000000000..27e1c4e180224b4c4e11b2364b085245aac90056
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.C
@@ -0,0 +1,264 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "runTimeControl.H"
+#include "dictionary.H"
+#include "runTimeCondition.H"
+#include "fvMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(runTimeControl, 0);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::runTimeControl::runTimeControl
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool loadFromFiles
+)
+:
+    functionObjectState(obr, name),
+    obr_(obr),
+    conditions_(),
+    groupMap_(),
+    nWriteStep_(0),
+    writeStepI_(0)
+{
+    // Check if the available mesh is an fvMesh, otherwise deactivate
+    if (setActive<fvMesh>())
+    {
+        read(dict);
+
+        // Check that some conditions are set
+        if (conditions_.empty())
+        {
+            Info<< type() << " " << name_ << " output:" << nl
+                << "    No conditions present - deactivating" << nl
+                << endl;
+
+            active_ = false;
+        }
+        else
+        {
+            // Check that at least one condition is active
+            active_ = false;
+            forAll(conditions_, conditionI)
+            {
+                if (conditions_[conditionI].active())
+                {
+                    active_ = true;
+                    break;
+                }
+            }
+
+            if (!active_)
+            {
+                Info<< type() << " " << name_ << " output:" << nl
+                    << "    All conditions inactive - deactivating" << nl
+                    << endl;
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::runTimeControl::~runTimeControl()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::runTimeControl::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        const dictionary& conditionsDict = dict.subDict("conditions");
+        const wordList conditionNames(conditionsDict.toc());
+        conditions_.setSize(conditionNames.size());
+
+        label uniqueGroupI = 0;
+        forAll(conditionNames, conditionI)
+        {
+            const word& conditionName = conditionNames[conditionI];
+            const dictionary& dict = conditionsDict.subDict(conditionName);
+
+            conditions_.set
+            (
+                conditionI,
+                runTimeCondition::New(conditionName, obr_, dict, *this)
+            );
+
+            label groupI = conditions_[conditionI].groupID();
+
+            if (groupMap_.insert(groupI, uniqueGroupI))
+            {
+                uniqueGroupI++;
+            }
+        }
+
+        dict.readIfPresent("nWriteStep", nWriteStep_);
+    }
+}
+
+
+void Foam::runTimeControl::execute()
+{
+    if (!active_)
+    {
+        return;
+    }
+
+    Info<< type() << " " << name_ << " output:" << nl;
+
+    // IDs of satisfied conditions
+    DynamicList<label> IDs(conditions_.size());
+
+    // Run stops only if all conditions within a group are satisfied
+    List<bool> groupSatisfied(groupMap_.size(), true);
+    List<bool> groupActive(groupMap_.size(), false);
+
+    forAll(conditions_, conditionI)
+    {
+        runTimeCondition& condition = conditions_[conditionI];
+
+        if (condition.active())
+        {
+            bool conditionSatisfied = condition.apply();
+
+            label groupI = condition.groupID();
+
+            Map<label>::const_iterator conditionIter = groupMap_.find(groupI);
+
+            if (conditionIter == groupMap_.end())
+            {
+                FatalErrorIn("void Foam::runTimeControl::execute()")
+                    << "group " << groupI << " not found in map"
+                    << abort(FatalError);
+            }
+
+            if (conditionSatisfied)
+            {
+                IDs.append(conditionI);
+
+                groupActive[conditionIter()] = true;
+
+                if (groupI == -1)
+                {
+                    // Condition not part of a group - only requires this to be
+                    // satisfied for completion flag to be set
+                    groupSatisfied[conditionIter()] = true;
+                    break;
+                }
+            }
+            else
+            {
+                groupSatisfied[conditionIter()] = false;
+            }
+        }
+    }
+
+    bool done = false;
+    forAll(groupSatisfied, groupI)
+    {
+        if (groupSatisfied[groupI] && groupActive[groupI])
+        {
+            done = true;
+            break;
+        }
+    }
+
+    if (done)
+    {
+        forAll(IDs, conditionI)
+        {
+            Info<< "    " << conditions_[conditionI].type() << ": "
+                <<  conditions_[conditionI].name()
+                << " condition satisfied" << nl;
+        }
+
+
+        // Set to write a data dump or finalise the calculation
+        Time& time = const_cast<Time&>(obr_.time());
+
+        if (writeStepI_ < nWriteStep_ - 1)
+        {
+            writeStepI_++;
+            Info<< "    Writing fields - step " << writeStepI_ << nl;
+            time.writeNow();
+        }
+        else
+        {
+            Info<< "    Stopping calculation" << nl
+                << "    Writing fields - final step" << nl;
+            time.writeAndEnd();
+        }
+    }
+    else
+    {
+        Info<< "    Conditions not met - calculations proceeding" << nl;
+    }
+
+    Info<< endl;
+}
+
+
+void Foam::runTimeControl::end()
+{
+    if (active_)
+    {
+        execute();
+    }
+}
+
+
+void Foam::runTimeControl::timeSet()
+{
+    // Do nothing
+}
+
+
+void Foam::runTimeControl::write()
+{
+    if (active_)
+    {
+        forAll(conditions_, conditionI)
+        {
+            conditions_[conditionI].write();
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H
new file mode 100644
index 0000000000000000000000000000000000000000..fff6c446485755c3ac3e34cba680bcaef25620e4
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControl.H
@@ -0,0 +1,161 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::runTimeControl
+
+Group
+    grpJobControlFunctionObjects
+
+Description
+    This function object controls when the calculation is terminated based on
+    satisfying user-specified conditions.
+
+    Optionally specify a number of write steps before the calculation is
+    terminated.  Here, a write is performed each time that all conditons are
+    satisfied.
+
+SourceFiles
+    runTimeControl.C
+    IOrunTimeControl.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef runTimeControl_H
+#define runTimeControl_H
+
+#include "functionObjectState.H"
+#include "Map.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class polyMesh;
+class mapPolyMesh;
+class runTimeCondition;
+
+/*---------------------------------------------------------------------------*\
+                       Class runTimeControl Declaration
+\*---------------------------------------------------------------------------*/
+
+class runTimeControl
+:
+    public functionObjectState
+{
+    // Private data
+
+        //- Reference to the database
+        const objectRegistry& obr_;
+
+        //- List of conditions to satisfy
+        PtrList<runTimeCondition> conditions_;
+
+        //- Map to define group IDs
+        Map<label> groupMap_;
+
+        //- Number of write steps before exiting
+        label nWriteStep_;
+
+        //- Current number of steps written
+        label writeStepI_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        runTimeControl(const runTimeControl&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const runTimeControl&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("runTimeControl");
+
+
+    // Constructors
+
+        //- Construct for given objectRegistry and dictionary.
+        //  Allow the possibility to load fields from files
+        runTimeControl
+        (
+            const word& name,
+            const objectRegistry&,
+            const dictionary&,
+            const bool loadFromFiles = false
+        );
+
+
+    //- Destructor
+    virtual ~runTimeControl();
+
+
+    // Member Functions
+
+        //- Return name of the set of runTimeControl
+        virtual const word& name() const
+        {
+            return name_;
+        }
+
+        //- Read the runTimeControl data
+        virtual void read(const dictionary&);
+
+        //- Execute, currently does nothing
+        virtual void execute();
+
+        //- Execute at the final time-loop, currently does nothing
+        virtual void end();
+
+        //- Called when time was set at the end of the Time::operator++
+        virtual void timeSet();
+
+        //- Calculate the runTimeControl and write
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&)
+        {}
+
+        //- Update for changes of mesh
+        virtual void movePoints(const polyMesh&)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..7ba3518564ab65c147dc49eb8096ef0a11620718
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.C
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "runTimeControlFunctionObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineNamedTemplateTypeNameAndDebug(runTimeControlFunctionObject, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        runTimeControlFunctionObject,
+        dictionary
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..6b600c33d158b22a2e438edc985494d0a1608aa6
--- /dev/null
+++ b/src/postProcessing/functionObjects/jobControl/runTimeControl/runTimeControlFunctionObject.H
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::runTimeControlFunctionObject
+
+Description
+    FunctionObject wrapper around runTimeControl to allow it to be created
+    via the functions entry within controlDict.
+
+SourceFiles
+    runTimeControlFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef runTimeControlFunctionObject_H
+#define runTimeControlFunctionObject_H
+
+#include "runTimeControl.H"
+#include "OutputFilterFunctionObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef OutputFilterFunctionObject<runTimeControl>
+        runTimeControlFunctionObject;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C
index 5653a6a177af2645fef993aa0c463c4f8591ce8e..160481398817b45e5b86db9aa083e13b0d5c3fe3 100644
--- a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C
+++ b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,7 +68,9 @@ Foam::CourantNo::CourantNo
     obr_(obr),
     active_(true),
     phiName_("phi"),
-    rhoName_("rho")
+    rhoName_("rho"),
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -99,7 +101,7 @@ Foam::CourantNo::CourantNo
             (
                 IOobject
                 (
-                    type(),
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -128,8 +130,11 @@ void Foam::CourantNo::read(const dictionary& dict)
 {
     if (active_)
     {
-        phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
-        rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
+        log_.readIfPresent("log", dict);
+
+        dict.readIfPresent("phiName", phiName_);
+        dict.readIfPresent("rhoName", rhoName_);
+        dict.readIfPresent("resultName", resultName_);
     }
 }
 
@@ -146,7 +151,7 @@ void Foam::CourantNo::execute()
         volScalarField& Co =
             const_cast<volScalarField&>
             (
-                mesh.lookupObject<volScalarField>(type())
+                mesh.lookupObject<volScalarField>(resultName_)
             );
 
         Co.dimensionedInternalField() = byRho
@@ -178,9 +183,10 @@ void Foam::CourantNo::write()
     if (active_)
     {
         const volScalarField& CourantNo =
-            obr_.lookupObject<volScalarField>(type());
+            obr_.lookupObject<volScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << CourantNo.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H
index 7460d74ffb42a7094fb9059cb823885a3c7d7fbd..df22943ae11e873b846bcc014dc89c73db2945e2 100644
--- a/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H
+++ b/src/postProcessing/functionObjects/utilities/CourantNo/CourantNo.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,6 +32,27 @@ Description
     volScalarField.  The field is stored on the mesh database so that it can
     be retrieved and used for other applications.
 
+    Example of function object specification to calculate the Courant number:
+    \verbatim
+    CourantNo1
+    {
+        type        CourantNo;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: CourantNo    | yes         |
+        rhoName      | Name of density field   | no          | rho
+        phiName      | Name of flux field      | no          | phi
+        resultName   | Name of Courant number field | no     | <function name>
+        log          | Log to standard output  | no          | yes
+    \endtable
+
+
 SourceFiles
     CourantNo.C
     IOCourantNo.H
@@ -77,6 +98,12 @@ class CourantNo
         //- Name of density field (optional)
         word rhoName_;
 
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C
index 3c72fbfd9b57032b983996b0e1d24e6cc7f2ccb2..90388fa751dda79e71d526c790c694186afbb1db 100644
--- a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C
+++ b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,7 +50,9 @@ Foam::Lambda2::Lambda2
     name_(name),
     obr_(obr),
     active_(true),
-    UName_("U")
+    UName_("U"),
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -81,7 +83,7 @@ Foam::Lambda2::Lambda2
             (
                 IOobject
                 (
-                    type(),
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -109,7 +111,17 @@ void Foam::Lambda2::read(const dictionary& dict)
 {
     if (active_)
     {
-        UName_ = dict.lookupOrDefault<word>("UName", "U");
+        log_.readIfPresent("log", dict);
+        dict.readIfPresent("UName", UName_);
+
+        if (!dict.readIfPresent("resultName", resultName_))
+        {
+            resultName_ = name_;
+            if (UName_ != "U")
+            {
+                resultName_ = resultName_ + "(" + UName_ + ")";
+            }
+        }
     }
 }
 
@@ -134,7 +146,7 @@ void Foam::Lambda2::execute()
         volScalarField& Lambda2 =
             const_cast<volScalarField&>
             (
-                mesh.lookupObject<volScalarField>(type())
+                mesh.lookupObject<volScalarField>(resultName_)
             );
 
         Lambda2 = -eigenValues(SSplusWW)().component(vector::Y);
@@ -162,9 +174,10 @@ void Foam::Lambda2::write()
     if (active_)
     {
         const volScalarField& Lambda2 =
-            obr_.lookupObject<volScalarField>(type());
+            obr_.lookupObject<volScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << Lambda2.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H
index f4360f46404b714b6043422eb95bbc71042a307d..3de1eb049b9cc89a21f6bb01d76300cfc0a3d7e2 100644
--- a/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H
+++ b/src/postProcessing/functionObjects/utilities/Lambda2/Lambda2.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -32,6 +32,25 @@ Description
     of the sum of the square of the symmetrical and anti-symmetrical parts of
     the velocity gradient tensor.
 
+    Example of function object specification to calculate Lambda2:
+    \verbatim
+    Lambda2_1
+    {
+        type        Lambda2;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: Lambda2      | yes         |
+        UName        | Name of velocity field  | no          | U
+        resultName   | Name of Lambda2 field   | no          | <function name>
+        log          | Log to standard output  | no          | yes
+    \endtable
+
 SourceFiles
     Lambda2.C
     IOLambda2.H
@@ -77,6 +96,12 @@ class Lambda2
         //- Name of velocity field, default is "U"
         word UName_;
 
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/Make/files b/src/postProcessing/functionObjects/utilities/Make/files
index 4c38b4ba67926fff719b85b654a6782259ecff51..8e4eaaf81cb5b464d7220c9a68150211cda6c168 100644
--- a/src/postProcessing/functionObjects/utilities/Make/files
+++ b/src/postProcessing/functionObjects/utilities/Make/files
@@ -1,28 +1,28 @@
+blendingFactor/blendingFactor.C
+blendingFactor/blendingFactorFunctionObject.C
+
 codedFunctionObject/codedFunctionObject.C
 
 CourantNo/CourantNo.C
 CourantNo/CourantNoFunctionObject.C
 
+dsmcFields/dsmcFields.C
+dsmcFields/dsmcFieldsFunctionObject.C
+
+fluxSummary/fluxSummary.C
+fluxSummary/fluxSummaryFunctionObject.C
+
 Lambda2/Lambda2.C
 Lambda2/Lambda2FunctionObject.C
 
 Peclet/Peclet.C
 Peclet/PecletFunctionObject.C
 
-Q/Q.C
-Q/QFunctionObject.C
-
-blendingFactor/blendingFactor.C
-blendingFactor/blendingFactorFunctionObject.C
-
-dsmcFields/dsmcFields.C
-dsmcFields/dsmcFieldsFunctionObject.C
-
 pressureTools/pressureTools.C
 pressureTools/pressureToolsFunctionObject.C
 
-residuals/residuals.C
-residuals/residualsFunctionObject.C
+Q/Q.C
+Q/QFunctionObject.C
 
 scalarTransport/scalarTransport.C
 scalarTransport/scalarTransportFunctionObject.C
diff --git a/src/postProcessing/functionObjects/utilities/Make/options b/src/postProcessing/functionObjects/utilities/Make/options
index b59c6b86db480ed889122927494e68e979973061..5886ed3e42988c543635a4d6c13aea83df9dade9 100644
--- a/src/postProcessing/functionObjects/utilities/Make/options
+++ b/src/postProcessing/functionObjects/utilities/Make/options
@@ -11,7 +11,8 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
-    -I$(LIB_SRC)/sampling/lnInclude
+    -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/surfMesh/lnInclude
 
 LIB_LIBS = \
     -lfvOptions \
@@ -26,4 +27,5 @@ LIB_LIBS = \
     -lDSMC \
     -lfiniteVolume \
     -lmeshTools \
-    -lsampling
+    -lsampling \
+    -lsurfMesh
diff --git a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C
index 18ac584332129824455c325359ab82ac51cb63fc..8785efbb32428979e54d9a36ba0df291f607c7b3 100644
--- a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C
+++ b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,7 +53,8 @@ Foam::Peclet::Peclet
     obr_(obr),
     active_(true),
     phiName_("phi"),
-    rhoName_("rho")
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -84,7 +85,7 @@ Foam::Peclet::Peclet
             (
                 IOobject
                 (
-                    type(),
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -112,8 +113,9 @@ void Foam::Peclet::read(const dictionary& dict)
 {
     if (active_)
     {
-        phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
-        rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
+        log_.readIfPresent("log", dict);
+        dict.readIfPresent("phiName", phiName_);
+        dict.readIfPresent("resultName", resultName_);
     }
 }
 
@@ -127,7 +129,10 @@ void Foam::Peclet::execute()
     {
         const fvMesh& mesh = refCast<const fvMesh>(obr_);
 
-        tmp<volScalarField> nuEff;
+        // Obtain nuEff of muEff.  Assumes that a compressible flux is present
+        // when using a compressible turbulence model, and an incompressible
+        // flux when using an incompressible turbulence model
+        tmp<volScalarField> nuOrMuEff;
         if (mesh.foundObject<cmpTurbModel>(turbulenceModel::propertiesName))
         {
             const cmpTurbModel& model =
@@ -136,10 +141,7 @@ void Foam::Peclet::execute()
                     turbulenceModel::propertiesName
                 );
 
-            const volScalarField& rho =
-                mesh.lookupObject<volScalarField>(rhoName_);
-
-            nuEff = model.muEff()/rho;
+            nuOrMuEff = model.muEff();
         }
         else if
         (
@@ -152,14 +154,14 @@ void Foam::Peclet::execute()
                     turbulenceModel::propertiesName
                 );
 
-            nuEff = model.nuEff();
+            nuOrMuEff = model.nuEff();
         }
         else if (mesh.foundObject<dictionary>("transportProperties"))
         {
             const dictionary& model =
                 mesh.lookupObject<dictionary>("transportProperties");
 
-            nuEff =
+            nuOrMuEff =
                 tmp<volScalarField>
                 (
                     new volScalarField
@@ -179,18 +181,20 @@ void Foam::Peclet::execute()
         }
         else
         {
-            FatalErrorIn("void Foam::Peclet::write()")
+            FatalErrorIn("void Foam::Peclet::execute()")
                 << "Unable to determine the viscosity"
                 << exit(FatalError);
         }
 
+        // Note: dimensions of phi will change depending on whether this is
+        //       applied to an incompressible or compressible case
         const surfaceScalarField& phi =
             mesh.lookupObject<surfaceScalarField>(phiName_);
 
         surfaceScalarField& Peclet =
             const_cast<surfaceScalarField&>
             (
-                mesh.lookupObject<surfaceScalarField>(type())
+                mesh.lookupObject<surfaceScalarField>(resultName_)
             );
 
         Peclet =
@@ -198,7 +202,7 @@ void Foam::Peclet::execute()
            /(
                 mesh.magSf()
                *mesh.surfaceInterpolation::deltaCoeffs()
-               *fvc::interpolate(nuEff)
+               *fvc::interpolate(nuOrMuEff)
             );
     }
 }
@@ -212,6 +216,7 @@ void Foam::Peclet::end()
     }
 }
 
+
 void Foam::Peclet::timeSet()
 {
     // Do nothing
@@ -223,9 +228,10 @@ void Foam::Peclet::write()
     if (active_)
     {
         const surfaceScalarField& Peclet =
-            obr_.lookupObject<surfaceScalarField>(type());
+            obr_.lookupObject<surfaceScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << Peclet.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H
index 5becbe93e951172d1697de0d4f5c7bdb3017896d..e72129a21b1a5b5c555e790e0c3823ec39eec561 100644
--- a/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H
+++ b/src/postProcessing/functionObjects/utilities/Peclet/Peclet.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,6 +31,25 @@ Description
     This function object calculates and outputs the Peclet number as a
     surfaceScalarField.
 
+    Example of function object specification to calculate the Peclet number:
+    \verbatim
+    Peclet1
+    {
+        type        Peclet;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | type name: Peclet       | yes         |
+        phiName      | Name of flux field      | no          | phi
+        resultName   | Name of Peclet field    | no          | <function name>
+        log          | Log to standard output  | no          | yes
+    \endtable
+
 SourceFiles
     Peclet.C
     IOPeclet.H
@@ -76,8 +95,11 @@ class Peclet
         //- Name of flux field, default is "phi"
         word phiName_;
 
-        //- Name of density field (compressible cases only), default is "rho"
-        word rhoName_;
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
 
 
     // Private Member Functions
diff --git a/src/postProcessing/functionObjects/utilities/Q/Q.C b/src/postProcessing/functionObjects/utilities/Q/Q.C
index 2dda80a88ba632a103161752fc09834aaf511aa6..243f2e92d463d43058c70b088118b2798e70481a 100644
--- a/src/postProcessing/functionObjects/utilities/Q/Q.C
+++ b/src/postProcessing/functionObjects/utilities/Q/Q.C
@@ -49,7 +49,9 @@ Foam::Q::Q
     name_(name),
     obr_(obr),
     active_(true),
-    UName_("U")
+    UName_("U"),
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -80,7 +82,7 @@ Foam::Q::Q
             (
                 IOobject
                 (
-                    type(),
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -108,7 +110,17 @@ void Foam::Q::read(const dictionary& dict)
 {
     if (active_)
     {
-        UName_ = dict.lookupOrDefault<word>("UName", "U");
+        log_.readIfPresent("log", dict);
+        dict.readIfPresent("UName", UName_);
+
+        if (!dict.readIfPresent("resultName", resultName_))
+        {
+            resultName_ = name_;
+            if (UName_ != "U")
+            {
+                resultName_ = resultName_ + "(" + UName_ + ")";
+            }
+        }
     }
 }
 
@@ -127,7 +139,7 @@ void Foam::Q::execute()
         volScalarField& Q =
             const_cast<volScalarField&>
             (
-                mesh.lookupObject<volScalarField>(type())
+                mesh.lookupObject<volScalarField>(resultName_)
             );
 
         Q = 0.5*(sqr(tr(gradU)) - tr(((gradU) & (gradU))));
@@ -155,9 +167,10 @@ void Foam::Q::write()
     if (active_)
     {
         const volScalarField& Q =
-            obr_.lookupObject<volScalarField>(type());
+            obr_.lookupObject<volScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << Q.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/Q/Q.H b/src/postProcessing/functionObjects/utilities/Q/Q.H
index aed626228c8c61d627fa166907da83af6b0b8506..15452f71a4cb8582afb0a49d90a9f772b315194c 100644
--- a/src/postProcessing/functionObjects/utilities/Q/Q.H
+++ b/src/postProcessing/functionObjects/utilities/Q/Q.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -35,6 +35,30 @@ Description
         Q = 0.5(sqr(tr(\nabla U)) - tr(((\nabla U) \cdot (\nabla U))))
     \f]
 
+    where
+    \vartable
+        U           | velocity [m/s]
+    \endvartable
+
+    Example of function object specification to calculate Q:
+    \verbatim
+    Q1
+    {
+        type        Q;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | type name: Q            | yes         |
+        UName        | Name of velocity field  | no          | U
+        resultName   | Name of Q field         | no          | <function name>
+        log          | Log to standard output  | no          | yes
+    \endtable
+
 SourceFiles
     Q.C
     IOQ.H
@@ -80,6 +104,12 @@ class Q
         //- Name of velocity field, default is "U"
         word UName_;
 
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C
index 3c98c9d86f237b13d41dadf32d9a37ed8d2d9ef6..73277fc27fb5098681057a21868fcec27a60532d 100644
--- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C
+++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,6 +34,19 @@ namespace Foam
 }
 
 
+// * * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * //
+
+void Foam::blendingFactor::writeFileHeader(Ostream& os) const
+{
+    writeHeader(os, "Blending factor");
+    writeCommented(os, "Time");
+    writeTabbed(os, "Scheme1");
+    writeTabbed(os, "Scheme2");
+    writeTabbed(os, "Blended");
+    os  << endl;
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::blendingFactor::blendingFactor
@@ -44,30 +57,44 @@ Foam::blendingFactor::blendingFactor
     const bool loadFromFiles
 )
 :
+    functionObjectState(obr, name),
+    functionObjectFile(obr, name, typeName, dict),
     name_(name),
     obr_(obr),
-    active_(true),
-    phiName_("unknown-phiName"),
-    fieldName_("unknown-fieldName")
+    phiName_("phi"),
+    fieldName_("unknown-fieldName"),
+    resultName_(word::null),
+    tolerance_(0.001),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
-    if (!isA<fvMesh>(obr_))
+    if (setActive<fvMesh>())
     {
-        active_ = false;
-        WarningIn
+        read(dict);
+        writeFileHeader(file());
+
+        const fvMesh& mesh = refCast<const fvMesh>(obr_);
+
+        volScalarField* indicatorPtr
         (
-            "blendingFactor::blendingFactor"
-            "("
-                "const word&, "
-                "const objectRegistry&, "
-                "const dictionary&, "
-                "const bool"
-            ")"
-        )   << "No fvMesh available, deactivating " << name_ << nl
-            << endl;
+            new volScalarField
+            (
+                IOobject
+                (
+                    resultName_,
+                    mesh.time().timeName(),
+                    mesh,
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                mesh,
+                dimensionedScalar("0", dimless, 0.0),
+                zeroGradientFvPatchScalarField::typeName
+            )
+        );
+
+        mesh.objectRegistry::store(indicatorPtr);
     }
-
-    read(dict);
 }
 
 
@@ -83,8 +110,26 @@ void Foam::blendingFactor::read(const dictionary& dict)
 {
     if (active_)
     {
-        phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
+        functionObjectFile::read(dict);
+
+        log_.readIfPresent("log", dict);
+
+        dict.readIfPresent("phiName", phiName_);
         dict.lookup("fieldName") >> fieldName_;
+
+
+        if (!dict.readIfPresent("resultName", resultName_))
+        {
+            resultName_ = name_ + ':' + fieldName_;
+        }
+
+        dict.readIfPresent("tolerance", tolerance_);
+        if ((tolerance_ < 0) || (tolerance_ > 1))
+        {
+            FatalErrorIn("void Foam::blendingFactor::read(const dictionary&)")
+                << "tolerance must be in the range 0 to 1.  Supplied value: "
+                << tolerance_ << exit(FatalError);
+        }
     }
 }
 
@@ -117,16 +162,15 @@ void Foam::blendingFactor::write()
 {
     if (active_)
     {
-        const word fieldName = "blendingFactor:" + fieldName_;
-
-        const volScalarField& blendingFactor =
-            obr_.lookupObject<volScalarField>(fieldName);
+        const volScalarField& indicator =
+            obr_.lookupObject<volScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
-            << "    writing field " << blendingFactor.name() << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    writing field " << indicator.name() << nl
             << endl;
 
-        blendingFactor.write();
+        indicator.write();
     }
 }
 
diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H
index 8b86a25cea60707f2cd5dc7208c6af2344f064b3..f7166470afd563e3b5874ea01211b6fd8e37d22b 100644
--- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H
+++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactor.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,10 +28,49 @@ Group
     grpUtilitiesFunctionObjects
 
 Description
-    This function object calculates and outputs the blendingFactor as used by
-    the bended convection schemes.  The output is a volume field (cells) whose
-    value is calculated via the maximum blending factor for any cell face.
-
+    This function object provides information on the mode of operation of
+    blended convection schemes.
+
+    The weight of a blended scheme is given by a function of the blending
+    factor, f:
+
+        weight = f*scheme1 + (1 - f)*scheme2
+
+    The factor is a face-based quantity, which is converted to a cell-based
+    quantity by assigning the minimum blending factor for any cell face.
+
+    An indicator (volume) field, named <functionObjectName>:<fieldName>, is
+    generated that is set to (1 - f), i.e. values of:
+    - 0 represent scheme1 as active, and
+    - 1 represent scheme2 as active.
+    - intermediate values show the contribution to scheme2
+
+    Additional reporting is written to the standard output, providing
+    statistics as to the number of cells used by each scheme.
+
+    Example of function object specification to calculate the blending factor:
+    \verbatim
+    blendingFactor1
+    {
+        type        blendingFactor;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+
+        ...
+
+        // Name of field
+        fieldName   U;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: blendingFactor | yes       |
+        phiName      | Name of flux field      | no          | phi
+        fieldName    | Name of field to evaluate | yes       |
+        tolerance    | Tolerance for number of blended cells | no | 0.001
+        log          | Log to standard output  | no          | yes
+    \endtable
 
 SourceFiles
     blendingFactor.C
@@ -42,6 +81,8 @@ SourceFiles
 #ifndef blendingFactor_H
 #define blendingFactor_H
 
+#include "functionObjectState.H"
+#include "functionObjectFile.H"
 #include "volFieldsFwd.H"
 #include "surfaceFieldsFwd.H"
 #include "OFstream.H"
@@ -59,28 +100,37 @@ class polyMesh;
 class mapPolyMesh;
 
 /*---------------------------------------------------------------------------*\
-                          Class blendingFactor Declaration
+                       Class blendingFactor Declaration
 \*---------------------------------------------------------------------------*/
 
 class blendingFactor
+:
+    public functionObjectState,
+    public functionObjectFile
 {
     // Private data
 
-        //- Name of this set of blendingFactor objects
-        word name_;
+        //- Name
+        const word name_;
 
         //- Reference to the database
         const objectRegistry& obr_;
 
-        //- On/off switch
-        bool active_;
-
         //- Name of flux field, default is "phi"
         word phiName_;
 
         //- Field name
         word fieldName_;
 
+        //- Result field name
+        word resultName_;
+
+        //- Tolerance used when calculating the number of blended cells
+        scalar tolerance_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
@@ -90,18 +140,19 @@ class blendingFactor
         //- Disallow default bitwise assignment
         void operator=(const blendingFactor&);
 
-        //- Return the blending factor field from the database
-        template<class Type>
-        volScalarField& factor
-        (
-            const GeometricField<Type, fvPatchField, volMesh>& field
-        );
-
         //- Calculate the blending factor
         template<class Type>
         void calc();
 
 
+protected:
+
+    // Protected Member Functions
+
+        //- Write the file header
+        virtual void writeFileHeader(Ostream& os) const;
+
+
 public:
 
     //- Runtime type information
diff --git a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C
index 3a284b8c731b0d83025cb989674f7c9c93662135..8dec0602fc8cf7e300de91966b9bf121a8cb25f1 100644
--- a/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C
+++ b/src/postProcessing/functionObjects/utilities/blendingFactor/blendingFactorTemplates.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2013-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,45 +29,6 @@ License
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<class Type>
-Foam::volScalarField& Foam::blendingFactor::factor
-(
-    const GeometricField<Type, fvPatchField, volMesh>& field
-)
-{
-    const word fieldName = "blendingFactor:" + field.name();
-
-    if (!obr_.foundObject<volScalarField>(fieldName))
-    {
-        const fvMesh& mesh = refCast<const fvMesh>(obr_);
-
-        volScalarField* factorPtr =
-            new volScalarField
-            (
-                IOobject
-                (
-                    fieldName,
-                    mesh.time().timeName(),
-                    mesh,
-                    IOobject::NO_READ,
-                    IOobject::NO_WRITE
-                ),
-                mesh,
-                dimensionedScalar("0", dimless, 0.0),
-                zeroGradientFvPatchScalarField::typeName
-            );
-
-        obr_.store(factorPtr);
-    }
-
-    return
-        const_cast<volScalarField&>
-        (
-            obr_.lookupObject<volScalarField>(fieldName)
-        );
-}
-
-
 template<class Type>
 void Foam::blendingFactor::calc()
 {
@@ -104,15 +65,60 @@ void Foam::blendingFactor::calc()
             << exit(FatalError);
     }
 
-    // retrieve the face-based blending factor
+    // Retrieve the face-based blending factor
     const blendedSchemeBase<Type>& blendedScheme =
         refCast<const blendedSchemeBase<Type> >(interpScheme);
     const surfaceScalarField factorf(blendedScheme.blendingFactor(field));
 
-    // convert into vol field whose values represent the local face maxima
-    volScalarField& factor = this->factor(field);
-    factor = fvc::cellReduce(factorf, maxEqOp<scalar>());
-    factor.correctBoundaryConditions();
+    // Convert into vol field whose values represent the local face minima
+    // Note: factor applied to 1st scheme, and (1-factor) to 2nd scheme
+    volScalarField& indicator =
+        const_cast<volScalarField&>
+        (
+            obr_.lookupObject<volScalarField>(resultName_)
+        );
+    indicator = 1 - fvc::cellReduce(factorf, minEqOp<scalar>(), GREAT);
+    indicator.correctBoundaryConditions();
+
+    // Generate scheme statistics
+    label nCellsScheme1 = 0;
+    label nCellsScheme2 = 0;
+    label nCellsBlended = 0;
+    forAll(indicator, cellI)
+    {
+        scalar i = indicator[cellI];
+
+        if (i < tolerance_)
+        {
+            nCellsScheme1++;
+        }
+        else if (i > (1 - tolerance_))
+        {
+            nCellsScheme2++;
+        }
+        else
+        {
+            nCellsBlended++;
+        }
+    }
+
+    reduce(nCellsScheme1, sumOp<label>());
+    reduce(nCellsScheme2, sumOp<label>());
+    reduce(nCellsBlended, sumOp<label>());
+
+    if (log_) Info
+        << type() << " " << name_ << " output:" << nl
+        << "    scheme 1 cells :  " << nCellsScheme1 << nl
+        << "    scheme 2 cells :  " << nCellsScheme2 << nl
+        << "    blended cells  :  " << nCellsBlended << nl
+        << endl;
+
+    file()
+        << obr_.time().time().value()
+        << token::TAB << nCellsScheme1
+        << token::TAB << nCellsScheme2
+        << token::TAB << nCellsBlended
+        << endl;
 }
 
 
diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
index dd9400bb94fcc564fa099a6727f0b7d478590fac..348798ef783e9e2b73a4b8d6c22b12fc675476a9 100644
--- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
+++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -52,7 +52,8 @@ Foam::dsmcFields::dsmcFields
 :
     name_(name),
     obr_(obr),
-    active_(true)
+    active_(true),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -87,7 +88,7 @@ void Foam::dsmcFields::read(const dictionary& dict)
 {
     if (active_)
     {
-
+        log_.readIfPresent("log", dict);
     }
 }
 
@@ -122,46 +123,32 @@ void Foam::dsmcFields::write()
         word iDofMeanName = "iDofMean";
         word fDMeanName = "fDMean";
 
-        const volScalarField& rhoNMean = obr_.lookupObject<volScalarField>
-        (
-            rhoNMeanName
-        );
+        const volScalarField& rhoNMean =
+            obr_.lookupObject<volScalarField>(rhoNMeanName);
 
-        const volScalarField& rhoMMean = obr_.lookupObject<volScalarField>
-        (
-            rhoMMeanName
-        );
+        const volScalarField& rhoMMean =
+            obr_.lookupObject<volScalarField>(rhoMMeanName);
 
-        const volVectorField& momentumMean = obr_.lookupObject<volVectorField>
-        (
-            momentumMeanName
-        );
+        const volVectorField& momentumMean =
+            obr_.lookupObject<volVectorField>(momentumMeanName);
 
-        const volScalarField& linearKEMean = obr_.lookupObject<volScalarField>
-        (
-            linearKEMeanName
-        );
+        const volScalarField& linearKEMean =
+            obr_.lookupObject<volScalarField>(linearKEMeanName);
 
-        const volScalarField& internalEMean = obr_.lookupObject<volScalarField>
-        (
-            internalEMeanName
-        );
+        const volScalarField& internalEMean =
+            obr_.lookupObject<volScalarField>(internalEMeanName);
 
-        const volScalarField& iDofMean = obr_.lookupObject<volScalarField>
-        (
-            iDofMeanName
-        );
+        const volScalarField& iDofMean =
+            obr_.lookupObject<volScalarField>(iDofMeanName);
 
-        const volVectorField& fDMean = obr_.lookupObject<volVectorField>
-        (
-            fDMeanName
-        );
+        const volVectorField& fDMean =
+            obr_.lookupObject<volVectorField>(fDMeanName);
 
         if (min(mag(rhoNMean)).value() > VSMALL)
         {
-            Info<< "Calculating dsmcFields." << endl;
+            if (log_) Info<< type() << " " << name_ << " output:" << endl;
 
-            Info<< "    Calculating UMean field." << endl;
+            if (log_) Info<< "    Calculating UMean field" << endl;
             volVectorField UMean
             (
                 IOobject
@@ -174,7 +161,7 @@ void Foam::dsmcFields::write()
                 momentumMean/rhoMMean
             );
 
-            Info<< "    Calculating translationalT field." << endl;
+            if (log_) Info<< "    Calculating translationalT field" << endl;
             volScalarField translationalT
             (
                 IOobject
@@ -189,7 +176,7 @@ void Foam::dsmcFields::write()
                *(linearKEMean - 0.5*rhoMMean*(UMean & UMean))
             );
 
-            Info<< "    Calculating internalT field." << endl;
+            if (log_) Info<< "    Calculating internalT field" << endl;
             volScalarField internalT
             (
                 IOobject
@@ -202,7 +189,7 @@ void Foam::dsmcFields::write()
                 (2.0/physicoChemical::k.value())*(internalEMean/iDofMean)
             );
 
-            Info<< "    Calculating overallT field." << endl;
+            if (log_) Info<< "    Calculating overallT field" << endl;
             volScalarField overallT
             (
                 IOobject
@@ -216,7 +203,7 @@ void Foam::dsmcFields::write()
                *(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean)
             );
 
-            Info<< "    Calculating pressure field." << endl;
+            if (log_) Info<< "    Calculating pressure field" << endl;
             volScalarField p
             (
                 IOobject
@@ -243,25 +230,28 @@ void Foam::dsmcFields::write()
                 }
             }
 
-            Info<< "    mag(UMean) max/min : "
-                << max(mag(UMean)).value() << " "
-                << min(mag(UMean)).value() << endl;
+            if (log_)
+            {
+                Info<< "    mag(UMean) max/min: "
+                    << max(mag(UMean)).value() << " "
+                    << min(mag(UMean)).value() << endl;
 
-            Info<< "    translationalT max/min : "
-                << max(translationalT).value() << " "
-                << min(translationalT).value() << endl;
+                Info<< "    translationalT max/min: "
+                    << max(translationalT).value() << " "
+                    << min(translationalT).value() << endl;
 
-            Info<< "    internalT max/min : "
-                << max(internalT).value() << " "
-                << min(internalT).value() << endl;
+                Info<< "    internalT max/min: "
+                    << max(internalT).value() << " "
+                    << min(internalT).value() << endl;
 
-            Info<< "    overallT max/min : "
-                << max(overallT).value() << " "
-                << min(overallT).value() << endl;
+                Info<< "    overallT max/min: "
+                    << max(overallT).value() << " "
+                    << min(overallT).value() << endl;
 
-            Info<< "    p max/min : "
-                << max(p).value() << " "
-                << min(p).value() << endl;
+                Info<< "    p max/min: "
+                    << max(p).value() << " "
+                    << min(p).value() << endl;
+            }
 
             UMean.write();
 
@@ -273,13 +263,14 @@ void Foam::dsmcFields::write()
 
             p.write();
 
-            Info<< "dsmcFields written." << nl << endl;
+            if (log_) Info<< "    " << type() << " written" << nl << endl;
         }
         else
         {
-            Info<< "Small value (" << min(mag(rhoNMean))
+            if (log_) Info
+                << "Small value (" << min(mag(rhoNMean))
                 << ") found in rhoNMean field. "
-                << "Not calculating dsmcFields to avoid division by zero."
+                << "Not calculating " << type() << " to avoid division by zero."
                 << endl;
         }
     }
diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H
index b6f7ae68d61dc0bd968fbfc4b8eef43cf3bd02fb..ccef65a1075a5ea52da92a9c99c36acbaf0124a4 100644
--- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H
+++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,13 +28,32 @@ Group
     grpUtilitiesFunctionObjects
 
 Description
-    Calculate intensive fields:
+    This function object calculates and outputs the intensive fields:
     - UMean
     - translationalT
     - internalT
     - overallT
     from averaged extensive fields from a DSMC calculation.
 
+
+    Example of function object specification to calculate DSMC fields:
+    \verbatim
+    dsmcFields1
+    {
+        type        dsmcFields;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: dsmcFields   | yes         |
+        log          | Log to standard output  | no          | yes
+    \endtable
+
+
 SourceFiles
     dsmcFields.C
     IOdsmcFields.H
@@ -45,6 +64,7 @@ SourceFiles
 #define dsmcFields_H
 
 #include "typeInfo.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -73,6 +93,9 @@ class dsmcFields
         //- on/off switch
         bool active_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H b/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H
new file mode 100644
index 0000000000000000000000000000000000000000..f29c2e41d17e4453bc7e4b8f92f466dea312b7e1
--- /dev/null
+++ b/src/postProcessing/functionObjects/utilities/fluxSummary/IOfluxSummary.H
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::IOfluxSummary
+
+Description
+    Instance of the generic IOOutputFilter for fluxSummary.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IOfluxSummary_H
+#define IOfluxSummary_H
+
+#include "fluxSummary.H"
+#include "IOOutputFilter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef IOOutputFilter<fluxSummary> IOfluxSummary;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C
new file mode 100644
index 0000000000000000000000000000000000000000..7ec070bef00cf97fb365ccc29fee1df47b6123c9
--- /dev/null
+++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.C
@@ -0,0 +1,956 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "fluxSummary.H"
+#include "surfaceFields.H"
+#include "dictionary.H"
+#include "Time.H"
+#include "syncTools.H"
+#include "meshTools.H"
+#include "PatchEdgeFaceWave.H"
+#include "patchEdgeFaceRegion.H"
+#include "globalIndex.H"
+#include "OBJstream.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(fluxSummary, 0);
+
+    template<>
+    const char* NamedEnum
+    <
+        fluxSummary::modeType,
+        3
+    >::names[] =
+    {
+        "faceZone",
+        "faceZoneAndDirection",
+        "cellZoneAndDirection"
+    };
+}
+
+
+const Foam::NamedEnum<Foam::fluxSummary::modeType, 3>
+Foam::fluxSummary::modeTypeNames_;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::fluxSummary::initialiseFaceZone
+(
+    const word& faceZoneName,
+    DynamicList<word>& faceZoneNames,
+    DynamicList<List<label> >& faceID,
+    DynamicList<List<label> >& facePatchID,
+    DynamicList<List<scalar> >& faceSign
+) const
+{
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+
+    label zoneI = mesh.faceZones().findZoneID(faceZoneName);
+
+    if (zoneI == -1)
+    {
+        FatalErrorIn
+        (
+            "void  Foam::fluxSummary::initialiseFaceZone"
+            "("
+                "const word&, "
+                "DynamicList<word>&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<scalar> >&"
+            ") const"
+        )
+            << "Unable to find faceZone " << faceZoneName
+            << ".  Valid faceZones are: " << mesh.faceZones().names()
+            << exit(FatalError);
+    }
+
+    faceZoneNames.append(faceZoneName);
+
+    const faceZone& fZone = mesh.faceZones()[zoneI];
+
+    DynamicList<label> faceIDs(fZone.size());
+    DynamicList<label> facePatchIDs(fZone.size());
+    DynamicList<scalar> faceSigns(fZone.size());
+
+    forAll(fZone, i)
+    {
+        label faceI = fZone[i];
+
+        label faceID = -1;
+        label facePatchID = -1;
+        if (mesh.isInternalFace(faceI))
+        {
+            faceID = faceI;
+            facePatchID = -1;
+        }
+        else
+        {
+            facePatchID = mesh.boundaryMesh().whichPatch(faceI);
+            const polyPatch& pp = mesh.boundaryMesh()[facePatchID];
+            if (isA<coupledPolyPatch>(pp))
+            {
+                if (refCast<const coupledPolyPatch>(pp).owner())
+                {
+                    faceID = pp.whichFace(faceI);
+                }
+                else
+                {
+                    faceID = -1;
+                }
+            }
+            else if (!isA<emptyPolyPatch>(pp))
+            {
+                faceID = faceI - pp.start();
+            }
+            else
+            {
+                faceID = -1;
+                facePatchID = -1;
+            }
+        }
+
+        if (faceID >= 0)
+        {
+            // orientation set by faceZone flip map
+            if (fZone.flipMap()[faceI])
+            {
+                faceSigns.append(-1);
+            }
+            else
+            {
+                faceSigns.append(1);
+            }
+
+            faceIDs.append(faceID);
+            facePatchIDs.append(facePatchID);
+        }
+    }
+
+    faceID.append(faceIDs);
+    facePatchID.append(facePatchIDs);
+    faceSign.append(faceSigns);
+}
+
+
+void Foam::fluxSummary::initialiseFaceZoneAndDirection
+(
+    const word& faceZoneName,
+    const vector& dir,
+    DynamicList<vector>& zoneRefDir,
+    DynamicList<word>& faceZoneNames,
+    DynamicList<List<label> >& faceID,
+    DynamicList<List<label> >& facePatchID,
+    DynamicList<List<scalar> >& faceSign
+) const
+{
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+
+    vector refDir = dir/(mag(dir) + ROOTVSMALL);
+
+    label zoneI = mesh.faceZones().findZoneID(faceZoneName);
+
+    if (zoneI == -1)
+    {
+        FatalErrorIn
+        (
+            "void  Foam::fluxSummary::initialiseFaceZoneAndDirection"
+            "("
+                "const word&, "
+                "const vector&, "
+                "DynamicList<vector>&, "
+                "DynamicList<word>&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<scalar> >&"
+            ") const"
+        )
+            << "Unable to find faceZone " << faceZoneName
+            << ".  Valid faceZones are: " << mesh.faceZones().names()
+            << exit(FatalError);
+    }
+
+    faceZoneNames.append(faceZoneName);
+    zoneRefDir.append(refDir);
+
+    const faceZone& fZone = mesh.faceZones()[zoneI];
+
+    DynamicList<label> faceIDs(fZone.size());
+    DynamicList<label> facePatchIDs(fZone.size());
+    DynamicList<scalar> faceSigns(fZone.size());
+
+    const surfaceVectorField& Sf = mesh.Sf();
+    const surfaceScalarField& magSf = mesh.magSf();
+
+    vector n = vector::zero;
+
+    forAll(fZone, i)
+    {
+        label faceI = fZone[i];
+
+        label faceID = -1;
+        label facePatchID = -1;
+        if (mesh.isInternalFace(faceI))
+        {
+            faceID = faceI;
+            facePatchID = -1;
+        }
+        else
+        {
+            facePatchID = mesh.boundaryMesh().whichPatch(faceI);
+            const polyPatch& pp = mesh.boundaryMesh()[facePatchID];
+            if (isA<coupledPolyPatch>(pp))
+            {
+                if (refCast<const coupledPolyPatch>(pp).owner())
+                {
+                    faceID = pp.whichFace(faceI);
+                }
+                else
+                {
+                    faceID = -1;
+                }
+            }
+            else if (!isA<emptyPolyPatch>(pp))
+            {
+                faceID = faceI - pp.start();
+            }
+            else
+            {
+                faceID = -1;
+                facePatchID = -1;
+            }
+        }
+
+        if (faceID >= 0)
+        {
+            // orientation set by comparison with reference direction
+            if (facePatchID != -1)
+            {
+                n = Sf.boundaryField()[facePatchID][faceID]
+                   /(magSf.boundaryField()[facePatchID][faceID] + ROOTVSMALL);
+            }
+            else
+            {
+                n = Sf[faceID]/(magSf[faceID] + ROOTVSMALL);
+            }
+
+            if ((n & refDir) > tolerance_)
+            {
+                faceSigns.append(1);
+            }
+            else
+            {
+                faceSigns.append(-1);
+            }
+
+            faceIDs.append(faceID);
+            facePatchIDs.append(facePatchID);
+        }
+    }
+
+    faceID.append(faceIDs);
+    facePatchID.append(facePatchIDs);
+    faceSign.append(faceSigns);
+}
+
+
+void Foam::fluxSummary::initialiseCellZoneAndDirection
+(
+    const word& cellZoneName,
+    const vector& dir,
+    DynamicList<vector>& zoneRefDir,
+    DynamicList<word>& faceZoneNames,
+    DynamicList<List<label> >& faceID,
+    DynamicList<List<label> >& facePatchID,
+    DynamicList<List<scalar> >& faceSign
+) const
+{
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+
+    vector refDir = dir/(mag(dir) + ROOTVSMALL);
+
+    const label cellZoneI = mesh.cellZones().findZoneID(cellZoneName);
+
+    if (cellZoneI == -1)
+    {
+        FatalErrorIn
+        (
+            "void Foam::fluxSummary::initialiseCellZoneAndDirection"
+            "("
+                "const word&, "
+                "const vector&, "
+                "DynamicList<vector>&, "
+                "DynamicList<word>&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<label> >&, "
+                "DynamicList<List<scalar> >&"
+            ") const"
+        )
+            << "Unable to find cellZone " << cellZoneName
+            << ". Valid zones are: " << mesh.cellZones().names()
+            << exit(FatalError);
+    }
+
+    const label nInternalFaces = mesh.nInternalFaces();
+    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+
+    labelList cellAddr(mesh.nCells(), -1);
+    const labelList& cellIDs = mesh.cellZones()[cellZoneI];
+    UIndirectList<label>(cellAddr, cellIDs) = identity(cellIDs.size());
+    labelList nbrFaceCellAddr(mesh.nFaces() - nInternalFaces, -1);
+
+    forAll(pbm, patchI)
+    {
+        const polyPatch& pp = pbm[patchI];
+
+        if (pp.coupled())
+        {
+            forAll(pp, i)
+            {
+                label faceI = pp.start() + i;
+                label nbrFaceI = faceI - nInternalFaces;
+                label own = mesh.faceOwner()[faceI];
+                nbrFaceCellAddr[nbrFaceI] = cellAddr[own];
+            }
+        }
+    }
+
+    // correct boundary values for parallel running
+    syncTools::swapBoundaryFaceList(mesh, nbrFaceCellAddr);
+
+    // collect faces
+    DynamicList<label> faceIDs(floor(0.1*mesh.nFaces()));
+    DynamicList<label> facePatchIDs(faceIDs.size());
+    DynamicList<label> faceLocalPatchIDs(faceIDs.size());
+    DynamicList<scalar> faceSigns(faceIDs.size());
+
+    // internal faces
+    for (label faceI = 0; faceI < nInternalFaces; faceI++)
+    {
+        const label own = cellAddr[mesh.faceOwner()[faceI]];
+        const label nbr = cellAddr[mesh.faceNeighbour()[faceI]];
+
+        if (((own != -1) && (nbr == -1)) || ((own == -1) && (nbr != -1)))
+        {
+            vector n = mesh.faces()[faceI].normal(mesh.points());
+            n /= mag(n) + ROOTVSMALL;
+
+            if ((n & refDir) > tolerance_)
+            {
+                faceIDs.append(faceI);
+                faceLocalPatchIDs.append(faceI);
+                facePatchIDs.append(-1);
+                faceSigns.append(1);
+            }
+            else if ((n & -refDir) > tolerance_)
+            {
+                faceIDs.append(faceI);
+                faceLocalPatchIDs.append(faceI);
+                facePatchIDs.append(-1);
+                faceSigns.append(-1);
+            }
+        }
+    }
+
+    // loop of boundary faces
+    forAll(pbm, patchI)
+    {
+        const polyPatch& pp = pbm[patchI];
+
+        forAll(pp, localFaceI)
+        {
+            const label faceI = pp.start() + localFaceI;
+            const label own = cellAddr[mesh.faceOwner()[faceI]];
+            const label nbr = nbrFaceCellAddr[faceI - nInternalFaces];
+
+            if ((own != -1) && (nbr == -1))
+            {
+                vector n = mesh.faces()[faceI].normal(mesh.points());
+                n /= mag(n) + ROOTVSMALL;
+
+                if ((n & refDir) > tolerance_)
+                {
+                    faceIDs.append(faceI);
+                    faceLocalPatchIDs.append(localFaceI);
+                    facePatchIDs.append(patchI);
+                    faceSigns.append(1);
+                }
+                else if ((n & -refDir) > tolerance_)
+                {
+                    faceIDs.append(faceI);
+                    faceLocalPatchIDs.append(localFaceI);
+                    facePatchIDs.append(patchI);
+                    faceSigns.append(-1);
+                }
+            }
+        }
+    }
+
+    // convert into primitivePatch for convenience
+    indirectPrimitivePatch patch
+    (
+        IndirectList<face>(mesh.faces(), faceIDs),
+        mesh.points()
+    );
+
+    if (debug)
+    {
+        OBJstream os(mesh.time().path()/"patch.obj");
+        faceList faces(patch);
+        os.write(faces, mesh.points(), false);
+    }
+
+
+    // data on all edges and faces
+    List<patchEdgeFaceRegion> allEdgeInfo(patch.nEdges());
+    List<patchEdgeFaceRegion> allFaceInfo(patch.size());
+
+    bool search = true;
+
+    if (debug)
+    {
+        Info<< "initialiseCellZoneAndDirection: "
+            << "Starting walk to split patch into faceZones"
+            << endl;
+    }
+
+    globalIndex globalFaces(patch.size());
+
+    label oldFaceID = 0;
+    label regionI = 0;
+    while (search)
+    {
+        DynamicList<label> changedEdges;
+        DynamicList<patchEdgeFaceRegion> changedInfo;
+
+        label seedFaceI = labelMax;
+        for (; oldFaceID < patch.size(); oldFaceID++)
+        {
+            if (allFaceInfo[oldFaceID].region() == -1)
+            {
+                seedFaceI = globalFaces.toGlobal(oldFaceID);
+                break;
+            }
+        }
+        reduce(seedFaceI, minOp<label>());
+
+        if (seedFaceI == labelMax)
+        {
+            break;
+        }
+
+        if (globalFaces.isLocal(seedFaceI))
+        {
+            label localFaceI = globalFaces.toLocal(seedFaceI);
+            const labelList& fEdges = patch.faceEdges()[localFaceI];
+
+            forAll(fEdges, i)
+            {
+                if (allEdgeInfo[fEdges[i]].region() != -1)
+                {
+                    WarningIn
+                    (
+                        "void Foam::fluxSummary::initialiseCellZoneAndDirection"
+                        "("
+                            "const word&, "
+                            "const vector&, "
+                            "DynamicList<vector>&, "
+                            "DynamicList<word>&, "
+                            "DynamicList<List<label> >&, "
+                            "DynamicList<List<label> >&, "
+                            "DynamicList<List<scalar> >&"
+                        ") const"
+                    )   << "Problem in edge face wave: attempted to assign a "
+                        << "value to an edge that has already been visited. "
+                        << "Edge info: " << allEdgeInfo[fEdges[i]]
+                        << endl;
+                }
+
+                changedEdges.append(fEdges[i]);
+                changedInfo.append(regionI);
+            }
+        }
+
+
+        PatchEdgeFaceWave
+        <
+            indirectPrimitivePatch,
+            patchEdgeFaceRegion
+        > calc
+        (
+            mesh,
+            patch,
+            changedEdges,
+            changedInfo,
+            allEdgeInfo,
+            allFaceInfo,
+            returnReduce(patch.nEdges(), sumOp<label>())
+        );
+
+        label nCells = 0;
+        forAll(allFaceInfo, faceI)
+        {
+            if (allFaceInfo[faceI].region() == regionI)
+            {
+                nCells++;
+            }
+        }
+
+        if (debug)
+        {
+            Info<< "*** region:" << regionI
+                << "  found:" << returnReduce(nCells, sumOp<label>())
+                << " faces" << endl;
+        }
+
+        regionI++;
+    }
+
+    // collect the data per region
+    label nRegion = regionI;
+
+    List<DynamicList<label> > regionFaceIDs(nRegion);
+    List<DynamicList<label> > regionFacePatchIDs(nRegion);
+    List<DynamicList<scalar> > regionFaceSigns(nRegion);
+
+    forAll(allFaceInfo, faceI)
+    {
+        regionI = allFaceInfo[faceI].region();
+
+        regionFaceIDs[regionI].append(faceLocalPatchIDs[faceI]);
+        regionFacePatchIDs[regionI].append(facePatchIDs[faceI]);
+        regionFaceSigns[regionI].append(faceSigns[faceI]);
+    }
+
+    // transfer to persistent storage
+    forAll(regionFaceIDs, regionI)
+    {
+        const word zoneName = cellZoneName + ":faceZone" + Foam::name(regionI);
+        faceZoneNames.append(zoneName);
+        zoneRefDir.append(refDir);
+        faceID.append(regionFaceIDs[regionI]);
+        facePatchID.append(regionFacePatchIDs[regionI]);
+        faceSign.append(regionFaceSigns[regionI]);
+
+        // write OBJ of faces to file
+        if (debug)
+        {
+            OBJstream os(mesh.time().path()/zoneName + ".obj");
+            faceList faces(mesh.faces(), regionFaceIDs[regionI]);
+            os.write(faces, mesh.points(), false);
+        }
+    }
+
+    if (log_)
+    {
+        Info<< type() << " " << name_ << " output:" << nl
+            << "    Created " << faceID.size()
+            << " separate face zones from cell zone " << cellZoneName << nl;
+
+        forAll(faceZoneNames, i)
+        {
+            label nFaces = returnReduce(faceID[i].size(), sumOp<label>());
+            Info<< "    " << faceZoneNames[i] << ": "
+                << nFaces << " faces" << nl;
+        }
+
+        Info<< endl;
+    }
+}
+
+
+void Foam::fluxSummary::initialiseFaceArea()
+{
+    faceArea_.setSize(faceID_.size(), 0);
+
+    const fvMesh& mesh = refCast<const fvMesh>(obr_);
+    const surfaceScalarField& magSf = mesh.magSf();
+
+    forAll(faceID_, zoneI)
+    {
+        const labelList& faceIDs = faceID_[zoneI];
+        const labelList& facePatchIDs = facePatchID_[zoneI];
+
+        scalar sumMagSf = 0;
+
+        forAll(faceIDs, i)
+        {
+            label faceI = faceIDs[i];
+
+            if (facePatchIDs[i] == -1)
+            {
+                sumMagSf += magSf[faceI];
+            }
+            else
+            {
+                label patchI = facePatchIDs[i];
+                sumMagSf += magSf.boundaryField()[patchI][faceI];
+            }
+        }
+
+        faceArea_[zoneI] = returnReduce(sumMagSf, sumOp<scalar>());
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fluxSummary::fluxSummary
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool loadFromFiles
+)
+:
+    functionObjectFile(obr, name),
+    name_(name),
+    obr_(obr),
+    active_(true),
+    log_(true),
+    mode_(mdFaceZone),
+    scaleFactor_(1),
+    phiName_("phi"),
+    faceZoneName_(),
+    refDir_(),
+    faceID_(),
+    facePatchID_(),
+    faceSign_(),
+    faceArea_(),
+    filePtrs_(),
+    tolerance_(0.8)
+{
+    // Check if the available mesh is an fvMesh otherise deactivate
+    if (!isA<fvMesh>(obr_))
+    {
+        active_ = false;
+        WarningIn
+        (
+            "fluxSummary::fluxSummary"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "const bool"
+            ")"
+        )   << "No fvMesh available, deactivating " << name_
+            << endl;
+    }
+
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fluxSummary::~fluxSummary()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::fluxSummary::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        functionObjectFile::read(dict);
+
+        log_ = dict.lookupOrDefault<Switch>("log", true);
+
+        mode_ = modeTypeNames_.read(dict.lookup("mode"));
+        phiName_= dict.lookupOrDefault<word>("phiName", "phi");
+        dict.readIfPresent("scaleFactor", scaleFactor_);
+        dict.readIfPresent("tolerance", tolerance_);
+
+        // initialise with capacity of 10 faceZones
+        DynamicList<vector> refDir(10);
+        DynamicList<word> faceZoneName(refDir.size());
+        DynamicList<List<label> > faceID(refDir.size());
+        DynamicList<List<label> > facePatchID(refDir.size());
+        DynamicList<List<scalar> > faceSign(refDir.size());
+
+        switch (mode_)
+        {
+            case mdFaceZone:
+            {
+                List<word> zones(dict.lookup("faceZones"));
+
+                forAll(zones, i)
+                {
+                    initialiseFaceZone
+                    (
+                        zones[i],
+                        faceZoneName,
+                        faceID,
+                        facePatchID,
+                        faceSign
+                    );
+                }
+                break;
+            }
+            case mdFaceZoneAndDirection:
+            {
+                List<Tuple2<word, vector> >
+                    zoneAndDirection(dict.lookup("faceZoneAndDirection"));
+
+                forAll(zoneAndDirection, i)
+                {
+                    initialiseFaceZoneAndDirection
+                    (
+                        zoneAndDirection[i].first(),
+                        zoneAndDirection[i].second(),
+                        refDir,
+                        faceZoneName,
+                        faceID,
+                        facePatchID,
+                        faceSign
+                    );
+                }
+                break;
+            }
+            case mdCellZoneAndDirection:
+            {
+                List<Tuple2<word, vector> >
+                    zoneAndDirection(dict.lookup("cellZoneAndDirection"));
+
+                forAll(zoneAndDirection, i)
+                {
+                    initialiseCellZoneAndDirection
+                    (
+                        zoneAndDirection[i].first(),
+                        zoneAndDirection[i].second(),
+                        refDir,
+                        faceZoneName,
+                        faceID,
+                        facePatchID,
+                        faceSign
+                    );
+                }
+                break;
+            }
+            default:
+            {
+                FatalIOErrorIn
+                (
+                    "void Foam::fluxSummary::read(const dictionary&)",
+                    dict
+                )
+                    << "unhandled enumeration " << modeTypeNames_[mode_]
+                    << abort(FatalIOError);
+            }
+        }
+
+        faceZoneName_.transfer(faceZoneName);
+        refDir_.transfer(refDir);
+        faceID_.transfer(faceID);
+        facePatchID_.transfer(facePatchID);
+        faceSign_.transfer(faceSign);
+
+        initialiseFaceArea();
+
+        if (writeToFile())
+        {
+            filePtrs_.setSize(faceZoneName_.size());
+
+            forAll(filePtrs_, fileI)
+            {
+                const word& fzName = faceZoneName_[fileI];
+                filePtrs_.set(fileI, createFile(fzName));
+                writeFileHeader
+                (
+                    fzName,
+                    faceArea_[fileI],
+                    refDir_[fileI],
+                    filePtrs_[fileI]
+                );
+            }
+        }
+    }
+}
+
+
+void Foam::fluxSummary::writeFileHeader
+(
+    const word& fzName,
+    const scalar area,
+    const vector& refDir,
+    Ostream& os
+) const
+{
+    writeHeader(os, "Flux summary");
+    writeHeaderValue(os, "Face zone", fzName);
+    writeHeaderValue(os, "Total area", area);
+
+    switch (mode_)
+    {
+        case mdFaceZoneAndDirection:
+        case mdCellZoneAndDirection:
+        {
+            writeHeaderValue(os, "Reference direction", refDir);
+            break;
+        }
+        default:
+        {}
+    }
+
+    writeHeaderValue(os, "Scale factor", scaleFactor_);
+
+    writeCommented(os, "Time");
+    os  << tab << "positive"
+        << tab << "negative"
+        << tab << "net"
+        << tab << "absolute"
+        << endl;
+}
+
+
+void Foam::fluxSummary::execute()
+{
+    // Do nothing - only valid on write
+}
+
+
+void Foam::fluxSummary::end()
+{
+    // Do nothing - only valid on write
+}
+
+
+void Foam::fluxSummary::timeSet()
+{
+    // Do nothing - only valid on write
+}
+
+
+void Foam::fluxSummary::write()
+{
+    if (!active_)
+    {
+        return;
+    }
+
+    const surfaceScalarField& phi =
+        obr_.lookupObject<surfaceScalarField>(phiName_);
+
+    word flowType = "";
+    if (phi.dimensions() == dimVolume/dimTime)
+    {
+        flowType = "volumetric";
+    }
+    else if (phi.dimensions() == dimMass/dimTime)
+    {
+        flowType = "mass";
+    }
+    else
+    {
+        FatalErrorIn("void Foam::fluxSummary::write()")
+            << "Unsupported flux field " << phi.name() << " with dimensions "
+            << phi.dimensions() << ".  Expected eithe mass flow or volumetric "
+            << "flow rate" << abort(FatalError);
+    }
+
+    if (log_)
+    {
+        Info<< type() << " " << name_ << ' ' << flowType << " flux output:"
+            << nl;
+    }
+
+    forAll(faceZoneName_, zoneI)
+    {
+        const labelList& faceID = faceID_[zoneI];
+        const labelList& facePatchID = facePatchID_[zoneI];
+        const scalarList& faceSign = faceSign_[zoneI];
+
+        scalar phiPos = scalar(0);
+        scalar phiNeg = scalar(0);
+        scalar phif = scalar(0);
+
+        forAll(faceID, i)
+        {
+            label faceI = faceID[i];
+            label patchI = facePatchID[i];
+
+            if (patchI != -1)
+            {
+                phif = phi.boundaryField()[patchI][faceI];
+            }
+            else
+            {
+                phif = phi[faceI];
+            }
+
+            phif *= faceSign[i];
+
+            if (phif > 0)
+            {
+                phiPos += phif;
+            }
+            else
+            {
+                phiNeg += phif;
+            }
+        }
+
+        reduce(phiPos, sumOp<scalar>());
+        reduce(phiNeg, sumOp<scalar>());
+
+        phiPos *= scaleFactor_;
+        phiNeg *= scaleFactor_;
+
+        scalar netFlux = phiPos + phiNeg;
+        scalar absoluteFlux = phiPos - phiNeg;
+
+        if (log_)
+        {
+            Info<< "    faceZone " << faceZoneName_[zoneI] << ':' << nl
+                << "        positive : " << phiPos << nl
+                << "        negative : " << phiNeg << nl
+                << "        net      : " << netFlux << nl
+                << "        absolute : " << absoluteFlux
+                << nl << endl;
+        }
+
+        if (writeToFile())
+        {
+            filePtrs_[zoneI]
+                << obr_.time().value() << token::TAB
+                << phiPos << token::TAB
+                << phiNeg << token::TAB
+                << netFlux << token::TAB
+                << absoluteFlux
+                << endl;
+        }
+    }
+
+    if (log_) Info<< endl;
+}
+
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H
new file mode 100644
index 0000000000000000000000000000000000000000..777167b171ffc4b3a575d2f3df735010ab3ea313
--- /dev/null
+++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummary.H
@@ -0,0 +1,302 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::fluxSummary
+
+Group
+    grpUtilityFunctionObjects
+
+Description
+    This function object calculates the flux across selections of faces.
+
+    Output comprises, per set of faces, the:
+    - positive
+    - negative
+    - net
+    - absolute
+    fluxes
+
+    Example of function object specification:
+    \verbatim
+    fluxSummary1
+    {
+        type        fluxSummary;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+        write       yes;
+        log         yes;
+        mode        cellZoneAndDirection;
+        cellZoneAndDirection
+        (
+            (porosity (1 0 0))
+        );
+        scaleFactor 1.2;
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | type name: fluxSummary  | yes         |
+        write        | write flux data to file |  no  | yes
+        log          | write flux data to standard output | no | yes
+        mode         | mode to generate faces to test | yes |
+        scaleFactor  | optional factor to scale result | no | 1
+    \endtable
+
+    The mode is one of:
+    - faceZone
+    - faceZoneAndDirection
+    - cellZoneAndDirection
+
+    Output data is written to files of the form \<timeDir\>/<faceZoneName>.dat
+
+SeeAlso
+    Foam::functionObject
+    Foam::OutputFilterFunctionObject
+
+SourceFiles
+    fluxSummary.C
+    IOfluxSummary.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fluxSummary_H
+#define fluxSummary_H
+
+#include "functionObjectFile.H"
+#include "Switch.H"
+#include "vector.H"
+#include "DynamicList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class polyMesh;
+class mapPolyMesh;
+
+/*---------------------------------------------------------------------------*\
+                    Class fluxSummary Declaration
+\*---------------------------------------------------------------------------*/
+
+class fluxSummary
+:
+    public functionObjectFile
+{
+public:
+
+    // Public enumerations
+
+        //- Face mode type
+        enum modeType
+        {
+            mdFaceZone,
+            mdFaceZoneAndDirection,
+            mdCellZoneAndDirection
+        };
+
+        //- Mode type names
+        static const NamedEnum<modeType, 3> modeTypeNames_;
+
+
+protected:
+
+    // Protected data
+
+        //- Name of function object
+        //  Also used as the name of the output directory
+        word name_;
+
+        //- Reference to the database
+        const objectRegistry& obr_;
+
+        //- on/off switch
+        bool active_;
+
+        //- Switch to send output to Info as well
+        Switch log_;
+
+        //- Mode for face determination
+        modeType mode_;
+
+        //- Scale factor
+        scalar scaleFactor_;
+
+        //- Name of flux field, default = phi
+        word phiName_;
+
+
+        // Per-faceZone information
+
+            //- Region names
+            List<word> faceZoneName_;
+
+            //- Reference direction
+            List<vector> refDir_;
+
+            //- Face IDs
+            List<List<label> > faceID_;
+
+            //- Face patch IDs
+            List<List<label> > facePatchID_;
+
+            //- Face flip map signs
+            List<List<scalar> > faceSign_;
+
+            //- Sum of face areas
+            List<scalar> faceArea_;
+
+            //- Output file per face zone
+            PtrList<OFstream> filePtrs_;
+
+
+        //- Tolerance applied when matching face normals
+        scalar tolerance_;
+
+
+    // Private Member Functions
+
+        //- Initialise face set from face zone
+        void initialiseFaceZone
+        (
+            const word& faceZoneName,
+            DynamicList<word>& faceZoneNames,
+            DynamicList<List<label> >& faceID,
+            DynamicList<List<label> >& facePatchID,
+            DynamicList<List<scalar> >& faceSign
+        ) const;
+
+        //- Initialise face set from face zone and direction
+        void initialiseFaceZoneAndDirection
+        (
+            const word& faceZoneName,
+            const vector& refDir,
+            DynamicList<vector>& dir,
+            DynamicList<word>& faceZoneNames,
+            DynamicList<List<label> >& faceID,
+            DynamicList<List<label> >& facePatchID,
+            DynamicList<List<scalar> >& faceSign
+        ) const;
+
+        //- Initialise face set from cell zone and direction
+        void initialiseCellZoneAndDirection
+        (
+            const word& cellZoneName,
+            const vector& refDir,
+            DynamicList<vector>& dir,
+            DynamicList<word>& faceZoneNames,
+            DynamicList<List<label> >& faceID,
+            DynamicList<List<label> >& facePatchID,
+            DynamicList<List<scalar> >& faceSign
+        ) const;
+
+        //- Initialise the total area per derived faceZone
+        void initialiseFaceArea();
+
+        //- Output file header information
+        virtual void writeFileHeader
+        (
+            const word& fzName,
+            const scalar area,
+            const vector& refDir,
+            Ostream& os
+        ) const;
+
+        //- Disallow default bitwise copy construct
+        fluxSummary(const fluxSummary&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const fluxSummary&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("fluxSummary");
+
+
+    // Constructors
+
+        //- Construct for given objectRegistry and dictionary.
+        //  Allow the possibility to load fields from files
+        fluxSummary
+        (
+            const word& name,
+            const objectRegistry&,
+            const dictionary&,
+            const bool loadFromFiles = false
+        );
+
+
+    //- Destructor
+    virtual ~fluxSummary();
+
+
+    // Member Functions
+
+        //- Return name of the set of field min/max
+        virtual const word& name() const
+        {
+            return name_;
+        }
+
+        //- Read the field min/max data
+        virtual void read(const dictionary&);
+
+        //- Execute, currently does nothing
+        virtual void execute();
+
+        //- Execute at the final time-loop, currently does nothing
+        virtual void end();
+
+        //- Called when time was set at the end of the Time::operator++
+        virtual void timeSet();
+
+        //- Write the fluxSummary
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&)
+        {}
+
+        //- Update for changes of mesh
+        virtual void movePoints(const polyMesh&)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..32c61e2df39a96767deba45878275a98ad5912c8
--- /dev/null
+++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.C
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "fluxSummaryFunctionObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineNamedTemplateTypeNameAndDebug(fluxSummaryFunctionObject, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        fluxSummaryFunctionObject,
+        dictionary
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..b0b4380bff5da4a9eca0e98cc67342cd7eaa9178
--- /dev/null
+++ b/src/postProcessing/functionObjects/utilities/fluxSummary/fluxSummaryFunctionObject.H
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::fluxSummaryFunctionObject
+
+Description
+    FunctionObject wrapper around fluxSummary to allow them to be created
+    via the functions entry within controlDict.
+
+SourceFiles
+    fluxSummaryFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fluxSummaryFunctionObject_H
+#define fluxSummaryFunctionObject_H
+
+#include "fluxSummary.H"
+#include "OutputFilterFunctionObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef OutputFilterFunctionObject<fluxSummary> fluxSummaryFunctionObject;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C
index e760f43107bd3fa39c218e80bd7e7b69d125109a..7d26627af68a43aa4d63dc6265df3e1e06f1aad7 100644
--- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C
+++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,28 +37,6 @@ namespace Foam
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::word Foam::pressureTools::pName() const
-{
-    word fieldName = pName_;
-
-    if (calcTotal_)
-    {
-        fieldName = "total(" + fieldName + ")";
-    }
-    else
-    {
-        fieldName = "static(" + fieldName + ")";
-    }
-
-    if (calcCoeff_)
-    {
-        fieldName = fieldName + "_coeff";
-    }
-
-    return fieldName;
-}
-
-
 Foam::dimensionedScalar Foam::pressureTools::rhoScale
 (
     const volScalarField& p
@@ -86,7 +64,23 @@ Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho
     }
     else
     {
-        return
+        if (!rhoInfInitialised_)
+        {
+            FatalErrorIn
+            (
+                "Foam::tmp<Foam::volScalarField> Foam::pressureTools::rho"
+                "("
+                "    const volScalarField&"
+                ") const"
+            )
+                << type() << " " << name_ << ": "
+                << "pressure identified as incompressible, but reference "
+                << "density is not set.  Please set rhoName to rhoInf, and "
+                << "set an appropriate value for rhoInf"
+                << exit(FatalError);
+        }
+
+       return
             tmp<volScalarField>
             (
                 new volScalarField
@@ -193,12 +187,15 @@ Foam::pressureTools::pressureTools
     pName_("p"),
     UName_("U"),
     rhoName_("rho"),
+    resultName_(word::null),
+    log_(true),
     calcTotal_(false),
     pRef_(0.0),
     calcCoeff_(false),
     pInf_(0.0),
     UInf_(vector::zero),
-    rhoInf_(0.0)
+    rhoInf_(0.0),
+    rhoInfInitialised_(false)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -236,7 +233,7 @@ Foam::pressureTools::pressureTools
             (
                 IOobject
                 (
-                    pName(),
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -264,13 +261,18 @@ void Foam::pressureTools::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
+
         dict.readIfPresent("pName", pName_);
         dict.readIfPresent("UName", UName_);
         dict.readIfPresent("rhoName", rhoName_);
 
+        rhoInfInitialised_ = false;
+
         if (rhoName_ == "rhoInf")
         {
             dict.lookup("rhoInf") >> rhoInf_;
+            rhoInfInitialised_ = true;
         }
 
         dict.lookup("calcTotal") >> calcTotal_;
@@ -296,6 +298,27 @@ void Foam::pressureTools::read(const dictionary& dict)
                     << "pressure level is zero.  Please check the supplied "
                     << "values of pInf, UInf and rhoInf" << endl;
             }
+
+            rhoInfInitialised_ = true;
+        }
+
+        if (!dict.readIfPresent("resultName", resultName_))
+        {
+            resultName_ = pName_;
+
+            if (calcTotal_)
+            {
+                resultName_ = "total(" + resultName_ + ")";
+            }
+            else
+            {
+                resultName_ = "static(" + resultName_ + ")";
+            }
+
+            if (calcCoeff_)
+            {
+                resultName_ = resultName_ + "_coeff";
+            }
         }
     }
 }
@@ -310,7 +333,7 @@ void Foam::pressureTools::execute()
         volScalarField& pResult =
             const_cast<volScalarField&>
             (
-                obr_.lookupObject<volScalarField>(pName())
+                obr_.lookupObject<volScalarField>(resultName_)
             );
 
         pResult == convertToCoeff(rhoScale(p)*p + pDyn(p) + pRef());
@@ -338,9 +361,10 @@ void Foam::pressureTools::write()
     if (active_)
     {
         const volScalarField& pResult =
-            obr_.lookupObject<volScalarField>(pName());
+            obr_.lookupObject<volScalarField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << pResult.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H
index 6f7607e6e0f76afdc3d518f288c3a95c4532180d..aa5623ebd5416d196d27ef3bbe01c360bf51e284 100644
--- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H
+++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H
@@ -101,6 +101,8 @@ Description
         pInf         | Freestream pressure for coefficient calculation | no |
         UInf         | Freestream velocity for coefficient calculation | no |
         rhoInf       | Freestream density for coefficient calculation | no |
+        resultName   | Name of derived pressure field | no   | auto generated
+        log          | log to standard output  | no          | yes
     \endtable
 
 SourceFiles
@@ -114,6 +116,7 @@ SourceFiles
 
 #include "volFieldsFwd.H"
 #include "dimensionedScalar.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -152,6 +155,12 @@ class pressureTools
         //- Name of density field, default is "rho"
         word rhoName_;
 
+        //- Result name
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
         // Total pressure calculation
 
@@ -176,13 +185,13 @@ class pressureTools
             //- Freestream density
             scalar rhoInf_;
 
+            //- Flag to show whether rhoInf has been initialised
+            bool rhoInfInitialised_;
 
-    // Private Member Functions
 
-        //- Return the name of the derived pressure field
-        word pName() const;
+    // Private Member Functions
 
-        //- Return the density scaling if supplied with kinematic pressure
+        //- Return the density scale
         dimensionedScalar rhoScale(const volScalarField& p) const;
 
         //- Return the density field
diff --git a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C
index d38cc9d14d1554930e9c40a8ef87b227c7c4f4b8..2b9c1eb5875e7fe356b3077ba58a54b915bdb60f 100644
--- a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C
+++ b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.C
@@ -186,7 +186,8 @@ Foam::scalarTransport::scalarTransport
     resetOnStartUp_(false),
     nCorr_(0),
     autoSchemes_(false),
-    fvOptions_(mesh_)
+    fvOptions_(mesh_),
+    log_(true)
 {
     read(dict);
 
@@ -209,11 +210,13 @@ void Foam::scalarTransport::read(const dictionary& dict)
 {
     if (active_)
     {
-        Info<< type() << ":" << nl;
+        log_.readIfPresent("log", dict);
 
-        phiName_ = dict.lookupOrDefault<word>("phiName", "phi");
-        UName_ = dict.lookupOrDefault<word>("UName", "U");
-        rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho");
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
+
+        dict.readIfPresent("phiName", phiName_);
+        dict.readIfPresent("UName", UName_);
+        dict.readIfPresent("rhoName", rhoName_);
 
         userDT_ = false;
         if (dict.readIfPresent("DT", DT_))
@@ -221,10 +224,8 @@ void Foam::scalarTransport::read(const dictionary& dict)
             userDT_ = true;
         }
 
-        dict.lookup("resetOnStartUp") >> resetOnStartUp_;
-
         dict.readIfPresent("nCorr", nCorr_);
-
+        dict.lookup("resetOnStartUp") >> resetOnStartUp_;
         dict.lookup("autoSchemes") >> autoSchemes_;
 
         fvOptions_.reset(dict.subDict("fvOptions"));
@@ -236,7 +237,7 @@ void Foam::scalarTransport::execute()
 {
     if (active_)
     {
-        Info<< type() << " output:" << endl;
+        if (log_) Info<< type() << " " << name_ << " output:" << nl;
 
         const surfaceScalarField& phi =
             mesh_.lookupObject<surfaceScalarField>(phiName_);
@@ -316,7 +317,7 @@ void Foam::scalarTransport::execute()
                 << dimVolume/dimTime << endl;
         }
 
-        Info<< endl;
+        if (log_) Info<< endl;
     }
 }
 
diff --git a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H
index c2ffbcec2cd838b4b64b5952235f42b526fd8061..c541c925a31a6d5aadb9c26a193d14baed8ba165 100644
--- a/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H
+++ b/src/postProcessing/functionObjects/utilities/scalarTransport/scalarTransport.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2012-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2012-2014 OpenFOAM Foundation
      \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -29,9 +29,10 @@ Group
 
 Description
     This function object evolves a passive scalar transport equation.  The
-    field in ininitially zero, to which sources are added.  The field name
+    field is initially zero, to which sources are added.  The field name
     is assigned the name of the function object.  Boundary conditions are
-    automatically applied, based on the velocity boundary conditions.
+    read from file if the field file is available, or automatically applied
+    based on the velocity boundary conditions.
 
     - the field can be zeroed on start-up using the resetOnStartUp flag
     - to employ the same numerical schemes as the flow velocity, use the
@@ -39,10 +40,51 @@ Description
     - the diffusivity can be set manually using the DT entry, or retrieved
       from the turbulence model (if applicable)
 
+    Example of function object specification to solve a scalar transport
+    equation:
+    \verbatim
+    functions
+    {
+        scalar1                                     // <--- NOTE: SCALAR NAME
+        {
+            type            scalarTransport;
+            functionObjectLibs ("libutilityFunctionObjects.so");
+            resetOnStartUp  no;
+
+            autoSchemes     yes;
+
+            fvOptions
+            {
+                ...
+            }
+        }
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: scalarTransport | yes      |
+        phiName      | Name of flux field      | no          | phi
+        UName        | Name of velocity field  | no          | U
+        rhoName      | Name of density field   | no          | rho
+        nCorr        | Number of correctors    | no          | 0
+        DT           | Diffision coefficient   | no          | auto generated
+        resetOnStartUp | Reset source to zero on start-up | no | no
+        autoSchemes  | Use U schemes to evolve scalar | no   | yes
+        fvOptions    | List of scalar sources  | yes         |
+        log          | Log to standard output  | no          | yes
+    \endtable
+
+SeeAlso
+    fvOption.H
+    fvOptionList.H
+
 SourceFiles
     scalarTransport.C
     IOscalarTransport.H
 
+
 \*---------------------------------------------------------------------------*/
 
 #ifndef scalarTransport_H
@@ -108,6 +150,9 @@ class scalarTransport
         //- Run-time selectable finite volume options, e.g. sources, constraints
         fv::optionList fvOptions_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C
index a8d540771b3afb5d9e4c14a01845af0b55fd514e..1720091977b265df27a190dd2e5bf5ca7c2b4820 100644
--- a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C
+++ b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -116,7 +116,7 @@ bool Foam::setTimeStepFunctionObject::adjustTimeStep()
 
 bool Foam::setTimeStepFunctionObject::read(const dictionary& dict)
 {
-    enabled_ = dict.lookupOrDefault("enabled", true);
+    enabled_.readIfPresent("enabled", dict);
 
     if (enabled_)
     {
@@ -133,7 +133,7 @@ bool Foam::setTimeStepFunctionObject::read(const dictionary& dict)
         )
         {
             FatalIOErrorIn("setTimeStep::read(const dictionary&)", dict)
-                << "Need to have 'adjustTimeStep' true to enable external"
+                << "'adjustTimeStep' must be set to true to enable external"
                 << " timestep control" << exit(FatalIOError);
         }
     }
diff --git a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H
index 3f03f3ddcccc351283a0df367c76ea34923a21be..10bd6fec3cadd3123d4347f155de9ff90b7e544d 100644
--- a/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H
+++ b/src/postProcessing/functionObjects/utilities/setTimeStep/setTimeStepFunctionObject.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2013-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,12 +28,30 @@ Group
     grpUtilitiesFunctionObjects
 
 Description
-    Overrides the timeStep. Can only be used with
-    solvers with adjustTimeStep control (e.g. pimpleFoam). Makes no attempt
-    to cooperate with other timeStep 'controllers' (maxCo, other
-    functionObjects). Supports 'enabled' flag but none of othe other ones
+    This function object overrides the calculation time step. Can only be used
+    with solvers with adjustTimeStep control (e.g. pimpleFoam).  It makes no
+    attempt to co-operate with other time step 'controllers', e.g. maxCo, other
+    functionObjects. Supports 'enabled' flag but none of the other options
     'timeStart', 'timeEnd', 'outputControl' etc.
 
+
+    Example of function object specification to manipulate the time step:
+    \verbatim
+    setTimeStep1
+    {
+        type        setTimeStep;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: setTimeStep  | yes         |
+        enabled      | On/off switch           | no          | yes
+    \endtable
+
 SourceFiles
     setTimeStepFunctionObject.C
 
@@ -45,6 +63,7 @@ SourceFiles
 #include "functionObject.H"
 #include "dictionary.H"
 #include "DataEntry.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -68,7 +87,7 @@ class setTimeStepFunctionObject
         // Optional user inputs
 
             //- Switch for the execution - defaults to 'yes/on'
-            bool enabled_;
+            Switch enabled_;
 
             //- Time step
             autoPtr<DataEntry<scalar> > timeStepPtr_;
@@ -82,6 +101,7 @@ class setTimeStepFunctionObject
 
 
 public:
+
     //- Runtime type information
     TypeName("setTimeStep");
 
@@ -121,7 +141,6 @@ public:
             //- Switch the function object off
             virtual void off();
 
-
             //- Called at the start of the time-loop
             virtual bool start();
 
@@ -145,7 +164,6 @@ public:
 
             //- Update for changes of mesh
             virtual void movePoints(const polyMesh& mesh);
-
 };
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
index 91d5f381f601279637dd2025d04dfc28c17921ef..68c09980cc270a735a7fb611fc14dfd5a8b75509 100644
--- a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
+++ b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,7 +52,8 @@ void Foam::timeActivatedFileUpdate::updateFile()
 
     if (i > lastIndex_)
     {
-        Info<< nl << type() << ": copying file" << nl << timeVsFile_[i].second()
+        if (log_) Info
+            << nl << type() << ": copying file" << nl << timeVsFile_[i].second()
             << nl << "to:" << nl << fileToUpdate_ << nl << endl;
 
         cp(timeVsFile_[i].second(), fileToUpdate_);
@@ -74,9 +75,10 @@ Foam::timeActivatedFileUpdate::timeActivatedFileUpdate
     name_(name),
     obr_(obr),
     active_(true),
-    fileToUpdate_(dict.lookup("fileToUpdate")),
+    fileToUpdate_("unknown-fileToUpdate"),
     timeVsFile_(),
-    lastIndex_(-1)
+    lastIndex_(-1),
+    log_(true)
 {
     read(dict);
 }
@@ -94,13 +96,18 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
+
         dict.lookup("fileToUpdate") >> fileToUpdate_;
         dict.lookup("timeVsFile") >> timeVsFile_;
 
         lastIndex_ = -1;
         fileToUpdate_.expand();
 
-        Info<< type() << ": time vs file list:" << nl;
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    time vs file list:" << endl;
+
         forAll(timeVsFile_, i)
         {
             timeVsFile_[i].second() = timeVsFile_[i].second().expand();
@@ -111,10 +118,11 @@ void Foam::timeActivatedFileUpdate::read(const dictionary& dict)
                     << nl << exit(FatalError);
             }
 
-            Info<< "    " << timeVsFile_[i].first() << tab
+            if (log_) Info
+                << "    " << timeVsFile_[i].first() << tab
                 << timeVsFile_[i].second() << endl;
         }
-        Info<< endl;
+        if (log_) Info<< endl;
 
         updateFile();
     }
diff --git a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H
index e2f168eaf2dcabfa39c6a5cedbee9760944d49cd..927f88a609fa31bbf1d8029258ff04d54f13b6fe 100644
--- a/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H
+++ b/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -28,18 +28,16 @@ Group
     grpUtilitiesFunctionObjects
 
 Description
-    Performs a file copy/replacement once a specified time has been reached.
+    This function object performs a file copy/replacement once a specified
+    time has been reached.
 
     Example usage to update the fvSolution dictionary at various times
     throughout the calculation:
-
     \verbatim
     fileUpdate1
     {
         type              timeActivatedFileUpdate;
         functionObjectLibs ("libutilityFunctionObjects.so");
-        outputControl     timeStep;
-        outputInterval    1;
         fileToUpdate      "$FOAM_CASE/system/fvSolution";
         timeVsFile
         (
@@ -48,9 +46,20 @@ Description
             (0.20 "$FOAM_CASE/system/fvSolution.20")
             (0.35 "$FOAM_CASE/system/fvSolution.35")
         );
+        ...
     }
     \endverbatim
 
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: timeActivatedFileUpdate | yes |
+        fileToUpdate | Name of file to update  | yes         |
+        timeVsFile   | List of time vs file    | yes         |
+        log          | Log to standard output  | no          | yes
+    \endtable
+
+
 SourceFiles
     timeActivatedFileUpdate.C
     IOtimeActivatedFileUpdate.H
@@ -61,6 +70,7 @@ SourceFiles
 #define timeActivatedFileUpdate_H
 
 #include "Tuple2.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -99,6 +109,9 @@ class timeActivatedFileUpdate
         //- Index of last file copied
         label lastIndex_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Private Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C
index 6a16f35c1379cffe6a322bccd50466ba2d0a2762..7e7d1aff8cb5de2961cd5b4457b5ad33e082bc89 100644
--- a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C
+++ b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.C
@@ -102,7 +102,8 @@ Foam::turbulenceFields::turbulenceFields
     name_(name),
     obr_(obr),
     active_(true),
-    fieldSet_()
+    fieldSet_(),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
     if (isA<fvMesh>(obr_))
@@ -139,21 +140,26 @@ void Foam::turbulenceFields::read(const dictionary& dict)
 {
     if (active_)
     {
+        log_.readIfPresent("log", dict);
         fieldSet_.insert(wordList(dict.lookup("fields")));
 
         Info<< type() << " " << name_ << ": ";
-        if (fieldSet_.size())
+        if (log_)
         {
-            Info<< "storing fields:" << nl;
-            forAllConstIter(wordHashSet, fieldSet_, iter)
+            Info<< type() << " " << name_ << " output:" << nl;
+            if (fieldSet_.size())
             {
-                Info<< "    " << modelName << ':' << iter.key() << nl;
+                Info<< "storing fields:" << nl;
+                forAllConstIter(wordHashSet, fieldSet_, iter)
+                {
+                    Info<< "    " << modelName << ':' << iter.key() << nl;
+                }
+                Info<< endl;
+            }
+            else
+            {
+                Info<< "no fields requested to be stored" << nl << endl;
             }
-            Info<< endl;
-        }
-        else
-        {
-            Info<< "no fields requested to be stored" << nl << endl;
         }
     }
 }
diff --git a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H
index af412a9711273b09e2ef96e01f19c71cfdd36d36..7903afa246b3e4a6a4e0d6304069873f1483136d 100644
--- a/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H
+++ b/src/postProcessing/functionObjects/utilities/turbulenceFields/turbulenceFields.H
@@ -25,7 +25,7 @@ Class
     Foam::turbulenceFields
 
 Group
-    grpFieldFunctionObjects
+    grpUtilitiesFunctionObjects
 
 Description
     This function object stores turbulence fields on the mesh database for
@@ -89,6 +89,7 @@ SourceFiles
 #include "IOobject.H"
 #include "NamedEnum.H"
 #include "volFieldsFwd.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -151,6 +152,9 @@ protected:
         //- Fields to load
         wordHashSet fieldSet_;
 
+        //- Switch to send output to Info as well as to file
+        Switch log_;
+
 
     // Protected Member Functions
 
diff --git a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C
index ac9c5e392c6fb52aaefa81b6ae0e8cfb0437028c..f59b8a4c204a7f5f74aca9e8f80a7cc16cf686b9 100644
--- a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C
+++ b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.C
@@ -50,7 +50,8 @@ Foam::vorticity::vorticity
     obr_(obr),
     active_(true),
     UName_("U"),
-    outputName_(typeName)
+    resultName_(name),
+    log_(true)
 {
     // Check if the available mesh is an fvMesh, otherwise deactivate
     if (!isA<fvMesh>(obr_))
@@ -81,7 +82,7 @@ Foam::vorticity::vorticity
             (
                 IOobject
                 (
-                    outputName_,
+                    resultName_,
                     mesh.time().timeName(),
                     mesh,
                     IOobject::NO_READ,
@@ -109,10 +110,16 @@ void Foam::vorticity::read(const dictionary& dict)
 {
     if (active_)
     {
-        UName_ = dict.lookupOrDefault<word>("UName", "U");
-        if (UName_ != "U")
+        log_.readIfPresent("log", dict);
+        dict.readIfPresent("UName", UName_);
+
+        if (!dict.readIfPresent("resultName", resultName_))
         {
-            outputName_ = typeName + "(" + UName_ + ")";
+            resultName_ = name_;
+            if (UName_ != "U")
+            {
+                resultName_ = resultName_ + "(" + UName_ + ")";
+            }
         }
     }
 }
@@ -127,7 +134,7 @@ void Foam::vorticity::execute()
         volVectorField& vorticity =
             const_cast<volVectorField&>
             (
-                obr_.lookupObject<volVectorField>(outputName_)
+                obr_.lookupObject<volVectorField>(resultName_)
             );
 
         vorticity = fvc::curl(U);
@@ -155,9 +162,10 @@ void Foam::vorticity::write()
     if (active_)
     {
         const volVectorField& vorticity =
-            obr_.lookupObject<volVectorField>(outputName_);
+            obr_.lookupObject<volVectorField>(resultName_);
 
-        Info<< type() << " " << name_ << " output:" << nl
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
             << "    writing field " << vorticity.name() << nl
             << endl;
 
diff --git a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H
index bce5d943ebc1a1390cda05422b706c5565f80419..87209915cf6da5a42ba86c8e77bebfe29b5f05d6 100644
--- a/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H
+++ b/src/postProcessing/functionObjects/utilities/vorticity/vorticity.H
@@ -28,7 +28,29 @@ Group
     grpUtilitiesFunctionObjects
 
 Description
-    This function object calculates the vorticity, the curl of the velocity.
+    This function object calculates and outputs the vorticity, the curl of
+    the velocity as a volvectorField.  The field is stored on the mesh
+    database so that it can be retrieved and used for other applications.
+
+    Example of function object specification to calculate the vorticity:
+    \verbatim
+    vorticity1
+    {
+        type        vorticity;
+        functionObjectLibs ("libutilityFunctionObjects.so");
+        ...
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description             | Required    | Default value
+        type         | Type name: vorticity    | yes         |
+        UName        | Name of velocity field  | no          | U
+        resultName   | Name of Courant number field | no    | \<function name\>
+        log          | Log to standard output  | no          | yes
+    \endtable
+
 
 SourceFiles
     vorticity.C
@@ -40,6 +62,7 @@ SourceFiles
 #define vorticity_H
 
 #include "volFieldsFwd.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -73,7 +96,10 @@ class vorticity
         word UName_;
 
         //- Name of vorticity field
-        word outputName_;
+        word resultName_;
+
+        //- Switch to send output to Info as well as to file
+        Switch log_;
 
 
     // Private Member Functions
diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C
index 0f5be2bbb04ead5b8941a1f3045b95fbca2be0e4..c0885773e3fca5389344cb109e7948715a49c354 100644
--- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C
+++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C
@@ -80,11 +80,9 @@ void Foam::wallShearStress::calcShearStress
             << token::TAB << maxSsp
             << endl;
 
-        if (log_)
-        {
-            Info<< "    min/max(" << pp.name() << ") = "
-                << minSsp << ", " << maxSsp << endl;
-        }
+        if (log_) Info
+            << "    min/max(" << pp.name() << ") = "
+            << minSsp << ", " << maxSsp << endl;
     }
 }
 
@@ -296,12 +294,10 @@ void Foam::wallShearStress::write()
         const volVectorField& wallShearStress =
             obr_.lookupObject<volVectorField>(resultName_);
 
-        if (log_)
-        {
-            Info<< type() << " " << name_ << " output:" << nl
-                << "    writing field " << wallShearStress.name() << nl
-                << endl;
-        }
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    writing field " << wallShearStress.name() << nl
+            << endl;
 
         wallShearStress.write();
     }
diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H
index 7d51167335bbae37cf86370e6b7e6460d48aa513..83bafbab532e306df8fbd8bca43270771407210d 100644
--- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H
+++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H
@@ -61,7 +61,7 @@ Description
     \table
         Property | Description                | Required   | Default value
         type     | type name: wallShearStress | yes        |
-        resultName | Name of wall shear stress field | no  | <function name>
+        resultName | Name of wall shear stress field | no  | \<function name\>
         patches  | list of patches to process | no         | all wall patches
         log      | Log to standard output     | no         | yes
     \endtable
diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C
index 01630313c846a1ef83dd5c988dee74a7c9dc3a95..a88623b1cece97fd54516ac6b62ad06a2f77c77a 100644
--- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C
+++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C
@@ -229,13 +229,10 @@ void Foam::yPlus::write()
         const volScalarField& yPlus =
             obr_.lookupObject<volScalarField>(resultName_);
 
-        if (log_)
-        {
-            Info
-                << type() << " " << name_ << " output:" << nl
-                << "    writing field " << yPlus.name() << nl
-                << endl;
-        }
+        if (log_) Info
+            << type() << " " << name_ << " output:" << nl
+            << "    writing field " << yPlus.name() << nl
+            << endl;
 
         yPlus.write();
     }
diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H
index 80ce1abb8d82d13b638124cececcc32451a3b7d3..7c1461ae4e52b187a775a37eabfb23a2a0a7b133 100644
--- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H
+++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H
@@ -47,7 +47,7 @@ Description
         Property     | Description             | Required    | Default value
         type         | Type name: yPlus        | yes         |
         phiName      | Name of flux field      | no          | phi
-        resultName   | Name of y+ field        | no          | <function name>
+        resultName   | Name of y+ field        | no          | \<function name\>
         log          | Log to standard output  | no          | yes
     \endtable
 
diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C
index 0e7a625879d55ec79979543847a02cb154c35033..0358fa760b56cff87117683dc019e384b1942554 100644
--- a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C
+++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C
@@ -69,12 +69,9 @@ void Foam::yPlus::calcYPlus
             const scalar maxYplus = gMax(yPlusp);
             const scalar avgYplus = gAverage(yPlusp);
 
-            if (log_)
-            {
-                Info<< "    patch " << patch.name()
-                    << " y+ : min = " << minYplus << ", max = " << maxYplus
-                    << ", average = " << avgYplus << nl;
-            }
+            if (log_) Info<< "    patch " << patch.name()
+                << " y+ : min = " << minYplus << ", max = " << maxYplus
+                << ", average = " << avgYplus << nl;
 
             file() << obr_.time().value()
                 << token::TAB << patch.name()
diff --git a/src/sampling/probes/patchProbes.C b/src/sampling/probes/patchProbes.C
index b6792ea08cd35ba9befff7b07b9f6ead6c9c5508..3c6d2329b38215138874c1da2e040b8ecc502d61 100644
--- a/src/sampling/probes/patchProbes.C
+++ b/src/sampling/probes/patchProbes.C
@@ -46,32 +46,41 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
 
     const polyBoundaryMesh& bm = mesh.boundaryMesh();
 
-    label patchI = bm.findPatchID(patchName_);
+    // All the info for nearest. Construct to miss
+    List<mappedPatchBase::nearInfo> nearest(this->size());
 
-    if (patchI == -1)
-    {
-        FatalErrorIn
-        (
-            " Foam::patchProbes::findElements(const fvMesh&)"
-        )   << " Unknown patch name "
-            << patchName_ << endl
-            << exit(FatalError);
-    }
 
-     // All the info for nearest. Construct to miss
-    List<mappedPatchBase::nearInfo> nearest(this->size());
+    const labelList patchIDs(bm.patchSet(patchNames_).sortedToc());
 
-    const polyPatch& pp = bm[patchI];
+    label nFaces = 0;
+    forAll(patchIDs, i)
+    {
+        nFaces += bm[patchIDs[i]].size();
+    }
 
-    if (pp.size() > 0)
+    if (nFaces > 0)
     {
-        labelList bndFaces(pp.size());
-        forAll(bndFaces, i)
+        // Collect mesh faces and bounding box
+        labelList bndFaces(nFaces);
+        treeBoundBox overallBb(treeBoundBox::invertedBox);
+
+        nFaces = 0;
+        forAll(patchIDs, i)
         {
-            bndFaces[i] =  pp.start() + i;
+            const polyPatch& pp = bm[patchIDs[i]];
+            forAll(pp, i)
+            {
+                bndFaces[nFaces++] = pp.start()+i;
+                const face& f = pp[i];
+                forAll(f, fp)
+                {
+                    const point& pt = pp.points()[f[fp]];
+                    overallBb.min() = min(overallBb.min(), pt);
+                    overallBb.max() = max(overallBb.max(), pt);
+                }
+            }
         }
 
-        treeBoundBox overallBb(pp.points());
         Random rndGen(123456);
         overallBb = overallBb.extend(rndGen, 1e-4);
         overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
@@ -106,11 +115,7 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
 
             if (!info.hit())
             {
-                info = boundaryTree.findNearest
-                (
-                    sample,
-                    Foam::sqr(GREAT)
-                );
+                info = boundaryTree.findNearest(sample, Foam::sqr(GREAT));
             }
 
             label faceI = boundaryTree.shapes().faceLabels()[info.index()];
@@ -129,20 +134,26 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
                 << " This sample will not be included "
                 << endl;
             }
-            else
+            else if (info.hit())
             {
-                const point& fc = mesh.faceCentres()[faceI];
+                // Note: do we store the face centre or the actual nearest?
+                // We interpolate using the faceI only though (no
+                // interpolation) so it does not actually matter much, just for
+                // the location written to the header.
+
+                //const point& facePt = mesh.faceCentres()[faceI];
+                const point& facePt = info.hitPoint();
 
                 mappedPatchBase::nearInfo sampleInfo;
 
                 sampleInfo.first() = pointIndexHit
                 (
                     true,
-                    fc,
+                    facePt,
                     faceI
                 );
 
-                sampleInfo.second().first() = magSqr(fc-sample);
+                sampleInfo.second().first() = magSqr(facePt-sample);
                 sampleInfo.second().second() = Pstream::myProcNo();
 
                 nearest[probeI]= sampleInfo;
@@ -155,6 +166,14 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
     Pstream::listCombineGather(nearest, mappedPatchBase::nearestEqOp());
     Pstream::listCombineScatter(nearest);
 
+
+    // Update actual probe locations
+    forAll(nearest, sampleI)
+    {
+        operator[](sampleI) = nearest[sampleI].first().rawPoint();
+    }
+
+
     if (debug)
     {
         Info<< "patchProbes::findElements" << " : " << endl;
@@ -165,26 +184,41 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
 
             Info<< "    " << sampleI << " coord:"<< operator[](sampleI)
                 << " found on processor:" << procI
-                << " in local cell/face:" << localI
-                << " with fc:" << nearest[sampleI].first().rawPoint() << endl;
+                << " in local face:" << localI
+                << " with location:" << nearest[sampleI].first().rawPoint()
+                << endl;
         }
     }
 
 
     // Extract any local faces to sample
-    elementList_.setSize(nearest.size(), -1);
+    elementList_.setSize(nearest.size());
+    elementList_ = -1;
+    faceList_.setSize(nearest.size());
+    faceList_ = -1;
 
     forAll(nearest, sampleI)
     {
         if (nearest[sampleI].second().second() == Pstream::myProcNo())
         {
             // Store the face to sample
-            elementList_[sampleI] = nearest[sampleI].first().index();
+            faceList_[sampleI] = nearest[sampleI].first().index();
         }
     }
 }
 
 
+void Foam::patchProbes::readDict(const dictionary& dict)
+{
+    if (!dict.readIfPresent("patches", patchNames_))
+    {
+        word patchName(dict.lookup("patchName"));
+        patchNames_ = wordReList(1, wordRe(patchName));
+    }
+    probes::readDict(dict);
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::patchProbes::patchProbes
@@ -192,19 +226,22 @@ Foam::patchProbes::patchProbes
     const word& name,
     const objectRegistry& obr,
     const dictionary& dict,
-    const bool loadFromFiles
+    const bool loadFromFiles,
+    const bool doFindElements
 )
 :
-    probes(name, obr, dict, loadFromFiles)
+    probes(name, obr, dict, loadFromFiles, false)
 {
-    // When constructing probes above it will have called the
-    // probes::findElements (since the virtual mechanism not yet operating).
-    // Not easy to workaround (apart from feeding through flag into constructor)
-    // so clear out any cells found for now.
-    elementList_.clear();
-    faceList_.clear();
-
-    read(dict);
+    readDict(dict);
+
+    if (doFindElements)
+    {
+        // Find the elements
+        findElements(mesh_);
+
+        // Open the probe streams
+        prepare();
+    }
 }
 
 
@@ -232,10 +269,16 @@ void Foam::patchProbes::write()
     }
 }
 
+
 void Foam::patchProbes::read(const dictionary& dict)
 {
-    dict.lookup("patchName") >> patchName_;
-    probes::read(dict);
+    readDict(dict);
+
+    // Find the elements
+    findElements(mesh_);
+
+    // Open the probe streams
+    prepare();
 }
 
 
diff --git a/src/sampling/probes/patchProbes.H b/src/sampling/probes/patchProbes.H
index 2425b67f776bff4d4bc5464b42a9acea84d55fb9..e24b05efcec3f5ad4d9a621af52f3ac3369d450a 100644
--- a/src/sampling/probes/patchProbes.H
+++ b/src/sampling/probes/patchProbes.H
@@ -25,9 +25,45 @@ Class
     Foam::patchProbes
 
 Description
-    Set of locations to sample.at patches
+    Set of locations to sample at patches
 
     Call write() to sample and write files.
+    - find nearest location on nearest face
+    - update *this with location (so header contains 'snapped' locations
+    - use *this as the sampling location
+
+    Example of function object specification:
+    \verbatim
+    patchProbes
+    {
+        type            patchProbes;
+        functionObjectLibs ( "libsampling.so" );
+
+        // Name of the directory for probe data
+        name            patchProbes;
+
+        // Patches to sample (wildcards allowed)
+        patches         (".*inl.*");
+
+        // Write at same frequency as fields
+        outputControl   outputTime;
+        outputInterval  1;
+
+        // Fields to be probed
+        fields
+        (
+            p U
+        );
+
+        // Locations to probe. These get snapped onto the nearest point
+        // on the selected patches
+        probeLocations
+        (
+            ( -100 0 0.01 )      // at inlet
+        );
+    }
+    \endverbatim
+
 
 SourceFiles
     patchProbes.C
@@ -58,13 +94,15 @@ class patchProbes
 :
     public probes
 {
-    // Private data
+protected:
+
+    // Protected data
 
-        //- Patch name
-        word patchName_;
+        //- Patches to sample
+        wordReList patchNames_;
 
 
-    // Private Member Functions
+    // Protected Member Functions
 
         //- Sample and write a particular volume field
         template<class Type>
@@ -73,7 +111,6 @@ class patchProbes
             const GeometricField<Type, fvPatchField, volMesh>&
         );
 
-
         //- Sample and write a particular surface field
         template<class Type>
         void sampleAndWrite
@@ -81,17 +118,14 @@ class patchProbes
             const GeometricField<Type, fvsPatchField, surfaceMesh>&
         );
 
-
         //- Sample and write all the fields of the given type
         template<class Type>
         void sampleAndWrite(const fieldGroup<Type>&);
 
-
          //- Sample and write all the surface fields of the given type
         template<class Type>
         void sampleAndWriteSurfaceFields(const fieldGroup<Type>&);
 
-
         //- Sample a volume field at all locations
         template<class Type>
         tmp<Field<Type> > sample
@@ -99,7 +133,6 @@ class patchProbes
             const GeometricField<Type, fvPatchField, volMesh>&
         ) const;
 
-
         //- Sample a surface field at all locations
         template<class Type>
         tmp<Field<Type> > sample
@@ -107,11 +140,18 @@ class patchProbes
             const GeometricField<Type, fvsPatchField, surfaceMesh>&
         ) const;
 
-
         //- Sample a single field on all sample locations
         template<class Type>
         tmp<Field<Type> > sample(const word& fieldName) const;
 
+        //- Find elements containing patchProbes
+        virtual void findElements(const fvMesh&);
+
+        //- Read dictionary settings
+        void readDict(const dictionary& dict);
+
+
+private:
 
         //- Disallow default bitwise copy construct
         patchProbes(const patchProbes&);
@@ -135,7 +175,8 @@ public:
             const word& name,
             const objectRegistry&,
             const dictionary&,
-            const bool loadFromFiles = false
+            const bool loadFromFiles = false,
+            const bool findElements = true
         );
 
 
@@ -149,9 +190,6 @@ public:
 
         //- Read
         virtual void read(const dictionary&);
-
-        //- Find elements containing patchProbes
-        virtual void findElements(const fvMesh&);
 };
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/probes/patchProbesTemplates.C b/src/sampling/probes/patchProbesTemplates.C
index 7e8ddd74b427bfcdaddc957e16f053a768c6b1d5..e0ff2206e74b893c498f5ebf2529efb1ef9d92bf 100644
--- a/src/sampling/probes/patchProbesTemplates.C
+++ b/src/sampling/probes/patchProbesTemplates.C
@@ -208,7 +208,7 @@ Foam::patchProbes::sample
 
     forAll(*this, probeI)
     {
-        label faceI = elementList_[probeI];
+        label faceI = faceList_[probeI];
 
         if (faceI >= 0)
         {
@@ -259,7 +259,7 @@ Foam::patchProbes::sample
 
     forAll(*this, probeI)
     {
-        label faceI = elementList_[probeI];
+        label faceI = faceList_[probeI];
 
         if (faceI >= 0)
         {
@@ -274,4 +274,6 @@ Foam::patchProbes::sample
 
     return tValues;
 }
+
+
 // ************************************************************************* //
diff --git a/src/sampling/probes/probes.C b/src/sampling/probes/probes.C
index 38ef3a63b47cca6388358bd289e320a3842d8f51..fd13764fab37c3e3725d1b462a9b51ddec0ef67d 100644
--- a/src/sampling/probes/probes.C
+++ b/src/sampling/probes/probes.C
@@ -265,6 +265,25 @@ Foam::label Foam::probes::prepare()
 }
 
 
+void Foam::probes::readDict(const dictionary& dict)
+{
+    dict.lookup("probeLocations") >> *this;
+    dict.lookup("fields") >> fieldSelection_;
+
+    dict.readIfPresent("fixedLocations", fixedLocations_);
+    if (dict.readIfPresent("interpolationScheme", interpolationScheme_))
+    {
+        if (!fixedLocations_ && interpolationScheme_ != "cell")
+        {
+            WarningIn("void Foam::probes::read(const dictionary&)")
+                << "Only cell interpolation can be applied when "
+                << "not using fixedLocations. InterpolationScheme "
+                << "entry will be ignored";
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::probes::probes
@@ -272,7 +291,8 @@ Foam::probes::probes
     const word& name,
     const objectRegistry& obr,
     const dictionary& dict,
-    const bool loadFromFiles
+    const bool loadFromFiles,
+    const bool doFindElements
 )
 :
     pointField(0),
@@ -283,7 +303,18 @@ Foam::probes::probes
     fixedLocations_(true),
     interpolationScheme_("cell")
 {
-    read(dict);
+    // Read dictionary (but do not search for elements)
+    readDict(dict);
+
+    // Optionally find elements in constructor
+    if (doFindElements)
+    {
+        // Find the elements
+        findElements(mesh_);
+
+        // Open the probe streams
+        prepare();
+    }
 }
 
 
@@ -334,24 +365,12 @@ void Foam::probes::write()
 
 void Foam::probes::read(const dictionary& dict)
 {
-    dict.lookup("probeLocations") >> *this;
-    dict.lookup("fields") >> fieldSelection_;
+    readDict(dict);
 
-    dict.readIfPresent("fixedLocations", fixedLocations_);
-    if (dict.readIfPresent("interpolationScheme", interpolationScheme_))
-    {
-        if (!fixedLocations_ && interpolationScheme_ != "cell")
-        {
-            WarningIn("void Foam::probes::read(const dictionary&)")
-                << "Only cell interpolation can be applied when "
-                << "not using fixedLocations.  InterpolationScheme "
-                << "entry will be ignored";
-        }
-    }
-
-    // Initialise cells to sample from supplied locations
+    // Find the elements
     findElements(mesh_);
 
+    // Open the probe streams
     prepare();
 }
 
@@ -382,20 +401,28 @@ void Foam::probes::updateMesh(const mapPolyMesh& mpm)
             forAll(elementList_, i)
             {
                 label cellI = elementList_[i];
-                label newCellI = reverseMap[cellI];
-                if (newCellI == -1)
+                if (cellI != -1)
                 {
-                    // cell removed
-                }
-                else if (newCellI < -1)
-                {
-                    // cell merged
-                    elems.append(-newCellI - 2);
+                    label newCellI = reverseMap[cellI];
+                    if (newCellI == -1)
+                    {
+                        // cell removed
+                    }
+                    else if (newCellI < -1)
+                    {
+                        // cell merged
+                        elems.append(-newCellI - 2);
+                    }
+                    else
+                    {
+                        // valid new cell
+                        elems.append(newCellI);
+                    }
                 }
                 else
                 {
-                    // valid new cell
-                    elems.append(newCellI);
+                    // Keep -1 elements so the size stays the same
+                    elems.append(-1);
                 }
             }
 
@@ -410,20 +437,28 @@ void Foam::probes::updateMesh(const mapPolyMesh& mpm)
             forAll(faceList_, i)
             {
                 label faceI = faceList_[i];
-                label newFaceI = reverseMap[faceI];
-                if (newFaceI == -1)
-                {
-                    // face removed
-                }
-                else if (newFaceI < -1)
+                if (faceI != -1)
                 {
-                    // face merged
-                    elems.append(-newFaceI - 2);
+                    label newFaceI = reverseMap[faceI];
+                    if (newFaceI == -1)
+                    {
+                        // face removed
+                    }
+                    else if (newFaceI < -1)
+                    {
+                        // face merged
+                        elems.append(-newFaceI - 2);
+                    }
+                    else
+                    {
+                        // valid new face
+                        elems.append(newFaceI);
+                    }
                 }
                 else
                 {
-                    // valid new face
-                    elems.append(newFaceI);
+                    // Keep -1 elements
+                    elems.append(-1);
                 }
             }
 
diff --git a/src/sampling/probes/probes.H b/src/sampling/probes/probes.H
index 5cc8c9f50c0ec9a050f5b857b56c9f9ffbfad830..ec759f11139df2fc067fad5accba6a2cbc185796 100644
--- a/src/sampling/probes/probes.H
+++ b/src/sampling/probes/probes.H
@@ -32,6 +32,42 @@ Description
 
     Call write() to sample and write files.
 
+    Example of function object specification:
+    \verbatim
+    probes
+    {
+        type            probes;
+        functionObjectLibs ( "libsampling.so" );
+
+        // Name of the directory for probe data
+        name            probes;
+
+        // Write at same frequency as fields
+        outputControl   outputTime;
+        outputInterval  1;
+
+        // Fields to be probed
+        fields
+        (
+            p U
+        );
+
+        // Optional: do not recalculate cells if mesh moves
+        fixedLocations  false;
+
+        // Optional: interpolation scheme to use (default is cell)
+        interpolationScheme cellPoint;
+
+        probeLocations
+        (
+            ( 1e-06 0 0.01 )      // at inlet
+            (0.21 -0.20999 0.01)  // at outlet1
+            (0.21 0.20999 0.01)   // at outlet2
+            (0.21 0 0.01)         // at central block
+        );
+    }
+    \endverbatim
+
 SourceFiles
     probes.C
 
@@ -91,13 +127,13 @@ protected:
 
         //- Name of this set of probes,
         //  Also used as the name of the probes directory.
-        word name_;
+        const word name_;
 
         //- Const reference to fvMesh
         const fvMesh& mesh_;
 
         //- Load fields from files (not from objectRegistry)
-        bool loadFromFiles_;
+        const bool loadFromFiles_;
 
 
         // Read from dictonary
@@ -106,7 +142,7 @@ protected:
             wordReList fieldSelection_;
 
             //- Fixed locations, default = yes
-            //  Note: set to false for moving mesh calations where locations
+            //  Note: set to false for moving mesh calculations where locations
             //        should move with the mesh
             bool fixedLocations_;
 
@@ -141,7 +177,7 @@ protected:
             HashPtrTable<OFstream> probeFilePtrs_;
 
 
-    // Private Member Functions
+    // Protected Member Functions
 
         //- Clear old field groups
         void clearFieldGroups();
@@ -159,6 +195,8 @@ protected:
         //  returns number of fields to sample
         label prepare();
 
+        //- Read dictionary settings
+        void readDict(const dictionary& dict);
 
 private:
 
@@ -207,7 +245,8 @@ public:
             const word& name,
             const objectRegistry&,
             const dictionary&,
-            const bool loadFromFiles = false
+            const bool loadFromFiles = false,
+            const bool findElements = true
         );
 
 
diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
index 27433a57dac4af59d7ecc625be326b5070bdd003..b70b4d47c5b0be71102b019f25baa1baf7d4eea6 100644
--- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
@@ -27,30 +27,32 @@ Class
 Description
     A surfaceWriter for outputting to a form useable for the
     timeVaryingMapped boundary condition. This reads the data from
-    constant/boundaryData/<patch>
+    constant/boundaryData/\<patch\> directory
 
     Typical way of working:
     - use a sampledSurface of type 'patch' (to sample a patch):
+    \verbatim
+    surfaces
+    {
+        type            surfaces;
+        surfaceFormat   boundaryData;
+        fields          ( p );
         surfaces
-        {
-            type            surfaces;
-            surfaceFormat   boundaryData;
-            fields          ( p );
-            surfaces
-            (
-                outlet
-                {
-                    type            patch;
-                    patches         (outlet);
-                    interpolate     false;
-                }
-            );
-        }
+        (
+            outlet
+            {
+                type            patch;
+                patches         (outlet);
+                interpolate     false;
+            }
+        );
+    }
+    \endverbatim
 
     - write using this writer.
     - move postProcessing/surfaces/outlet to constant/boundaryData/outlet
       in your destination case.
-    - use a timeVaryingMappedFixedValue bc to read&interpolate
+    - use a timeVaryingMappedFixedValue condition to read and interpolate
       the profile:
         type            timeVaryingMappedFixedValue;
         setAverage      false;  // do not use read average
diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H b/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H
index 54902fa26105b483c25c9709a7d53bd042136a17..910371fb4abc30131a4ac7c0df848e80c2d97be5 100644
--- a/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H
+++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/radiationCoupledBase/radiationCoupledBase.H
@@ -22,7 +22,7 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    radiationCoupledBase
+    Foam::radiationCoupledBase
 
 Description
     Common functions to emissivity. It gets supplied from lookup into a