diff --git a/applications/test/faces/Make/files b/applications/test/faces/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..8418bb2b93aa267c53b55aae8ba4fc2eb7d2729d
--- /dev/null
+++ b/applications/test/faces/Make/files
@@ -0,0 +1,3 @@
+Test-faces.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-faces
diff --git a/applications/test/faces/Make/options b/applications/test/faces/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/conversion/ensight/part/ensightPartsTemplates.C b/applications/test/faces/Test-faces.C
similarity index 55%
rename from src/conversion/ensight/part/ensightPartsTemplates.C
rename to applications/test/faces/Test-faces.C
index fe2f712a0b4e9f40d4b1d76cf6129eddc4eb039b..823f33e3e10046f8836158180c2d22f033b855f1 100644
--- a/src/conversion/ensight/part/ensightPartsTemplates.C
+++ b/applications/test/faces/Test-faces.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,54 +21,63 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
+Application
+    Test-faces
+
 Description
-    Template to write generalized field components
+    Simple tests for various faces
 
 \*---------------------------------------------------------------------------*/
 
-#include "ensightParts.H"
+#include "argList.H"
+#include "labelledTri.H"
+
+using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+//  Main program:
 
-template<class Type>
-void Foam::ensightParts::writeField
-(
-    ensightFile& os,
-    const GeometricField<Type, fvPatchField, volMesh>& field
-) const
+int main(int argc, char *argv[])
 {
-    // find offset to patch parts (ie, the first face data)
-    label patchOffset = 0;
-    forAll(partsList_, partI)
+    face f1{ 1, 2, 3, 4 };
+    Info<< "face:" << f1 << nl;
+
+    triFace t1{ 1, 2, 3 };
+    Info<< "triFace:" << t1 << nl;
+
+    f1 = t1;
+    Info<< "face:" << f1 << nl;
+
+    f1 = t1.triFaceFace();
+    Info<< "face:" << f1 << nl;
+
+    // expect these to fail
+    FatalError.throwExceptions();
+    try
     {
-        if (partsList_[partI].isFaceData())
-        {
-            patchOffset = partI;
-            break;
-        }
+        labelledTri l1{ 1, 2, 3, 10, 24 };
+        Info<< "labelled:" << l1 << nl;
     }
-
-    forAll(partsList_, partI)
+    catch (Foam::error& err)
     {
-        label patchi = partI - patchOffset;
-
-        if (partsList_[partI].isCellData())
-        {
-            partsList_[partI].writeField
-            (
-                os,
-                field
-            );
-        }
-        else if (patchi < field.boundaryField().size())
-        {
-            partsList_[partI].writeField
-            (
-                os,
-                field.boundaryField()[patchi]
-            );
-        }
+        WarningInFunction
+            << "Caught FatalError " << err << nl << endl;
     }
+    FatalError.dontThrowExceptions();
+
+    labelledTri l2{ 1, 2, 3 };
+    Info<< "labelled:" << l2 << nl;
+
+    labelledTri l3{ 1, 2, 3, 10 };
+    Info<< "labelled:" << l3 << nl;
+
+    t1.flip();
+    l3.flip();
+
+    Info<< "flip:" << t1 << nl;
+    Info<< "flip:" << l3 << nl;
+
+    return 0;
 }
 
 
diff --git a/applications/test/xfer/Test-xferList.C b/applications/test/xfer/Test-xferList.C
index 77231e2118dff2e8d5c1ed7d9f154cd76dc79aa2..9b800220ca72788ff8563d190883e567ba62d2da 100644
--- a/applications/test/xfer/Test-xferList.C
+++ b/applications/test/xfer/Test-xferList.C
@@ -34,6 +34,8 @@ Description
 #include "labelList.H"
 #include "DynamicList.H"
 #include "face.H"
+#include "pointField.H"
+#include "DynamicField.H"
 
 using namespace Foam;
 
@@ -45,7 +47,10 @@ using namespace Foam;
 int main(int argc, char *argv[])
 {
     List<label> lstA(10);
-    List<label> lstC(IStringStream("(1 2 3 4)")());
+    List<label> lstC
+    {
+        1, 2, 3, 4
+    };
 
     forAll(lstA, i)
     {
@@ -128,6 +133,57 @@ int main(int argc, char *argv[])
     Info<< "f1: " << f1 << endl;
     Info<< "f3: " << f3 << endl;
 
+
+    {
+        Info<<"\nTest xfer with fields:" << endl;
+        List<point> list1
+        {
+            { 0, 1, 2 },
+            { 3, 4, 5 },
+            { 6, 7, 8 },
+            { 9, 10, 11 },
+        };
+
+        // Field from Xfer<List>
+        pointField field1(list1.xfer());
+        Info<<nl
+            << "xfer construct from List" << nl
+            <<"input (list) = " << list1 << nl
+            <<"output (field) = " << field1 << nl;
+
+
+        // Field from Xfer<List> ... again
+        pointField field2(field1.xfer());
+        Info<<nl
+            <<"xfer construct from Field (as List): " << nl
+            <<"input (field) = " << field1 << nl
+            <<"output (field) = " << field2 << nl;
+
+
+        // Field from Xfer<Field>
+        pointField field3(xferMove(field2));
+        Info<<nl
+            <<"xfer construct from Field (as Field): " << nl
+            <<"input (field) = " << field2 << nl
+            <<"output (field) = " << field3 << nl;
+
+
+        // Field from Xfer<Field> .. again
+        pointField field4(xferCopy(field3));
+        Info<<nl
+            <<"xfer copy construct from Field (as Field): " << nl
+            <<"input (field) = " << field3 << nl
+            <<"output (field) = " << field4 << nl;
+
+
+        DynamicField<point> dyfield1(xferCopy(field4));
+        Info<<nl
+            <<"xfer copy construct from Field (as Field): " << nl
+            <<"input (field) = " << field4 << nl
+            <<"output (dyn-field) = " << dyfield1 << nl;
+
+    }
+
     return 0;
 }
 
diff --git a/applications/utilities/mesh/conversion/Optional/Allwmake b/applications/utilities/mesh/conversion/Optional/Allwmake
index 19654fcf899028dc1f2e9b4f3e027c16e28d5082..a7a614f5cad3ab3c3253a0a6a5a0bc04433708fe 100755
--- a/applications/utilities/mesh/conversion/Optional/Allwmake
+++ b/applications/utilities/mesh/conversion/Optional/Allwmake
@@ -6,6 +6,7 @@ cd ${0%/*} || exit 1    # Run from this directory
 
 # Parse arguments for compilation (at least for error catching)
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
 # Get version info and arch-path
 . $WM_PROJECT_DIR/etc/config.sh/functions
 _foamSource $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/ccmio)
diff --git a/applications/utilities/mesh/conversion/ccm/Allwmake b/applications/utilities/mesh/conversion/ccm/Allwmake
new file mode 100755
index 0000000000000000000000000000000000000000..7f59349f938d1226dedd2f21374253faba698a27
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/Allwmake
@@ -0,0 +1,17 @@
+#!/bin/sh
+cd ${0%/*} || exit 1    # Run from this directory
+
+# Parse arguments for compilation (at least for error catching)
+. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
+# Only build if libraries already exist
+if [ -e $FOAM_LIBBIN/libccm.so ]
+then
+    echo "Building optional ccm conversion components."
+    wmake $targetType ccmToFoam
+    wmake $targetType foamToCcm
+else
+    echo "Skipping optional ccm conversion components (no libccm.so)."
+fi
+
+#------------------------------------------------------------------------------
diff --git a/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/files b/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..f23232f5e96fec5b699265e74e94cd2d964ea87b
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/files
@@ -0,0 +1,3 @@
+ccmToFoam.C
+
+EXE = $(FOAM_APPBIN)/ccmToFoam
diff --git a/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/options b/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..8b1f005a7833c6c646d3983fc9d54014120a747e
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/ccmToFoam/Make/options
@@ -0,0 +1,12 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/conversion/ccm/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude
+
+EXE_LIBS = \
+    -lfiniteVolume \
+    -lgenericPatchFields \
+    -lmeshTools \
+    -lconversion -lccm
diff --git a/applications/utilities/mesh/conversion/ccm/ccmToFoam/ccmToFoam.C b/applications/utilities/mesh/conversion/ccm/ccmToFoam/ccmToFoam.C
new file mode 100644
index 0000000000000000000000000000000000000000..5b0a4cf660521e2a28e9449e7c0954331e83d244
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/ccmToFoam/ccmToFoam.C
@@ -0,0 +1,314 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Application
+    ccmToFoam
+
+Group
+    grpMeshConversionUtilities
+
+Description
+    Reads CCM files as written by PROSTAR/STARCCM and writes an
+    OPENFOAM polyMesh.
+
+Usage
+    \b ccmToFoam [OPTION] ccmMesh
+
+    Options:
+      - \par -ascii
+        Write in ASCII format instead of binary
+
+      - \par -export
+        re-export mesh in CCM format for post-processing
+
+      - \par -list
+        List some information about the geometry
+
+      - \par -name \<name\>
+        Provide alternative base name for export. Default is <tt>meshExport</tt>.
+
+      - \par -combine
+        Combine identically named patches
+
+      - \par -noBaffles
+        Remove any baffles by merging the faces.
+
+      - \par -merge
+        Merge in-place interfaces
+
+      - \par -numbered
+        Use numbered patch/zone (not names) directly from ccm ids.
+
+      - \par -remap \<name\>
+        use specified remapping dictionary instead of <tt>constant/remapping</tt>
+
+      - \par -scale \<factor\>
+        Specify an alternative geometry scaling factor.
+        The default is \b 1 (no scaling).
+
+      - \par -solids
+        Treat any solid cells present just like fluid cells.
+        The default is to remove them.
+
+Note
+    - sub-domains (fluid | solid | porosity) are stored as separate domains
+      within the CCM file. These are merged together to form a single mesh.
+    - baffles are written as interfaces for later use
+
+See also
+    Foam::ccm::reader for more information about the File Locations
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "ccm.H"
+#include "regionSplit.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char *argv[])
+{
+    argList::addNote
+    (
+        "Reads CCM files as written by PROSTAR/STARCCM and writes an"
+        " OPENFOAM polyMesh."
+    );
+
+    argList::noParallel();
+    argList::validArgs.append("ccmMesh");
+    argList::addBoolOption
+    (
+        "ascii",
+        "write in ASCII format instead of binary"
+    );
+    argList::addBoolOption
+    (
+        "export",
+        "re-export mesh in CCM format for post-processing"
+    );
+    argList::addBoolOption
+    (
+        "list",
+        "list some information about the geometry"
+    );
+    argList::addOption
+    (
+        "remap",
+        "name",
+        "use specified remapping dictionary instead of <constant/remapping>"
+    );
+    argList::addOption
+    (
+        "name",
+        "name",
+        "provide alternative base name when re-exporting (implies -export). "
+        "Default is <meshExport>."
+    );
+    argList::addBoolOption
+    (
+        "combine",
+        "combine identically named patches"
+    );
+    argList::addBoolOption
+    (
+        "noBaffles",
+        "remove any baffles by merging the faces"
+    );
+    argList::addBoolOption
+    (
+        "merge",
+        "merge in-place interfaces"
+    );
+    argList::addBoolOption
+    (
+        "numbered",
+        "use numbered names (eg, patch_0, zone_0) only"
+    );
+    argList::addOption
+    (
+        "scale",
+        "scale",
+        "geometry scaling factor - default is 1 (ie, no scaling)"
+    );
+    argList::addBoolOption
+    (
+        "withSolid",
+        "treat any solid cells present just like fluid cells. "
+        "the default is to remove them."
+    );
+
+    argList args(argc, argv);
+    Time runTime(args.rootPath(), args.caseName());
+    runTime.functionObjects().off();
+
+    const bool optList = args.optionFound("list");
+
+    // exportName only has a size when export is in effect
+    fileName exportName;
+    if (args.optionReadIfPresent("name", exportName))
+    {
+        const word ext = exportName.ext();
+        // strip erroneous extension (.ccm, .ccmg, .ccmp)
+        if (ext == "ccm" || ext == "ccmg" || ext == "ccmp")
+        {
+            exportName = exportName.lessExt();
+        }
+    }
+    else if (args.optionFound("export"))
+    {
+        exportName = ccm::writer::defaultMeshName;
+        if (args.optionFound("case"))
+        {
+            exportName += '-' + args.globalCaseName();
+        }
+    }
+
+    // By default, no scaling
+    const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
+
+    // Default to binary output, unless otherwise specified
+    const IOstream::streamFormat format =
+    (
+        args.optionFound("ascii")
+      ? IOstream::ASCII
+      : IOstream::BINARY
+    );
+
+    // Increase the precision of the points data
+    IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
+
+
+    // Read control options
+    // ~~~~~~~~~~~~~~~~~~~~
+
+    ccm::reader::options rOpts;
+    rOpts.removeBaffles(args.optionFound("noBaffles"));
+    rOpts.mergeInterfaces(args.optionFound("merge"));
+
+    if (args.optionFound("numbered"))
+    {
+        rOpts.useNumberedNames(true);
+    }
+    else if (args.optionFound("combine"))
+    {
+        rOpts.combineBoundaries(true);
+    }
+
+    if (args.optionFound("solids"))
+    {
+        Info<< "treating solids like fluids" << endl;
+        rOpts.keepSolid(true);
+    }
+    else
+    {
+        rOpts.keepSolid(false);
+    }
+
+    // CCM reader for reading geometry/solution
+    ccm::reader reader(args[1], rOpts);
+
+    // list the geometry information
+    if (optList)
+    {
+        Info<< "mesh geometry information:" << endl;
+        if (reader.hasGeometry())
+        {
+            Info<< nl << "cellTable:" << reader.cellTableInfo()
+                << nl << "boundaryRegion:" << reader.boundaryTableInfo()
+                << nl << "interfaces:" << reader.interfaceDefinitionsInfo()
+                << endl;
+
+            if
+            (
+                args.optionFound("remap")
+              ? reader.remapMeshInfo(runTime, args["remap"])
+              : reader.remapMeshInfo(runTime)
+            )
+            {
+                Info<< nl
+                    << "Remapped cellTable:" << reader.cellTableInfo() << nl
+                    << "Remapped boundaryRegion:" << reader.boundaryTableInfo()
+                    << endl;
+            }
+        }
+        else
+        {
+            Info<< "NONE" << endl;
+        }
+
+        return 0;
+    }
+    else if (reader.readGeometry(scaleFactor))
+    {
+        autoPtr<polyMesh> mesh =
+        (
+            args.optionFound("remap")
+          ? reader.mesh(runTime, args["remap"])
+          : reader.mesh(runTime)
+        );
+
+        // report mesh bounding box information
+        Info<< nl << "Bounding box size: " << mesh().bounds().span() << nl;
+
+        // check number of regions
+        regionSplit rs(mesh);
+
+        Info<< "Number of regions: " << rs.nRegions();
+        if (rs.nRegions() == 1)
+        {
+            Info<< " (OK)." << nl;
+        }
+        else
+        {
+            Info<< nl << nl
+                << "**************************************************" << nl
+                << "**  WARNING: the mesh has disconnected regions  **" << nl
+                << "**************************************************" << nl;
+        }
+        Info<< endl;
+        reader.writeMesh(mesh, format);
+
+        // exportName only has a size when export is in effect
+        if (exportName.size())
+        {
+            const fileName geomName = exportName + ".ccmg";
+            Info<< nl << "Re-exporting geometry as " << geomName << nl;
+            ccm::writer(geomName, mesh).writeGeometry();
+        }
+    }
+    else
+    {
+        FatalErrorIn("ccmToFoam")
+            << "could not read geometry"
+            << exit(FatalError);
+    }
+
+    Info<< "\nEnd\n" << endl;
+
+    return 0;
+}
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/files b/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..dd5d32f698998c0c1b955605c15096a6deb47c1b
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/files
@@ -0,0 +1,3 @@
+foamToCcm.C
+
+EXE = $(FOAM_APPBIN)/foamToCcm
diff --git a/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/options b/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..df1a41bde0ac5a0fa70a0ee9372ab01cdd4c9b9d
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/foamToCcm/Make/options
@@ -0,0 +1,10 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/conversion/ccm/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude
+
+EXE_LIBS = \
+    -lfiniteVolume \
+    -lgenericPatchFields \
+    -lconversion -lccm
diff --git a/applications/utilities/mesh/conversion/ccm/foamToCcm/foamToCcm.C b/applications/utilities/mesh/conversion/ccm/foamToCcm/foamToCcm.C
new file mode 100644
index 0000000000000000000000000000000000000000..9d64cc09b063abf3e6fb862e797fff8d021402a6
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/foamToCcm/foamToCcm.C
@@ -0,0 +1,272 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Application
+    foamToCcm
+
+Group
+    grpMeshConversionUtilities
+
+Description
+    Translates OPENFOAM mesh and/or results to CCM format
+
+Usage
+    \b foamToCcm [OPTION]
+
+    Options:
+      - \par -mesh
+        convert mesh only to CCM format
+
+      - \par -name \<name\>
+        Provide alternative base name. Default is <tt>meshExport</tt>.
+
+      - \par -overwrite
+        No backup of existing output files.
+
+      - \par -remap \<name\>
+        use specified remapping dictionary instead of <tt>constant/remapping</tt>
+
+      - \par -results
+        convert results only to CCM format
+
+Note
+    - No parallel data
+    - No Lagrangian elements
+    - the -noZero time option can be useful to avoid the often incomplete
+      initial conditions (missing useful calculated values)
+
+See also
+    Foam::ccm::writer for information about the
+    <tt>constant/remapping</tt> file.
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "timeSelector.H"
+
+#include "volFields.H"
+#include "OFstream.H"
+#include "IOobjectList.H"
+#include "scalarIOField.H"
+#include "tensorIOField.H"
+
+#include "ccm.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    argList::addNote
+    (
+        "Translate OPENFOAM data to CCM format"
+    );
+
+    Foam::timeSelector::addOptions();
+    argList::noParallel();
+    argList::addBoolOption
+    (
+        "mesh",
+        "convert mesh only"
+    );
+    argList::addOption
+    (
+        "name",
+        "name",
+        "provide alternative base name. Default is <meshExport>."
+    );
+    argList::addBoolOption
+    (
+        "overwrite",
+        "no backup of existing output files"
+    );
+    argList::addOption
+    (
+        "remap",
+        "name",
+        "use specified remapping dictionary instead of <constant/remapping>"
+    );
+    argList::addBoolOption
+    (
+        "results",
+        "convert results only"
+    );
+
+    #include "setRootCase.H"
+    #include "createTime.H"
+    runTime.functionObjects().off();
+
+    // get times list
+    instantList timeDirs = Foam::timeSelector::select0(runTime, args);
+
+    const bool optMesh      = args.optionFound("mesh");
+    const bool optResults   = args.optionFound("results");
+    const bool optOverwrite = args.optionFound("overwrite");
+
+    fileName exportName = ccm::writer::defaultMeshName;
+    if (args.optionReadIfPresent("name", exportName))
+    {
+        const word ext = exportName.ext();
+        // strip erroneous extension (.ccm, .ccmg, .ccmp)
+        if (ext == "ccm" || ext == "ccmg" || ext == "ccmp")
+        {
+            exportName = exportName.lessExt();
+        }
+    }
+    else if (args.optionFound("case"))
+    {
+        exportName += '-' + args.globalCaseName();
+    }
+
+    if (optMesh && optResults)
+    {
+        Warning
+            << "\n-mesh and -results options are mutually exclusive\n"
+            << endl;
+        args.printUsage();
+        FatalError.exit();
+    }
+
+//     // skip over time=0, unless some other time option has been specified
+//     if
+//     (
+//         !args.optionFound("zeroTime")
+//      && !args.optionFound("time")
+//      && !args.optionFound("latestTime")
+//      && Times.size() > 2
+//     )
+//     {
+//         startTime = 2;
+//     }
+//
+//    runTime.setTime(Times[startTime], startTime);
+
+    runTime.setTime(timeDirs[0], 0);
+    if (optMesh)
+    {
+        // convert mesh only
+        #include "createPolyMesh.H"
+
+        forAll(timeDirs, timeI)
+        {
+            runTime.setTime(timeDirs[timeI], timeI);
+
+            #include "getTimeIndex.H"
+
+            if (timeI == 0)
+            {
+                ccm::writer writer
+                (
+                    exportName + ".ccmg",
+                    mesh,
+                    !optOverwrite
+                );
+                writer.writeGeometry();
+            }
+            else if (mesh.moving())
+            {
+                ccm::writer writer
+                (
+                    exportName + ".ccmg_" + timeName,
+                    mesh,
+                    !optOverwrite
+                );
+                writer.writeGeometry();
+            }
+        }
+    }
+    else
+    {
+        // convert fields with or without converting mesh
+        #include "createMesh.H"
+
+        // #include "checkHasMovingMesh.H"
+        // #include "checkHasLagrangian.H"
+
+        IOobjectList objects(mesh, timeDirs[timeDirs.size()-1].name());
+        //  IOobjectList sprayObjects(mesh, Times[Times.size()-1].name(), "lagrangian");
+
+        forAll(timeDirs, timeI)
+        {
+            runTime.setTime(timeDirs[timeI], timeI);
+
+            #include "getTimeIndex.H"
+
+            Info<< "has "
+                << mesh.nCells() << " cells, "
+                << mesh.nPoints() << " points, "
+                << mesh.boundaryMesh().size() << " patches"
+                << endl;
+
+            if (!optResults)
+            {
+                if (timeI == 0)
+                {
+                    ccm::writer writer
+                    (
+                        exportName + ".ccmg",
+                        mesh,
+                        !optOverwrite
+                    );
+                    writer.writeGeometry();
+                }
+                else if (mesh.moving())
+                {
+                    ccm::writer writer
+                    (
+                        exportName + ".ccmg_" + timeName,
+                        mesh,
+                        !optOverwrite
+                    );
+                    writer.writeGeometry();
+                }
+            }
+
+            ccm::writer writer
+            (
+                exportName + ".ccmp_" + timeName,
+                mesh,
+                !optOverwrite
+            );
+            // writer.setTopologyFile(exportName + ".ccmg");
+            Info<< "writing solution:";
+            if (args.optionFound("remap"))
+            {
+                writer.writeSolution(objects, args["remap"]);
+            }
+            else
+            {
+                writer.writeSolution(objects);
+            }
+        }
+    }
+
+    Info<< "\nEnd\n" << endl;
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/ccm/foamToCcm/getTimeIndex.H b/applications/utilities/mesh/conversion/ccm/foamToCcm/getTimeIndex.H
new file mode 100644
index 0000000000000000000000000000000000000000..4547e06457e9faf3f96bc5c0fc35bc28cdd7d1dc
--- /dev/null
+++ b/applications/utilities/mesh/conversion/ccm/foamToCcm/getTimeIndex.H
@@ -0,0 +1,49 @@
+// Read time index from */uniform/time, but treat 0 and constant specially
+
+    word timeName = "0";
+
+    if
+    (
+        runTime.timeName() != runTime.constant()
+     && runTime.timeName() != "0"
+    )
+    {
+        IOobject io
+        (
+            "time",
+            runTime.timeName(),
+            "uniform",
+            runTime,
+            IOobject::READ_IF_PRESENT,
+            IOobject::NO_WRITE,
+            false
+        );
+
+        if (io.typeHeaderOk<IOdictionary>(true))
+        {
+            IOdictionary timeObject
+            (
+                IOobject
+                (
+                    "time",
+                    runTime.timeName(),
+                    "uniform",
+                    runTime,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
+
+            label index;
+            timeObject.lookup("index") >> index;
+            timeName = Foam::name(index);
+        }
+        else
+        {
+            timeName = runTime.timeName();
+        }
+    }
+
+    Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;
+
diff --git a/applications/utilities/mesh/conversion/fireToFoam/Make/files b/applications/utilities/mesh/conversion/fireToFoam/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..a8734855d05090b2b37c953497224a46ac205a5e
--- /dev/null
+++ b/applications/utilities/mesh/conversion/fireToFoam/Make/files
@@ -0,0 +1,3 @@
+fireToFoam.C
+
+EXE = $(FOAM_APPBIN)/fireToFoam
diff --git a/applications/utilities/mesh/conversion/fireToFoam/Make/options b/applications/utilities/mesh/conversion/fireToFoam/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e3af2fe661b0e1a9cc1f77fbe4b08a9923d2bd35
--- /dev/null
+++ b/applications/utilities/mesh/conversion/fireToFoam/Make/options
@@ -0,0 +1,7 @@
+EXE_INC = \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude
+
+EXE_LIBS = \
+    -lconversion
diff --git a/applications/utilities/mesh/conversion/fireToFoam/fireToFoam.C b/applications/utilities/mesh/conversion/fireToFoam/fireToFoam.C
new file mode 100644
index 0000000000000000000000000000000000000000..0f7c32c701dea259c602298d4dc933c4c0eef449
--- /dev/null
+++ b/applications/utilities/mesh/conversion/fireToFoam/fireToFoam.C
@@ -0,0 +1,123 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Application
+    fireToFoam
+
+Group
+    grpMeshConversionUtilities
+
+Description
+    Converts an AVL/FIRE polyhedral mesh to OPENFOAM
+
+Usage
+    \b fireToFoam [OPTION] firePolyMesh
+
+    Options:
+
+      - \param -ascii
+        Write in ASCII format instead of binary
+
+      - \par -check
+        Perform edge checking
+
+      - \par -scale \<factor\>
+        Specify an alternative geometry scaling factor.
+        The default is \b 1 (no scaling).
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "FIREMeshReader.H"
+#include "checkFireEdges.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char *argv[])
+{
+    argList::addNote
+    (
+        "Convert AVL/FIRE polyhedral mesh to OPENFOAM format"
+    );
+
+    argList::noParallel();
+    argList::validArgs.append("firePolyMesh");
+    argList::addBoolOption
+    (
+        "ascii",
+        "write in ASCII format instead of binary"
+    );
+    argList::addBoolOption
+    (
+        "check",
+        "perform edge checking as well"
+    );
+    argList::addOption
+    (
+        "scale",
+        "scale",
+        "geometry scaling factor - default is 1 (no scaling)"
+    );
+
+
+    argList args(argc, argv);
+    Time runTime(args.rootPath(), args.caseName());
+
+
+    // Binary output, unless otherwise specified
+    const IOstream::streamFormat format =
+    (
+        args.optionFound("ascii")
+      ? IOstream::ASCII
+      : IOstream::BINARY
+    );
+
+    // increase the precision of the points data
+    IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
+
+
+    fileFormats::FIREMeshReader reader
+    (
+        args[1],
+        // Default no scaling
+        args.optionLookupOrDefault("scale", 1.0)
+    );
+
+
+    autoPtr<polyMesh> mesh = reader.mesh(runTime);
+    reader.writeMesh(mesh(), format);
+
+
+    if (args.optionFound("check"))
+    {
+        checkFireEdges(mesh());
+    }
+
+    Info<< "\nEnd\n" << endl;
+    return 0;
+}
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/foamToFireMesh/Make/files b/applications/utilities/mesh/conversion/foamToFireMesh/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..0cc67f4f557a5542705ef177178f54e44518a35e
--- /dev/null
+++ b/applications/utilities/mesh/conversion/foamToFireMesh/Make/files
@@ -0,0 +1,3 @@
+foamToFireMesh.C
+
+EXE = $(FOAM_APPBIN)/foamToFireMesh
diff --git a/applications/utilities/mesh/conversion/foamToFireMesh/Make/options b/applications/utilities/mesh/conversion/foamToFireMesh/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e3af2fe661b0e1a9cc1f77fbe4b08a9923d2bd35
--- /dev/null
+++ b/applications/utilities/mesh/conversion/foamToFireMesh/Make/options
@@ -0,0 +1,7 @@
+EXE_INC = \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude
+
+EXE_LIBS = \
+    -lconversion
diff --git a/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C b/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..87ddd4dff938fdef1f9d626dbd180d92978db89d
--- /dev/null
+++ b/applications/utilities/mesh/conversion/foamToFireMesh/foamToFireMesh.C
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Application
+    foamToFireMesh
+
+Description
+    Reads an OpenFOAM mesh and writes an AVL/FIRE fpma format
+
+Usage
+    \b foamToFireMesh [OPTION]
+
+    Options:
+      - \par -ascii
+        Write in ASCII format instead of binary
+
+      - \par -scale \<factor\>
+        Specify an alternative geometry scaling factor.
+        The default is \b 1 (ie, no scaling).
+
+See also
+    Foam::cellTable, Foam::meshWriter and Foam::fileFormats::FIREMeshWriter
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "timeSelector.H"
+#include "Time.H"
+#include "polyMesh.H"
+#include "FIREMeshWriter.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    argList::addNote
+    (
+        "read OpenFOAM mesh and write an AVL/FIRE fpma format"
+    );
+    argList::noParallel();
+    timeSelector::addOptions();
+
+    argList::addBoolOption
+    (
+        "ascii",
+        "write in ASCII format instead of binary"
+    );
+    argList::addOption
+    (
+        "scale",
+        "factor",
+        "geometry scaling factor - default is 1 (none)"
+    );
+
+    #include "setRootCase.H"
+    #include "createTime.H"
+
+    instantList timeDirs = timeSelector::select0(runTime, args);
+
+    fileName exportName = meshWriter::defaultMeshName;
+    if (args.optionFound("case"))
+    {
+        exportName += '-' + args.globalCaseName();
+    }
+
+
+    // write control options
+    // ~~~~~~~~~~~~~~~~~~~~~
+    fileFormats::FIREMeshWriter::binary = !args.optionFound("ascii");
+
+    // default: rescale from [m] to [mm]
+    scalar scaleFactor = 1;
+    if (args.optionReadIfPresent("scale", scaleFactor))
+    {
+        if (scaleFactor <= 0)
+        {
+            scaleFactor = 1;
+        }
+    }
+
+    #include "createPolyMesh.H"
+
+    forAll(timeDirs, timeI)
+    {
+        runTime.setTime(timeDirs[timeI], timeI);
+
+        #include "getTimeIndex.H"
+
+        polyMesh::readUpdateState state = mesh.readUpdate();
+
+        if (!timeI || state != polyMesh::UNCHANGED)
+        {
+            fileFormats::FIREMeshWriter writer(mesh, scaleFactor);
+
+            fileName meshName(exportName);
+            if (state != polyMesh::UNCHANGED)
+            {
+                meshName += '_' + runTime.timeName();
+            }
+
+            writer.write(meshName);
+        }
+
+        Info<< nl << endl;
+    }
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/foamToFireMesh/getTimeIndex.H b/applications/utilities/mesh/conversion/foamToFireMesh/getTimeIndex.H
new file mode 100644
index 0000000000000000000000000000000000000000..11b8993f28bd3efd8f8efd44d2880271d3a0419e
--- /dev/null
+++ b/applications/utilities/mesh/conversion/foamToFireMesh/getTimeIndex.H
@@ -0,0 +1,51 @@
+// Read time index from */uniform/time, but treat 0 and constant specially
+
+    word timeName = "0";
+
+    if
+    (
+        runTime.timeName() != runTime.constant()
+     && runTime.timeName() != "0"
+    )
+    {
+        IOobject io
+        (
+            "time",
+            runTime.timeName(),
+            "uniform",
+            runTime,
+            IOobject::READ_IF_PRESENT,
+            IOobject::NO_WRITE,
+            false
+        );
+
+        if (io.typeHeaderOk<IOdictionary>(true))
+        {
+            IOdictionary timeObject
+            (
+                IOobject
+                (
+                    "time",
+                    runTime.timeName(),
+                    "uniform",
+                    runTime,
+                    IOobject::MUST_READ_IF_MODIFIED,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
+
+            label index;
+            timeObject.lookup("index") >> index;
+            timeName = Foam::name(index);
+        }
+        else
+        {
+            timeName = runTime.timeName();
+            // Info<< "skip ... missing entry " << io.objectPath() << endl;
+            // continue;
+        }
+    }
+
+    Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;
+
diff --git a/applications/utilities/mesh/conversion/foamToStarMesh/foamToStarMesh.C b/applications/utilities/mesh/conversion/foamToStarMesh/foamToStarMesh.C
index b4692d201ac15c2d2329fe8867de35766d1b7771..f8fe44f19fc05c81ff81eaa76bf2032e73a89d76 100644
--- a/applications/utilities/mesh/conversion/foamToStarMesh/foamToStarMesh.C
+++ b/applications/utilities/mesh/conversion/foamToStarMesh/foamToStarMesh.C
@@ -94,15 +94,9 @@ int main(int argc, char *argv[])
         exportName += '-' + args.globalCaseName();
     }
 
-    // default: rescale from [m] to [mm]
-    scalar scaleFactor = 1000;
-    if (args.optionReadIfPresent("scale", scaleFactor))
-    {
-        if (scaleFactor <= 0)
-        {
-            scaleFactor = 1;
-        }
-    }
+    // Default rescale from [m] to [mm]
+    const scalar scaleFactor = args.optionLookupOrDefault("scale", 1000.0);
+    const bool  writeBndFile = !args.optionFound("noBnd");
 
     #include "createPolyMesh.H"
 
@@ -116,12 +110,12 @@ int main(int argc, char *argv[])
 
         if (!timeI || state != polyMesh::UNCHANGED)
         {
-            fileFormats::STARCDMeshWriter writer(mesh, scaleFactor);
-
-            if (args.optionFound("noBnd"))
-            {
-                writer.noBoundary();
-            }
+            fileFormats::STARCDMeshWriter writer
+            (
+                mesh,
+                scaleFactor,
+                writeBndFile
+            );
 
             fileName meshName(exportName);
             if (state != polyMesh::UNCHANGED)
diff --git a/applications/utilities/mesh/conversion/star4ToFoam/star4ToFoam.C b/applications/utilities/mesh/conversion/star4ToFoam/star4ToFoam.C
index af57977d788beb9b155e978a82be2f61d8cb11c0..65261399d076de189a31b6c7fbb206ac1a6f36ca 100644
--- a/applications/utilities/mesh/conversion/star4ToFoam/star4ToFoam.C
+++ b/applications/utilities/mesh/conversion/star4ToFoam/star4ToFoam.C
@@ -48,7 +48,7 @@ Usage
 Note
     Baffles are written as interfaces for later use
 
-See Also
+See also
     Foam::cellTable, Foam::meshReader and Foam::fileFormats::STARCDMeshReader
 
 \*---------------------------------------------------------------------------*/
@@ -88,32 +88,35 @@ int main(int argc, char *argv[])
         "retain solid cells and treat them like fluid cells"
     );
 
+
     argList args(argc, argv);
     Time runTime(args.rootPath(), args.caseName());
 
-    // default rescale from [mm] to [m]
-    scalar scaleFactor = args.optionLookupOrDefault("scale", 0.001);
-    if (scaleFactor <= 0)
-    {
-        scaleFactor = 1;
-    }
-
-    fileFormats::STARCDMeshReader::keepSolids = args.optionFound("solids");
-
-    // default to binary output, unless otherwise specified
-    IOstream::streamFormat format = IOstream::BINARY;
-    if (args.optionFound("ascii"))
-    {
-        format = IOstream::ASCII;
-    }
+    // Binary output, unless otherwise specified
+    const IOstream::streamFormat format =
+    (
+        args.optionFound("ascii")
+      ? IOstream::ASCII
+      : IOstream::BINARY
+    );
 
-    // increase the precision of the points data
+    // Increase the precision of the points data
     IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
 
-    // remove extensions and/or trailing '.'
+
+    // Remove extensions and/or trailing '.'
     const fileName prefix = fileName(args[1]).lessExt();
 
-    fileFormats::STARCDMeshReader reader(prefix, runTime, scaleFactor);
+
+    fileFormats::STARCDMeshReader reader
+    (
+        prefix,
+        runTime,
+        // Default rescale from [mm] to [m]
+        args.optionLookupOrDefault("scale", 0.001),
+        args.optionFound("solids")
+    );
+
 
     autoPtr<polyMesh> mesh = reader.mesh(runTime);
     reader.writeMesh(mesh, format);
diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
index f4a01a7f89d96778b6becb82aa52855623755061..14b3ca71eb37cd90890403768bf931d58bf18977 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -785,7 +785,7 @@ int main(int argc, char *argv[])
         if (flipNormals)
         {
             Info<< "Flipping faces." << nl << endl;
-            faceList& faces = const_cast<faceList&>(fMesh.faces());
+            faceList& faces = const_cast<faceList&>(fMesh.surfFaces());
             forAll(faces, i)
             {
                 faces[i] = fMesh[i].reverseFace();
diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C
index 15bc659154e8dee2103ba6f351c44befcadeee46..20ebc345168de757765ab8f15f3856e082a04edc 100644
--- a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C
+++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMesh/patchToPoly2DMesh/patchToPoly2DMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -172,7 +172,7 @@ void Foam::patchToPoly2DMesh::addPatchFacesToFaces()
 void Foam::patchToPoly2DMesh::addPatchFacesToOwner()
 {
     const label nInternalEdges = patch_.nInternalEdges();
-    const faceList& faces = patch_.faces();
+    const faceList& faces = patch_.surfFaces();
     const label nExternalEdges = patch_.edges().size() - nInternalEdges;
     const labelList& meshPoints = patch_.meshPoints();
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/Allwmake b/applications/utilities/mesh/generation/foamyMesh/Allwmake
index 4090d594e41a78e8f10f6d88a1edae5367ddbb0f..85f046473cbd3b9ada96efc73eaef278e9aa5be1 100755
--- a/applications/utilities/mesh/generation/foamyMesh/Allwmake
+++ b/applications/utilities/mesh/generation/foamyMesh/Allwmake
@@ -4,8 +4,8 @@ cd ${0%/*} || exit 1    # Run from this directory
 # Parse arguments for library compilation
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
 
-if [ -d "$CGAL_ARCH_PATH/include/CGAL" ] || \
-   [ "${CGAL_ARCH_PATH##*-}" = system -a -d /usr/include/CGAL ]
+if [ -f "$CGAL_ARCH_PATH/include/CGAL/version.h" ] || \
+   [ "${CGAL_ARCH_PATH##*-}" = system -a -f /usr/include/CGAL/version.h ]
 then
     set -x
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C
index 025ba5885d9cc0cc051b650996ee57b2ddc3b6ad..9b69ae120e1234a2170a23ab638d88a1e39f9c26 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -289,8 +289,11 @@ Foam::tmp<Foam::triSurfacePointScalarField> Foam::automatic::load()
         (
             surface_.searchableSurface::time().constant()/"triSurface",
             surfaceName_.lessExt().name(),
-            surface_.points(),
-            faces,
+            meshedSurfRef
+            (
+                surface_.points(),
+                faces
+            ),
             "cellSize",
             pointCellSize,
             true,
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/shortEdgeFilter2D.C b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/shortEdgeFilter2D.C
index fc2c048d7d1c027c24457fe8e99bbba6c1d9a6f2..0e8d4963a5697df780c83482c13622ae2fc97c48 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/shortEdgeFilter2D.C
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/shortEdgeFilter2D.C
@@ -232,7 +232,7 @@ Foam::shortEdgeFilter2D::filter()
     // These are global indices.
     const pointField& points = ms_.points();
     const edgeList& edges = ms_.edges();
-    const faceList& faces = ms_.faces();
+    const faceList& faces = ms_.surfFaces();
     const labelList& meshPoints = ms_.meshPoints();
     const labelList& boundaryPoints = ms_.boundaryPoints();
 
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
index b78f327073d7f5af9d437f69f9006a58267ac0d7..6261216c655cca786a8818f1d050499c2d47f1c1 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
@@ -20,23 +20,18 @@ snap            true;
 addLayers       false;
 
 
-//Optional: single region surfaces get patch names according to
-//          surface only. Multi-region surfaces get patch name
-//          surface "_ "region. Default is true
-//singleRegionName false;
+// Optional: single region surfaces get patch names according to
+//           surface only. Multi-region surfaces get patch name
+//           surface "_ "region. Default is true
+// singleRegionName false;
 
 // Optional: avoid patch-face merging. Allows mesh to be used for
 //           refinement/unrefinement
-//mergePatchFaces    false; // default true
+// mergePatchFaces    false; // default true
 
-// Optional: keep zero-sized patches. By default snappyHexMesh filters
-//           these out.
-//keepPatches    true; // default false
-
-
-//Optional: preserve all generated patches. Default is to remove
+// Optional: preserve all generated patches. Default is to remove
 //          zero-sized patches.
-//keepPatches true;
+// keepPatches true;
 
 
 // Geometry. Definition of all surfaces. All surfaces are of class
@@ -138,8 +133,10 @@ castellatedMeshControls
     (
         //{
         //    file "someLine.eMesh";
-        //    //level 2;
-        //    levels ((0.0 2) (1.0 3));
+        //    //level 2;        // Have level 2 for all cells intersected
+        //                      // by feature.
+        //    levels ((0.1 2)); // Have level 2 for all cells within
+        //                      // 0.1 of feature.
         //}
     );
 
@@ -260,8 +257,11 @@ castellatedMeshControls
         //    //  that in small gaps we're getting more cells.
         //    //  The specification is
         //    //  - numGapCells : minimum number of cells in the gap
+        //    //                  (usually >3; lower than this might not
+        //    //                   resolve correctly)
         //    //  - minLevel    : min refinement level at which to kick in
-        //    //  - maxLevel    : upper refinement level
+        //    //  - maxLevel    : upper refinement level (to avoid refinement
+        //    //                  continuing on a single extraneous feature)
         //    // All three settings can be overridden on a surface by
         //    // surface basis in the refinementSurfaces section.
         //    gapLevel (<numGapCells> <minLevel> <maxlevel>);
diff --git a/applications/utilities/mesh/manipulation/checkMesh/Make/options b/applications/utilities/mesh/manipulation/checkMesh/Make/options
index 0653767f3e68f60836c1dae1f8e304fc0034ec53..5d3dac934f252f42f27253552d7492fe1e4db6dc 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/Make/options
+++ b/applications/utilities/mesh/manipulation/checkMesh/Make/options
@@ -9,5 +9,4 @@ EXE_INC = \
 EXE_LIBS = \
     -lmeshTools \
     -lsampling \
-    -lsurfMesh \
     -ldynamicMesh
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
index 220e8275f9aee4086832473c60750ec5b3b286d3..b2b265cc05075b0346118ade70d6cf75b69f0b08 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
@@ -1019,8 +1019,11 @@ Foam::label Foam::checkGeometry
                             (
                                 "postProcessing",
                                 "src_" + tmName,
-                                mergedPoints,
-                                mergedFaces,
+                                meshedSurfRef
+                                (
+                                    mergedPoints,
+                                    mergedFaces
+                                ),
                                 "weightsSum",
                                 mergedWeights,
                                 false
@@ -1066,8 +1069,11 @@ Foam::label Foam::checkGeometry
                             (
                                 "postProcessing",
                                 "tgt_" + tmName,
-                                mergedPoints,
-                                mergedFaces,
+                                meshedSurfRef
+                                (
+                                    mergedPoints,
+                                    mergedFaces
+                                ),
                                 "weightsSum",
                                 mergedWeights,
                                 false
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
index 00afbde48972f4d7fed431c1c4c394a138ee2e3a..a26d98912371bd25efd022aa2a728e724d8b24d6 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2015-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -42,6 +42,7 @@ License
 #include "globalIndex.H"
 #include "PatchTools.H"
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
 {
@@ -238,7 +239,16 @@ void Foam::mergeAndWrite
         // Write
         if (Pstream::master())
         {
-            writer.write(outputDir, name, mergedPoints, mergedFaces);
+            writer.write
+            (
+                outputDir,
+                name,
+                meshedSurfRef
+                (
+                    mergedPoints,
+                    mergedFaces
+                )
+            );
         }
     }
     else
@@ -247,8 +257,11 @@ void Foam::mergeAndWrite
         (
             outputDir,
             name,
-            setPatch.localPoints(),
-            setPatch.localFaces()
+            meshedSurfRef
+            (
+                setPatch.localPoints(),
+                setPatch.localFaces()
+            )
         );
     }
 }
diff --git a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
index 563979e14a83c1bba5dc9f2ee3176d796a95eac9..1a4deffd5fc589ff05376a26baef804fed3191fb 100644
--- a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
+++ b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,6 +30,7 @@ License
 #include "polyAddPoint.H"
 #include "polyAddCell.H"
 #include "polyAddFace.H"
+#include "processorPolyPatch.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -104,11 +105,11 @@ Foam::label Foam::mergePolyMesh::zoneIndex
     const word& curName
 )
 {
-    forAll(names, zoneI)
+    forAll(names, zonei)
     {
-        if (names[zoneI] == curName)
+        if (names[zonei] == curName)
         {
-            return zoneI;
+            return zonei;
         }
     }
 
@@ -119,6 +120,84 @@ Foam::label Foam::mergePolyMesh::zoneIndex
 }
 
 
+void Foam::mergePolyMesh::sortProcessorPatches()
+{
+    Info<< "Reordering processor patches last" << endl;
+
+    // Updates boundaryMesh() and meshMod_ to guarantee processor patches
+    // are last. This could be done inside the merge() but it is far easier
+    // to do separately.
+
+
+    // 1. Shuffle the patches in the boundaryMesh
+
+    const polyBoundaryMesh& oldPatches = boundaryMesh();
+
+    DynamicList<polyPatch*> newPatches(oldPatches.size());
+
+    labelList oldToSorted(oldPatches.size());
+
+    forAll(oldPatches, patchi)
+    {
+        const polyPatch& pp = oldPatches[patchi];
+
+        if (!isA<processorPolyPatch>(pp))
+        {
+            oldToSorted[patchi] = newPatches.size();
+            newPatches.append
+            (
+                pp.clone
+                (
+                    oldPatches,
+                    oldToSorted[patchi],
+                    0,
+                    nInternalFaces()
+                ).ptr()
+            );
+        }
+    }
+    forAll(oldPatches, patchi)
+    {
+        const polyPatch& pp = oldPatches[patchi];
+
+        if (isA<processorPolyPatch>(pp))
+        {
+            oldToSorted[patchi] = newPatches.size();
+            newPatches.append
+            (
+                pp.clone
+                (
+                    oldPatches,
+                    oldToSorted[patchi],
+                    0,
+                    nInternalFaces()
+                ).ptr()
+            );
+        }
+    }
+
+
+    removeBoundary();
+    addPatches(newPatches);
+
+
+    // Update the polyTopoChange
+    DynamicList<label>& patchID = const_cast<DynamicList<label>&>
+    (
+        meshMod_.region()
+    );
+
+    forAll(patchID, facei)
+    {
+        label patchi = patchID[facei];
+        if (patchi != -1)
+        {
+            patchID[facei] = oldToSorted[patchID[facei]];
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
@@ -183,9 +262,6 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::mergePolyMesh::addMesh(const polyMesh& m)
@@ -506,6 +582,10 @@ void Foam::mergePolyMesh::merge()
         }
     }
 
+
+    // Shuffle the processor patches to be last
+    sortProcessorPatches();
+
     // Change mesh. No inflation
     meshMod_.changeMesh(*this, false);
 
diff --git a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.H b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.H
index a9db4fb32e3f28c95de3dc98aaa4fd0cc22a591b..6ce6f6e4efc87c70ff42181806a00972e775bed3 100644
--- a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.H
+++ b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -89,6 +89,9 @@ class mergePolyMesh
         //- Return zone index given a list of active zones and a name
         label zoneIndex(DynamicList<word>&, const word&);
 
+        //- Shuffle processor patches to be last
+        void sortProcessorPatches();
+
 
 public:
 
diff --git a/applications/utilities/mesh/manipulation/moveDynamicMesh/Make/options b/applications/utilities/mesh/manipulation/moveDynamicMesh/Make/options
index f7e149613f4faae128e4ad776740c45a075fba02..79021d1a46c1b4819b0786bdc977afc390c48380 100644
--- a/applications/utilities/mesh/manipulation/moveDynamicMesh/Make/options
+++ b/applications/utilities/mesh/manipulation/moveDynamicMesh/Make/options
@@ -2,6 +2,7 @@ EXE_INC = \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude
 
 EXE_LIBS = \
diff --git a/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C b/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
index b5f74359bcc1a0d484952bb34e8099b25ae05a39..477d4cbafc621461ed260dc23e3313e4d7d331a6 100644
--- a/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
+++ b/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -95,8 +95,11 @@ void writeWeights
         (
             directory,
             prefix + "_" + timeName,
-            mergedPoints,
-            mergedFaces,
+            meshedSurfRef
+            (
+                mergedPoints,
+                mergedFaces
+            ),
             "weightsSum",
             mergedWeights,
             false
diff --git a/applications/utilities/mesh/manipulation/renumberMesh/Allwmake b/applications/utilities/mesh/manipulation/renumberMesh/Allwmake
index 3acf4a1da70abac63f3b9717d3da8e308f0cd901..fae482e08b088ce26faa1f02b6e63728adb3afa8 100755
--- a/applications/utilities/mesh/manipulation/renumberMesh/Allwmake
+++ b/applications/utilities/mesh/manipulation/renumberMesh/Allwmake
@@ -3,7 +3,6 @@ cd ${0%/*} || exit 1    # Run from this directory
 
 # Parse arguments for compilation (at least for error catching)
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
-set -x
 
 export COMPILE_FLAGS=''
 export LINK_FLAGS=''
@@ -21,6 +20,7 @@ then
     export LINK_FLAGS="${LINK_FLAGS} -lzoltanRenumber -L${ZOLTAN_ARCH_PATH}/lib -lzoltan"
 fi
 
+set -x
 wmake $targetType
 
 #------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files
index 421e8392b88501e3efa3ae9323578c59721d8012..a474a8fcfc5ca8a0593a612b2f5aceb2246ead9b 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files
@@ -1,5 +1,4 @@
-ensightMesh.C
-ensightCloud.C
+ensightOutputCloud.C
 foamToEnsight.C
 
 EXE = $(FOAM_APPBIN)/foamToEnsight
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options
index e2fc5311ffe99a7d649b81856ec502200b5f9cd9..dc8f10f1f1ac5dd01a0c4f00e26c11bf6694e9ed 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options
@@ -3,14 +3,12 @@ EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/fileFormats/lnInclude \
-    -I$(LIB_SRC)/sampling/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/conversion/lnInclude
 
 EXE_LIBS = \
     -ldynamicMesh \
     -lfileFormats \
-    -lsampling \
     -lgenericPatchFields \
     -llagrangian \
     -lconversion
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H
index bda9220acbddf7feca356febe22a9724f7f27ce9..912f48b28ac7d8b9c653d0d1e03fe31f08117ee1 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H
@@ -38,8 +38,7 @@ if (timeDirs.size() > 1 && Pstream::master())
 
     if (meshMoving)
     {
-        Info<< "found." << nl
-            << "    Writing meshes for every timestep." << endl;
+        Info<< "found. Writing meshes for every timestep." << endl;
     }
     else
     {
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightAsciiStream.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightAsciiStream.H
deleted file mode 100644
index ceccc987aeae269798cf88d87adbcb315f0455bf..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightAsciiStream.H
+++ /dev/null
@@ -1,153 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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/>.
-
-Class
-    Foam::ensightAsciiStream
-
-Description
-
-SourceFiles
-    ensightAsciiStream.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef ensightAsciiStream_H
-#define ensightAsciiStream_H
-
-#include "ensightStream.H"
-#include "OFstream.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                         Class ensightAsciiStream Declaration
-\*---------------------------------------------------------------------------*/
-
-class ensightAsciiStream
-:
-    public ensightStream
-{
-    // Private data
-
-        //- Output file stream
-        OFstream str_;
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        ensightAsciiStream(const ensightAsciiStream&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const ensightAsciiStream&) = delete;
-
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        ensightAsciiStream(const fileName& f)
-        :
-            ensightStream(f),
-            str_
-            (
-                f,
-                IOstream::ASCII,
-                IOstream::currentVersion,
-                IOstream::UNCOMPRESSED
-            )
-        {
-
-            str_.setf(ios_base::scientific, ios_base::floatfield);
-            str_.precision(5);
-        }
-
-
-    //- Destructor
-    virtual ~ensightAsciiStream()
-    {}
-
-
-    // Member Functions
-
-        virtual bool ascii() const
-        {
-            return true;
-        }
-
-        virtual void write(const char* c)
-        {
-            str_ << c << nl;
-        }
-
-        virtual void write(const int v)
-        {
-            str_ << setw(10) << v << nl;
-        }
-
-        virtual void write(const scalarField& sf)
-        {
-            forAll(sf, i)
-            {
-                if (mag(sf[i]) >= scalar(floatScalarVSMALL))
-                {
-                    str_ << setw(12) << sf[i] << nl;
-                }
-                else
-                {
-                    str_ << setw(12) << scalar(0) << nl;
-                }
-            }
-        }
-
-        virtual void write(const List<int>& sf)
-        {
-            forAll(sf, i)
-            {
-                str_ << setw(10) << sf[i];
-            }
-            str_<< nl;
-        }
-
-        virtual void writePartHeader(const label partI)
-        {
-            str_<< "part" << nl
-                << setw(10) << partI << nl;
-        }
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightBinaryStream.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightBinaryStream.H
deleted file mode 100644
index d1c3d6e3b37aa7f9b10da495ae7612798845a23c..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightBinaryStream.H
+++ /dev/null
@@ -1,150 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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/>.
-
-Class
-    Foam::ensightBinaryStream
-
-Description
-
-SourceFiles
-    ensightBinaryStream.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef ensightBinaryStream_H
-#define ensightBinaryStream_H
-
-#include "ensightStream.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                         Class ensightBinaryStream Declaration
-\*---------------------------------------------------------------------------*/
-
-class ensightBinaryStream
-:
-    public ensightStream
-{
-    // Private data
-
-        //- Output file stream
-        autoPtr<std::ofstream> str_;
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        ensightBinaryStream(const ensightBinaryStream&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const ensightBinaryStream&) = delete;
-
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        ensightBinaryStream(const fileName& f)
-        :
-            ensightStream(f),
-            str_
-            (
-                new std::ofstream
-                (
-                    f.c_str(),
-                    ios_base::out | ios_base::binary | ios_base::trunc
-                )
-            )
-        {}
-
-
-    //- Destructor
-    virtual ~ensightBinaryStream()
-    {}
-
-
-    // Member Functions
-
-        virtual void write(const char* val)
-        {
-            char buffer[80];
-            strncpy(buffer, val, 80);
-            str_().write(buffer, 80*sizeof(char));
-        }
-
-        virtual void write(const int val)
-        {
-            str_().write(reinterpret_cast<const char*>(&val), sizeof(int));
-        }
-
-        virtual void write(const scalarField& sf)
-        {
-            if (sf.size())
-            {
-                List<float> temp(sf.size());
-
-                forAll(sf, i)
-                {
-                    temp[i] = float(sf[i]);
-                }
-
-                str_().write
-                (
-                    reinterpret_cast<const char*>(temp.begin()),
-                    sf.size()*sizeof(float)
-                );
-            }
-        }
-
-        virtual void write(const List<int>& sf)
-        {
-            str_().write
-            (
-                reinterpret_cast<const char*>(sf.begin()),
-                sf.size()*sizeof(int)
-            );
-        }
-
-        virtual void writePartHeader(const label partI)
-        {
-            write("part");
-            write(partI);
-        }
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCaseTail.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCaseTail.H
deleted file mode 100644
index 5a18a953c70b0f634621a3d03c95a01bf3a1887b..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCaseTail.H
+++ /dev/null
@@ -1,33 +0,0 @@
-if (Pstream::master())
-{
-    ensightCaseFile.setf(ios_base::scientific, ios_base::floatfield);
-    ensightCaseFile.precision(5);
-
-    ensightCaseFile << nl << "TIME" << nl
-        << "time set:                      " << 1 << nl
-        << "number of steps:               " << nTimeSteps << nl
-        << "filename start number:         " << 0 << nl
-        << "filename increment:            " << 1 << nl;
-
-    ensightCaseFile << "time values:" << nl;
-
-    label count = 0;
-    scalar Tcorr = 0.0;
-    if (timeDirs[0].value() < 0)
-    {
-        Tcorr = -timeDirs[0].value();
-        Info<< "Correcting time values. Adding " << Tcorr << endl;
-    }
-
-    forAll(timeDirs, n)
-    {
-        ensightCaseFile << setw(12) << timeDirs[n].value() + Tcorr << " ";
-
-        if (++count % 6 == 0)
-        {
-            ensightCaseFile << nl;
-        }
-    }
-
-    ensightCaseFile << nl;
-}
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.C
deleted file mode 100644
index 1755c7d2a1cab677c4aa0c2ce4b14c1bb9082202..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.C
+++ /dev/null
@@ -1,816 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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 "ensightFile.H"
-#include "ensightField.H"
-#include "fvMesh.H"
-#include "volFields.H"
-#include "OFstream.H"
-#include "IOmanip.H"
-#include "volPointInterpolation.H"
-#include "ensightBinaryStream.H"
-#include "ensightAsciiStream.H"
-#include "globalIndex.H"
-#include "ensightPTraits.H"
-#include "zeroGradientFvPatchField.H"
-
-using namespace Foam;
-
-// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
-
-template<class Type>
-tmp<GeometricField<Type, fvPatchField, volMesh>>
-volField
-(
-    const fvMeshSubset& meshSubsetter,
-    const GeometricField<Type, fvPatchField, volMesh>& vf
-)
-{
-    if (meshSubsetter.hasSubMesh())
-    {
-        tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
-        (
-            meshSubsetter.interpolate(vf)
-        );
-        tfld.ref().checkOut();
-        tfld.ref().rename(vf.name());
-        return tfld;
-    }
-    else
-    {
-        return vf;
-    }
-}
-
-
-template<class Type>
-tmp<GeometricField<Type, fvPatchField, volMesh>>
-volField
-(
-    const fvMeshSubset& meshSubsetter,
-    const typename GeometricField<Type, fvPatchField, volMesh>::Internal& df
-)
-{
-    // Construct volField (with zeroGradient) from dimensioned field
-
-    IOobject io(df);
-    io.readOpt()  = IOobject::NO_READ;
-    io.writeOpt() = IOobject::NO_WRITE;
-    io.registerObject() = false;
-
-    tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
-    (
-        new GeometricField<Type, fvPatchField, volMesh>
-        (
-            io,
-            df.mesh(),
-            dimensioned<Type>("0", df.dimensions(), Zero),
-            zeroGradientFvPatchField<Type>::typeName
-        )
-    );
-    tvf.ref().primitiveFieldRef() = df;
-    tvf.ref().correctBoundaryConditions();
-
-    if (meshSubsetter.hasSubMesh())
-    {
-        const GeometricField<Type, fvPatchField, volMesh>& vf = tvf();
-
-        tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
-        (
-            meshSubsetter.interpolate(vf)
-        );
-        tfld.ref().checkOut();
-        tfld.ref().rename(vf.name());
-        return tfld;
-    }
-    else
-    {
-        return tvf;
-    }
-}
-
-
-//template<class Container>
-//void readAndConvertField
-//(
-//    const fvMeshSubset& meshSubsetter,
-//    const IOobject& io,
-//    const fvMesh& mesh,
-//    const ensightMesh& eMesh,
-//    const fileName& dataDir,
-//    const label timeIndex,
-//    const bool nodeValues,
-//    Ostream& ensightCaseFile
-//)
-//{
-//    Container fld(io, mesh);
-//    ensightField<typename Container::value_type>
-//    (
-//        volField<typename Container::value_type>(meshSubsetter, fld),
-//        eMesh,
-//        dataDir,
-//        timeIndex,
-//        nodeValues,
-//        ensightCaseFile
-//    );
-//}
-
-
-template<class Type>
-Field<Type> map
-(
-    const Field<Type>& vf,
-    const labelList& map1,
-    const labelList& map2
-)
-{
-    Field<Type> mf(map1.size() + map2.size());
-
-    forAll(map1, i)
-    {
-        mf[i] = vf[map1[i]];
-    }
-
-    label offset = map1.size();
-
-    forAll(map2, i)
-    {
-        mf[i + offset] = vf[map2[i]];
-    }
-
-    return mf;
-}
-
-
-template<class Type>
-void writeField
-(
-    const char* key,
-    const Field<Type>& vf,
-    ensightStream& os
-)
-{
-    if (returnReduce(vf.size(), sumOp<label>()) > 0)
-    {
-        if (Pstream::master())
-        {
-            os.write(key);
-
-            for (direction i=0; i < pTraits<Type>::nComponents; ++i)
-            {
-                label cmpt = ensightPTraits<Type>::componentOrder[i];
-
-                os.write(vf.component(cmpt));
-
-                for (int slave=1; slave<Pstream::nProcs(); slave++)
-                {
-                    IPstream fromSlave(Pstream::scheduled, slave);
-                    scalarField slaveData(fromSlave);
-                    os.write(slaveData);
-                }
-            }
-        }
-        else
-        {
-            for (direction i=0; i < pTraits<Type>::nComponents; ++i)
-            {
-                label cmpt = ensightPTraits<Type>::componentOrder[i];
-
-                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-                toMaster<< vf.component(cmpt);
-            }
-        }
-    }
-}
-
-
-template<class Type>
-bool writePatchField
-(
-    const Field<Type>& pf,
-    const label patchi,
-    const label ensightPatchi,
-    const faceSets& boundaryFaceSet,
-    const ensightMesh::nFacePrimitives& nfp,
-    ensightStream& os
-)
-{
-    if (nfp.nTris || nfp.nQuads || nfp.nPolys)
-    {
-        if (Pstream::master())
-        {
-            os.writePartHeader(ensightPatchi);
-        }
-
-        writeField
-        (
-            "tria3",
-            Field<Type>(pf, boundaryFaceSet.tris),
-            os
-        );
-
-        writeField
-        (
-            "quad4",
-            Field<Type>(pf, boundaryFaceSet.quads),
-            os
-        );
-
-        writeField
-        (
-            "nsided",
-            Field<Type>(pf, boundaryFaceSet.polys),
-            os
-        );
-
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-
-template<class Type>
-void writePatchField
-(
-    const word& fieldName,
-    const Field<Type>& pf,
-    const word& patchName,
-    const ensightMesh& eMesh,
-    const fileName& dataDir,
-    const label timeIndex,
-    Ostream& ensightCaseFile
-)
-{
-    const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
-    const wordList& allPatchNames = eMesh.allPatchNames();
-    const HashTable<ensightMesh::nFacePrimitives>&
-        nPatchPrims = eMesh.nPatchPrims();
-
-    label ensightPatchi = eMesh.patchPartOffset();
-
-    label patchi = -1;
-
-    forAll(allPatchNames, i)
-    {
-        if (allPatchNames[i] == patchName)
-        {
-            patchi = i;
-            break;
-        }
-        ensightPatchi++;
-    }
-
-    ensightStream* filePtr(nullptr);
-    if (Pstream::master())
-    {
-        // TODO: verify that these are indeed valid ensight variable names
-        const word varName = patchName + '.' + fieldName;
-        const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
-
-        // the data/ITER subdirectory must exist
-        mkDir(dataDir/postFileName.path());
-
-        if (timeIndex == 0)
-        {
-            const fileName dirName = dataDir.name()/ensightFile::mask();
-
-            ensightCaseFile.setf(ios_base::left);
-            ensightCaseFile
-                << ensightPTraits<Type>::typeName << " per "
-                << setw(20)
-                << "element:"
-                << " 1  "
-                << setw(15)
-                << varName.c_str() << ' '
-                << (dirName/varName).c_str()
-                << nl;
-        }
-
-        if (eMesh.format() == IOstream::BINARY)
-        {
-            filePtr = new ensightBinaryStream
-            (
-                dataDir/postFileName
-            );
-        }
-        else
-        {
-            filePtr = new ensightAsciiStream
-            (
-                dataDir/postFileName
-            );
-        }
-
-        filePtr->write(ensightPTraits<Type>::typeName);
-    }
-
-    ensightStream& os = *filePtr;
-
-    if (patchi >= 0)
-    {
-        writePatchField
-        (
-            pf,
-            patchi,
-            ensightPatchi,
-            boundaryFaceSets[patchi],
-            nPatchPrims.find(patchName)(),
-            os
-        );
-    }
-    else
-    {
-        faceSets nullFaceSets;
-
-        writePatchField
-        (
-            Field<Type>(),
-            -1,
-            ensightPatchi,
-            nullFaceSets,
-            nPatchPrims.find(patchName)(),
-            os
-        );
-    }
-
-    if (filePtr) // on master only
-    {
-        delete filePtr;
-    }
-}
-
-
-template<class Type>
-void ensightField
-(
-    const GeometricField<Type, fvPatchField, volMesh>& vf,
-    const ensightMesh& eMesh,
-    const fileName& dataDir,
-    const label timeIndex,
-    Ostream& ensightCaseFile
-)
-{
-    Info<< ' ' << vf.name();
-
-    const fvMesh& mesh = eMesh.mesh();
-
-    const cellSets& meshCellSets = eMesh.meshCellSets();
-    const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
-    const wordList& allPatchNames = eMesh.allPatchNames();
-    const wordHashSet& patchNames = eMesh.patchNames();
-    const HashTable<ensightMesh::nFacePrimitives>&
-        nPatchPrims = eMesh.nPatchPrims();
-    const List<faceSets>& faceZoneFaceSets = eMesh.faceZoneFaceSets();
-    const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
-    const HashTable<ensightMesh::nFacePrimitives>&
-        nFaceZonePrims = eMesh.nFaceZonePrims();
-
-    const labelList& tets = meshCellSets.tets;
-    const labelList& pyrs = meshCellSets.pyrs;
-    const labelList& prisms = meshCellSets.prisms;
-    const labelList& wedges = meshCellSets.wedges;
-    const labelList& hexes = meshCellSets.hexes;
-    const labelList& polys = meshCellSets.polys;
-
-    ensightStream* filePtr(nullptr);
-    if (Pstream::master())
-    {
-        const ensight::VarName varName(vf.name());
-        const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
-
-        // the data/ITER subdirectory must exist
-        mkDir(dataDir/postFileName.path());
-
-        if (timeIndex == 0)
-        {
-            const fileName dirName = dataDir.name()/ensightFile::mask();
-
-            ensightCaseFile.setf(ios_base::left);
-            ensightCaseFile
-                << ensightPTraits<Type>::typeName
-                << " per element:     1  "
-                << setw(15)
-                << varName.c_str() << ' '
-                << (dirName/varName).c_str()
-                << nl;
-        }
-
-        if (eMesh.format() == IOstream::BINARY)
-        {
-            filePtr = new ensightBinaryStream
-            (
-                dataDir/postFileName
-            );
-        }
-        else
-        {
-            filePtr = new ensightAsciiStream
-            (
-                dataDir/postFileName
-            );
-        }
-
-        filePtr->write(ensightPTraits<Type>::typeName);
-    }
-
-    ensightStream& os = *filePtr;
-
-    if (patchNames.empty())
-    {
-        eMesh.barrier();
-
-        if (Pstream::master())
-        {
-            os.writePartHeader(1);
-        }
-
-        writeField
-        (
-            "hexa8",
-            map(vf, hexes, wedges),
-            os
-        );
-
-        writeField
-        (
-            "penta6",
-            Field<Type>(vf, prisms),
-            os
-        );
-
-        writeField
-        (
-            "pyramid5",
-            Field<Type>(vf, pyrs),
-            os
-        );
-
-        writeField
-        (
-            "tetra4",
-            Field<Type>(vf, tets),
-            os
-        );
-
-        writeField
-        (
-            "nfaced",
-            Field<Type>(vf, polys),
-            os
-        );
-    }
-
-    label ensightPatchi = eMesh.patchPartOffset();
-
-    forAll(allPatchNames, patchi)
-    {
-        const word& patchName = allPatchNames[patchi];
-
-        eMesh.barrier();
-
-        if (patchNames.empty() || patchNames.found(patchName))
-        {
-            if
-            (
-                writePatchField
-                (
-                    vf.boundaryField()[patchi],
-                    patchi,
-                    ensightPatchi,
-                    boundaryFaceSets[patchi],
-                    nPatchPrims.find(patchName)(),
-                    os
-                )
-            )
-            {
-                ensightPatchi++;
-            }
-        }
-    }
-
-    // write faceZones, if requested
-    if (faceZoneNames.size())
-    {
-        // Interpolates cell values to faces - needed only when exporting
-        // faceZones...
-        GeometricField<Type, fvsPatchField, surfaceMesh> sf
-        (
-            linearInterpolate(vf)
-        );
-
-        forAllConstIter(wordHashSet, faceZoneNames, iter)
-        {
-            const word& faceZoneName = iter.key();
-
-            eMesh.barrier();
-
-            const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
-            const faceZone& fz = mesh.faceZones()[zoneID];
-
-            // Prepare data to write
-            label nIncluded = 0;
-            forAll(fz, i)
-            {
-                if (eMesh.faceToBeIncluded(fz[i]))
-                {
-                    ++nIncluded;
-                }
-            }
-
-            Field<Type> values(nIncluded);
-
-            // Loop on the faceZone and store the needed field values
-            label j = 0;
-            forAll(fz, i)
-            {
-                label facei = fz[i];
-                if (mesh.isInternalFace(facei))
-                {
-                    values[j] = sf[facei];
-                    ++j;
-                }
-                else
-                {
-                    if (eMesh.faceToBeIncluded(facei))
-                    {
-                        label patchi = mesh.boundaryMesh().whichPatch(facei);
-                        const polyPatch& pp = mesh.boundaryMesh()[patchi];
-                        label patchFacei = pp.whichFace(facei);
-                        Type value = sf.boundaryField()[patchi][patchFacei];
-                        values[j] = value;
-                        ++j;
-                    }
-                }
-            }
-
-            if
-            (
-                writePatchField
-                (
-                    values,
-                    zoneID,
-                    ensightPatchi,
-                    faceZoneFaceSets[zoneID],
-                    nFaceZonePrims.find(faceZoneName)(),
-                    os
-                )
-            )
-            {
-                ensightPatchi++;
-            }
-        }
-    }
-
-    if (filePtr) // on master only
-    {
-        delete filePtr;
-    }
-}
-
-
-template<class Type>
-void ensightPointField
-(
-    const GeometricField<Type, pointPatchField, pointMesh>& pf,
-    const ensightMesh& eMesh,
-    const fileName& dataDir,
-    const label timeIndex,
-    Ostream& ensightCaseFile
-)
-{
-    Info<< ' ' << pf.name();
-
-    const fvMesh& mesh = eMesh.mesh();
-    const wordList& allPatchNames = eMesh.allPatchNames();
-    const wordHashSet& patchNames = eMesh.patchNames();
-    const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
-
-    ensightStream* filePtr(nullptr);
-    if (Pstream::master())
-    {
-        const ensight::VarName varName(pf.name());
-        const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
-
-        // the data/ITER subdirectory must exist
-        mkDir(dataDir/postFileName.path());
-
-        if (timeIndex == 0)
-        {
-            const fileName dirName = dataDir.name()/ensightFile::mask();
-
-            ensightCaseFile.setf(ios_base::left);
-            ensightCaseFile
-                << ensightPTraits<Type>::typeName
-                << " per "
-                << setw(20)
-                << " node:"
-                << " 1  "
-                << setw(15)
-                << varName.c_str() << ' '
-                << (dirName/varName).c_str()
-                << nl;
-        }
-
-        if (eMesh.format() == IOstream::BINARY)
-        {
-            filePtr = new ensightBinaryStream
-            (
-                dataDir/postFileName
-            );
-        }
-        else
-        {
-            filePtr = new ensightAsciiStream
-            (
-                dataDir/postFileName
-            );
-        }
-
-        filePtr->write(ensightPTraits<Type>::typeName);
-    }
-
-    ensightStream& os = *filePtr;
-
-    if (eMesh.patchNames().empty())
-    {
-        eMesh.barrier();
-
-        if (Pstream::master())
-        {
-            os.writePartHeader(1);
-        }
-
-        writeField
-        (
-            "coordinates",
-            Field<Type>(pf.primitiveField(), eMesh.uniquePointMap()),
-            os
-        );
-    }
-
-
-    label ensightPatchi = eMesh.patchPartOffset();
-
-    forAll(allPatchNames, patchi)
-    {
-        const word& patchName = allPatchNames[patchi];
-
-        eMesh.barrier();
-
-        if (patchNames.empty() || patchNames.found(patchName))
-        {
-            const fvPatch& p = mesh.boundary()[patchi];
-
-            if (returnReduce(p.size(), sumOp<label>()) > 0)
-            {
-                // Renumber the patch points/faces into unique points
-                labelList pointToGlobal;
-                labelList uniqueMeshPointLabels;
-                autoPtr<globalIndex> globalPointsPtr =
-                mesh.globalData().mergePoints
-                (
-                    p.patch().meshPoints(),
-                    p.patch().meshPointMap(),
-                    pointToGlobal,
-                    uniqueMeshPointLabels
-                );
-
-                if (Pstream::master())
-                {
-                    os.writePartHeader(ensightPatchi);
-                }
-
-                writeField
-                (
-                    "coordinates",
-                    Field<Type>(pf.primitiveField(), uniqueMeshPointLabels),
-                    os
-                );
-
-                ensightPatchi++;
-            }
-        }
-    }
-
-    // write faceZones, if requested
-    if (faceZoneNames.size())
-    {
-        forAllConstIter(wordHashSet, faceZoneNames, iter)
-        {
-            const word& faceZoneName = iter.key();
-
-            eMesh.barrier();
-
-            const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
-            const faceZone& fz = mesh.faceZones()[zoneID];
-
-            if (returnReduce(fz().nPoints(), sumOp<label>()) > 0)
-            {
-                // Renumber the faceZone points/faces into unique points
-                labelList pointToGlobal;
-                labelList uniqueMeshPointLabels;
-                autoPtr<globalIndex> globalPointsPtr =
-                    mesh.globalData().mergePoints
-                    (
-                        fz().meshPoints(),
-                        fz().meshPointMap(),
-                        pointToGlobal,
-                        uniqueMeshPointLabels
-                    );
-
-                if (Pstream::master())
-                {
-                    os.writePartHeader(ensightPatchi);
-                }
-
-                writeField
-                (
-                    "coordinates",
-                    Field<Type>
-                    (
-                        pf.primitiveField(),
-                        uniqueMeshPointLabels
-                    ),
-                    os
-                );
-
-                ensightPatchi++;
-            }
-        }
-    }
-
-    if (filePtr) // on master only
-    {
-        delete filePtr;
-    }
-}
-
-
-template<class Type>
-void ensightField
-(
-    const GeometricField<Type, fvPatchField, volMesh>& vf,
-    const ensightMesh& eMesh,
-    const fileName& dataDir,
-    const label timeIndex,
-    const bool nodeValues,
-    Ostream& ensightCaseFile
-)
-{
-    if (nodeValues)
-    {
-        tmp<GeometricField<Type, pointPatchField, pointMesh>> pfld
-        (
-            volPointInterpolation::New(vf.mesh()).interpolate(vf)
-        );
-        pfld.ref().rename(vf.name());
-
-        ensightPointField<Type>
-        (
-            pfld,
-            eMesh,
-            dataDir,
-            timeIndex,
-            ensightCaseFile
-        );
-    }
-    else
-    {
-        ensightField<Type>
-        (
-            vf,
-            eMesh,
-            dataDir,
-            timeIndex,
-            ensightCaseFile
-        );
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.H
deleted file mode 100644
index 3769f93714c9b99074e1bd4323b16e4e40d9279a..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightField.H
+++ /dev/null
@@ -1,102 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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/>.
-
-InApplication
-    foamToEnsight
-
-Description
-
-SourceFiles
-    ensightField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef ensightField_H
-#define ensightField_H
-
-#include "ensightMesh.H"
-#include "fvMeshSubset.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-//- Wrapper to get hold of the field or the subsetted field
-template<class Type>
-Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
-volField
-(
-    const Foam::fvMeshSubset&,
-    const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf
-);
-
-
-//- Wrapper to convert dimensionedInternalField to volField
-template<class Type>
-Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
-volField
-(
-    const Foam::fvMeshSubset&,
-    const typename Foam::GeometricField
-    <
-        Type,
-        Foam::fvPatchField,
-        Foam::volMesh
-    >::Internal& df
-);
-
-
-template<class Type>
-void ensightField
-(
-    const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf,
-    const Foam::ensightMesh& eMesh,
-    const Foam::fileName& dataDir,
-    const Foam::label timeIndex,
-    const bool nodeValues,
-    Foam::Ostream& ensightCaseFile
-);
-
-
-template<class Type>
-void writePatchField
-(
-    const Foam::word& fieldName,
-    const Foam::Field<Type>& pf,
-    const Foam::word& patchName,
-    const Foam::ensightMesh& eMesh,
-    const Foam::fileName& dataDir,
-    const Foam::label timeIndex,
-    Foam::Ostream& ensightCaseFile
-);
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-    #include "ensightField.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.C
deleted file mode 100644
index 5efc64bca8cac9d55ad2df65cec4735471d9c810..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.C
+++ /dev/null
@@ -1,1326 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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 "ensightMesh.H"
-#include "argList.H"
-#include "Time.H"
-#include "fvMesh.H"
-#include "globalMeshData.H"
-#include "PstreamCombineReduceOps.H"
-#include "processorPolyPatch.H"
-#include "cellModeller.H"
-#include "IOmanip.H"
-#include "globalIndex.H"
-#include "mapDistribute.H"
-#include "stringListOps.H"
-
-#include "ensightFile.H"
-#include "ensightBinaryStream.H"
-#include "ensightAsciiStream.H"
-
-#include <fstream>
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-const char* Foam::ensightMesh::geometryName = "geometry";
-
-
-// * * * * * * * * * * * * * Private Functions * * * * * * * * * * * * * * //
-
-void Foam::ensightMesh::correct()
-{
-    patchPartOffset_ = 2;
-    meshCellSets_.setSize(mesh_.nCells());
-
-    boundaryFaceSets_.setSize(mesh_.boundary().size());
-    boundaryFaceSets_ = faceSets(); // if number of patches changes
-    allPatchNames_.clear();
-    patchNames_.clear();
-    nPatchPrims_ = 0;
-    faceZoneFaceSets_.setSize(mesh_.faceZones().size());
-    faceZoneFaceSets_ = faceSets(); // if number of patches changes
-    faceZoneNames_.clear();
-    nFaceZonePrims_ = 0;
-    boundaryFaceToBeIncluded_.clear();
-
-    if (!noPatches_)
-    {
-        // Patches are output. Check that they're synced.
-        mesh_.boundaryMesh().checkParallelSync(true);
-
-        allPatchNames_ = mesh_.boundaryMesh().names();
-        if (Pstream::parRun())
-        {
-            allPatchNames_.setSize
-            (
-                mesh_.boundary().size()
-              - mesh_.globalData().processorPatches().size()
-            );
-        }
-
-        if (patches_)
-        {
-            if (patchPatterns_.empty())
-            {
-                forAll(allPatchNames_, nameI)
-                {
-                    patchNames_.insert(allPatchNames_[nameI]);
-                }
-            }
-            else
-            {
-                // Find patch names which match that requested at command-line
-                forAll(allPatchNames_, nameI)
-                {
-                    const word& patchName = allPatchNames_[nameI];
-                    if (findStrings(patchPatterns_, patchName))
-                    {
-                        patchNames_.insert(patchName);
-                    }
-                }
-            }
-        }
-    }
-
-    if (patchNames_.size())
-    {
-        // no internalMesh
-        patchPartOffset_ = 1;
-    }
-    else
-    {
-        const cellShapeList& cellShapes = mesh_.cellShapes();
-
-        const cellModel& tet = *(cellModeller::lookup("tet"));
-        const cellModel& pyr = *(cellModeller::lookup("pyr"));
-        const cellModel& prism = *(cellModeller::lookup("prism"));
-        const cellModel& wedge = *(cellModeller::lookup("wedge"));
-        const cellModel& hex = *(cellModeller::lookup("hex"));
-
-
-
-        // Count the shapes
-        labelList& tets = meshCellSets_.tets;
-        labelList& pyrs = meshCellSets_.pyrs;
-        labelList& prisms = meshCellSets_.prisms;
-        labelList& wedges = meshCellSets_.wedges;
-        labelList& hexes = meshCellSets_.hexes;
-        labelList& polys = meshCellSets_.polys;
-
-        label nTets = 0;
-        label nPyrs = 0;
-        label nPrisms = 0;
-        label nWedges = 0;
-        label nHexes = 0;
-        label nPolys = 0;
-
-        forAll(cellShapes, celli)
-        {
-            const cellShape& cellShape = cellShapes[celli];
-            const cellModel& cellModel = cellShape.model();
-
-            if (cellModel == tet)
-            {
-                tets[nTets++] = celli;
-            }
-            else if (cellModel == pyr)
-            {
-                pyrs[nPyrs++] = celli;
-            }
-            else if (cellModel == prism)
-            {
-                prisms[nPrisms++] = celli;
-            }
-            else if (cellModel == wedge)
-            {
-                wedges[nWedges++] = celli;
-            }
-            else if (cellModel == hex)
-            {
-                hexes[nHexes++] = celli;
-            }
-            else
-            {
-                polys[nPolys++] = celli;
-            }
-        }
-
-        tets.setSize(nTets);
-        pyrs.setSize(nPyrs);
-        prisms.setSize(nPrisms);
-        wedges.setSize(nWedges);
-        hexes.setSize(nHexes);
-        polys.setSize(nPolys);
-
-        meshCellSets_.nTets = nTets;
-        reduce(meshCellSets_.nTets, sumOp<label>());
-
-        meshCellSets_.nPyrs = nPyrs;
-        reduce(meshCellSets_.nPyrs, sumOp<label>());
-
-        meshCellSets_.nPrisms = nPrisms;
-        reduce(meshCellSets_.nPrisms, sumOp<label>());
-
-        meshCellSets_.nHexesWedges = nWedges+nHexes;
-        reduce(meshCellSets_.nHexesWedges, sumOp<label>());
-
-        meshCellSets_.nPolys = nPolys;
-        reduce(meshCellSets_.nPolys, sumOp<label>());
-
-
-        // Determine parallel shared points
-        globalPointsPtr_ = mesh_.globalData().mergePoints
-        (
-            pointToGlobal_,
-            uniquePointMap_
-        );
-    }
-
-    if (!noPatches_)
-    {
-        forAll(mesh_.boundary(), patchi)
-        {
-            if (mesh_.boundary()[patchi].size())
-            {
-                const polyPatch& p = mesh_.boundaryMesh()[patchi];
-
-                labelList& tris = boundaryFaceSets_[patchi].tris;
-                labelList& quads = boundaryFaceSets_[patchi].quads;
-                labelList& polys = boundaryFaceSets_[patchi].polys;
-
-                tris.setSize(p.size());
-                quads.setSize(p.size());
-                polys.setSize(p.size());
-
-                label nTris = 0;
-                label nQuads = 0;
-                label nPolys = 0;
-
-                forAll(p, facei)
-                {
-                    const face& f = p[facei];
-
-                    if (f.size() == 3)
-                    {
-                        tris[nTris++] = facei;
-                    }
-                    else if (f.size() == 4)
-                    {
-                        quads[nQuads++] = facei;
-                    }
-                    else
-                    {
-                        polys[nPolys++] = facei;
-                    }
-                }
-
-                tris.setSize(nTris);
-                quads.setSize(nQuads);
-                polys.setSize(nPolys);
-            }
-        }
-    }
-
-    forAll(allPatchNames_, patchi)
-    {
-        const word& patchName = allPatchNames_[patchi];
-        nFacePrimitives nfp;
-
-        if (patchNames_.empty() || patchNames_.found(patchName))
-        {
-            if (mesh_.boundary()[patchi].size())
-            {
-                nfp.nTris   = boundaryFaceSets_[patchi].tris.size();
-                nfp.nQuads  = boundaryFaceSets_[patchi].quads.size();
-                nfp.nPolys  = boundaryFaceSets_[patchi].polys.size();
-            }
-        }
-
-        reduce(nfp.nTris, sumOp<label>());
-        reduce(nfp.nQuads, sumOp<label>());
-        reduce(nfp.nPolys, sumOp<label>());
-
-        nPatchPrims_.insert(patchName, nfp);
-    }
-
-    // faceZones
-    if (faceZones_)
-    {
-        wordList faceZoneNamesAll = mesh_.faceZones().names();
-        // Need to sort the list of all face zones since the index may vary
-        // from processor to processor...
-        sort(faceZoneNamesAll);
-
-        // Find faceZone names which match that requested at command-line
-        forAll(faceZoneNamesAll, nameI)
-        {
-            const word& zoneName = faceZoneNamesAll[nameI];
-            if (findStrings(faceZonePatterns_, zoneName))
-            {
-                faceZoneNames_.insert(zoneName);
-            }
-        }
-
-        // Build list of boundary faces to be exported
-        boundaryFaceToBeIncluded_.setSize
-        (
-            mesh_.nFaces()
-          - mesh_.nInternalFaces(),
-            1
-        );
-
-        forAll(mesh_.boundaryMesh(), patchi)
-        {
-            const polyPatch& pp = mesh_.boundaryMesh()[patchi];
-            if
-            (
-                isA<processorPolyPatch>(pp)
-             && !refCast<const processorPolyPatch>(pp).owner()
-            )
-            {
-                label bFacei = pp.start()-mesh_.nInternalFaces();
-                forAll(pp, i)
-                {
-                    boundaryFaceToBeIncluded_[bFacei++] = 0;
-                }
-            }
-        }
-
-        // Count face types in each faceZone
-        forAll(faceZoneNamesAll, zoneI)
-        {
-            const word& zoneName = faceZoneNamesAll[zoneI];
-            const label faceZoneId = mesh_.faceZones().findZoneID(zoneName);
-
-            const faceZone& fz = mesh_.faceZones()[faceZoneId];
-
-            if (fz.size())
-            {
-                labelList& tris = faceZoneFaceSets_[faceZoneId].tris;
-                labelList& quads = faceZoneFaceSets_[faceZoneId].quads;
-                labelList& polys = faceZoneFaceSets_[faceZoneId].polys;
-
-                tris.setSize(fz.size());
-                quads.setSize(fz.size());
-                polys.setSize(fz.size());
-
-                label nTris = 0;
-                label nQuads = 0;
-                label nPolys = 0;
-
-                label faceCounter = 0;
-
-                forAll(fz, i)
-                {
-                    label facei = fz[i];
-
-                    // Avoid counting faces on processor boundaries twice
-                    if (faceToBeIncluded(facei))
-                    {
-                        const face& f = mesh_.faces()[facei];
-
-                        if (f.size() == 3)
-                        {
-                            tris[nTris++] = faceCounter;
-                        }
-                        else if (f.size() == 4)
-                        {
-                            quads[nQuads++] = faceCounter;
-                        }
-                        else
-                        {
-                            polys[nPolys++] = faceCounter;
-                        }
-
-                        ++faceCounter;
-                    }
-                }
-
-                tris.setSize(nTris);
-                quads.setSize(nQuads);
-                polys.setSize(nPolys);
-            }
-        }
-
-        forAll(faceZoneNamesAll, zoneI)
-        {
-            const word& zoneName = faceZoneNamesAll[zoneI];
-            nFacePrimitives nfp;
-            const label faceZoneId = mesh_.faceZones().findZoneID(zoneName);
-
-            if (faceZoneNames_.found(zoneName))
-            {
-                if
-                (
-                    faceZoneFaceSets_[faceZoneId].tris.size()
-                 || faceZoneFaceSets_[faceZoneId].quads.size()
-                 || faceZoneFaceSets_[faceZoneId].polys.size()
-                )
-                {
-                    nfp.nTris   = faceZoneFaceSets_[faceZoneId].tris.size();
-                    nfp.nQuads  = faceZoneFaceSets_[faceZoneId].quads.size();
-                    nfp.nPolys  = faceZoneFaceSets_[faceZoneId].polys.size();
-                }
-            }
-
-            reduce(nfp.nTris, sumOp<label>());
-            reduce(nfp.nQuads, sumOp<label>());
-            reduce(nfp.nPolys, sumOp<label>());
-
-            nFaceZonePrims_.insert(zoneName, nfp);
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::ensightMesh::ensightMesh
-(
-    const fvMesh& mesh,
-    const bool noPatches,
-
-    const bool patches,
-    const wordReList& patchPatterns,
-
-    const bool faceZones,
-    const wordReList& faceZonePatterns,
-
-    const IOstream::streamFormat format
-)
-:
-    mesh_(mesh),
-    noPatches_(noPatches),
-    patches_(patches),
-    patchPatterns_(patchPatterns),
-    faceZones_(faceZones),
-    faceZonePatterns_(faceZonePatterns),
-    format_(format),
-    meshCellSets_(mesh.nCells())
-{
-    correct();
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::ensightMesh::~ensightMesh()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-bool Foam::ensightMesh::faceToBeIncluded(const label facei) const
-{
-    bool res = false;
-
-    if (mesh_.isInternalFace(facei))
-    {
-        res = true;
-    }
-    else
-    {
-        res = boundaryFaceToBeIncluded_[facei-mesh_.nInternalFaces()];
-    }
-
-    return res;
-}
-
-
-void Foam::ensightMesh::barrier()
-{
-    label appI = 0;
-    reduce(appI,maxOp<label>());
-}
-
-
-Foam::cellShapeList Foam::ensightMesh::map
-(
-    const cellShapeList& cellShapes,
-    const labelList& prims,
-    const labelList& pointToGlobal
-) const
-{
-    cellShapeList mcsl(prims.size());
-
-    forAll(prims, i)
-    {
-        mcsl[i] = cellShapes[prims[i]];
-        inplaceRenumber(pointToGlobal, mcsl[i]);
-    }
-
-    return mcsl;
-}
-
-
-Foam::cellShapeList Foam::ensightMesh::map
-(
-    const cellShapeList& cellShapes,
-    const labelList& hexes,
-    const labelList& wedges,
-    const labelList& pointToGlobal
-) const
-{
-    cellShapeList mcsl(hexes.size() + wedges.size());
-
-    forAll(hexes, i)
-    {
-        mcsl[i] = cellShapes[hexes[i]];
-        inplaceRenumber(pointToGlobal, mcsl[i]);
-    }
-
-    label offset = hexes.size();
-
-    const cellModel& hex = *(cellModeller::lookup("hex"));
-    labelList hexLabels(8);
-
-    forAll(wedges, i)
-    {
-        const cellShape& cellPoints = cellShapes[wedges[i]];
-
-        hexLabels[0] = cellPoints[0];
-        hexLabels[1] = cellPoints[1];
-        hexLabels[2] = cellPoints[0];
-        hexLabels[3] = cellPoints[2];
-        hexLabels[4] = cellPoints[3];
-        hexLabels[5] = cellPoints[4];
-        hexLabels[6] = cellPoints[6];
-        hexLabels[7] = cellPoints[5];
-
-        mcsl[i + offset] = cellShape(hex, hexLabels);
-        inplaceRenumber(pointToGlobal, mcsl[i + offset]);
-    }
-
-    return mcsl;
-}
-
-
-void Foam::ensightMesh::writePrims
-(
-    const cellShapeList& cellShapes,
-    ensightStream& ensightGeometryFile
-) const
-{
-    // Create a temp int array
-    if (cellShapes.size())
-    {
-        if (format_ == IOstream::ASCII)
-        {
-            // Workaround for paraview issue : write one cell per line
-
-            forAll(cellShapes, i)
-            {
-                const cellShape& cellPoints = cellShapes[i];
-
-                List<int> temp(cellPoints.size());
-
-                forAll(cellPoints, pointi)
-                {
-                    temp[pointi] = cellPoints[pointi] + 1;
-                }
-                ensightGeometryFile.write(temp);
-            }
-        }
-        else
-        {
-            // All the cellShapes have the same number of elements!
-            int numIntElem = cellShapes.size()*cellShapes[0].size();
-            List<int> temp(numIntElem);
-
-            int n = 0;
-
-            forAll(cellShapes, i)
-            {
-                const cellShape& cellPoints = cellShapes[i];
-
-                forAll(cellPoints, pointi)
-                {
-                    temp[n] = cellPoints[pointi] + 1;
-                    n++;
-                }
-            }
-            ensightGeometryFile.write(temp);
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writePolysNFaces
-(
-    const labelList& polys,
-    const cellList& cellFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    forAll(polys, i)
-    {
-        ensightGeometryFile.write(cellFaces[polys[i]].size());
-    }
-}
-
-
-void Foam::ensightMesh::writePolysNPointsPerFace
-(
-    const labelList& polys,
-    const cellList& cellFaces,
-    const faceList& faces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    forAll(polys, i)
-    {
-        const labelList& cf = cellFaces[polys[i]];
-
-        forAll(cf, facei)
-        {
-            ensightGeometryFile.write(faces[cf[facei]].size());
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writePolysPoints
-(
-    const labelList& polys,
-    const cellList& cellFaces,
-    const faceList& faces,
-    const labelList& faceOwner,
-    ensightStream& ensightGeometryFile
-) const
-{
-    forAll(polys, i)
-    {
-        const labelList& cf = cellFaces[polys[i]];
-
-        forAll(cf, facei)
-        {
-            const label faceId = cf[facei];
-            const face& f = faces[faceId];  // points of face (in global points)
-            const label np = f.size();
-            bool reverseOrder = false;
-            if (faceId >= faceOwner.size())
-            {
-                // Boundary face.
-                // Nothing should be done for processor boundary.
-                // The current cell always owns them. Given that we
-                // are reverting the
-                // order when the cell is the neighbour to the face,
-                // the orientation of
-                // all the boundaries, no matter if they are "real"
-                // or processorBoundaries, is consistent.
-            }
-            else
-            {
-                if (faceOwner[faceId] != polys[i])
-                {
-                    reverseOrder = true;
-                }
-            }
-
-            // If the face owner is the current cell, write the points
-            // in the standard order.
-            // If the face owner is not the current cell, write the points
-            // in reverse order.
-            // EnSight prefers to have all the faces of an nfaced cell
-            // oriented in the same way.
-            List<int> temp(np);
-            forAll(f, pointi)
-            {
-                if (reverseOrder)
-                {
-                    temp[np-1-pointi] = f[pointi] + 1;
-                }
-                else
-                {
-                    temp[pointi] = f[pointi] + 1;
-                }
-            }
-            ensightGeometryFile.write(temp);
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writeAllPolys
-(
-    const labelList& pointToGlobal,
-    ensightStream& ensightGeometryFile
-) const
-{
-    if (meshCellSets_.nPolys)
-    {
-        const cellList& cellFaces = mesh_.cells();
-        const labelList& faceOwner = mesh_.faceOwner();
-
-        // Renumber faces to use global point numbers
-        faceList faces(mesh_.faces());
-        forAll(faces, i)
-        {
-            inplaceRenumber(pointToGlobal, faces[i]);
-        }
-
-        if (Pstream::master())
-        {
-            ensightGeometryFile.write("nfaced");
-            ensightGeometryFile.write(meshCellSets_.nPolys);
-        }
-
-        // Number of faces for each poly cell
-
-        if (Pstream::master())
-        {
-            // Master
-            writePolysNFaces
-            (
-                meshCellSets_.polys,
-                cellFaces,
-                ensightGeometryFile
-            );
-            // Slaves
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                labelList polys(fromSlave);
-                cellList cellFaces(fromSlave);
-
-                writePolysNFaces
-                (
-                    polys,
-                    cellFaces,
-                    ensightGeometryFile
-                );
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< meshCellSets_.polys << cellFaces;
-        }
-
-
-        // Number of points for each face of the above list
-        if (Pstream::master())
-        {
-            // Master
-            writePolysNPointsPerFace
-            (
-                meshCellSets_.polys,
-                cellFaces,
-                faces,
-                ensightGeometryFile
-            );
-            // Slaves
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                labelList polys(fromSlave);
-                cellList cellFaces(fromSlave);
-                faceList faces(fromSlave);
-
-                writePolysNPointsPerFace
-                (
-                    polys,
-                    cellFaces,
-                    faces,
-                    ensightGeometryFile
-                );
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< meshCellSets_.polys << cellFaces << faces;
-        }
-
-
-        // List of points id for each face of the above list
-        if (Pstream::master())
-        {
-            // Master
-            writePolysPoints
-            (
-                meshCellSets_.polys,
-                cellFaces,
-                faces,
-                faceOwner,
-                ensightGeometryFile
-            );
-            // Slaves
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                labelList polys(fromSlave);
-                cellList cellFaces(fromSlave);
-                faceList faces(fromSlave);
-                labelList faceOwner(fromSlave);
-
-                writePolysPoints
-                (
-                    polys,
-                    cellFaces,
-                    faces,
-                    faceOwner,
-                    ensightGeometryFile
-                );
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< meshCellSets_.polys << cellFaces << faces << faceOwner;
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writeAllPrims
-(
-    const char* key,
-    const label nPrims,
-    const cellShapeList& cellShapes,
-    ensightStream& ensightGeometryFile
-) const
-{
-    if (nPrims)
-    {
-        if (Pstream::master())
-        {
-            ensightGeometryFile.write(key);
-            ensightGeometryFile.write(nPrims);
-
-            writePrims(cellShapes, ensightGeometryFile);
-
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                cellShapeList cellShapes(fromSlave);
-
-                writePrims(cellShapes, ensightGeometryFile);
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< cellShapes;
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writeFacePrims
-(
-    const faceList& patchFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    forAll(patchFaces, i)
-    {
-        const face& patchFace = patchFaces[i];
-
-        List<int> temp(patchFace.size());
-        forAll(patchFace, pointi)
-        {
-            temp[pointi] = patchFace[pointi] + 1;
-        }
-
-        ensightGeometryFile.write(temp);
-    }
-}
-
-
-void Foam::ensightMesh::writeAllFacePrims
-(
-    const char* key,
-    const labelList& prims,
-    const label nPrims,
-    const faceList& patchFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    if (nPrims)
-    {
-        if (Pstream::master())
-        {
-            ensightGeometryFile.write(key);
-            ensightGeometryFile.write(nPrims);
-
-            writeFacePrims
-            (
-                UIndirectList<face>(patchFaces, prims)(),
-                ensightGeometryFile
-            );
-
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                faceList patchFaces(fromSlave);
-
-                writeFacePrims(patchFaces, ensightGeometryFile);
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< UIndirectList<face>(patchFaces, prims);
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writeNSidedNPointsPerFace
-(
-    const faceList& patchFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    forAll(patchFaces, i)
-    {
-        ensightGeometryFile.write(patchFaces[i].size());
-    }
-}
-
-
-void Foam::ensightMesh::writeNSidedPoints
-(
-    const faceList& patchFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    writeFacePrims(patchFaces, ensightGeometryFile);
-}
-
-
-void Foam::ensightMesh::writeAllNSided
-(
-    const labelList& prims,
-    const label nPrims,
-    const faceList& patchFaces,
-    ensightStream& ensightGeometryFile
-) const
-{
-    if (nPrims)
-    {
-        if (Pstream::master())
-        {
-            ensightGeometryFile.write("nsided");
-            ensightGeometryFile.write(nPrims);
-        }
-
-        // Number of points for each face
-        if (Pstream::master())
-        {
-            writeNSidedNPointsPerFace
-            (
-                UIndirectList<face>(patchFaces, prims)(),
-                ensightGeometryFile
-            );
-
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                faceList patchFaces(fromSlave);
-
-                writeNSidedNPointsPerFace
-                (
-                    patchFaces,
-                    ensightGeometryFile
-                );
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< UIndirectList<face>(patchFaces, prims);
-        }
-
-        // List of points id for each face
-        if (Pstream::master())
-        {
-            writeNSidedPoints
-            (
-                UIndirectList<face>(patchFaces, prims)(),
-                ensightGeometryFile
-            );
-
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                faceList patchFaces(fromSlave);
-
-                writeNSidedPoints(patchFaces, ensightGeometryFile);
-            }
-        }
-        else
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< UIndirectList<face>(patchFaces, prims);
-        }
-    }
-}
-
-
-void Foam::ensightMesh::writeAllPoints
-(
-    const label ensightPartI,
-    const word& ensightPartName,
-    const pointField& uniquePoints,
-    const label nPoints,
-    ensightStream& ensightGeometryFile
-) const
-{
-    barrier();
-
-    if (Pstream::master())
-    {
-        ensightGeometryFile.writePartHeader(ensightPartI);
-        ensightGeometryFile.write(ensightPartName.c_str());
-        ensightGeometryFile.write("coordinates");
-        ensightGeometryFile.write(nPoints);
-
-        for (direction d=0; d<vector::nComponents; d++)
-        {
-            ensightGeometryFile.write(uniquePoints.component(d));
-            for (int slave=1; slave<Pstream::nProcs(); slave++)
-            {
-                IPstream fromSlave(Pstream::scheduled, slave);
-                scalarField patchPointsComponent(fromSlave);
-                ensightGeometryFile.write(patchPointsComponent);
-            }
-        }
-    }
-    else
-    {
-        for (direction d=0; d<vector::nComponents; d++)
-        {
-            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< uniquePoints.component(d);
-        }
-    }
-}
-
-
-void Foam::ensightMesh::write
-(
-    const fileName& dataDir,
-    const label timeIndex,
-    const bool meshMoving,
-    Ostream& ensightCaseFile
-) const
-{
-    const cellShapeList& cellShapes = mesh_.cellShapes();
-
-    ensightStream* filePtr(nullptr);
-    if (Pstream::master())
-    {
-        // set the filename of the ensight file
-        fileName geoFileName = dataDir.path()/ensightMesh::geometryName;
-
-        if (meshMoving)
-        {
-            geoFileName =
-                dataDir/ensightFile::subDir(timeIndex)
-               /ensightMesh::geometryName;
-
-            mkDir(geoFileName.path());
-        }
-
-        if (format_ == IOstream::BINARY)
-        {
-            filePtr = new ensightBinaryStream
-            (
-                geoFileName
-            );
-            filePtr->write("C binary");
-        }
-        else
-        {
-            filePtr = new ensightAsciiStream
-            (
-                geoFileName
-            );
-        }
-    }
-
-    ensightStream& os = *filePtr;
-
-    if (Pstream::master())
-    {
-        string desc = string("written by OpenFOAM-") + Foam::FOAMversion;
-
-        os.write("EnSight Geometry File");
-        os.write(desc.c_str());
-        os.write("node id assign");
-        os.write("element id assign");
-    }
-
-    if (patchNames_.empty())
-    {
-        label nPoints = globalPoints().size();
-
-        const pointField uniquePoints(mesh_.points(), uniquePointMap_);
-
-        writeAllPoints
-        (
-            1,
-            "internalMesh",
-            uniquePoints,
-            nPoints,
-            os
-        );
-
-        writeAllPrims
-        (
-            "hexa8",
-            meshCellSets_.nHexesWedges,
-            map         // Rewrite cellShapes to global numbering
-            (
-                cellShapes,
-                meshCellSets_.hexes,
-                meshCellSets_.wedges,
-                pointToGlobal_
-            ),
-            os
-        );
-
-        writeAllPrims
-        (
-            "penta6",
-            meshCellSets_.nPrisms,
-            map(cellShapes, meshCellSets_.prisms, pointToGlobal_),
-            os
-        );
-
-        writeAllPrims
-        (
-            "pyramid5",
-            meshCellSets_.nPyrs,
-            map(cellShapes, meshCellSets_.pyrs, pointToGlobal_),
-            os
-        );
-
-        writeAllPrims
-        (
-            "tetra4",
-            meshCellSets_.nTets,
-            map(cellShapes, meshCellSets_.tets, pointToGlobal_),
-            os
-        );
-
-        writeAllPolys
-        (
-            pointToGlobal_,
-            os
-        );
-    }
-
-
-    label ensightPatchi = patchPartOffset_;
-
-    forAll(allPatchNames_, patchi)
-    {
-        const word& patchName = allPatchNames_[patchi];
-
-        if (patchNames_.empty() || patchNames_.found(patchName))
-        {
-            const nFacePrimitives& nfp = nPatchPrims_[patchName];
-
-            if (nfp.nTris || nfp.nQuads || nfp.nPolys)
-            {
-                const polyPatch& p = mesh_.boundaryMesh()[patchi];
-
-                const labelList& tris = boundaryFaceSets_[patchi].tris;
-                const labelList& quads = boundaryFaceSets_[patchi].quads;
-                const labelList& polys = boundaryFaceSets_[patchi].polys;
-
-                // Renumber the patch points/faces into unique points
-                labelList pointToGlobal;
-                labelList uniqueMeshPointLabels;
-                autoPtr<globalIndex> globalPointsPtr =
-                    mesh_.globalData().mergePoints
-                    (
-                        p.meshPoints(),
-                        p.meshPointMap(),
-                        pointToGlobal,
-                        uniqueMeshPointLabels
-                    );
-
-                pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
-                // Renumber the patch faces
-                faceList patchFaces(p.localFaces());
-                forAll(patchFaces, i)
-                {
-                    inplaceRenumber(pointToGlobal, patchFaces[i]);
-                }
-
-                writeAllPoints
-                (
-                    ensightPatchi++,
-                    patchName,
-                    uniquePoints,
-                    globalPointsPtr().size(),
-                    os
-                );
-
-                writeAllFacePrims
-                (
-                    "tria3",
-                    tris,
-                    nfp.nTris,
-                    patchFaces,
-                    os
-                );
-
-                writeAllFacePrims
-                (
-                    "quad4",
-                    quads,
-                    nfp.nQuads,
-                    patchFaces,
-                    os
-                );
-
-                writeAllNSided
-                (
-                    polys,
-                    nfp.nPolys,
-                    patchFaces,
-                    os
-                );
-            }
-        }
-    }
-
-    // write faceZones, if requested
-    forAllConstIter(wordHashSet, faceZoneNames_, iter)
-    {
-        const word& faceZoneName = iter.key();
-
-        label faceID = mesh_.faceZones().findZoneID(faceZoneName);
-
-        const faceZone& fz = mesh_.faceZones()[faceID];
-
-        const nFacePrimitives& nfp = nFaceZonePrims_[faceZoneName];
-
-        if (nfp.nTris || nfp.nQuads || nfp.nPolys)
-        {
-            const labelList& tris = faceZoneFaceSets_[faceID].tris;
-            const labelList& quads = faceZoneFaceSets_[faceID].quads;
-            const labelList& polys = faceZoneFaceSets_[faceID].polys;
-
-            // Renumber the faceZone points/faces into unique points
-            labelList pointToGlobal;
-            labelList uniqueMeshPointLabels;
-            autoPtr<globalIndex> globalPointsPtr =
-                mesh_.globalData().mergePoints
-                (
-                    fz().meshPoints(),
-                    fz().meshPointMap(),
-                    pointToGlobal,
-                    uniqueMeshPointLabels
-                );
-
-            pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
-
-            // Find the list of master faces belonging to the faceZone,
-            // in local numbering
-            faceList faceZoneFaces(fz().localFaces());
-
-            // Count how many master faces belong to the faceZone. Is there
-            // a better way of doing this?
-            label nMasterFaces = 0;
-
-            forAll(fz, facei)
-            {
-                if (faceToBeIncluded(fz[facei]))
-                {
-                    ++nMasterFaces;
-                }
-            }
-
-            // Create the faceList for the master faces only and fill it.
-            faceList faceZoneMasterFaces(nMasterFaces);
-
-            label currentFace = 0;
-
-            forAll(fz, facei)
-            {
-                if (faceToBeIncluded(fz[facei]))
-                {
-                    faceZoneMasterFaces[currentFace] = faceZoneFaces[facei];
-                    ++currentFace;
-                }
-            }
-
-            // Renumber the faceZone master faces
-            forAll(faceZoneMasterFaces, i)
-            {
-                inplaceRenumber(pointToGlobal, faceZoneMasterFaces[i]);
-            }
-
-            writeAllPoints
-            (
-                ensightPatchi++,
-                faceZoneName,
-                uniquePoints,
-                globalPointsPtr().size(),
-                os
-            );
-
-            writeAllFacePrims
-            (
-                "tria3",
-                tris,
-                nfp.nTris,
-                faceZoneMasterFaces,
-                os
-            );
-
-            writeAllFacePrims
-            (
-                "quad4",
-                quads,
-                nfp.nQuads,
-                faceZoneMasterFaces,
-                os
-            );
-
-            writeAllNSided
-            (
-                polys,
-                nfp.nPolys,
-                faceZoneMasterFaces,
-                os
-            );
-        }
-    }
-
-    if (filePtr) // only on master
-    {
-        delete filePtr;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.H
deleted file mode 100644
index 47e27730fe01a93a799d1bec259f13539f76ae11..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightMesh.H
+++ /dev/null
@@ -1,398 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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/>.
-
-Class
-    Foam::ensightMesh
-
-Description
-
-SourceFiles
-    ensightMesh.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef ensightMesh_H
-#define ensightMesh_H
-
-#include "cellSets.H"
-#include "faceSets.H"
-#include "HashTable.H"
-#include "HashSet.H"
-#include "PackedBoolList.H"
-#include "wordReList.H"
-#include "scalarField.H"
-#include "cellShapeList.H"
-#include "cellList.H"
-
-#include <fstream>
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-class fvMesh;
-class argList;
-class globalIndex;
-class ensightStream;
-
-/*---------------------------------------------------------------------------*\
-                         Class ensightMesh Declaration
-\*---------------------------------------------------------------------------*/
-
-class ensightMesh
-{
-public:
-
-    //- The name for geometry files
-    static const char* geometryName;
-
-        //- Helper class for managing face primitives
-        class nFacePrimitives
-        {
-        public:
-
-            label nTris;
-            label nQuads;
-            label nPolys;
-
-            nFacePrimitives()
-            :
-                nTris(0),
-                nQuads(0),
-                nPolys(0)
-            {}
-        };
-
-private:
-
-    // Private data
-
-        //- Reference to the OpenFOAM mesh
-        const fvMesh& mesh_;
-
-        //- Suppress patches
-        const bool noPatches_;
-
-        //- Output selected patches only
-        const bool patches_;
-        const wordReList patchPatterns_;
-
-        //- Output selected faceZones
-        const bool faceZones_;
-        const wordReList faceZonePatterns_;
-
-        //- Ascii/Binary file output
-        const IOstream::streamFormat format_;
-
-        //- The ensight part id for the first patch
-        label patchPartOffset_;
-
-        cellSets meshCellSets_;
-
-        List<faceSets> boundaryFaceSets_;
-
-        wordList allPatchNames_;
-
-        wordHashSet patchNames_;
-
-        HashTable<nFacePrimitives> nPatchPrims_;
-
-        // faceZone - related variables
-        List<faceSets> faceZoneFaceSets_;
-
-        wordHashSet faceZoneNames_;
-
-        HashTable<nFacePrimitives> nFaceZonePrims_;
-
-        //- Per boundary face whether to include or not
-        PackedBoolList boundaryFaceToBeIncluded_;
-
-
-        // Parallel merged points
-
-            //- Global numbering for merged points
-            autoPtr<globalIndex> globalPointsPtr_;
-
-            //- From mesh point to global merged point
-            labelList pointToGlobal_;
-
-            //- Local points that are unique
-            labelList uniquePointMap_;
-
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        ensightMesh(const ensightMesh&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const ensightMesh&) = delete;
-
-        void writePoints
-        (
-            const scalarField& pointsComponent,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        cellShapeList map
-        (
-            const cellShapeList& cellShapes,
-            const labelList& prims,
-            const labelList& pointToGlobal
-        ) const;
-
-        cellShapeList map
-        (
-            const cellShapeList& cellShapes,
-            const labelList& hexes,
-            const labelList& wedges,
-            const labelList& pointToGlobal
-        ) const;
-
-        void writePrims
-        (
-            const cellShapeList& cellShapes,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writePolysNFaces
-        (
-            const labelList& polys,
-            const cellList& cellFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writePolysNPointsPerFace
-        (
-            const labelList& polys,
-            const cellList& cellFaces,
-            const faceList& faces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writePolysPoints
-        (
-            const labelList& polys,
-            const cellList& cellFaces,
-            const faceList& faces,
-            const labelList& faceOwner,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeAllPolys
-        (
-            const labelList& pointToGlobal,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeAllPrims
-        (
-            const char* key,
-            const label nPrims,
-            const cellShapeList& cellShapes,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeFacePrims
-        (
-            const faceList& patchFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeAllFacePrims
-        (
-            const char* key,
-            const labelList& prims,
-            const label nPrims,
-            const faceList& patchFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeNSidedNPointsPerFace
-        (
-            const faceList& patchFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeNSidedPoints
-        (
-            const faceList& patchFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeAllNSided
-        (
-            const labelList& prims,
-            const label nPrims,
-            const faceList& patchFaces,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-        void writeAllPoints
-        (
-            const label ensightPartI,
-            const word& ensightPartName,
-            const pointField& uniquePoints,
-            const label nPoints,
-            ensightStream& ensightGeometryFile
-        ) const;
-
-public:
-
-    // Constructors
-
-        //- Construct from fvMesh
-        ensightMesh
-        (
-            const fvMesh& mesh,
-            const bool noPatches,
-            const bool patches,
-            const wordReList& patchPatterns,
-            const bool faceZones,
-            const wordReList& faceZonePatterns,
-            const IOstream::streamFormat format = IOstream::BINARY
-        );
-
-
-    //- Destructor
-    ~ensightMesh();
-
-
-    // Member Functions
-
-        // Access
-
-            const fvMesh& mesh() const
-            {
-                return mesh_;
-            }
-
-            IOstream::streamFormat format() const
-            {
-                return format_;
-            }
-
-            const cellSets& meshCellSets() const
-            {
-                return meshCellSets_;
-            }
-
-            const List<faceSets>& boundaryFaceSets() const
-            {
-                return boundaryFaceSets_;
-            }
-
-            const wordList& allPatchNames() const
-            {
-                return allPatchNames_;
-            }
-
-            const wordHashSet& patchNames() const
-            {
-                return patchNames_;
-            }
-
-            const HashTable<nFacePrimitives>& nPatchPrims() const
-            {
-                return nPatchPrims_;
-            }
-
-            const List<faceSets>& faceZoneFaceSets() const
-            {
-                return faceZoneFaceSets_;
-            }
-
-            const wordHashSet& faceZoneNames() const
-            {
-                return faceZoneNames_;
-            }
-
-            const HashTable<nFacePrimitives>& nFaceZonePrims() const
-            {
-                return nFaceZonePrims_;
-            }
-
-            //- The ensight part id for the first patch
-            label patchPartOffset() const
-            {
-                return patchPartOffset_;
-            }
-
-
-        // Parallel point merging
-
-            //- Global numbering for merged points
-            const globalIndex& globalPoints() const
-            {
-                return globalPointsPtr_();
-            }
-
-            //- From mesh point to global merged point
-            const labelList& pointToGlobal() const
-            {
-                return pointToGlobal_;
-            }
-
-            //- Local points that are unique
-            const labelList& uniquePointMap() const
-            {
-                return uniquePointMap_;
-            }
-
-
-    // Other
-
-        //- Update for new mesh
-        void correct();
-
-        //- When exporting faceZones, check if a given face has to be included
-        //  or not (i.e. faces on processor boundaries)
-        bool faceToBeIncluded(const label facei) const;
-
-        //- Helper to cause barrier. Necessary on Quadrics.
-        static void barrier();
-
-
-    // I-O
-
-        void write
-        (
-            const fileName& ensightDir,
-            const label timeIndex,
-            const bool meshMoving,
-            Ostream& ensightCaseFile
-        ) const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.C
similarity index 79%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.C
rename to applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.C
index 08779ff0a8c4b7d7a34cfdf35a234b342c4b8503..a3ca62ee2221d2dfab204623f6a88a48aa056de4 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.C
@@ -23,8 +23,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "ensightCloud.H"
-#include "ensightFile.H"
+#include "ensightOutputCloud.H"
+
 #include "fvMesh.H"
 #include "passiveParticle.H"
 #include "Cloud.H"
@@ -32,30 +32,19 @@ License
 
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
-void Foam::ensightParticlePositions
+void Foam::ensightCloud::writePositions
 (
     const fvMesh& mesh,
-    const fileName& dataDir,
-    const label timeIndex,
     const word& cloudName,
-    const bool dataExists,
-    IOstream::streamFormat format
+    const bool exists,
+    autoPtr<ensightFile>& output
 )
 {
-    if (dataExists)
-    {
-        Info<< " positions";
-    }
-    else
-    {
-        Info<< " positions{0}";
-    }
-
     // Total number of parcels on all processes
     label nTotParcels = 0;
     autoPtr<Cloud<passiveParticle>> cloudPtr;
 
-    if (dataExists)
+    if (exists)
     {
         cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
         nTotParcels = cloudPtr().size();
@@ -64,29 +53,15 @@ void Foam::ensightParticlePositions
 
     if (Pstream::master())
     {
-        const fileName postFileName =
-            ensightFile::subDir(timeIndex)/cloud::prefix/cloudName/"positions";
-
-        // the ITER/lagrangian subdirectory must exist
-        mkDir(dataDir/postFileName.path());
-
-        ensightFile os(dataDir, postFileName, format);
-
-        // tag binary format (just like geometry files)
-        os.writeBinaryHeader();
-        os.write(postFileName); // description
-        os.newline();
-        os.write("particle coordinates");
-        os.newline();
-        os.write(nTotParcels, 8);   // unusual width
-        os.newline();
+        ensightFile& os = output();
 
+        os.beginParticleCoordinates(nTotParcels);
         if (!nTotParcels)
         {
             return;  // DONE
         }
 
-        if (format == IOstream::BINARY)
+        if (os.format() == IOstream::BINARY)
         {
             // binary write is Ensight6 - first ids, then positions
 
@@ -131,7 +106,7 @@ void Foam::ensightParticlePositions
             {
                 const point& p = elmnt().position();
 
-                os.write(++parcelId, 8);    // unusual width
+                os.write(++parcelId, 8); // unusual width
                 os.write(p.x());
                 os.write(p.y());
                 os.write(p.z());
@@ -148,7 +123,7 @@ void Foam::ensightParticlePositions
                 {
                     const point& p = points[pti];
 
-                    os.write(++parcelId, 8);    // unusual width
+                    os.write(++parcelId, 8); // unusual width
                     os.write(p.x());
                     os.write(p.y());
                     os.write(p.z());
@@ -171,10 +146,11 @@ void Foam::ensightParticlePositions
 
         {
             OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< points;
+            toMaster
+                << points;
         }
     }
-
 }
 
+
 // ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.H
similarity index 59%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.H
rename to applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.H
index 0b02a997e659c32b5b9d14d16b996c3e8bad1d78..982790b2f64e21a3385ef438187c1c309a854b7e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloud.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -21,78 +21,73 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
+Namespace
+    ensightOutput
+
 Description
-    Miscellaneous collection of functions and template related to Ensight data
+    A collection of global functions for writing ensight file content.
 
 SourceFiles
-    ensightOutputFunctions.C
+    ensightOutputCloud.C
+    ensightOutputCloudTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef ensightOutputFunctions_H
-#define ensightOutputFunctions_H
+#ifndef ensightOutputCloud_H
+#define ensightOutputCloud_H
 
 #include "ensightFile.H"
-#include "Cloud.H"
-#include "polyMesh.H"
-#include "IOobject.H"
+#include "ensightMesh.H"
 
-namespace Foam
-{
+#include "autoPtr.H"
+#include "IOField.H"
+#include "volFields.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-void ensightCaseEntry
-(
-    OFstream& caseFile,
-    const string& ensightType,
-    const word& fieldName,
-    const fileName& dataMask,
-    const fileName& local=fileName::null,
-    const label cloudNo=-1,
-    const label timeSet=1
-);
 
+namespace Foam
+{
+namespace ensightCloud
+{
 
-void ensightParticlePositions
+//- Write cloud positions
+void writePositions
 (
-    const polyMesh& mesh,
-    const fileName& dataDir,
-    const fileName& subDir,
+    const fvMesh& mesh,
     const word& cloudName,
-    IOstream::streamFormat format
+    const bool exists,
+    autoPtr<ensightFile>& output
 );
 
 
-//- Write lagrangian parcels
+//- Write cloud field, returning true if the field is non-empty.
 template<class Type>
-void ensightLagrangianField
+bool writeCloudField
 (
-    const IOobject& fieldObject,
-    const fileName& dataDir,
-    const fileName& subDir,
-    const word& cloudName,
-    IOstream::streamFormat format
+    const IOField<Type>& field,
+    ensightFile& os
 );
 
-//- Write generalized field components
+
+//- Write cloud field from IOobject, always returning true.
 template<class Type>
-void ensightVolField
+bool writeCloudField
 (
-    const ensightParts& partsList,
     const IOobject& fieldObject,
-    const fvMesh& mesh,
-    const fileName& dataDir,
-    const fileName& subDir,
-    IOstream::streamFormat format
+    const bool exists,
+    autoPtr<ensightFile>& output
 );
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+} // namespace ensightCloud
 } // namespace Foam
 
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #ifdef NoRepository
-    #include "ensightOutputFunctions.C"
+    #include "ensightOutputCloudTemplates.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloudTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloudTemplates.C
similarity index 62%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloudTemplates.C
rename to applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloudTemplates.C
index ac2559f17cfbb66b78a53c52e2a405c6daee4b1e..1b2c006c62381a42dcf61811135e1e219481f750 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloudTemplates.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightOutputCloudTemplates.C
@@ -23,24 +23,26 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "ensightCloud.H"
-#include "ensightFile.H"
-#include "Time.H"
-#include "IOField.H"
-#include "OFstream.H"
-#include "IOmanip.H"
+#include "ensightOutputCloud.H"
 #include "ensightPTraits.H"
 
+#include "IOField.H"
+#include "Time.H"
+#include "globalIndex.H"
+
+
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::writeCloudField
+bool Foam::ensightCloud::writeCloudField
 (
     const Foam::IOField<Type>& field,
     Foam::ensightFile& os
 )
 {
-    if (returnReduce(field.size(), sumOp<label>()) > 0)
+    const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0);
+
+    if (exists)
     {
         if (Pstream::master())
         {
@@ -106,86 +108,30 @@ void Foam::writeCloudField
         else
         {
             OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
-            toMaster<< field;
+            toMaster
+                << field;
         }
     }
+
+    return exists;
 }
 
 
 template<class Type>
-void Foam::ensightCloudField
+bool Foam::ensightCloud::writeCloudField
 (
     const Foam::IOobject& fieldObject,
-    const Foam::fileName& dataDir,
-    const Foam::label timeIndex,
-    const Foam::word& cloudName,
-    const Foam::label cloudNo,
-    Foam::Ostream& ensightCaseFile,
-    const bool dataExists,
-    Foam::IOstream::streamFormat format
+    const bool exists,
+    Foam::autoPtr<Foam::ensightFile>& output
 )
 {
-    const ensight::VarName varName(fieldObject.name());
-
-    if (dataExists)
-    {
-        Info<< ' ' << fieldObject.name();
-    }
-    else
-    {
-        Info<< ' ' << fieldObject.name() << "{0}"; // ie, empty field
-    }
-
-    ensightFile* filePtr(nullptr);
-    if (Pstream::master())
-    {
-        const fileName postFileName =
-            ensightFile::subDir(timeIndex)/cloud::prefix/cloudName/varName;
-
-        // the ITER/lagrangian subdirectory must exist
-        // the ITER/lagrangian subdirectory was already created
-        // when writing positions
-
-        mkDir(dataDir/postFileName.path());
-
-        if (timeIndex == 0)
-        {
-            const fileName dirName =
-                dataDir.name()/ensightFile::mask()/cloud::prefix/cloudName;
-
-            ensightCaseFile.setf(ios_base::left);
-
-            // prefix variables with 'c' (cloud)
-            ensightCaseFile
-                << ensightPTraits<Type>::typeName << " per "
-                << setw(20)
-                << "measured node:"
-                << " 1  "
-                << setw(15)
-                << ("c" + Foam::name(cloudNo) + varName).c_str() << ' '
-                << (dirName/varName).c_str()
-                << nl;
-        }
-
-        filePtr = new ensightFile(dataDir, postFileName, format);
-        // description
-        filePtr->write
-        (
-            string(postFileName + " <" + pTraits<Type>::typeName + ">")
-        );
-        filePtr->newline();
-    }
-
-    if (dataExists)
+    if (exists)
     {
         IOField<Type> field(fieldObject);
-        writeCloudField(field, *filePtr);
+        writeCloudField(field, output.rawRef());
     }
 
-    if (filePtr) // on master only
-    {
-        delete filePtr;
-    }
+    return true;
 }
 
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H
index 0f228f723fe1b355c109ba7220a2f64b07df9f27..a37bbb7c09b96c4e778ad4f403155b1f71befc3c 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H
@@ -50,7 +50,7 @@ if (timeDirs.size() && !noLagrangian)
 
                 forAllConstIter(IOobjectList, cloudObjs, fieldIter)
                 {
-                    const IOobject obj = *fieldIter();
+                    const IOobject& obj = *fieldIter();
 
                     // Add field and field type
                     cloudIter().insert
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
index 654b14b868db0250eeec0cc6268c6365b5a5698b..5080d840ebc1e3da0ab29f58a411f2c9a43da133 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
@@ -61,6 +61,9 @@ Usage
       - \par -width \<n\>
         Width of EnSight data subdir (default: 8)
 
+      - \par -deprecatedOrder
+        Use older ordering for volume cells (hex prism pyr tet poly)
+
 Note
     Writes to \a EnSight directory to avoid collisions with
     foamToEnsightParts
@@ -73,20 +76,22 @@ Note
 #include "IOmanip.H"
 #include "OFstream.H"
 
+#include "fvc.H"
 #include "volFields.H"
 
 #include "labelIOField.H"
 #include "scalarIOField.H"
 #include "tensorIOField.H"
 
-#include "ensightFile.H"
+// file-format/conversion
+#include "ensightCase.H"
+#include "ensightGeoFile.H"
 #include "ensightMesh.H"
-#include "ensightField.H"
-#include "ensightCloud.H"
+#include "ensightOutput.H"
 
-#include "fvc.H"
-#include "cellSet.H"
-#include "fvMeshSubset.H"
+// local files
+#include "meshSubsetHelper.H"
+#include "ensightOutputCloud.H"
 
 #include "memInfo.H"
 
@@ -94,7 +99,12 @@ using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-bool inFileNameList(const fileNameList& nameList, const word& name)
+// file-scope helper
+static bool inFileNameList
+(
+    const fileNameList& nameList,
+    const word& name
+)
 {
     forAll(nameList, i)
     {
@@ -171,10 +181,16 @@ int main(int argc, char *argv[])
         "n",
         "width of ensight data subdir"
     );
+    argList::addBoolOption
+    (
+        "deprecatedOrder",
+        "Use old ordering (hex prism pyr tet poly) "
+        "instead of the ascending number of points "
+        "(tet pyr prism hex poly)."
+    );
 
-    // the volume field types that we handle
-    const label nVolFieldTypes = 10;
-    const word volFieldTypes[] =
+    // The volume field types that we handle
+    const wordList volFieldTypes
     {
         volScalarField::typeName,
         volVectorField::typeName,
@@ -203,180 +219,113 @@ int main(int argc, char *argv[])
 
     cpuTime timer;
     memInfo mem;
-    Info<< "Initial memory "
-        << mem.update().size() << " kB" << endl;
+    Info<< "Initial memory " << mem.update().size() << " kB" << endl;
 
     #include "createTime.H"
 
     instantList timeDirs = timeSelector::select0(runTime, args);
 
-    // adjust output width
-    if (args.optionFound("width"))
-    {
-        ensightFile::subDirWidth(args.optionRead<label>("width"));
-    }
-
-    // define sub-directory name to use for EnSight data
-    fileName ensightDir = "EnSight";
-    args.optionReadIfPresent("name", ensightDir);
-
-    // Path to EnSight directory at case level only
-    // - For parallel cases, data only written from master
-    if (!ensightDir.isAbsolute())
-    {
-        ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
-    }
-
-    const fileName dataDir  = ensightDir/"data";
-    const fileName dataMask = dataDir.name()/ensightFile::mask();
-
-    if (Pstream::master())
-    {
-        // EnSight and EnSight/data directories must exist
-        // - remove old data for a clean conversion of everything
-        if (isDir(ensightDir))
-        {
-            rmDir(ensightDir);
-        }
-
-        mkDir(dataDir);
-    }
-
     #include "createNamedMesh.H"
 
-    // Mesh instance (region0 gets filtered out)
-    fileName regionPrefix;
+    fileName regionPrefix; // Mesh instance (region0 gets filtered out)
     if (regionName != polyMesh::defaultRegion)
     {
         regionPrefix = regionName;
     }
 
-    // Start of case file header output
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    OFstream *ensightCaseFilePtr(nullptr);
-    if (Pstream::master())
-    {
-        fileName caseFileName = args.globalCaseName() + ".case";
+    //
+    // general (case) output options
+    //
+    ensightCase::options caseOpts(format);
 
-        Info<< "Converting " << timeDirs.size() << " time steps" << nl
-            << "Ensight case: " << caseFileName.c_str() << endl;
+    caseOpts.nodeValues(args.optionFound("nodeValues"));
+    caseOpts.width(args.optionLookupOrDefault<label>("width", 8));
+    caseOpts.overwrite(true); // remove existing output directory
 
-        // The case file is always ASCII
-        ensightCaseFilePtr = new OFstream
-        (
-            ensightDir/caseFileName,
-            IOstream::ASCII
-        );
+    // Can also have separate directory for lagrangian
+    // caseOpts.separateCloud(true);
 
-        ensightCaseFilePtr->setf(ios_base::left);
-        ensightCaseFilePtr->setf(ios_base::scientific, ios_base::floatfield);
-        ensightCaseFilePtr->precision(5);
 
-        *ensightCaseFilePtr
-            << "FORMAT" << nl
-            << "type: ensight gold" << nl << nl;
+    // Define sub-directory name to use for EnSight data.
+    // The path to the ensight directory is at case level only
+    // - For parallel cases, data only written from master
+    fileName ensightDir = args.optionLookupOrDefault<word>("name", "EnSight");
+    if (!ensightDir.isAbsolute())
+    {
+        ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
     }
 
-    OFstream& ensightCaseFile = *ensightCaseFilePtr;
 
-    // Construct the EnSight mesh
-    const bool selectedPatches = args.optionFound("patches");
-    wordReList patchPatterns;
-    if (selectedPatches)
+    //
+    // output configuration (geometry related)
+    //
+    ensightMesh::options writeOpts(format);
+    writeOpts.noPatches(args.optionFound("noPatches"));
+    writeOpts.deprecatedOrder(args.optionFound("deprecatedOrder"));
+
+    if (args.optionFound("patches"))
     {
-        patchPatterns = wordReList(args.optionLookup("patches")());
+        writeOpts.patchSelection(args.optionReadList<wordRe>("patches"));
     }
-    const bool selectedZones = args.optionFound("faceZones");
-    wordReList zonePatterns;
-    if (selectedZones)
+    if (args.optionFound("faceZones"))
     {
-        zonePatterns = wordReList(args.optionLookup("faceZones")());
+        writeOpts.faceZoneSelection(args.optionReadList<wordRe>("faceZones"));
     }
 
-    const bool selectedFields = args.optionFound("fields");
+    //
+    // output configuration (field related)
+    //
+    const bool noLagrangian = args.optionFound("noLagrangian");
+
     wordReList fieldPatterns;
-    if (selectedFields)
+    if (args.optionFound("fields"))
     {
-        fieldPatterns = wordReList(args.optionLookup("fields")());
+        fieldPatterns = args.optionReadList<wordRe>("fields");
     }
 
-    const bool noLagrangian = args.optionFound("noLagrangian");
-
     word cellZoneName;
-    const bool doCellZone = args.optionReadIfPresent("cellZone", cellZoneName);
-
-    fvMeshSubset meshSubsetter(mesh);
-    if (doCellZone)
+    if (args.optionReadIfPresent("cellZone", cellZoneName))
     {
         Info<< "Converting cellZone " << cellZoneName
             << " only (puts outside faces into patch "
-            << mesh.boundaryMesh()[0].name()
-            << ")" << endl;
-        const cellZone& cz = mesh.cellZones()[cellZoneName];
-        cellSet c0(mesh, "c0", labelHashSet(cz));
-        meshSubsetter.setLargeCellSubset(c0, 0);
+            << mesh.boundaryMesh()[0].name() << ")"
+            << endl;
     }
+    meshSubsetHelper myMesh(mesh, meshSubsetHelper::ZONE, cellZoneName);
 
-    ensightMesh eMesh
+    //
+    // Open new ensight case file, initialize header etc.
+    //
+    ensightCase ensCase
     (
-        (
-            meshSubsetter.hasSubMesh()
-          ? meshSubsetter.subMesh()
-          : meshSubsetter.baseMesh()
-        ),
-        args.optionFound("noPatches"),
-        selectedPatches,
-        patchPatterns,
-        selectedZones,
-        zonePatterns,
-        format
+        ensightDir,
+        args.globalCaseName(),
+        caseOpts
     );
 
-    // Set Time to the last time before looking for the lagrangian objects
-    runTime.setTime(timeDirs.last(), timeDirs.size()-1);
 
-    IOobjectList objects(mesh, runTime.timeName());
-
-    #include "checkMeshMoving.H"
-    #include "findCloudFields.H"
+    // Construct the Ensight mesh
+    ensightMesh ensMesh(myMesh.mesh(), writeOpts);
 
     if (Pstream::master())
     {
-        // test the pre-check variable if there is a moving mesh
-        // time-set for geometries
-        // TODO: split off into separate time-set,
-        // but need to verify ensight spec
+        Info<< "Converting " << timeDirs.size() << " time steps" << nl;
+        ensCase.printInfo(Info) << endl;
+    }
 
-        if (meshMoving)
-        {
-            ensightCaseFile
-                << "GEOMETRY" << nl
-                << setw(16) << "model: 1"
-                << (dataMask/ensightMesh::geometryName).c_str() << nl;
-        }
-        else
-        {
-            ensightCaseFile
-                << "GEOMETRY" << nl
-                << setw(16) << "model:"
-                << ensightMesh::geometryName << nl;
-        }
 
+    // Set Time to the last time before looking for lagrangian objects
+    runTime.setTime(timeDirs.last(), timeDirs.size()-1);
 
-        // Add the name of the cloud(s) to the case file header
-        forAll(cloudNames, cloudNo)
-        {
-            const word& cloudName = cloudNames[cloudNo];
+    IOobjectList objects(mesh, runTime.timeName());
 
-            ensightCaseFile
-                << setw(16) << "measured: 1"
-                << fileName
-                (
-                    dataMask/cloud::prefix/cloudName/"positions"
-                ).c_str() << nl;
-        }
-    }
+    #include "checkMeshMoving.H"
+    #include "findCloudFields.H"
+
+    // test the pre-check variable if there is a moving mesh
+    // time-set for geometries
+    // TODO: split off into separate time-set,
+    // but need to verify ensight spec
 
     Info<< "Startup in "
         << timer.cpuTimeIncrement() << " s, "
@@ -387,63 +336,25 @@ int main(int argc, char *argv[])
     // ignore fields that are not available for all time-steps
     HashTable<bool> fieldsToUse;
 
-    label nTimeSteps = 0;
     forAll(timeDirs, timeIndex)
     {
-        ++nTimeSteps;
         runTime.setTime(timeDirs[timeIndex], timeIndex);
+        ensCase.nextTime(timeDirs[timeIndex]);
 
         Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
 
-        if (Pstream::master())
-        {
-            // the data/ITER subdirectory must exist
-            // Note that data/ITER is indeed a valid ensight::FileName
-            const fileName subDir = ensightFile::subDir(timeIndex);
-            mkDir(dataDir/subDir);
-
-            // place a timestamp in the directory for future reference
-            OFstream timeStamp(dataDir/subDir/"time");
-            timeStamp
-                << "#   timestep time" << nl
-                << subDir.c_str() << " " << runTime.timeName() << nl;
-        }
-
         polyMesh::readUpdateState meshState = mesh.readUpdate();
-        if (timeIndex != 0 && meshSubsetter.hasSubMesh())
-        {
-            Info<< "Converting cellZone " << cellZoneName
-                << " only (puts outside faces into patch "
-                << mesh.boundaryMesh()[0].name()
-                << ")" << endl;
-            const cellZone& cz = mesh.cellZones()[cellZoneName];
-            cellSet c0(mesh, "c0", labelHashSet(cz));
-            meshSubsetter.setLargeCellSubset(c0, 0);
-        }
-
         if (meshState != polyMesh::UNCHANGED)
         {
-            eMesh.correct();
+            myMesh.correct();
+            ensMesh.expire();
+            ensMesh.correct();
         }
 
         if (timeIndex == 0 || meshMoving)
         {
-            eMesh.write
-            (
-                dataDir,
-                timeIndex,
-                meshMoving,
-                ensightCaseFile
-            );
-        }
-
-
-        // Start of field data output
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        if (timeIndex == 0 && Pstream::master())
-        {
-            ensightCaseFile<< nl << "VARIABLE" << nl;
+            autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
+            ensMesh.write(os);
         }
 
 
@@ -451,22 +362,20 @@ int main(int argc, char *argv[])
         // ~~~~~~~~~~~~~~~~~~~~~~
         Info<< "Write volume field (";
 
-        for (label i=0; i<nVolFieldTypes; ++i)
+        forAll(volFieldTypes, typei)
         {
-            wordList fieldNames = objects.names(volFieldTypes[i]);
+            const word& fieldType = volFieldTypes[typei];
+            wordList fieldNames = objects.names(fieldType);
 
-            forAll(fieldNames, j)
+            // Filter on name as required
+            if (!fieldPatterns.empty())
             {
-                const word& fieldName = fieldNames[j];
+                inplaceSubsetStrings(fieldPatterns, fieldNames);
+            }
 
-                // Check if the field has to be exported
-                if (selectedFields)
-                {
-                    if (!findStrings(fieldPatterns, fieldName))
-                    {
-                        continue;
-                    }
-                }
+            forAll(fieldNames, fieldi)
+            {
+                const word& fieldName = fieldNames[fieldi];
 
                 #include "checkData.H"
 
@@ -484,151 +393,206 @@ int main(int argc, char *argv[])
                     IOobject::NO_WRITE
                 );
 
-                if (volFieldTypes[i] == volScalarField::typeName)
+                bool wrote = false;
+                if (fieldType == volScalarField::typeName)
                 {
+                    autoPtr<ensightFile> os = ensCase.newData<scalar>
+                    (
+                        fieldName
+                    );
+
                     volScalarField vf(fieldObject, mesh);
-                    ensightField<scalar>
+                    wrote = ensightOutput::writeField<scalar>
                     (
-                        volField(meshSubsetter, vf),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate(vf),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
-                else if (volFieldTypes[i] == volVectorField::typeName)
+                else if (fieldType == volVectorField::typeName)
                 {
+                    autoPtr<ensightFile> os = ensCase.newData<vector>
+                    (
+                        fieldName
+                    );
+
                     volVectorField vf(fieldObject, mesh);
-                    ensightField<vector>
+                    wrote = ensightOutput::writeField<vector>
                     (
-                        volField(meshSubsetter, vf),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate(vf),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
-                else if (volFieldTypes[i] == volSphericalTensorField::typeName)
+                else if (fieldType == volSphericalTensorField::typeName)
                 {
+                    autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
+                    (
+                        fieldObject.name()
+                    );
+
                     volSphericalTensorField vf(fieldObject, mesh);
-                    ensightField<sphericalTensor>
+                    wrote = ensightOutput::writeField<sphericalTensor>
                     (
-                        volField(meshSubsetter, vf),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate(vf),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
-                else if (volFieldTypes[i] == volSymmTensorField::typeName)
+                else if (fieldType == volSymmTensorField::typeName)
                 {
+                    autoPtr<ensightFile> os = ensCase.newData<symmTensor>
+                    (
+                        fieldName
+                    );
+
                     volSymmTensorField vf(fieldObject, mesh);
-                    ensightField<symmTensor>
+                    wrote = ensightOutput::writeField<symmTensor>
                     (
-                        volField(meshSubsetter, vf),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate(vf),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
-                else if (volFieldTypes[i] == volTensorField::typeName)
+                else if (fieldType == volTensorField::typeName)
                 {
+                    autoPtr<ensightFile> os = ensCase.newData<tensor>
+                    (
+                        fieldName
+                    );
+
                     volTensorField vf(fieldObject, mesh);
-                    ensightField<tensor>
+                    wrote = ensightOutput::writeField<tensor>
                     (
-                        volField(meshSubsetter, vf),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate(vf),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 // DimensionedFields
                 else if
                 (
-                    volFieldTypes[i] == volScalarField::Internal::typeName
+                    fieldType
+                 == volScalarField::Internal::typeName
                 )
                 {
-                    volScalarField::Internal df(fieldObject, mesh);
-                    ensightField<scalar>
+                    autoPtr<ensightFile> os = ensCase.newData<scalar>
+                    (
+                        fieldName
+                    );
+
+                    volScalarField::Internal df
+                    (
+                        fieldObject,
+                        mesh
+                    );
+                    wrote = ensightOutput::writeField<scalar>
                     (
-                        volField<scalar>(meshSubsetter, df),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate<scalar>(df),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 else if
                 (
-                    volFieldTypes[i] == volVectorField::Internal::typeName
+                    fieldType
+                 == volVectorField::Internal::typeName
                 )
                 {
-                    volVectorField::Internal df(fieldObject, mesh);
-                    ensightField<vector>
+                    autoPtr<ensightFile> os = ensCase.newData<vector>
+                    (
+                        fieldName
+                    );
+
+                    volVectorField::Internal df
                     (
-                        volField<vector>(meshSubsetter, df),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        fieldObject,
+                        mesh
+                    );
+                    wrote = ensightOutput::writeField<vector>
+                    (
+                        myMesh.interpolate<vector>(df),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 else if
                 (
-                    volFieldTypes[i]
+                    fieldType
                  == volSphericalTensorField::Internal::typeName
                 )
                 {
-                    volSphericalTensorField::Internal df(fieldObject, mesh);
-                    ensightField<sphericalTensor>
+                    autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
                     (
-                        volField<sphericalTensor>(meshSubsetter, df),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        fieldName
+                    );
+
+                    volSphericalTensorField::Internal df
+                    (
+                        fieldObject,
+                        mesh
+                    );
+                    wrote = ensightOutput::writeField<sphericalTensor>
+                    (
+                        myMesh.interpolate<sphericalTensor>(df),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 else if
                 (
-                    volFieldTypes[i] == volSymmTensorField::Internal::typeName
+                    fieldType
+                 == volSymmTensorField::Internal::typeName
                 )
                 {
-                    volSymmTensorField::Internal df(fieldObject, mesh);
-                    ensightField<symmTensor>
+                    autoPtr<ensightFile> os = ensCase.newData<symmTensor>
+                    (
+                        fieldName
+                    );
+
+                    volSymmTensorField::Internal df
+                    (
+                        fieldObject,
+                        mesh
+                    );
+                    wrote = ensightOutput::writeField<symmTensor>
                     (
-                        volField<symmTensor>(meshSubsetter, df),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate<symmTensor>(df),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 else if
                 (
-                    volFieldTypes[i] == volTensorField::Internal::typeName
+                    fieldType
+                 == volTensorField::Internal::typeName
                 )
                 {
-                    volTensorField::Internal df(fieldObject, mesh);
-                    ensightField<tensor>
+                    autoPtr<ensightFile> os = ensCase.newData<tensor>
+                    (
+                        fieldName
+                    );
+
+                    volTensorField::Internal df
+                    (
+                        fieldObject,
+                        mesh
+                    );
+                    wrote = ensightOutput::writeField<tensor>
                     (
-                        volField<tensor>(meshSubsetter, df),
-                        eMesh,
-                        dataDir,
-                        timeIndex,
-                        nodeValues,
-                        ensightCaseFile
+                        myMesh.interpolate<tensor>(df),
+                        ensMesh,
+                        os,
+                        nodeValues
                     );
                 }
                 else
@@ -636,6 +600,11 @@ int main(int argc, char *argv[])
                     // Do not currently handle this type - blacklist for the future.
                     fieldsToUse.set(fieldName, false);
                 }
+
+                if (wrote)
+                {
+                    Info<< ' ' << fieldName;
+                }
             }
         }
         Info<< " )" << nl;
@@ -660,15 +629,23 @@ int main(int argc, char *argv[])
             bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
             reduce(cloudExists, orOp<bool>());
 
-            ensightParticlePositions
-            (
-                mesh,
-                dataDir,
-                timeIndex,
-                cloudName,
-                cloudExists,
-                format
-            );
+            {
+                autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
+
+                ensightCloud::writePositions
+                (
+                    mesh,
+                    cloudName,
+                    cloudExists,
+                    os
+                );
+
+                Info<< " positions";
+                if (!cloudExists)
+                {
+                    Info<< "{0}"; // report empty field
+                }
+            }
 
             forAllConstIter(HashTable<word>, theseCloudFields, fieldIter)
             {
@@ -684,40 +661,46 @@ int main(int argc, char *argv[])
                     IOobject::MUST_READ
                 );
 
-                bool fieldExists = fieldObject.typeHeaderOk<IOField<scalar>>
-                (
-                    false
-                );
-                reduce(fieldExists, orOp<bool>());
+                // cannot have field without cloud positions
+                bool fieldExists = cloudExists;
+                if (cloudExists)
+                {
+                    fieldExists =
+                        fieldObject.typeHeaderOk<IOField<scalar>>(false);
 
+                    reduce(fieldExists, orOp<bool>());
+                }
+
+                bool wrote = false;
                 if (fieldType == scalarIOField::typeName)
                 {
-                    ensightCloudField<scalar>
+                    autoPtr<ensightFile> os =
+                        ensCase.newCloudData<scalar>(cloudName, fieldName);
+
+                    wrote = ensightCloud::writeCloudField<scalar>
                     (
-                        fieldObject,
-                        dataDir,
-                        timeIndex,
-                        cloudName,
-                        cloudNo,
-                        ensightCaseFile,
-                        fieldExists,
-                        format
+                        fieldObject, fieldExists, os
                     );
                 }
                 else if (fieldType == vectorIOField::typeName)
                 {
-                    ensightCloudField<vector>
+                    autoPtr<ensightFile> os =
+                        ensCase.newCloudData<vector>(cloudName, fieldName);
+
+                    wrote = ensightCloud::writeCloudField<vector>
                     (
-                        fieldObject,
-                        dataDir,
-                        timeIndex,
-                        cloudName,
-                        cloudNo,
-                        ensightCaseFile,
-                        fieldExists,
-                        format
+                        fieldObject, fieldExists, os
                     );
                 }
+
+                if (wrote)
+                {
+                    Info<< ' ' << fieldName;
+                    if (!fieldExists)
+                    {
+                        Info<< "{0}"; // report empty field
+                    }
+                }
             }
             Info<< " )" << nl;
         }
@@ -727,12 +710,7 @@ int main(int argc, char *argv[])
             << mem.update().size() << " kB" << nl << nl;
     }
 
-    #include "ensightCaseTail.H"
-
-    if (ensightCaseFilePtr) // on master only
-    {
-        delete ensightCaseFilePtr;
-    }
+    ensCase.write();
 
     Info<< "End: "
         << timer.elapsedCpuTime() << " s, "
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files
index 739c971551520b88f08aac2001229792eb1031c5..63e999847803d64d0d8c930e43a9a4afb09a50ef 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files
@@ -1,3 +1,4 @@
+ensightOutputSerialCloud.C
 foamToEnsightParts.C
 
 EXE = $(FOAM_APPBIN)/foamToEnsightParts
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkMeshMoving.H
similarity index 88%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H
rename to applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkMeshMoving.H
index 15a4756949b36336a3f211896b70939341bf3a87..51c7a11e7337648272c889c477630eea44bd44a4 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkMeshMoving.H
@@ -1,7 +1,7 @@
 // check for "points" in all of the result directories
 // - could restrict to the selected times
 
-bool hasMovingMesh = false;
+bool meshMoving = false;
 
 if (timeDirs.size() > 1 && Pstream::master())
 {
@@ -13,7 +13,7 @@ if (timeDirs.size() > 1 && Pstream::master())
     Info<< "Search for moving mesh ... " << flush;
     forAll(timeDirs, timeI)
     {
-        hasMovingMesh =
+        meshMoving =
         (
             isDir(baseDir/timeDirs[timeI].name()/polyMesh::meshSubDir)
          && IOobject
@@ -28,13 +28,13 @@ if (timeDirs.size() > 1 && Pstream::master())
             ).typeHeaderOk<pointIOField>(true)
         );
 
-        if (hasMovingMesh)
+        if (meshMoving)
         {
             break;
         }
     }
 
-    if (hasMovingMesh)
+    if (meshMoving)
     {
         Info<< "found." << nl
             << "    Writing meshes for every timestep." << endl;
@@ -45,4 +45,4 @@ if (timeDirs.size() > 1 && Pstream::master())
     }
 }
 
-reduce(hasMovingMesh, orOp<bool>());
+reduce(meshMoving, orOp<bool>());
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H
deleted file mode 100644
index b0c3af822bbffb892c76a7be0241f086bd4f219e..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H
+++ /dev/null
@@ -1,270 +0,0 @@
-// write time values to case file
-
-scalar timeCorrection = 0;
-if (timeDirs[0].value() < 0)
-{
-    timeCorrection = - timeDirs[0].value();
-    Info<< "Correcting time values. Adding " << timeCorrection << endl;
-}
-
-// the case file is always ASCII
-Info<< "write case: " << caseFileName.c_str() << endl;
-
-OFstream caseFile(ensightDir/caseFileName, IOstream::ASCII);
-caseFile.setf(ios_base::left);
-
-caseFile.setf(ios_base::scientific, ios_base::floatfield);
-caseFile.precision(5);
-
-caseFile
-    << "FORMAT" << nl
-    << setw(16) << "type:" << "ensight gold" << nl << nl;
-
-// time-set for geometries
-// TODO: split off into separate time-set, but need to verify ensight spec
-if (geometryTimesUsed.size())
-{
-    caseFile
-        << "GEOMETRY" << nl
-        << setw(16) << "model: 1" << (dataMask/geometryName).c_str() << nl;
-}
-else
-{
-    caseFile
-        << "GEOMETRY" << nl
-        << setw(16) << "model:" << geometryName << nl;
-}
-
-
-// add information for clouds
-// multiple clouds currently require the same time index
-forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
-{
-    const word& cloudName = cloudIter.key();
-
-    caseFile
-        << setw(16) << "measured: 2"
-        << fileName(dataMask/cloud::prefix/cloudName/"positions").c_str()
-        << nl;
-}
-caseFile
-    << nl << "VARIABLE" << nl;
-
-forAllConstIter(HashTable<word>, volumeFields, fieldIter)
-{
-    const word& fieldName = fieldIter.key();
-    const word& fieldType = fieldIter();
-    string ensightType;
-
-    if (fieldType == volScalarField::typeName)
-    {
-        ensightType = ensightPTraits<scalar>::typeName;
-    }
-    else if (fieldType == volVectorField::typeName)
-    {
-        ensightType = ensightPTraits<vector>::typeName;
-    }
-    else if (fieldType == volSphericalTensorField::typeName)
-    {
-        ensightType = ensightPTraits<sphericalTensor>::typeName;
-    }
-    else if (fieldType == volSymmTensorField::typeName)
-    {
-        ensightType = ensightPTraits<symmTensor>::typeName;
-    }
-    else if (fieldType == volTensorField::typeName)
-    {
-        ensightType = ensightPTraits<tensor>::typeName;
-    }
-    else
-    {
-        continue;
-    }
-
-    ensightCaseEntry
-    (
-        caseFile,
-        ensightType,
-        fieldName,
-        dataMask
-    );
-}
-
-
-// TODO: allow similar/different time-steps for each cloud
-label cloudNo = 0;
-forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
-{
-    const word& cloudName = cloudIter.key();
-
-    forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
-    {
-        const word& fieldName = fieldIter.key();
-        const word& fieldType = fieldIter();
-        string ensightType;
-
-        if (fieldType == scalarIOField::typeName)
-        {
-            ensightType = ensightPTraits<scalar>::typeName;
-        }
-        else if (fieldType == vectorIOField::typeName)
-        {
-            ensightType = ensightPTraits<vector>::typeName;
-        }
-        else if (fieldType == tensorIOField::typeName)
-        {
-            ensightType = ensightPTraits<tensor>::typeName;
-        }
-        else
-        {
-            continue;
-        }
-
-        ensightCaseEntry
-        (
-            caseFile,
-            ensightType,
-            fieldName,
-            dataMask,
-            cloud::prefix/cloudName,
-            cloudNo,
-            2
-        );
-    }
-    cloudNo++;
-}
-
-
-// add time values
-caseFile << nl << "TIME" << nl;
-
-// time set 1 - volume fields
-if (fieldTimesUsed.size())
-{
-    caseFile
-        << "time set:        " << 1 << nl
-        << "number of steps: " << fieldTimesUsed.size() << nl
-        << "filename numbers:" << nl;
-
-    label count = 0;
-    forAll(fieldTimesUsed, i)
-    {
-        caseFile
-            << " " << setw(12) << fieldTimesUsed[i];
-
-        if (++count % 6 == 0)
-        {
-            caseFile << nl;
-        }
-    }
-
-    caseFile
-        << nl << "time values:" << nl;
-
-    count = 0;
-    forAll(fieldTimesUsed, i)
-    {
-        const label index = fieldTimesUsed[i];
-        caseFile
-            << " " << setw(12) << timeIndices[index] + timeCorrection;
-
-        if (++count % 6 == 0)
-        {
-            caseFile << nl;
-        }
-    }
-    caseFile << nl << nl;
-}
-
-
-// time set 2 - geometry
-// THIS NEEDS MORE CHECKING
-#if 0
-if (geometryTimesUsed.size())
-{
-    caseFile
-        << "time set:        " << 2 << nl
-        << "number of steps: " << geometryTimesUsed.size() << nl
-        << "filename numbers:" << nl;
-
-    label count = 0;
-    forAll(geometryTimesUsed, i)
-    {
-        caseFile
-            << " " << setw(12) << geometryTimesUsed[i];
-
-        if (++count % 6 == 0)
-        {
-            caseFile << nl;
-        }
-    }
-
-    caseFile
-        << nl << "time values:" << nl;
-
-    count = 0;
-    forAll(geometryTimesUsed, i)
-    {
-        const label index = geometryTimesUsed[i];
-        caseFile
-            << " " << setw(12) << timeIndices[index] + timeCorrection;
-
-        if (++count % 6 == 0)
-        {
-            caseFile << nl;
-        }
-    }
-    caseFile << nl << nl;
-}
-#endif
-
-// time set - clouds
-// TODO: allow similar/different time-steps for each cloud
-cloudNo = 0;
-forAllConstIter(HashTable<DynamicList<label>>, cloudTimesUsed, cloudIter)
-{
-    // const word& cloudName = cloudIter.key();
-    const DynamicList<label>& timesUsed = cloudIter();
-
-    if (timesUsed.size() && cloudNo == 0)
-    {
-        caseFile
-            << "time set:        " << 2 << nl
-            << "number of steps: " << timesUsed.size() << nl
-            << "filename numbers:" << nl;
-
-        label count = 0;
-        forAll(timesUsed, i)
-        {
-            caseFile
-                << " " << setw(12) << timesUsed[i];
-
-            if (++count % 6 == 0)
-            {
-                caseFile << nl;
-            }
-        }
-
-        caseFile
-            << nl << "time values:" << nl;
-
-        count = 0;
-        forAll(timesUsed, i)
-        {
-            const label index = timesUsed[i];
-            caseFile
-                << " " << setw(12) << timeIndices[index] + timeCorrection;
-
-            if (++count % 6 == 0)
-            {
-                caseFile << nl;
-            }
-        }
-        caseFile << nl << nl;
-
-        cloudNo++;
-    }
-}
-
-caseFile << "# end" << nl;
-
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C
deleted file mode 100644
index 148aa4014532744730f5f2c5e279c8f4609f3c51..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C
+++ /dev/null
@@ -1,245 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 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 "ensightOutputFunctions.H"
-#include "ensightPTraits.H"
-
-#include "passiveParticle.H"
-#include "IOField.H"
-#include "volFields.H"
-#include "surfaceFields.H"
-
-#include "OFstream.H"
-#include "IOmanip.H"
-
-
-// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
-
-void Foam::ensightCaseEntry
-(
-    OFstream& caseFile,
-    const string& ensightType,
-    const word& fieldName,
-    const fileName& dataMask,
-    const fileName& local,
-    const label cloudNo,
-    const label timeSet
-)
-{
-    const ensight::VarName varName(fieldName);
-
-    caseFile.setf(ios_base::left);
-
-    fileName dirName(dataMask);
-    if (local.size())
-    {
-        dirName = dirName/local;
-    }
-
-    if (cloudNo >= 0)
-    {
-        label ts = 1;
-        if (timeSet > ts)
-        {
-            ts = timeSet;
-        }
-
-        // prefix variables with 'c' (cloud)
-        caseFile
-            << ensightType.c_str()
-            << " per measured node: " << ts << " "
-            << setw(15)
-            << ("c" + Foam::name(cloudNo) + varName).c_str()
-            << " "
-            << (dirName/varName).c_str()
-            << nl;
-    }
-    else
-    {
-        caseFile
-            << ensightType.c_str()
-            << " per element: "
-            << setw(15) << varName
-            << " "
-            << (dirName/varName).c_str()
-            << nl;
-    }
-}
-
-
-void Foam::ensightParticlePositions
-(
-    const polyMesh& mesh,
-    const fileName& dataDir,
-    const fileName& subDir,
-    const word& cloudName,
-    IOstream::streamFormat format
-)
-{
-    Cloud<passiveParticle> parcels(mesh, cloudName, false);
-
-    const fileName postFileName =
-        subDir/cloud::prefix/cloudName/"positions";
-
-    // the ITER/lagrangian subdirectory must exist
-    mkDir(dataDir/postFileName.path());
-    ensightFile os(dataDir, postFileName, format);
-
-    // tag binary format (just like geometry files)
-    os.writeBinaryHeader();
-    os.write(postFileName); // description
-    os.newline();
-    os.write("particle coordinates");
-    os.newline();
-    os.write(parcels.size(), 8);   // unusual width
-    os.newline();
-
-    // binary write is Ensight6 - first ids, then positions
-    if (format == IOstream::BINARY)
-    {
-        forAll(parcels, i)
-        {
-            os.write(i+1);
-        }
-
-        forAllConstIter(Cloud<passiveParticle>, parcels, elmnt)
-        {
-            const vector& p = elmnt().position();
-
-            os.write(p.x());
-            os.write(p.y());
-            os.write(p.z());
-        }
-    }
-    else
-    {
-        label nParcels = 0;
-
-        forAllConstIter(Cloud<passiveParticle>, parcels, elmnt)
-        {
-            const vector& p = elmnt().position();
-
-            os.write(++nParcels, 8);    // unusual width
-            os.write(p.x());
-            os.write(p.y());
-            os.write(p.z());
-            os.newline();
-        }
-    }
-}
-
-
-
-template<class Type>
-void Foam::ensightLagrangianField
-(
-    const IOobject& fieldObject,
-    const fileName& dataDir,
-    const fileName& subDir,
-    const word& cloudName,
-    IOstream::streamFormat format
-)
-{
-    Info<< " " << fieldObject.name() << flush;
-
-    const fileName postFileName =
-        subDir/cloud::prefix/cloudName
-        /ensight::VarName(fieldObject.name());
-
-    // the ITER/lagrangian subdirectory was already created
-    // when writing positions
-
-    ensightFile os(dataDir, postFileName, format);
-    // description
-    os.write(string(postFileName + " <" + pTraits<Type>::typeName + ">"));
-    os.newline();
-
-    IOField<Type> field(fieldObject);
-
-    // 6 values per line
-    label count = 0;
-
-    forAll(field, i)
-    {
-        Type val = field[i];
-
-        if (mag(val) < 1e-90)
-        {
-            val = Zero;
-        }
-
-        for (direction d=0; d < pTraits<Type>::nComponents; ++d)
-        {
-            label cmpt = ensightPTraits<Type>::componentOrder[d];
-            os.write(component(val, cmpt));
-
-            if (++count % 6 == 0)
-            {
-                os.newline();
-            }
-        }
-    }
-
-    // add final newline if required
-    if (count % 6)
-    {
-        os.newline();
-    }
-}
-
-
-template<class Type>
-void Foam::ensightVolField
-(
-    const ensightParts& partsList,
-    const IOobject& fieldObject,
-    const fvMesh& mesh,
-    const fileName& dataDir,
-    const fileName& subDir,
-    IOstream::streamFormat format
-)
-{
-    Info<< " " << fieldObject.name() << flush;
-
-    const fileName postFileName = subDir/ensight::VarName(fieldObject.name());
-
-    ensightFile os(dataDir, postFileName, format);
-    os.write(postFileName); // description
-    os.newline();
-
-    // ie, volField<Type>
-    partsList.writeField
-    (
-        os,
-        GeometricField<Type, fvPatchField, volMesh>
-        (
-            fieldObject,
-            mesh
-        )
-    );
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.C
new file mode 100644
index 0000000000000000000000000000000000000000..5cc4a45f5cb312a62badd5b467d8720acecbbcc0
--- /dev/null
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.C
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "ensightOutputSerialCloud.H"
+#include "ensightPTraits.H"
+
+#include "passiveParticle.H"
+#include "IOField.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
+// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
+
+void Foam::ensightSerialCloud::writePositions
+(
+    const polyMesh& mesh,
+    const word& cloudName,
+    autoPtr<ensightFile> output
+)
+{
+    label nTotParcels = 0;
+    autoPtr<Cloud<passiveParticle>> cloudPtr;
+
+    cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
+    nTotParcels = cloudPtr().size();
+
+    Cloud<passiveParticle> parcels(mesh, cloudName, false);
+
+    if (Pstream::master())
+    {
+        ensightFile& os = output();
+        os.beginParticleCoordinates(nTotParcels);
+
+        // binary write is Ensight6 - first ids, then positions
+        if (os.format() == IOstream::BINARY)
+        {
+            // 1-index
+            for (label parcelId = 0; parcelId < nTotParcels; ++parcelId)
+            {
+                os.write(parcelId+1);
+            }
+
+
+            forAllConstIter(Cloud<passiveParticle>, cloudPtr(), elmnt)
+            {
+                const vector& p = elmnt().position();
+
+                os.write(p.x());
+                os.write(p.y());
+                os.write(p.z());
+            }
+        }
+        else
+        {
+            // ASCII id + position together
+
+            label parcelId = 0;
+            forAllConstIter(Cloud<passiveParticle>, cloudPtr(), elmnt)
+            {
+                const vector& p = elmnt().position();
+
+                os.write(++parcelId, 8); // unusual width
+                os.write(p.x());
+                os.write(p.y());
+                os.write(p.z());
+                os.newline();
+            }
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.H
similarity index 75%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.H
rename to applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.H
index 14661506622e2919f1140bc2f1b6ed588c61c73d..ff7608be5c5c4781a6076e72d6a66515ce2f36fa 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightCloud.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloud.H
@@ -21,68 +21,65 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-InApplication
-    foamToEnsight
-
 Description
+    Miscellaneous collection of functions and template related to Ensight data
 
 SourceFiles
-    ensightCloud.C
-    ensightCloudTemplates.C
+    ensightOutputFunctions.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef ensightCloud_H
-#define ensightCloud_H
+#ifndef ensightOutputSerialCloud_H
+#define ensightOutputSerialCloud_H
 
 #include "ensightFile.H"
-#include "fvMesh.H"
 #include "Cloud.H"
+#include "polyMesh.H"
 #include "IOobject.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+
 namespace Foam
 {
+namespace ensightSerialCloud
+{
 
-void ensightParticlePositions
+//- Write cloud positions
+void writePositions
 (
-    const fvMesh& mesh,
-    const fileName& dataDir,
-    const label timeIndex,
+    const polyMesh& mesh,
     const word& cloudName,
-    const bool dataExists,
-    const IOstream::streamFormat format
+    autoPtr<ensightFile> output
 );
 
 
+//- Write cloud field
 template<class Type>
-void ensightCloudField
+bool writeCloudField
 (
-    const IOobject& fieldObject,
-    const fileName& dataDir,
-    const label timeIndex,
-    const word& cloudName,
-    const label cloudNo,
-    Ostream& ensightCaseFile,
-    const bool dataExists,
-    const IOstream::streamFormat format
+    const IOField<Type>& field,
+    ensightFile& os
 );
 
 
+//- Write cloud field
 template<class Type>
-void writeCloudField
+bool writeCloudField
 (
-    const IOField<Type>& field,
-    ensightFile& os
+    const IOobject& fieldObject,
+    autoPtr<ensightFile> output
 );
 
-}
+
+} // namespace ensightSerialCloud
+} // namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+
 #ifdef NoRepository
-    #include "ensightCloudTemplates.C"
+    #include "ensightOutputSerialCloudTemplates.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/conversion/ensight/part/ensightPartTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloudTemplates.C
similarity index 54%
rename from src/conversion/ensight/part/ensightPartTemplates.C
rename to applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloudTemplates.C
index 13186460402ed81739c7856b4af8120470fb3385..42034d0a1e8420ff989702f5b549e68fffbad114 100644
--- a/src/conversion/ensight/part/ensightPartTemplates.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputSerialCloudTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
      \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
@@ -21,56 +21,69 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Description
-    Template to write generalized field components
-
 \*---------------------------------------------------------------------------*/
 
-#include "ensightPart.H"
+#include "ensightOutputSerialCloud.H"
+#include "ensightSerialOutput.H"
 #include "ensightPTraits.H"
 
+#include "passiveParticle.H"
+#include "IOField.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::ensightPart::writeField
+bool Foam::ensightSerialCloud::writeCloudField
 (
-    ensightFile& os,
-    const Field<Type>& field,
-    const bool perNode
-) const
+    const IOField<Type>& field,
+    ensightFile& os
+)
 {
-    if (this->size() && field.size())
+    // 6 values per line
+    label count = 0;
+
+    forAll(field, i)
     {
-        writeHeader(os);
+        Type val = field[i];
 
-        if (perNode)
+        if (mag(val) < 1e-90)
         {
-            os.writeKeyword("coordinates");
-            for (direction d=0; d < pTraits<Type>::nComponents; ++d)
-            {
-                label cmpt = ensightPTraits<Type>::componentOrder[d];
-                writeFieldList(os, field.component(cmpt), labelUList::null());
-            }
+            val = Zero;
         }
-        else
+
+        for (direction d=0; d < pTraits<Type>::nComponents; ++d)
         {
-            forAll(elementTypes(), elemI)
+            label cmpt = ensightPTraits<Type>::componentOrder[d];
+            os.write(component(val, cmpt));
+
+            if (++count % 6 == 0)
             {
-                const labelUList& idList = elemLists_[elemI];
-
-                if (idList.size())
-                {
-                    os.writeKeyword(elementTypes()[elemI]);
-
-                    for (direction d=0; d < pTraits<Type>::nComponents; ++d)
-                    {
-                        label cmpt = ensightPTraits<Type>::componentOrder[d];
-                        writeFieldList(os, field.component(cmpt), idList);
-                    }
-                }
+                os.newline();
             }
         }
     }
+
+    // add final newline if required
+    if (count % 6)
+    {
+        os.newline();
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightSerialCloud::writeCloudField
+(
+    const IOobject& fieldObject,
+    autoPtr<ensightFile> output
+)
+{
+    IOField<Type> field(fieldObject);
+    return writeCloudField(field, output.rawRef());
 }
 
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
index 8c0bfb376a0f8879fd7c46fa1e3e5c0c3558ab43..ab2e67e855e76b05d0753575cb18d612c93dee74 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
@@ -78,8 +78,14 @@ Note
 #include "scalarIOField.H"
 #include "tensorIOField.H"
 
+// file-format/conversion
+#include "ensightCase.H"
+#include "ensightGeoFile.H"
 #include "ensightParts.H"
-#include "ensightOutputFunctions.H"
+#include "ensightSerialOutput.H"
+
+// local files
+#include "ensightOutputSerialCloud.H"
 
 #include "memInfo.H"
 
@@ -133,33 +139,25 @@ int main(int argc, char *argv[])
     );
 
     // The volume field types that we handle
-    wordHashSet volFieldTypes;
-    volFieldTypes.insert(volScalarField::typeName);
-    volFieldTypes.insert(volVectorField::typeName);
-    volFieldTypes.insert(volSphericalTensorField::typeName);
-    volFieldTypes.insert(volSymmTensorField::typeName);
-    volFieldTypes.insert(volTensorField::typeName);
+    const wordHashSet volFieldTypes
+    {
+        volScalarField::typeName,
+        volVectorField::typeName,
+        volSphericalTensorField::typeName,
+        volSymmTensorField::typeName,
+        volTensorField::typeName
+    };
 
     // The lagrangian field types that we handle
-    wordHashSet cloudFieldTypes;
-    cloudFieldTypes.insert(scalarIOField::typeName);
-    cloudFieldTypes.insert(vectorIOField::typeName);
-    cloudFieldTypes.insert(tensorIOField::typeName);
-
-    const char* geometryName = "geometry";
+    const wordHashSet cloudFieldTypes
+    {
+        scalarIOField::typeName,
+        vectorIOField::typeName,
+        tensorIOField::typeName
+    };
 
     #include "setRootCase.H"
 
-    cpuTime timer;
-    memInfo mem;
-    Info<< "Initial memory "
-        << mem.update().size() << " kB" << endl;
-
-    #include "createTime.H"
-
-    // Get times list
-    instantList timeDirs = timeSelector::select0(runTime, args);
-
     // Default to binary output, unless otherwise specified
     const IOstream::streamFormat format =
     (
@@ -168,101 +166,91 @@ int main(int argc, char *argv[])
       : IOstream::BINARY
     );
 
-    // Control for renumbering iterations
-    label indexingNumber = 0;
-    const bool optIndex = args.optionReadIfPresent("index", indexingNumber);
-    const bool noLagrangian = args.optionFound("noLagrangian");
+    cpuTime timer;
+    memInfo mem;
+    Info<< "Initial memory " << mem.update().size() << " kB" << endl;
 
-    // Always write the geometry, unless the -noMesh option is specified
-    bool optNoMesh = args.optionFound("noMesh");
+    #include "createTime.H"
+
+    instantList timeDirs = timeSelector::select0(runTime, args);
+
+    #include "createNamedMesh.H"
 
-    // Adjust output width
-    if (args.optionFound("width"))
+    fileName regionPrefix; // Mesh instance (region0 gets filtered out)
+    if (regionName != polyMesh::defaultRegion)
     {
-        ensightFile::subDirWidth(args.optionRead<label>("width"));
+        regionPrefix = regionName;
     }
 
-    // Define sub-directory name to use for Ensight data
-    fileName ensightDir = "Ensight";
-    args.optionReadIfPresent("name", ensightDir);
+    //
+    // general (case) output options
+    //
+    ensightCase::options caseOpts(format);
 
+    caseOpts.width(args.optionLookupOrDefault<label>("width", 8));
+    caseOpts.overwrite(false); // leave existing output directory
+
+    // Can also have separate directory for lagrangian
+    // caseOpts.separateCloud(true);
+
+    // Define sub-directory name to use for EnSight data.
+    // The path to the ensight directory is at case level only
+    // - For parallel cases, data only written from master
+    fileName ensightDir = args.optionLookupOrDefault<word>("name", "Ensight");
     if (!ensightDir.isAbsolute())
     {
         ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
     }
 
-    const fileName caseFileName = "Ensight.case";
-    const fileName dataDir  = ensightDir/"data";
-    const fileName dataMask = dataDir.name()/ensightFile::mask();
+    //
+    // Open new ensight case file, initialize header etc.
+    //
+    ensightCase ensCase
+    (
+        ensightDir,
+        "Ensight",  // args.globalCaseName(),
+        caseOpts
+    );
 
-    // Ensight and Ensight/data directories must exist
-    // do not remove old data - we might wish to convert new results
-    // or a particular time interval
-    if (isDir(ensightDir))
-    {
-        Info<<"Warning: re-using existing directory" << nl
-            << "    " << ensightDir << endl;
-    }
 
-    // As per mkdir -p "Ensight/data"
-    mkDir(ensightDir);
-    mkDir(dataDir);
+    //
+    // Miscellaneous output configuration
+    //
 
-    #include "createNamedMesh.H"
+    // Control for renumbering iterations
+    label indexingNumber = 0;
+    const bool optIndex = args.optionReadIfPresent("index", indexingNumber);
+    const bool noLagrangian = args.optionFound("noLagrangian");
 
-    // Mesh instance (region0 gets filtered out)
-    fileName regionPrefix;
+    // Always write the geometry, unless the -noMesh option is specified
+    bool optNoMesh = args.optionFound("noMesh");
 
-    if (regionName != polyMesh::defaultRegion)
-    {
-        regionPrefix = regionName;
-    }
-
-    if (Pstream::master())
-    {
-        Info<< "Converting " << timeDirs.size() << " time steps" << endl;
-    }
 
     // Construct the list of ensight parts for the entire mesh
     ensightParts partsList(mesh);
 
     // Write summary information
+    if (Pstream::master())
     {
-        OFstream partsInfoFile(ensightDir/"partsInfo");
+        Info<< "Converting " << timeDirs.size() << " time steps" << endl;
+
+        OFstream info(ensCase.path()/"partsInfo");
 
-        partsInfoFile
+        info
             << "// summary of ensight parts" << nl << nl;
-        partsList.writeSummary(partsInfoFile);
+        partsList.writeSummary(info);
     }
 
-    #include "checkHasMovingMesh.H"
+    #include "checkMeshMoving.H"
     #include "findFields.H"
 
-    if (hasMovingMesh && optNoMesh)
+    if (meshMoving && optNoMesh)
     {
         Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
         optNoMesh = false;
     }
 
 
-    // Map times used
-    Map<scalar>  timeIndices;
-
-    // TODO: Track the time indices used by the geometry
-    DynamicList<label> geometryTimesUsed;
-
-    // Track the time indices used by the volume fields
-    DynamicList<label> fieldTimesUsed;
-
-    // Track the time indices used by each cloud
-    HashTable<DynamicList<label>> cloudTimesUsed;
-
-    // Create a new DynamicList for each cloud
-    forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
-    {
-        cloudTimesUsed.insert(cloudIter.key(), DynamicList<label>());
-    }
-
     Info<< "Startup in "
         << timer.cpuTimeIncrement() << " s, "
         << mem.update().size() << " kB" << nl << endl;
@@ -272,25 +260,10 @@ int main(int argc, char *argv[])
         runTime.setTime(timeDirs[timeI], timeI);
 
         #include "getTimeIndex.H"
-
-        // Remember the time index for the volume fields
-        fieldTimesUsed.append(timeIndex);
-
-        // The data/ITER subdirectory must exist
-        // Note that data/ITER is indeed a valid ensight::FileName
-        const fileName subDir = ensightFile::subDir(timeIndex);
-        mkDir(dataDir/subDir);
-
-        // Place a timestamp in the directory for future reference
-        {
-            OFstream timeStamp(dataDir/subDir/"time");
-            timeStamp
-                << "#   timestep time" << nl
-                << subDir.c_str() << " " << runTime.timeName() << nl;
-        }
-
         #include "moveMesh.H"
 
+        ensCase.setTime(timeDirs[timeI], timeIndex);
+
         if (timeI == 0 || mesh.moving())
         {
             if (mesh.moving())
@@ -300,19 +273,8 @@ int main(int argc, char *argv[])
 
             if (!optNoMesh)
             {
-                if (hasMovingMesh)
-                {
-                    // Remember the time index for the geometry
-                    geometryTimesUsed.append(timeIndex);
-                }
-
-                ensightGeoFile geoFile
-                (
-                    (hasMovingMesh ? dataDir/subDir : ensightDir),
-                    geometryName,
-                    format
-                );
-                partsList.writeGeometry(geoFile);
+                autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
+                partsList.write(os.rawRef());
             }
         }
 
@@ -332,69 +294,77 @@ int main(int argc, char *argv[])
                 IOobject::NO_WRITE
             );
 
+            bool wrote = false;
             if (fieldType == volScalarField::typeName)
             {
-                ensightVolField<scalar>
+                autoPtr<ensightFile> os = ensCase.newData<scalar>
                 (
-                    partsList,
-                    fieldObject,
-                    mesh,
-                    dataDir,
-                    subDir,
-                    format
+                    fieldName
                 );
 
+                volScalarField vf(fieldObject, mesh);
+                wrote = ensightSerialOutput::writeField<scalar>
+                (
+                    vf, partsList, os
+                );
             }
             else if (fieldType == volVectorField::typeName)
             {
-                ensightVolField<vector>
+                autoPtr<ensightFile> os = ensCase.newData<vector>
                 (
-                    partsList,
-                    fieldObject,
-                    mesh,
-                    dataDir,
-                    subDir,
-                    format
+                    fieldName
                 );
 
+                volVectorField vf(fieldObject, mesh);
+                wrote = ensightSerialOutput::writeField<vector>
+                (
+                    vf, partsList, os
+                );
             }
             else if (fieldType == volSphericalTensorField::typeName)
             {
-                ensightVolField<sphericalTensor>
+                autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
                 (
-                    partsList,
-                    fieldObject,
-                    mesh,
-                    dataDir,
-                    subDir,
-                    format
+                    fieldName
                 );
 
+                volSphericalTensorField vf(fieldObject, mesh);
+                wrote = ensightSerialOutput::writeField<sphericalTensor>
+                (
+                    vf, partsList, os
+                );
             }
             else if (fieldType == volSymmTensorField::typeName)
             {
-                ensightVolField<symmTensor>
+                autoPtr<ensightFile> os = ensCase.newData<symmTensor>
                 (
-                    partsList,
-                    fieldObject,
-                    mesh,
-                    dataDir,
-                    subDir,
-                    format
+                    fieldName
+                );
+
+                volSymmTensorField vf(fieldObject, mesh);
+                wrote = ensightSerialOutput::writeField<symmTensor>
+                (
+                    vf, partsList, os
                 );
             }
             else if (fieldType == volTensorField::typeName)
             {
-                ensightVolField<tensor>
+                autoPtr<ensightFile> os = ensCase.newData<tensor>
+                (
+                    fieldName
+                );
+
+                volTensorField vf(fieldObject, mesh);
+                wrote = ensightSerialOutput::writeField<tensor>
                 (
-                    partsList,
-                    fieldObject,
-                    mesh,
-                    dataDir,
-                    subDir,
-                    format
+                    vf, partsList, os
                 );
             }
+
+            if (wrote)
+            {
+                Info<< " " << fieldObject.name() << flush;
+            }
         }
         Info<< " )" << endl;
 
@@ -422,16 +392,16 @@ int main(int argc, char *argv[])
                 continue;
             }
 
-            Info<< "Write " << cloudName << " ( positions" << flush;
+            Info<< "Write " << cloudName << " (" << flush;
 
-            ensightParticlePositions
+            ensightSerialCloud::writePositions
             (
                 mesh,
-                dataDir,
-                subDir,
                 cloudName,
-                format
+                ensCase.newCloud(cloudName)
             );
+            Info<< " positions";
+
 
             forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
             {
@@ -449,48 +419,39 @@ int main(int argc, char *argv[])
                     continue;
                 }
 
+                bool wrote = false;
                 if (fieldType == scalarIOField::typeName)
                 {
-                    ensightLagrangianField<scalar>
+                    wrote = ensightSerialCloud::writeCloudField<scalar>
                     (
                         *fieldObject,
-                        dataDir,
-                        subDir,
-                        cloudName,
-                        format
+                        ensCase.newCloudData<scalar>(cloudName, fieldName)
                     );
-
                 }
                 else if (fieldType == vectorIOField::typeName)
                 {
-                    ensightLagrangianField<vector>
+                    wrote = ensightSerialCloud::writeCloudField<vector>
                     (
                         *fieldObject,
-                        dataDir,
-                        subDir,
-                        cloudName,
-                        format
+                        ensCase.newCloudData<vector>(cloudName, fieldName)
                     );
-
                 }
                 else if (fieldType == tensorIOField::typeName)
                 {
-                    ensightLagrangianField<tensor>
+                    wrote = ensightSerialCloud::writeCloudField<tensor>
                     (
                         *fieldObject,
-                        dataDir,
-                        subDir,
-                        cloudName,
-                        format
+                        ensCase.newCloudData<tensor>(cloudName, fieldName)
                     );
+                }
 
+                if (wrote)
+                {
+                    Info<< " " << fieldObject->name();
                 }
             }
 
             Info<< " )" << endl;
-
-            // Remember the time index
-            cloudTimesUsed[cloudName].append(timeIndex);
         }
 
         Info<< "Wrote in "
@@ -498,7 +459,7 @@ int main(int argc, char *argv[])
             << mem.update().size() << " kB" << endl;
     }
 
-    #include "ensightOutputCase.H"
+    ensCase.write();
 
     Info<< "\nEnd: "
         << timer.elapsedCpuTime() << " s, "
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/getTimeIndex.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/getTimeIndex.H
index 9d8e93dcd145b3c37eca3ed4aa16b06646d3dce3..a55e44e136420eafff0c92454fe786c2cfecc07b 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/getTimeIndex.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/getTimeIndex.H
@@ -38,6 +38,6 @@
         }
     }
 
-    timeIndices.insert(timeIndex, timeDirs[timeI].value());
     Info<< nl << "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
 
+// end-of-file
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake
index d2cc359d9e003f469d034eb92b1fdfd34dd13b77..0893798f67bd7f3035e64008d15f64d22c9878ed 100755
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake
@@ -4,11 +4,13 @@ cd ${0%/*} || exit 1    # Run from this directory
 # Parse arguments for application compilation (at least for error control)
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
 
-if [ ! -d ${WM_THIRD_PARTY_DIR}/tecio ]
+export TECIO_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/tecio
+if [ -f $TECIO_ARCH_PATH/TECIO.h -a -r $TECIO_ARCH_PATH/libtecio.a ]
 then
-    echo "Did not find tecio in ${WM_THIRD_PARTY_DIR}. Not building foamToTecplot360."
-else
+    echo "Building optional tecplot conversion component."
     wmake $targetType
+else
+    echo "Skipping optional tecplot conversion components (no tecio detected)."
 fi
 
 #------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/files b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/files
index 270e84931b599af46bf3a9db82024e3202dd5006..3eb58f17730826790e60e9c50a6ecc12f9c81c13 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/files
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/files
@@ -1,5 +1,4 @@
 tecplotWriter.C
-vtkMesh.C
 foamToTecplot360.C
 
 EXE = $(FOAM_APPBIN)/foamToTecplot360
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options
index 5cf2518dd7c75a9c64f32b859fb2f085eac3d920..eb87f412dfb1b632a8efa92fa20f0e786696bf69 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options
@@ -1,14 +1,14 @@
+/* Tecio doesn't have many files, so they are just in a single directory */
+
 EXE_INC = \
-    -I$(WM_THIRD_PARTY_DIR)/tecio/tecsrc/lnInclude \
+    -I$(TECIO_ARCH_PATH) \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude
 
-
 EXE_LIBS = \
+    -L$(TECIO_ARCH_PATH) -ltecio \
     -llagrangian \
     -ldynamicMesh \
-    -ldynamicMesh \
-    -lgenericPatchFields \
-    -L$(FOAM_EXT_LIBBIN) -ltecio
+    -lgenericPatchFields
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/foamToTecplot360.C b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/foamToTecplot360.C
index 6ec9aff2772060d06ea92c5c07e8859aa08428d1..7cc27fde20bd2aef6524c98cfea5395b33a00831 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/foamToTecplot360.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/foamToTecplot360.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,7 +43,6 @@ Usage
         information as a single argument.
 
       - \par -cellSet \<name\>
-
       - \par -faceSet \<name\>
         Restrict conversion to the cellSet, faceSet.
 
@@ -68,9 +67,6 @@ Usage
         information as a single argument. The double quotes denote a regular
         expression.
 
-      - \par -useTimeName
-        use the time index in the VTK file name instead of the time index
-
 \*---------------------------------------------------------------------------*/
 
 #include "pointMesh.H"
@@ -84,22 +80,17 @@ Usage
 #include "passiveParticleCloud.H"
 #include "faceSet.H"
 #include "stringListOps.H"
-#include "wordRe.H"
+#include "wordReList.H"
 
-#include "vtkMesh.H"
+#include "meshSubsetHelper.H"
 #include "readFields.H"
 #include "tecplotWriter.H"
-
-#include "TECIO.h"
-
-// Note: needs to be after TECIO to prevent Foam::Time conflicting with
-// Xlib Time.
 #include "fvCFD.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 template<class GeoField>
-void print(const char* msg, Ostream& os, const PtrList<GeoField>& flds)
+void print(const char* msg, Ostream& os, const PtrList<const GeoField>& flds)
 {
     if (flds.size())
     {
@@ -140,7 +131,7 @@ labelList getSelectedPatches
         if
         (
             isType<emptyPolyPatch>(pp)
-            || (Pstream::parRun() && isType<processorPolyPatch>(pp))
+         || (Pstream::parRun() && isType<processorPolyPatch>(pp))
         )
         {
             Info<< "    discarding empty/processor patch " << patchi
@@ -161,8 +152,7 @@ labelList getSelectedPatches
 }
 
 
-
-
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 int main(int argc, char *argv[])
 {
@@ -170,10 +160,8 @@ int main(int argc, char *argv[])
     (
         "Tecplot binary file format writer"
     );
-
     timeSelector::addOptions();
     #include "addRegionOption.H"
-
     argList::addOption
     (
         "fields",
@@ -190,7 +178,7 @@ int main(int argc, char *argv[])
     (
         "faceSet",
         "name",
-        "restrict conversion to the specified cellSet"
+        "restrict conversion to the specified faceSet"
     );
     argList::addBoolOption
     (
@@ -248,29 +236,26 @@ int main(int argc, char *argv[])
     }
 
     word cellSetName;
-    string vtkName;
+    word faceSetName;
+    string pltName = runTime.caseName();
 
     if (args.optionReadIfPresent("cellSet", cellSetName))
     {
-        vtkName = cellSetName;
+        pltName = cellSetName;
     }
     else if (Pstream::parRun())
     {
         // Strip off leading casename, leaving just processor_DDD ending.
-        vtkName = runTime.caseName();
+        pltName = runTime.caseName();
 
-        string::size_type i = vtkName.rfind("processor");
+        string::size_type i = pltName.rfind("processor");
 
         if (i != string::npos)
         {
-            vtkName = vtkName.substr(i);
+            pltName = pltName.substr(i);
         }
     }
-    else
-    {
-        vtkName = runTime.caseName();
-    }
-
+    args.optionReadIfPresent("faceSet", faceSetName);
 
     instantList timeDirs = timeSelector::select0(runTime, args);
 
@@ -278,9 +263,9 @@ int main(int argc, char *argv[])
 
     // TecplotData/ directory in the case
     fileName fvPath(runTime.path()/"Tecplot360");
-    // Directory of mesh (region0 gets filtered out)
-    fileName regionPrefix = "";
 
+    // Directory of mesh (region0 gets filtered out)
+    fileName regionPrefix;
     if (regionName != polyMesh::defaultRegion)
     {
         fvPath = fvPath/regionName;
@@ -294,14 +279,15 @@ int main(int argc, char *argv[])
             args.optionFound("time")
          || args.optionFound("latestTime")
          || cellSetName.size()
+         || faceSetName.size()
          || regionName != polyMesh::defaultRegion
         )
         {
-            Info<< "Keeping old files in " << fvPath << nl << endl;
+            Info<< "Keeping old tecplot files in " << fvPath << nl << endl;
         }
         else
         {
-            Info<< "Deleting old VTK files in " << fvPath << nl << endl;
+            Info<< "Deleting old tecplot files in " << fvPath << nl << endl;
 
             rmDir(fvPath);
         }
@@ -309,9 +295,8 @@ int main(int argc, char *argv[])
 
     mkDir(fvPath);
 
-
-    // mesh wrapper; does subsetting and decomposition
-    vtkMesh vMesh(mesh, cellSetName);
+    // Mesh wrapper: does subsetting
+    meshSubsetHelper myMesh(mesh, meshSubsetHelper::SET, cellSetName);
 
     forAll(timeDirs, timeI)
     {
@@ -319,21 +304,20 @@ int main(int argc, char *argv[])
 
         Info<< "Time: " << runTime.timeName() << endl;
 
-        const word timeDesc = name(timeI);    //name(runTime.timeIndex());
+        const word timeDesc = name(timeI); // Foam::name(runTime.timeIndex());
 
         // Check for new polyMesh/ and update mesh, fvMeshSubset and cell
         // decomposition.
-        polyMesh::readUpdateState meshState = vMesh.readUpdate();
+        polyMesh::readUpdateState meshState = myMesh.readUpdate();
+        const fvMesh& mesh = myMesh.mesh();
 
-        const fvMesh& mesh = vMesh.mesh();
-
-        INTEGER4 nFaceNodes = 0;
+        // TotalNumFaceNodes
+        int32_t nFaceNodes = 0;
         forAll(mesh.faces(), facei)
         {
             nFaceNodes += mesh.faces()[facei].size();
         }
 
-
         // Read all fields on the new mesh
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -348,24 +332,24 @@ int main(int argc, char *argv[])
 
         // Construct the vol fields (on the original mesh if subsetted)
 
-        PtrList<volScalarField> vsf;
-        readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vsf);
+        PtrList<const volScalarField> vsf;
+        readFields(myMesh, myMesh.baseMesh(), objects, selectedFields, vsf);
         print("    volScalarFields            :", Info, vsf);
 
-        PtrList<volVectorField> vvf;
-        readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vvf);
+        PtrList<const volVectorField> vvf;
+        readFields(myMesh, myMesh.baseMesh(), objects, selectedFields, vvf);
         print("    volVectorFields            :", Info, vvf);
 
-        PtrList<volSphericalTensorField> vSpheretf;
-        readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vSpheretf);
+        PtrList<const volSphericalTensorField> vSpheretf;
+        readFields(myMesh, myMesh.baseMesh(), objects, selectedFields, vSpheretf);
         print("    volSphericalTensorFields   :", Info, vSpheretf);
 
-        PtrList<volSymmTensorField> vSymmtf;
-        readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vSymmtf);
+        PtrList<const volSymmTensorField> vSymmtf;
+        readFields(myMesh, myMesh.baseMesh(), objects, selectedFields, vSymmtf);
         print("    volSymmTensorFields        :", Info, vSymmtf);
 
-        PtrList<volTensorField> vtf;
-        readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vtf);
+        PtrList<const volTensorField> vtf;
+        readFields(myMesh, myMesh.baseMesh(), objects, selectedFields, vtf);
         print("    volTensorFields            :", Info, vtf);
 
 
@@ -379,11 +363,11 @@ int main(int argc, char *argv[])
                 << " (\"-noPointValues\" (at your option)\n";
         }
 
-        PtrList<pointScalarField> psf;
-        PtrList<pointVectorField> pvf;
-        //PtrList<pointSphericalTensorField> pSpheretf;
-        //PtrList<pointSymmTensorField> pSymmtf;
-        //PtrList<pointTensorField> ptf;
+        PtrList<const pointScalarField> psf;
+        PtrList<const pointVectorField> pvf;
+        //PtrList<const pointSphericalTensorField> pSpheretf;
+        //PtrList<const pointSymmTensorField> pSymmtf;
+        //PtrList<const pointTensorField> ptf;
 
 
         if (!noPointValues)
@@ -418,8 +402,8 @@ int main(int argc, char *argv[])
 
             readFields
             (
-                vMesh,
-                pointMesh::New(vMesh.baseMesh()),
+                myMesh,
+                pointMesh::New(myMesh.baseMesh()),
                 objects,
                 selectedFields,
                 psf
@@ -428,8 +412,8 @@ int main(int argc, char *argv[])
 
             readFields
             (
-                vMesh,
-                pointMesh::New(vMesh.baseMesh()),
+                myMesh,
+                pointMesh::New(myMesh.baseMesh()),
                 objects,
                 selectedFields,
                 pvf
@@ -438,8 +422,8 @@ int main(int argc, char *argv[])
 
             //readFields
             //(
-            //    vMesh,
-            //    pointMesh::New(vMesh.baseMesh()),
+            //    myMesh,
+            //    pointMesh::New(myMesh.baseMesh()),
             //    objects,
             //    selectedFields,
             //    pSpheretf
@@ -448,8 +432,8 @@ int main(int argc, char *argv[])
             //
             //readFields
             //(
-            //    vMesh,
-            //    pointMesh::New(vMesh.baseMesh()),
+            //    myMesh,
+            //    pointMesh::New(myMesh.baseMesh()),
             //    objects,
             //    selectedFields,
             //    pSymmtf
@@ -458,8 +442,8 @@ int main(int argc, char *argv[])
             //
             //readFields
             //(
-            //    vMesh,
-            //    pointMesh::New(vMesh.baseMesh()),
+            //    myMesh,
+            //    pointMesh::New(myMesh.baseMesh()),
             //    objects,
             //    selectedFields,
             //    ptf
@@ -473,23 +457,23 @@ int main(int argc, char *argv[])
         // ~~~~~~~~~~~~~~~
 
         string varNames;
-        DynamicList<INTEGER4> varLocation;
+        DynamicList<int32_t> varLocation;
 
         string cellVarNames;
-        DynamicList<INTEGER4> cellVarLocation;
+        DynamicList<int32_t> cellVarLocation;
 
         // volFields
         tecplotWriter::getTecplotNames
         (
             vsf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             varNames,
             varLocation
         );
         tecplotWriter::getTecplotNames
         (
             vsf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             cellVarNames,
             cellVarLocation
         );
@@ -497,14 +481,14 @@ int main(int argc, char *argv[])
         tecplotWriter::getTecplotNames
         (
             vvf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             varNames,
             varLocation
         );
         tecplotWriter::getTecplotNames
         (
             vvf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             cellVarNames,
             cellVarLocation
         );
@@ -512,14 +496,14 @@ int main(int argc, char *argv[])
         tecplotWriter::getTecplotNames
         (
             vSpheretf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             varNames,
             varLocation
         );
         tecplotWriter::getTecplotNames
         (
             vSpheretf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             cellVarNames,
             cellVarLocation
         );
@@ -527,14 +511,14 @@ int main(int argc, char *argv[])
         tecplotWriter::getTecplotNames
         (
             vSymmtf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             varNames,
             varLocation
         );
         tecplotWriter::getTecplotNames
         (
             vSymmtf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             cellVarNames,
             cellVarLocation
         );
@@ -542,25 +526,24 @@ int main(int argc, char *argv[])
         tecplotWriter::getTecplotNames
         (
             vtf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             varNames,
             varLocation
         );
         tecplotWriter::getTecplotNames
         (
             vtf,
-            ValueLocation_CellCentered,
+            tecplotWriter::CELL_CENTERED,
             cellVarNames,
             cellVarLocation
         );
 
 
-
         // pointFields
         tecplotWriter::getTecplotNames
         (
             psf,
-            ValueLocation_Nodal,
+            tecplotWriter::NODE_CENTERED,
             varNames,
             varLocation
         );
@@ -568,44 +551,45 @@ int main(int argc, char *argv[])
         tecplotWriter::getTecplotNames
         (
             pvf,
-            ValueLocation_Nodal,
+            tecplotWriter::NODE_CENTERED,
             varNames,
             varLocation
         );
 
-        // strandID (= piece id. Gets incremented for every piece of geometry
-        // that is output)
-        INTEGER4 strandID = 1;
-
+        // strandID (= piece id).
+        // Gets incremented for every piece of geometry that is output.
+        int32_t strandID = 1;
 
         if (meshState != polyMesh::UNCHANGED)
         {
             if (doWriteInternal)
             {
                 // Output mesh and fields
-                fileName vtkFileName
+                fileName pltFileName
                 (
-                    fvPath/vtkName
+                    fvPath/pltName
                   + "_"
                   + timeDesc
                   + ".plt"
                 );
 
-                tecplotWriter writer(runTime);
-
-                string allVarNames = string("X Y Z ") + varNames;
-                DynamicList<INTEGER4> allVarLocation;
-                allVarLocation.append(ValueLocation_Nodal);
-                allVarLocation.append(ValueLocation_Nodal);
-                allVarLocation.append(ValueLocation_Nodal);
+                const string allVarNames = tecplotWriter::XYZ + " " + varNames;
+                DynamicList<int32_t> allVarLocation
+                {
+                    tecplotWriter::NODE_CENTERED,
+                    tecplotWriter::NODE_CENTERED,
+                    tecplotWriter::NODE_CENTERED
+                };
                 allVarLocation.append(varLocation);
 
+
+                tecplotWriter writer(runTime);
                 writer.writeInit
                 (
                     runTime.caseName(),
                     allVarNames,
-                    vtkFileName,
-                    DataFileType_Full
+                    pltFileName,
+                    tecplotWriter::FILETYPE_FULL
                 );
 
                 writer.writePolyhedralZone
@@ -617,41 +601,18 @@ int main(int argc, char *argv[])
                     nFaceNodes
                 );
 
-                // Write coordinates
-                writer.writeField(mesh.points().component(0)());
-                writer.writeField(mesh.points().component(1)());
-                writer.writeField(mesh.points().component(2)());
+                // Coordinates
+                writer.writeField(mesh.points());
 
                 // Write all fields
-                forAll(vsf, i)
-                {
-                    writer.writeField(vsf[i]);
-                }
-                forAll(vvf, i)
-                {
-                    writer.writeField(vvf[i]);
-                }
-                forAll(vSpheretf, i)
-                {
-                    writer.writeField(vSpheretf[i]);
-                }
-                forAll(vSymmtf, i)
-                {
-                    writer.writeField(vSymmtf[i]);
-                }
-                forAll(vtf, i)
-                {
-                    writer.writeField(vtf[i]);
-                }
+                writer.writeFields(vsf);
+                writer.writeFields(vvf);
+                writer.writeFields(vSpheretf);
+                writer.writeFields(vSymmtf);
+                writer.writeFields(vtf);
 
-                forAll(psf, i)
-                {
-                    writer.writeField(psf[i]);
-                }
-                forAll(pvf, i)
-                {
-                    writer.writeField(pvf[i]);
-                }
+                writer.writeFields(psf);
+                writer.writeFields(pvf);
 
                 writer.writeConnectivity(mesh);
                 writer.writeEnd();
@@ -664,22 +625,22 @@ int main(int argc, char *argv[])
                 if (timeI == 0)
                 {
                     // Output static mesh only
-                    fileName vtkFileName
+                    fileName pltFileName
                     (
-                        fvPath/vtkName
+                        fvPath/pltName
                       + "_grid_"
                       + timeDesc
                       + ".plt"
                     );
 
-                    tecplotWriter writer(runTime);
 
+                    tecplotWriter writer(runTime);
                     writer.writeInit
                     (
                         runTime.caseName(),
-                        "X Y Z",
-                        vtkFileName,
-                        DataFileType_Grid
+                        tecplotWriter::XYZ,
+                        pltFileName,
+                        tecplotWriter::FILETYPE_GRID
                     );
 
                     writer.writePolyhedralZone
@@ -687,36 +648,33 @@ int main(int argc, char *argv[])
                         mesh.name(),        // regionName
                         strandID,           // strandID
                         mesh,
-                        List<INTEGER4>(3, ValueLocation_Nodal),
+                        List<int32_t>(3, tecplotWriter::NODE_CENTERED),
                         nFaceNodes
                     );
 
-                    // Write coordinates
-                    writer.writeField(mesh.points().component(0)());
-                    writer.writeField(mesh.points().component(1)());
-                    writer.writeField(mesh.points().component(2)());
-
+                    // Coordinates
+                    writer.writeField(mesh.points());
                     writer.writeConnectivity(mesh);
                     writer.writeEnd();
                 }
 
                 // Output solution file
-                fileName vtkFileName
+                fileName pltFileName
                 (
-                    fvPath/vtkName
+                    fvPath/pltName
                   + "_"
                   + timeDesc
                   + ".plt"
                 );
 
-                tecplotWriter writer(runTime);
 
+                tecplotWriter writer(runTime);
                 writer.writeInit
                 (
                     runTime.caseName(),
                     varNames,
-                    vtkFileName,
-                    DataFileType_Solution
+                    pltFileName,
+                    tecplotWriter::FILETYPE_SOLUTION
                 );
 
                 writer.writePolyhedralZone
@@ -729,35 +687,15 @@ int main(int argc, char *argv[])
                 );
 
                 // Write all fields
-                forAll(vsf, i)
-                {
-                    writer.writeField(vsf[i]);
-                }
-                forAll(vvf, i)
-                {
-                    writer.writeField(vvf[i]);
-                }
-                forAll(vSpheretf, i)
-                {
-                    writer.writeField(vSpheretf[i]);
-                }
-                forAll(vSymmtf, i)
-                {
-                    writer.writeField(vSymmtf[i]);
-                }
-                forAll(vtf, i)
-                {
-                    writer.writeField(vtf[i]);
-                }
+                writer.writeFields(vsf);
+                writer.writeFields(vvf);
+                writer.writeFields(vSpheretf);
+                writer.writeFields(vSymmtf);
+                writer.writeFields(vtf);
+
+                writer.writeFields(psf);
+                writer.writeFields(pvf);
 
-                forAll(psf, i)
-                {
-                    writer.writeField(psf[i]);
-                }
-                forAll(pvf, i)
-                {
-                    writer.writeField(pvf[i]);
-                }
                 writer.writeEnd();
             }
         }
@@ -769,18 +707,17 @@ int main(int argc, char *argv[])
         //
         //---------------------------------------------------------------------
 
-        if (args.optionFound("faceSet"))
+        if (faceSetName.size())
         {
             // Load the faceSet
-            const word setName = args["faceSet"];
-            labelList faceLabels(faceSet(mesh, setName).toc());
+            labelList faceLabels(faceSet(mesh, faceSetName).toc());
 
             // Filename as if patch with same name.
-            mkDir(fvPath/setName);
+            mkDir(fvPath/faceSetName);
 
             fileName patchFileName
             (
-                fvPath/setName/setName
+                fvPath/faceSetName/faceSetName
               + "_"
               + timeDesc
               + ".plt"
@@ -788,21 +725,23 @@ int main(int argc, char *argv[])
 
             Info<< "    FaceSet   : " << patchFileName << endl;
 
-            tecplotWriter writer(runTime);
-
-            string allVarNames = string("X Y Z ") + cellVarNames;
-            DynamicList<INTEGER4> allVarLocation;
-            allVarLocation.append(ValueLocation_Nodal);
-            allVarLocation.append(ValueLocation_Nodal);
-            allVarLocation.append(ValueLocation_Nodal);
+            const string allVarNames = tecplotWriter::XYZ + " " + cellVarNames;
+            DynamicList<int32_t> allVarLocation
+            {
+                tecplotWriter::NODE_CENTERED,
+                tecplotWriter::NODE_CENTERED,
+                tecplotWriter::NODE_CENTERED
+            };
             allVarLocation.append(cellVarLocation);
 
+
+            tecplotWriter writer(runTime);
             writer.writeInit
             (
                 runTime.caseName(),
                 cellVarNames,
                 patchFileName,
-                DataFileType_Full
+                tecplotWriter::FILETYPE_FULL
             );
 
             const indirectPrimitivePatch ipp
@@ -813,16 +752,14 @@ int main(int argc, char *argv[])
 
             writer.writePolygonalZone
             (
-                setName,
+                faceSetName,
                 strandID++,
                 ipp,
                 allVarLocation
             );
 
-            // Write coordinates
-            writer.writeField(ipp.localPoints().component(0)());
-            writer.writeField(ipp.localPoints().component(1)());
-            writer.writeField(ipp.localPoints().component(2)());
+            // Coordinates
+            writer.writeField(ipp.localPoints());
 
             // Write all volfields
             forAll(vsf, i)
@@ -833,7 +770,7 @@ int main(int argc, char *argv[])
                     (
                         linearInterpolate(vsf[i])(),
                         faceLabels
-                    )()
+                    )
                 );
             }
             forAll(vvf, i)
@@ -844,7 +781,7 @@ int main(int argc, char *argv[])
                     (
                         linearInterpolate(vvf[i])(),
                         faceLabels
-                    )()
+                    )
                 );
             }
             forAll(vSpheretf, i)
@@ -855,7 +792,7 @@ int main(int argc, char *argv[])
                     (
                         linearInterpolate(vSpheretf[i])(),
                         faceLabels
-                    )()
+                    )
                 );
             }
             forAll(vSymmtf, i)
@@ -866,7 +803,7 @@ int main(int argc, char *argv[])
                     (
                         linearInterpolate(vSymmtf[i])(),
                         faceLabels
-                    )()
+                    )
                 );
             }
             forAll(vtf, i)
@@ -877,7 +814,7 @@ int main(int argc, char *argv[])
                     (
                         linearInterpolate(vtf[i])(),
                         faceLabels
-                    )()
+                    )
                 );
             }
             writer.writeConnectivity(ipp);
@@ -886,7 +823,6 @@ int main(int argc, char *argv[])
         }
 
 
-
         //---------------------------------------------------------------------
         //
         // Write patches as multi-zone file
@@ -901,7 +837,7 @@ int main(int argc, char *argv[])
 
         fileName patchFileName;
 
-        if (vMesh.useSubMesh())
+        if (myMesh.useSubMesh())
         {
             patchFileName =
                 fvPath/"boundaryMesh"/cellSetName
@@ -920,33 +856,37 @@ int main(int argc, char *argv[])
 
         Info<< "    Combined patches     : " << patchFileName << endl;
 
-        tecplotWriter writer(runTime);
-
-        string allVarNames = string("X Y Z ") + varNames;
-        DynamicList<INTEGER4> allVarLocation;
-        allVarLocation.append(ValueLocation_Nodal);
-        allVarLocation.append(ValueLocation_Nodal);
-        allVarLocation.append(ValueLocation_Nodal);
+        const string allVarNames = tecplotWriter::XYZ + " " + varNames;
+        DynamicList<int32_t> allVarLocation
+        {
+            tecplotWriter::NODE_CENTERED,
+            tecplotWriter::NODE_CENTERED,
+            tecplotWriter::NODE_CENTERED
+        };
         allVarLocation.append(varLocation);
 
+
+        tecplotWriter writer(runTime);
         writer.writeInit
         (
             runTime.caseName(),
             allVarNames,
             patchFileName,
-            DataFileType_Full
+            tecplotWriter::FILETYPE_FULL
         );
 
         forAll(patchIDs, i)
         {
             label patchID = patchIDs[i];
             const polyPatch& pp = patches[patchID];
-            //INTEGER4 strandID = 1 + i;
+            // int32_t strandID = 1 + i;
 
             if (pp.size() > 0)
             {
-                Info<< "    Writing patch " << patchID << "\t" << pp.name()
-                    << "\tstrand:" << strandID << nl << endl;
+                Info<< "    Writing patch " << patchID
+                    << tab << pp.name()
+                    << tab << "strand:" << strandID
+                    << nl << endl;
 
                 const indirectPrimitivePatch ipp
                 (
@@ -962,10 +902,8 @@ int main(int argc, char *argv[])
                     allVarLocation
                 );
 
-                // Write coordinates
-                writer.writeField(ipp.localPoints().component(0)());
-                writer.writeField(ipp.localPoints().component(1)());
-                writer.writeField(ipp.localPoints().component(2)());
+                // Coordinates
+                writer.writeField(ipp.localPoints());
 
                 // Write all fields
                 forAll(vsf, i)
@@ -977,7 +915,7 @@ int main(int argc, char *argv[])
                             nearCellValue,
                             vsf[i],
                             patchID
-                        )()
+                        )
                     );
                 }
                 forAll(vvf, i)
@@ -989,7 +927,7 @@ int main(int argc, char *argv[])
                             nearCellValue,
                             vvf[i],
                             patchID
-                        )()
+                        )
                     );
                 }
                 forAll(vSpheretf, i)
@@ -1001,7 +939,7 @@ int main(int argc, char *argv[])
                             nearCellValue,
                             vSpheretf[i],
                             patchID
-                        )()
+                        )
                     );
                 }
                 forAll(vSymmtf, i)
@@ -1013,7 +951,7 @@ int main(int argc, char *argv[])
                             nearCellValue,
                             vSymmtf[i],
                             patchID
-                        )()
+                        )
                     );
                 }
                 forAll(vtf, i)
@@ -1025,7 +963,7 @@ int main(int argc, char *argv[])
                             nearCellValue,
                             vtf[i],
                             patchID
-                        )()
+                        )
                     );
                 }
 
@@ -1033,14 +971,14 @@ int main(int argc, char *argv[])
                 {
                     writer.writeField
                     (
-                        psf[i].boundaryField()[patchID].patchInternalField()()
+                        psf[i].boundaryField()[patchID].patchInternalField()
                     );
                 }
                 forAll(pvf, i)
                 {
                     writer.writeField
                     (
-                        pvf[i].boundaryField()[patchID].patchInternalField()()
+                        pvf[i].boundaryField()[patchID].patchInternalField()
                     );
                 }
 
@@ -1049,7 +987,7 @@ int main(int argc, char *argv[])
             else
             {
                 Info<< "    Skipping zero sized patch " << patchID
-                    << "\t" << pp.name()
+                    << tab << pp.name()
                     << nl << endl;
             }
         }
@@ -1066,13 +1004,13 @@ int main(int argc, char *argv[])
 
         const faceZoneMesh& zones = mesh.faceZones();
 
-        if (doFaceZones && zones.size() > 0)
+        if (doFaceZones && !zones.empty())
         {
             mkDir(fvPath/"faceZoneMesh");
 
             fileName patchFileName;
 
-            if (vMesh.useSubMesh())
+            if (myMesh.useSubMesh())
             {
                 patchFileName =
                     fvPath/"faceZoneMesh"/cellSetName
@@ -1091,21 +1029,23 @@ int main(int argc, char *argv[])
 
             Info<< "    FaceZone  : " << patchFileName << endl;
 
-            tecplotWriter writer(runTime);
-
-            string allVarNames = string("X Y Z ") + cellVarNames;
-            DynamicList<INTEGER4> allVarLocation;
-            allVarLocation.append(ValueLocation_Nodal);
-            allVarLocation.append(ValueLocation_Nodal);
-            allVarLocation.append(ValueLocation_Nodal);
+            const string allVarNames = tecplotWriter::XYZ + " " + cellVarNames;
+            DynamicList<int32_t> allVarLocation
+            {
+                tecplotWriter::NODE_CENTERED,
+                tecplotWriter::NODE_CENTERED,
+                tecplotWriter::NODE_CENTERED
+            };
             allVarLocation.append(cellVarLocation);
 
+
+            tecplotWriter writer(runTime);
             writer.writeInit
             (
                 runTime.caseName(),
                 allVarNames,
                 patchFileName,
-                DataFileType_Full
+                tecplotWriter::FILETYPE_FULL
             );
 
             forAll(zones, zoneI)
@@ -1128,10 +1068,8 @@ int main(int argc, char *argv[])
                         allVarLocation
                     );
 
-                    // Write coordinates
-                    writer.writeField(ipp.localPoints().component(0)());
-                    writer.writeField(ipp.localPoints().component(1)());
-                    writer.writeField(ipp.localPoints().component(2)());
+                    // Coordinates
+                    writer.writeField(ipp.localPoints());
 
                     // Write all volfields
                     forAll(vsf, i)
@@ -1142,7 +1080,7 @@ int main(int argc, char *argv[])
                             (
                                 linearInterpolate(vsf[i])(),
                                 pp
-                            )()
+                            )
                         );
                     }
                     forAll(vvf, i)
@@ -1153,7 +1091,7 @@ int main(int argc, char *argv[])
                             (
                                 linearInterpolate(vvf[i])(),
                                 pp
-                            )()
+                            )
                         );
                     }
                     forAll(vSpheretf, i)
@@ -1164,7 +1102,7 @@ int main(int argc, char *argv[])
                             (
                                 linearInterpolate(vSpheretf[i])(),
                                 pp
-                            )()
+                            )
                         );
                     }
                     forAll(vSymmtf, i)
@@ -1175,7 +1113,7 @@ int main(int argc, char *argv[])
                             (
                                 linearInterpolate(vSymmtf[i])(),
                                 pp
-                            )()
+                            )
                         );
                     }
                     forAll(vtf, i)
@@ -1186,7 +1124,7 @@ int main(int argc, char *argv[])
                             (
                                 linearInterpolate(vtf[i])(),
                                 pp
-                            )()
+                            )
                         );
                     }
 
@@ -1195,16 +1133,16 @@ int main(int argc, char *argv[])
                 else
                 {
                     Info<< "    Skipping zero sized faceZone " << zoneI
-                        << "\t" << pp.name()
+                        << tab << pp.name()
                         << nl << endl;
                 }
             }
+
             writer.writeEnd();
             Info<< endl;
         }
 
 
-
         //---------------------------------------------------------------------
         //
         // Write lagrangian data
@@ -1295,16 +1233,18 @@ int main(int argc, char *argv[])
                 }
 
 
-                string allVarNames = string("X Y Z");
-                DynamicList<INTEGER4> allVarLocation;
-                allVarLocation.append(ValueLocation_Nodal);
-                allVarLocation.append(ValueLocation_Nodal);
-                allVarLocation.append(ValueLocation_Nodal);
+                string allVarNames = tecplotWriter::XYZ;
+                DynamicList<int32_t> allVarLocation
+                {
+                    tecplotWriter::NODE_CENTERED,
+                    tecplotWriter::NODE_CENTERED,
+                    tecplotWriter::NODE_CENTERED
+                };
 
                 tecplotWriter::getTecplotNames<label>
                 (
                     labelNames,
-                    ValueLocation_Nodal,
+                    tecplotWriter::NODE_CENTERED,
                     allVarNames,
                     allVarLocation
                 );
@@ -1312,7 +1252,7 @@ int main(int argc, char *argv[])
                 tecplotWriter::getTecplotNames<scalar>
                 (
                     scalarNames,
-                    ValueLocation_Nodal,
+                    tecplotWriter::NODE_CENTERED,
                     allVarNames,
                     allVarLocation
                 );
@@ -1320,20 +1260,19 @@ int main(int argc, char *argv[])
                 tecplotWriter::getTecplotNames<vector>
                 (
                     vectorNames,
-                    ValueLocation_Nodal,
+                    tecplotWriter::NODE_CENTERED,
                     allVarNames,
                     allVarLocation
                 );
 
 
                 tecplotWriter writer(runTime);
-
                 writer.writeInit
                 (
                     runTime.caseName(),
                     allVarNames,
                     lagrFileName,
-                    DataFileType_Full
+                    tecplotWriter::FILETYPE_FULL
                 );
 
                 writer.writeOrderedZone
@@ -1344,19 +1283,19 @@ int main(int argc, char *argv[])
                     allVarLocation
                 );
 
-                // Write coordinates
-                writer.writeField(positions.component(0)());
-                writer.writeField(positions.component(1)());
-                writer.writeField(positions.component(2)());
+                // Coordinates
+                writer.writeField(positions);
 
                 // labelFields
                 forAll(labelNames, i)
                 {
+                    const word& fieldName = labelNames[i];
+
                     IOField<label> fld
                     (
                         IOobject
                         (
-                            labelNames[i],
+                            fieldName,
                             mesh.time().timeName(),
                             cloud::prefix/cloudDirs[cloudI],
                             mesh,
@@ -1366,21 +1305,19 @@ int main(int argc, char *argv[])
                         )
                     );
 
-                    scalarField sfld(fld.size());
-                    forAll(fld, j)
-                    {
-                        sfld[j] = scalar(fld[j]);
-                    }
-                    writer.writeField(sfld);
+                    writer.writeField(fld);
                 }
+
                 // scalarFields
                 forAll(scalarNames, i)
                 {
+                    const word& fieldName = scalarNames[i];
+
                     IOField<scalar> fld
                     (
                         IOobject
                         (
-                            scalarNames[i],
+                            fieldName,
                             mesh.time().timeName(),
                             cloud::prefix/cloudDirs[cloudI],
                             mesh,
@@ -1389,16 +1326,20 @@ int main(int argc, char *argv[])
                             false
                         )
                     );
+
                     writer.writeField(fld);
                 }
+
                 // vectorFields
                 forAll(vectorNames, i)
                 {
+                    const word& fieldName = vectorNames[i];
+
                     IOField<vector> fld
                     (
                         IOobject
                         (
-                            vectorNames[i],
+                            fieldName,
                             mesh.time().timeName(),
                             cloud::prefix/cloudDirs[cloudI],
                             mesh,
@@ -1407,6 +1348,7 @@ int main(int argc, char *argv[])
                             false
                         )
                     );
+
                     writer.writeField(fld);
                 }
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.C
index c677fe439c7ef0a75b6beb96352a0c67ea42bb15..172a83cf2399cd5f8d4b8678d6e1531fcc16929a 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,37 +36,32 @@ namespace Foam
 template<class GeoField>
 void readFields
 (
-    const vtkMesh& vMesh,
+    const meshSubsetHelper& helper,
     const typename GeoField::Mesh& mesh,
     const IOobjectList& objects,
     const HashSet<word>& selectedFields,
-    PtrList<GeoField>& fields
+    PtrList<const GeoField>& fields
 )
 {
-    // Search list of objects for volScalarFields
+    // Search list of objects for fields of type GeomField
     IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
 
-    // Construct the vol scalar fields
-    label nFields = fields.size();
-    fields.setSize(nFields + fieldObjects.size());
+    // Construct the fields
+    fields.setSize(fieldObjects.size());
+    label nFields = 0;
 
-    forAllIter(IOobjectList, fieldObjects, iter)
+    forAllConstIter(IOobjectList, fieldObjects, iter)
     {
         if (selectedFields.empty() || selectedFields.found(iter()->name()))
         {
             fields.set
             (
-                nFields,
-                vMesh.interpolate
+                nFields++,
+                helper.interpolate
                 (
-                    GeoField
-                    (
-                        *iter(),
-                        mesh
-                    )
-                )
+                    GeoField(*iter(), mesh)
+                ).ptr()
             );
-            nFields++;
         }
     }
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.H
index b25c56755c2f2559bf4076ce57057268cad5b131..510bd11d2536419dea3c29bfce016e2dbd5ddd8e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/readFields.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,7 +34,7 @@ SourceFiles
 #ifndef readFields_H
 #define readFields_H
 
-#include "fvMesh.H"
+#include "meshSubsetHelper.H"
 #include "PtrList.H"
 #include "IOobjectList.H"
 #include "HashSet.H"
@@ -48,11 +48,11 @@ namespace Foam
 template<class GeoField>
 void readFields
 (
-    const vtkMesh& vMesh,
+    const meshSubsetHelper&,
     const typename GeoField::Mesh& mesh,
     const IOobjectList& objects,
     const HashSet<word>& selectedFields,
-    PtrList<GeoField>& fields
+    PtrList<const GeoField>& fields
 );
 
 } // End namespace Foam
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.C b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.C
index a43c625f1795a1e50ecf2779109972e8b299730d..317010c0de26070066c189d9d271706034559355 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,13 +25,23 @@ License
 
 #include "tecplotWriter.H"
 #include "fvMesh.H"
+#include "TECIO.h"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const int32_t Foam::tecplotWriter::tecConst_0 = 0;
+const int32_t Foam::tecplotWriter::tecConst_1 = 1;
+const int32_t Foam::tecplotWriter::tecConst_False = 0;
+const int32_t Foam::tecplotWriter::tecConst_True  = 1;
+
+const Foam::string Foam::tecplotWriter::XYZ = "X Y Z";
+
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 Foam::tecplotWriter::tecplotWriter(const Time& runTime)
 :
-    runTime_(runTime)
+    time_(runTime)
 {}
 
 
@@ -42,35 +52,37 @@ void Foam::tecplotWriter::writeInit
     const word& name,
     const string& varNames,
     const fileName& fName,
-    INTEGER4 tecplotFileType
+    const dataFileType fileType
 ) const
 {
-Pout<< endl
-    << endl
-    << "Name:" << name
-    << " varNames:" << varNames
-    << " to file:" << fName
-    << " of type:" << tecplotFileType
-    << endl;
-
-    INTEGER4 IsDouble = 0;  //float
-    INTEGER4 Debug = 0;     //nodebug
+    const int32_t FileType   = fileType;
+    const int32_t FileFormat = 0; // 0 = binary (plt), 1 = subzone (.szplt)
+
+    Pout<< nl << nl
+        << "Name:" << name
+        << " varNames:" << varNames
+        << " to file:" << fName
+        << " of type:" << int(fileType)
+        << endl;
+
     if
     (
-        !TECINI112
+        tecini142
         (
-            const_cast<char*>(name.c_str()),       /* Data Set Title       */
-            const_cast<char*>(varNames.c_str()),   /* Variable List        */
-            const_cast<char*>(fName.c_str()),      /* File Name            */
-            const_cast<char*>(runTime_.path().c_str()), /* Scratch Directory */
-            &tecplotFileType,
-            &Debug,
-            &IsDouble
+            name.c_str(),       //< DataSet Title
+            varNames.c_str(),   //< Variables List
+            fName.c_str(),      //< FileName
+            time_.path().c_str(), //< ScratchDir
+            &FileFormat,        //< FileFormat
+            &FileType,          //< FileType
+            &tecConst_False,    //< Debug (0: no debug, 1: debug)
+            &tecConst_False     //< VIsDouble (0: single, 1: double)
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECINI112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in tecini142."
+            << exit(FatalError);
     }
 }
 
@@ -78,78 +90,60 @@ Pout<< endl
 void Foam::tecplotWriter::writePolyhedralZone
 (
     const word& zoneName,
-    INTEGER4 strandID,
+    const int32_t strandID,
     const fvMesh& mesh,
-    const List<INTEGER4>& varLocArray,
-    INTEGER4 nFaceNodes
+    const UList<int32_t>& varLocArray,
+    const int32_t NumFaceNodes
 ) const
 {
-    /* Call TECZNE112 */
-    INTEGER4  NumNodes   = mesh.nPoints();         /* number of unique nodes */
-    INTEGER4  NumElems   = mesh.nCells();         /* number of elements */
-    INTEGER4  NumFaces   = mesh.nFaces();         /* number of unique faces */
-
-    INTEGER4  ICellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  JCellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  KCellMax   = 0;         /* Not Used, set to zero */
-
-    double    SolTime    = runTime_.value();     /* solution time   */
-    INTEGER4  ParentZone = 0;         /* no parent zone  */
-
-    INTEGER4  IsBlock    = 1;         /* block format  */
-
-    INTEGER4  NFConns    = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-    INTEGER4  FNMode     = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-Pout<< "zoneName:" << zoneName
-    //<< " varLocArray:" << varLocArray
-    << " solTime:" << SolTime
-    << endl;
-
-
-
-    INTEGER4 *PassiveVarArray = nullptr;
-    INTEGER4 *VarShareArray   = nullptr;
-    INTEGER4  ShrConn         = 0;
-
-    INTEGER4  NumBConns       = 0;   /* No Boundary Connections */
-    INTEGER4  NumBItems       = 0;   /* No Boundary Items */
-
-    INTEGER4  ZoneType = ZoneType_FEPolyhedron;
-
+    const int32_t NumNodes = mesh.nPoints();    // Number of unique nodes
+    const int32_t NumElems = mesh.nCells();     // Number of elements
+    const int32_t NumFaces = mesh.nFaces();     // Number of unique faces
+    const double  SolTime  = time_.value();     // Solution time
+
+    const int32_t ParentZone = 0;   // Bool: 0 = no parent zone
+    const int32_t ShrConn   = 0;
+    const int32_t NumBConns = 0;    // No Boundary Connections
+    const int32_t NumBItems = 0;    // No Boundary Items
+
+    Pout<< "zoneName:" << zoneName
+        //<< " varLocArray:" << varLocArray
+        << " solTime:" << SolTime
+        << " strand:"  << strandID
+        << endl;
+
+    const int32_t ZoneType  = ZONE_FEPOLYHEDRON;
     if
     (
-       !TECZNE112
+        teczne142
         (
-            const_cast<char*>(zoneName.c_str()),
-            &ZoneType,
-            &NumNodes,
-            &NumElems,
-            &NumFaces,
-            &ICellMax,
-            &JCellMax,
-            &KCellMax,
-            &SolTime,
-            &strandID,
-            &ParentZone,
-            &IsBlock,
-            &NFConns,
-            &FNMode,
-            &nFaceNodes,
-            &NumBConns,
-            &NumBItems,
-            PassiveVarArray,
-            const_cast<INTEGER4*>(varLocArray.begin()),
-            VarShareArray,
-            &ShrConn
+            zoneName.c_str(),   //< ZoneTitle
+            &ZoneType,          //< ZoneType
+            &NumNodes,          //< IMxOrNumPts
+            &NumElems,          //< JMxOrNumElements
+            &NumFaces,          //< KMxOrNumFaces
+            &tecConst_0,        //< (unused set to zero) ICellMax
+            &tecConst_0,        //< (unused set to zero) JCellMax
+            &tecConst_0,        //< (unused set to zero) KCellMax
+            &SolTime,           //< SolutionTime
+            &strandID,          //< StrandID
+            &ParentZone,        //< ParentZone
+            &tecConst_True,     //< IsBlock
+            &tecConst_0,        //< (unused) NumFaceConnections
+            &tecConst_0,        //< (unused) FaceNeighborMode
+            &NumFaceNodes,      //< TotalNumFaceNodes
+            &NumBConns,         //< NumConnectedBoundaryFaces
+            &NumBItems,         //< TotalNumBoundaryConnections
+            nullptr,            //< PassiveVarList
+            varLocArray.cdata(), //< ValueLocation
+            nullptr,            //< ShareVarFromZone
+            &ShrConn            //< ShareConnectivityFromZone
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECZNE112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in teczne142 - writing polyhedron zones."
+            << exit(FatalError);
     }
 }
 
@@ -157,79 +151,61 @@ Pout<< "zoneName:" << zoneName
 void Foam::tecplotWriter::writePolygonalZone
 (
     const word& zoneName,
-    INTEGER4 strandID,
+    const int32_t strandID,
     const indirectPrimitivePatch& pp,
-    const List<INTEGER4>& varLocArray
+    const UList<int32_t>& varLocArray
 ) const
 {
-    /* Call TECZNE112 */
-    INTEGER4  NumNodes   = pp.nPoints();         /* number of unique nodes */
-    INTEGER4  NumElems   = pp.size();         /* number of elements */
-    INTEGER4  NumFaces   = pp.nEdges();         /* number of unique faces */
-
-    INTEGER4  ICellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  JCellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  KCellMax   = 0;         /* Not Used, set to zero */
-
-    double    SolTime    = runTime_.value();     /* solution time   */
-    INTEGER4  ParentZone = 0;         /* no parent zone  */
-
-    INTEGER4  IsBlock    = 1;         /* block format  */
-
-    INTEGER4  NFConns    = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-    INTEGER4  FNMode     = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-    INTEGER4  NumFaceNodes    = 2*pp.nEdges();
+    const int32_t NumNodes = pp.nPoints();      // Number of unique nodes
+    const int32_t NumElems = pp.size();         // Number of elements
+    const int32_t NumFaces = pp.nEdges();       // Number of unique faces
+    const double  SolTime  = time_.value();     // Solution time
 
-Pout<< "zoneName:" << zoneName
-    << " strandID:" << strandID
-    //<< " varLocArray:" << varLocArray
-    << " solTime:" << SolTime
-    << endl;
+    const int32_t ParentZone = 0;   // Int: 0 = no parent zone
+    const int32_t NumFaceNodes = 2*pp.nEdges();
 
+    const int32_t ShrConn   = 0;
+    const int32_t NumBConns = 0;    // No Boundary Connections
+    const int32_t NumBItems = 0;    // No Boundary Items
 
-    INTEGER4 *PassiveVarArray = nullptr;
-    INTEGER4 *VarShareArray   = nullptr;
-    INTEGER4  ShrConn         = 0;
-
-    INTEGER4  NumBConns       = 0;   /* No Boundary Connections */
-    INTEGER4  NumBItems       = 0;   /* No Boundary Items */
-
-    INTEGER4  ZoneType = ZoneType_FEPolygon;
+    Pout<< "zoneName:" << zoneName
+        << " strandID:" << strandID
+        //<< " varLocArray:" << varLocArray
+        << " solTime:" << SolTime
+        << endl;
 
+    const int32_t ZoneType = ZONE_FEPOLYGON;
     if
     (
-       !TECZNE112
+        teczne142
         (
-            const_cast<char*>(zoneName.c_str()),
-            &ZoneType,
-            &NumNodes,
-            &NumElems,
-            &NumFaces,
-            &ICellMax,
-            &JCellMax,
-            &KCellMax,
-            &SolTime,
-            &strandID,
-            &ParentZone,
-            &IsBlock,
-            &NFConns,
-            &FNMode,
-            &NumFaceNodes,
-            &NumBConns,
-            &NumBItems,
-            PassiveVarArray,
-            const_cast<INTEGER4*>(varLocArray.begin()),
-            VarShareArray,
-            &ShrConn
+            zoneName.c_str(),   //< ZoneTitle
+            &ZoneType,          //< ZoneType
+            &NumNodes,          //< IMax or NumPts
+            &NumElems,          //< JMax or NumElements
+            &NumFaces,          //< KMax or NumFaces
+            &tecConst_0,        //< (Unused set to zero) ICellMax
+            &tecConst_0,        //< (Unused set to zero) JCellMax
+            &tecConst_0,        //< (Unused set to zero) KCellMax
+            &SolTime,           //< SolutionTime
+            &strandID,          //< StrandID
+            &ParentZone,        //< ParentZone
+            &tecConst_True,     //< IsBlock
+            &tecConst_0,        //< (Unused for polygon zone) NumFaceConnections
+            &tecConst_0,        //< (Unused for polygon zone) FaceNeighborMode
+            &NumFaceNodes,      //< TotalNumFaceNodes
+            &NumBConns,         //< NumConnectedBoundaryFaces
+            &NumBItems,         //< TotalNumBoundaryConnections
+            nullptr,            //< PassiveVarList
+            varLocArray.cdata(), //< ValueLocation
+            nullptr,            //< ShareVarFromZone
+            &ShrConn            //< ShareConnectivityFromZone
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECZNE112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in teczne142 - writing polygon zones."
+            << exit(FatalError);
     }
 }
 
@@ -237,120 +213,99 @@ Pout<< "zoneName:" << zoneName
 void Foam::tecplotWriter::writeOrderedZone
 (
     const word& zoneName,
-    INTEGER4 strandID,
+    const int32_t strandID,
     const label n,
-    const List<INTEGER4>& varLocArray
+    const UList<int32_t>& varLocArray
 ) const
 {
-    /* Call TECZNE112 */
-    INTEGER4  IMax   = n;         /* number of unique nodes */
-    INTEGER4  JMax   = 1;         /* number of elements */
-    INTEGER4  KMax   = 1;         /* number of unique faces */
-
-    INTEGER4  ICellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  JCellMax   = 0;         /* Not Used, set to zero */
-    INTEGER4  KCellMax   = 0;         /* Not Used, set to zero */
-
-    double    SolTime    = runTime_.value();     /* solution time   */
-    INTEGER4  ParentZone = 0;         /* no parent zone  */
-
-    INTEGER4  IsBlock    = 1;         /* block format  */
-
-    INTEGER4  NFConns    = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-    INTEGER4  FNMode     = 0;         /* not used for FEPolyhedron
-                                       * zones
-                                       */
-    INTEGER4  NumFaceNodes    = 1;
-    INTEGER4  NumBConns       = 1;   /* No Boundary Connections */
-    INTEGER4  NumBItems       = 1;   /* No Boundary Items */
-
-Pout<< "zoneName:" << zoneName
-    << " strandID:" << strandID
-    //<< " varLocArray:" << varLocArray
-    << " solTime:" << SolTime
-    << endl;
-
-
-    INTEGER4 *PassiveVarArray = nullptr;
-    INTEGER4 *VarShareArray   = nullptr;
-    INTEGER4  ShrConn         = 0;
-
-
-    INTEGER4  ZoneType = ZoneType_Ordered;
-
+    const int32_t IMax = n;     // Number in I direction
+    const int32_t JMax = 1;     // Number in J direction
+    const int32_t KMax = 1;     // Number in K direction
+    const double  SolTime = time_.value();  // Solution time
+
+    const int32_t ParentZone = 0;   // Bool: no parent zone
+    const int32_t NFConns = 0;      // Unused for ordered zones
+    const int32_t FNMode  = 0;      // Unused for ordered zones
+
+    const int32_t ShrConn  = 0;
+    const int32_t NumFaceNodes = 1;
+    const int32_t NumBConns = 0;    // No Boundary Connections
+    const int32_t NumBItems = 0;    // No Boundary Items
+
+    Pout<< "zoneName:" << zoneName
+        << " strandID:" << strandID
+        //<< " varLocArray:" << varLocArray
+        << " solTime:" << SolTime
+        << endl;
+
+    const int32_t ZoneType = ZONE_ORDERED;
     if
     (
-       !TECZNE112
+        teczne142
         (
-            const_cast<char*>(zoneName.c_str()),
-            &ZoneType,
-            &IMax,
-            &JMax,
-            &KMax,
-            &ICellMax,
-            &JCellMax,
-            &KCellMax,
-            &SolTime,
-            &strandID,
-            &ParentZone,
-            &IsBlock,
-            &NFConns,
-            &FNMode,
-            &NumFaceNodes,
-            &NumBConns,
-            &NumBItems,
-            PassiveVarArray,
-            const_cast<INTEGER4*>(varLocArray.begin()),
-            VarShareArray,
-            &ShrConn
+            zoneName.c_str(),   //< ZoneTitle
+            &ZoneType,          //< ZoneType
+            &IMax,              //< IMax or NumPts
+            &JMax,              //< JMax or NumElements
+            &KMax,              //< KMax or NumFaces
+            &tecConst_0,        //< (Unused set to zero) ICellMax
+            &tecConst_0,        //< (Unused set to zero) JCellMax
+            &tecConst_0,        //< (Unused set to zero) KCellMax
+            &SolTime,           //< SolutionTime
+            &strandID,          //< StrandID
+            &ParentZone,        //< ParentZone
+            &tecConst_True,     //< IsBlock
+            &NFConns,           //< NumFaceConnections
+            &FNMode,            //< FaceNeighborMode
+            &NumFaceNodes,      //< TotalNumFaceNodes
+            &NumBConns,         //< NumConnectedBoundaryFaces
+            &NumBItems,         //< TotalNumBoundaryConnections
+            nullptr,            //< PassiveVarList
+            varLocArray.cdata(), //< ValueLocation
+            nullptr,            //< ShareVarFromZone
+            &ShrConn            //< ShareConnectivityFromZone
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECZNE112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in teczne142 - writing ordered zones."
+            << exit(FatalError);
     }
 }
 
 
 void Foam::tecplotWriter::writeConnectivity(const fvMesh& mesh) const
 {
-    List<INTEGER4> FaceNodeCounts(mesh.nFaces());
-
+    // first pass: get the sizes
+    List<int32_t> FaceNodeCounts(mesh.nFaces());
+    label nFaceNodes = 0;
     forAll(mesh.faces(), facei)
     {
         const face& f = mesh.faces()[facei];
-        FaceNodeCounts[facei] = INTEGER4(f.size());
-    }
-
-
-    INTEGER4 nFaceNodes = 0;
-    forAll(mesh.faces(), facei)
-    {
-        nFaceNodes += mesh.faces()[facei].size();
+        nFaceNodes += f.size();
+        FaceNodeCounts[facei] = int32_t(f.size());
     }
 
-
-    List<INTEGER4> FaceNodes(nFaceNodes);
+    // second pass: get the nodes as a flat list
+    List<int32_t> FaceNodes(nFaceNodes);
     label nodeI = 0;
     forAll(mesh.faces(), facei)
     {
         const face& f = mesh.faces()[facei];
         forAll(f, fp)
         {
-            FaceNodes[nodeI++] = INTEGER4(f[fp]+1);
+            FaceNodes[nodeI++] = int32_t(f[fp]+1);
         }
     }
 
 
-    List<INTEGER4> FaceLeftElems(mesh.nFaces());
+    List<int32_t> FaceLeftElems(mesh.nFaces());
     forAll(mesh.faceOwner(), facei)
     {
         FaceLeftElems[facei] = mesh.faceOwner()[facei]+1;
     }
 
-    List<INTEGER4> FaceRightElems(mesh.nFaces());
+    List<int32_t> FaceRightElems(mesh.nFaces());
     forAll(mesh.faceNeighbour(), facei)
     {
         FaceRightElems[facei] = mesh.faceNeighbour()[facei]+1;
@@ -367,20 +322,21 @@ void Foam::tecplotWriter::writeConnectivity(const fvMesh& mesh) const
 
     if
     (
-       !TECPOLY112
+        tecpoly142
         (
-            FaceNodeCounts.begin(), /* The face node counts array */
-            FaceNodes.begin(),      /* The face nodes array */
-            FaceLeftElems.begin(),  /* The left elements array  */
-            FaceRightElems.begin(), /* The right elements array  */
-            nullptr,       /* No boundary connection counts */
-            nullptr,       /* No boundary connection elements */
-            nullptr        /* No boundary connection zones */
+            FaceNodeCounts.cdata(), // The face node counts array
+            FaceNodes.cdata(),      // The face nodes array
+            FaceLeftElems.cdata(),  // The left elements array
+            FaceRightElems.cdata(), // The right elements array
+            nullptr,       // No face boundary connection counts
+            nullptr,       // No face boundary connection elements
+            nullptr        // No face boundary connection zones
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECPOLY112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in tecpoly142."
+            << exit(FatalError);
     }
 }
 
@@ -389,25 +345,25 @@ void Foam::tecplotWriter::writeConnectivity
     const indirectPrimitivePatch& pp
 ) const
 {
-    INTEGER4  NumFaces   = pp.nEdges();         /* number of unique faces */
-    INTEGER4  NumFaceNodes    = 2*pp.nEdges();
+    const int32_t NumFaces     = pp.nEdges();   // Number of unique faces
+    const int32_t NumFaceNodes = 2*NumFaces;    // 2 nodes per edge
 
     // All faces (=edges) have 2 nodes
-    List<INTEGER4> FaceNodeCounts(NumFaces);
+    List<int32_t> FaceNodeCounts(NumFaces);
     FaceNodeCounts = 2;
 
-    List<INTEGER4> FaceNodes(NumFaceNodes);
+    List<int32_t> FaceNodes(NumFaceNodes);
     label nodeI = 0;
-    forAll(pp.edges(), edgeI)
+    forAll(pp.edges(), edgei)
     {
-        edge e = pp.edges()[edgeI];
+        edge e = pp.edges()[edgei];
         if (e[0] > e[1])
         {
             e.flip();
         }
 
-        FaceNodes[nodeI++] = INTEGER4(e[0]+1);
-        FaceNodes[nodeI++] = INTEGER4(e[1]+1);
+        FaceNodes[nodeI++] = int32_t(e[0]+1);
+        FaceNodes[nodeI++] = int32_t(e[1]+1);
     }
 
     /* Define the right and left elements of each face.
@@ -430,22 +386,22 @@ void Foam::tecplotWriter::writeConnectivity
      * (element 0).
      */
 
-    List<INTEGER4> FaceLeftElems(NumFaces);
-    List<INTEGER4> FaceRightElems(NumFaces);
+    List<int32_t> FaceLeftElems(NumFaces);
+    List<int32_t> FaceRightElems(NumFaces);
 
     const labelListList& edgeFaces = pp.edgeFaces();
-    forAll(edgeFaces, edgeI)
+    forAll(edgeFaces, edgei)
     {
-        const labelList& eFaces = edgeFaces[edgeI];
+        const labelList& eFaces = edgeFaces[edgei];
 
         if (eFaces.size() == 1)
         {
-            FaceLeftElems[edgeI] = 0;
-            FaceRightElems[edgeI] = eFaces[0]+1;
+            FaceLeftElems[edgei]  = 0;
+            FaceRightElems[edgei] = eFaces[0]+1;
         }
         else if (eFaces.size() == 2)
         {
-            edge e = pp.edges()[edgeI];
+            edge e = pp.edges()[edgei];
             if (e[0] > e[1])
             {
                 e.flip();
@@ -456,59 +412,60 @@ void Foam::tecplotWriter::writeConnectivity
             // The face that uses the vertices of e in increasing order
             // is the left face.
 
-            label fp = findIndex(f0, e[0]);
-            bool f0IsLeft = (f0.nextLabel(fp) == e[1]);
+            const label fp = findIndex(f0, e[0]);
+            const bool f0IsLeft = (f0.nextLabel(fp) == e[1]);
 
             if (f0IsLeft)
             {
-                FaceLeftElems[edgeI] = eFaces[0]+1;
-                FaceRightElems[edgeI] = eFaces[1]+1;
+                FaceLeftElems[edgei]  = eFaces[0]+1;
+                FaceRightElems[edgei] = eFaces[1]+1;
             }
             else
             {
-                FaceLeftElems[edgeI] = eFaces[1]+1;
-                FaceRightElems[edgeI] = eFaces[0]+1;
+                FaceLeftElems[edgei]  = eFaces[1]+1;
+                FaceRightElems[edgei] = eFaces[0]+1;
             }
         }
         else
         {
             // non-manifold. Treat as if open.
-            FaceLeftElems[edgeI] = 0;
-            FaceRightElems[edgeI] = eFaces[0]+1;
+            FaceLeftElems[edgei]  = 0;
+            FaceRightElems[edgei] = eFaces[0]+1;
         }
     }
 
-    /* Write the face map (created above) using TECPOLY112. */
+    // Write the face map (created above)
     if
     (
-       !TECPOLY112
+        tecpoly142
         (
-            FaceNodeCounts.begin(), /* The face node counts array */
-            FaceNodes.begin(),      /* The face nodes array */
-            FaceLeftElems.begin(),  /* The left elements array  */
-            FaceRightElems.begin(), /* The right elements array  */
-            nullptr,       /* No boundary connection counts */
-            nullptr,       /* No boundary connection elements */
-            nullptr        /* No boundary connection zones */
+            FaceNodeCounts.cdata(),     // Face node counts array
+            FaceNodes.cdata(),          // Face nodes array
+            FaceLeftElems.cdata(),      // Left elements array
+            FaceRightElems.cdata(),     // Right elements array
+            nullptr,                    // No boundary connection counts
+            nullptr,                    // No boundary connection elements
+            nullptr                     // No boundary connection zones
         )
     )
     {
-//        FatalErrorInFunction
-//            << "Error in TECPOLY112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in tecpoly142."
+            << exit(FatalError);
     }
 }
 
 
 void Foam::tecplotWriter::writeEnd() const
 {
-Pout<< "writeEnd" << endl;
+    Pout<< "writeEnd" << endl;
 
-    if (!TECEND112())
+    if (tecend142())
     {
-//        FatalErrorInFunction
-//            << "Error in TECEND112." << exit(FatalError);
+        FatalErrorInFunction
+            << "Error in tecend142."
+            << exit(FatalError);
     }
-
 }
 
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.H b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.H
index d00bec355794d312aa32cfa55aa6cbb7f0e970aa..1631545fc62a19d020fd0508513326e94bde59f5 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,6 +27,11 @@ Class
 Description
     Write binary tecplot files using tecio.
 
+Note
+    The tecplot API uses pass by reference for all routines.
+    Its standard integer is defined as INTEGER4 (ie, int32_t),
+    which is also used when passing boolean values.
+
 SourceFiles
     tecplotWriter.C
     tecplotWriterTemplates.C
@@ -36,14 +41,11 @@ SourceFiles
 #ifndef tecplotWriter_H
 #define tecplotWriter_H
 
-#include "TECIO.h"
 #include "Time.H"
 #include "indirectPrimitivePatch.H"
 #include "volFields.H"
 #include "surfaceFields.H"
 
-using namespace Foam;
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -52,15 +54,76 @@ namespace Foam
 class fvMesh;
 
 /*---------------------------------------------------------------------------*\
-                           Class tecplotWriter Declaration
+                        Class tecplotWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 class tecplotWriter
 {
-    const Time& runTime_;
+    //- Tecplot ZoneTypes
+    enum tecplotZoneType
+    {
+        ZONE_ORDERED         = 0,
+        ZONE_FELINESEG       = 1,
+        ZONE_FETRIANGLE      = 2,
+        ZONE_FEQUADRILATERAL = 3,
+        ZONE_FETETRAHEDRON   = 4,
+        ZONE_FEBRICK         = 5,
+        ZONE_FEPOLYGON       = 6,
+        ZONE_FEPOLYHEDRON    = 7
+    };
+
+
+    // Static data members
+
+        // Values commonly used internally
+        static const int32_t tecConst_0;
+        static const int32_t tecConst_1;
+        static const int32_t tecConst_False;
+        static const int32_t tecConst_True;
+
+
+    // Private data
+
+        //- Time reference. Used for paths and the solution time.
+        const Time& time_;
+
+
+    // Private Member Functions
+
+        template<class GeoField>
+        static wordList getNames(const PtrList<const GeoField>&);
+
+        //- Disallow default bitwise copy construct
+        tecplotWriter(const tecplotWriter&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const tecplotWriter&) = delete;
 
 public:
 
+    //- Data location types
+    enum dataLocation
+    {
+        CELL_CENTERED = 0,
+        NODE_CENTERED = 1
+    };
+
+
+    //- Data file type
+    enum dataFileType
+    {
+        FILETYPE_FULL = 0,
+        FILETYPE_GRID = 1,
+        FILETYPE_SOLUTION = 2
+    };
+
+
+    // Static data members
+
+        //- Commonly used "X Y Z" string
+        static const string XYZ;
+
+
     // Constructors
 
         //- Construct from components
@@ -69,92 +132,103 @@ public:
 
     // Member Functions
 
+        //- Initialize writing
         void writeInit
         (
             const word& name,
             const string& varNames,
             const fileName&,
-            INTEGER4 tecplotFileType
+            const dataFileType fileType
         ) const;
 
         //- Write mesh as polyhedral zone
         void writePolyhedralZone
         (
             const word& zoneName,
-            const INTEGER4 strandID,
+            const int32_t strandID,
             const fvMesh& mesh,
-            const List<INTEGER4>& varLocArray,
-            INTEGER4 nFaceNodes
+            const UList<int32_t>& varLocArray,
+            const int32_t NumFaceNodes
         ) const;
 
         //- Write surface as polygonal zone
         void writePolygonalZone
         (
             const word& zoneName,
-            const INTEGER4 strandID,
+            const int32_t strandID,
             const indirectPrimitivePatch& pp,
-            const List<INTEGER4>& varLocArray
+            const UList<int32_t>& varLocArray
         ) const;
 
         //- Write unordered data (or rather 1D ordered)
         void writeOrderedZone
         (
             const word& zoneName,
-            INTEGER4 strandID,
+            const int32_t strandID,
             const label n,
-            const List<INTEGER4>& varLocArray
+            const UList<int32_t>& varLocArray
         ) const;
 
         //- Write mesh
-        void writeConnectivity(const fvMesh& mesh) const;
+        void writeConnectivity(const fvMesh&) const;
 
         //- Write surface
         void writeConnectivity(const indirectPrimitivePatch& pp) const;
 
+        //- Finalize writing
         void writeEnd() const;
 
-        //- Write generic Field
+
+        //- Write generic Field, component-wise
         template<class Type>
-        void writeField(const Field<Type>& fld) const;
+        void writeField(const Field<Type>&) const;
+
+        //- Write generic Field, component-wise
+        template<class Type>
+        void writeField(const tmp<Field<Type>>&) const;
+
+        //- Write all fields listed
+        template<class GeoField>
+        void writeFields(const PtrList<const GeoField>&) const;
 
 
         //- Get either fvPatchField or patchInternalField
         template<class Type>
-        tmp<Field<Type>> getPatchField
+        static tmp<Field<Type>> getPatchField
         (
             const bool nearCellValue,
-            const GeometricField<Type, fvPatchField, volMesh>& vfld,
+            const GeometricField<Type, fvPatchField, volMesh>&,
             const label patchi
-        ) const;
+        );
 
         //- Get mixed field: fvsPatchField for boundary faces and
         //  internalField for internal faces.
         template<class Type>
-        tmp<Field<Type>> getFaceField
+        static tmp<Field<Type>> getFaceField
         (
             const GeometricField<Type, fvsPatchField, surfaceMesh>&,
-            const labelList& faceLabels
-        ) const;
+            const labelUList& faceLabels
+        );
 
-        template<class GeoField>
-        static wordList getNames(const PtrList<GeoField>&);
 
+        //- Fill in tecplot names/locations for the given input names
         template<class Type>
         static void getTecplotNames
         (
             const wordList& names,
-            const INTEGER4 loc,
+            const int32_t loc,
             string& varNames,
-            DynamicList<INTEGER4>& varLocation
+            DynamicList<int32_t>& varLocation
         );
 
+        //- Fill in tecplot names/locations for the given input fields
         template<class GeoField>
         static void getTecplotNames
         (
             const PtrList<GeoField>& flds,
-            const INTEGER4 loc,
+            const int32_t loc,
             string& varNames,
-            DynamicList<INTEGER4>& varLocation
+            DynamicList<int32_t>& varLocation
         );
 
 };
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriterTemplates.C
index 7d8496faabdef0ae0451c87b003072a85f384308..03ad615e6a08904284cb75863ac5aaa7993f576e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriterTemplates.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecplotWriterTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -23,14 +23,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-//extern "C"
-//{
-    #include "MASTER.h"
-    #include "GLOBAL.h"
-//}
-
 #include "tecplotWriter.H"
-
+#include "TECIO.h"
 #include "fvc.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -38,39 +32,71 @@ License
 template<class Type>
 void Foam::tecplotWriter::writeField(const Field<Type>& fld) const
 {
-    for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
+    typedef typename pTraits<Type>::cmptType cmptType;
+
+    for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; ++cmpt)
     {
-        scalarField cmptFld(fld.component(cmpt));
+        tmp<Field<cmptType>> tcmptFld = fld.component(cmpt);
+        const Field<cmptType>& cmptFld = tcmptFld();
+
+        const int32_t size = int32_t(cmptFld.size());
 
         // Convert to float
-        Field<float> floats(cmptFld.size());
+        Field<float> floats(size);
         forAll(cmptFld, i)
         {
             floats[i] = float(cmptFld[i]);
         }
 
-        INTEGER4 size = INTEGER4(floats.size());
-        INTEGER4 IsDouble = 0;  //float
-
         //Pout<< "Writing component:" << cmpt << " of size:" << size
         //    << " floats." << endl;
 
-        if (!TECDAT112(&size, floats.begin(), &IsDouble))
+        if
+        (
+            tecdat142
+            (
+                &size,
+                floats.cdata(),
+                &tecConst_False     //< VIsDouble (0: single, 1: double)
+            )
+        )
         {
-//            FatalErrorInFunction
-//                << "Error in TECDAT112." << exit(FatalError);
+            FatalErrorInFunction
+                << "Error in tecdat142."
+                << exit(FatalError);
         }
     }
 }
 
 
 template<class Type>
-Foam::tmp<Field<Type>> Foam::tecplotWriter::getPatchField
+void Foam::tecplotWriter::writeField(const tmp<Field<Type>>& tfld) const
+{
+    writeField(tfld());
+}
+
+
+template<class GeoField>
+void Foam::tecplotWriter::writeFields
+(
+    const PtrList<const GeoField>& flds
+) const
+{
+    forAll(flds, i)
+    {
+        writeField(flds[i]);
+    }
+}
+
+
+template<class Type>
+Foam::tmp<Foam::Field<Type>>
+Foam::tecplotWriter::getPatchField
 (
     const bool nearCellValue,
     const GeometricField<Type, fvPatchField, volMesh>& vfld,
     const label patchi
-) const
+)
 {
     if (nearCellValue)
     {
@@ -84,11 +110,12 @@ Foam::tmp<Field<Type>> Foam::tecplotWriter::getPatchField
 
 
 template<class Type>
-Foam::tmp<Field<Type>> Foam::tecplotWriter::getFaceField
+Foam::tmp<Foam::Field<Type>>
+Foam::tecplotWriter::getFaceField
 (
     const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld,
-    const labelList& faceLabels
-) const
+    const labelUList& faceLabels
+)
 {
     const polyBoundaryMesh& patches = sfld.mesh().boundaryMesh();
 
@@ -97,9 +124,8 @@ Foam::tmp<Field<Type>> Foam::tecplotWriter::getFaceField
 
     forAll(faceLabels, i)
     {
-        label facei = faceLabels[i];
-
-        label patchi = patches.whichPatch(facei);
+        const label facei  = faceLabels[i];
+        const label patchi = patches.whichPatch(facei);
 
         if (patchi == -1)
         {
@@ -117,9 +143,10 @@ Foam::tmp<Field<Type>> Foam::tecplotWriter::getFaceField
 
 
 template<class GeoField>
-Foam::wordList Foam::tecplotWriter::getNames
+Foam::wordList
+Foam::tecplotWriter::getNames
 (
-    const PtrList<GeoField>& flds
+    const PtrList<const GeoField>& flds
 )
 {
     wordList names(flds.size());
@@ -135,11 +162,13 @@ template<class Type>
 void Foam::tecplotWriter::getTecplotNames
 (
     const wordList& names,
-    const INTEGER4 loc,
+    const int32_t loc,
     string& varNames,
-    DynamicList<INTEGER4>& varLocation
+    DynamicList<int32_t>& varLocation
 )
 {
+    const direction nCmpts = pTraits<Type>::nComponents;
+
     forAll(names, i)
     {
         if (!varNames.empty())
@@ -147,8 +176,6 @@ void Foam::tecplotWriter::getTecplotNames
             varNames += " ";
         }
 
-        label nCmpts = pTraits<Type>::nComponents;
-
         if (nCmpts == 1)
         {
             varNames += names[i];
@@ -156,19 +183,13 @@ void Foam::tecplotWriter::getTecplotNames
         }
         else
         {
-            for
-            (
-                direction cmpt = 0;
-                cmpt < nCmpts;
-                cmpt++
-            )
+            for (direction cmpt = 0; cmpt < nCmpts; ++cmpt)
             {
-                string fldName =
-                    (cmpt != 0 ? " " : string::null)
-                  + names[i]
-                  + "_"
-                  + pTraits<Type>::componentNames[cmpt];
-                varNames += fldName;
+                varNames +=
+                (
+                    (cmpt ? " " : string::null)
+                  + names[i] + "_" + pTraits<Type>::componentNames[cmpt]
+                );
                 varLocation.append(loc);
             }
         }
@@ -180,9 +201,9 @@ template<class GeoField>
 void Foam::tecplotWriter::getTecplotNames
 (
     const PtrList<GeoField>& flds,
-    const INTEGER4 loc,
+    const int32_t loc,
     string& varNames,
-    DynamicList<INTEGER4>& varLocation
+    DynamicList<int32_t>& varLocation
 )
 {
     getTecplotNames<typename GeoField::value_type>
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.C b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.C
deleted file mode 100644
index 0a58e5d523c41724e0c4ca743a5daef9aab2fa4e..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.C
+++ /dev/null
@@ -1,83 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "vtkMesh.H"
-#include "fvMeshSubset.H"
-#include "Time.H"
-#include "cellSet.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-// Construct from components
-Foam::vtkMesh::vtkMesh
-(
-    fvMesh& baseMesh,
-    const word& setName
-)
-:
-    baseMesh_(baseMesh),
-    subsetter_(baseMesh),
-    setName_(setName)
-{
-    if (setName.size())
-    {
-        // Read cellSet using whole mesh
-        cellSet currentSet(baseMesh_, setName_);
-
-        // Set current subset
-        subsetter_.setLargeCellSubset(currentSet);
-    }
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-Foam::polyMesh::readUpdateState Foam::vtkMesh::readUpdate()
-{
-    polyMesh::readUpdateState meshState = baseMesh_.readUpdate();
-
-    if (meshState != polyMesh::UNCHANGED)
-    {
-        // Note: since fvMeshSubset has no movePoints() functionality
-        // reconstruct the subset even if only movement.
-
-//        topoPtr_.clear();
-
-        if (setName_.size())
-        {
-            Info<< "Subsetting mesh based on cellSet " << setName_ << endl;
-
-            // Read cellSet using whole mesh
-            cellSet currentSet(baseMesh_, setName_);
-
-            subsetter_.setLargeCellSubset(currentSet);
-        }
-    }
-
-    return meshState;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.H b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.H
deleted file mode 100644
index ec6045b5341b0516fd7742ec5f7a84f215d60f19..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/vtkMesh.H
+++ /dev/null
@@ -1,178 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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::vtkMesh
-
-Description
-    Encapsulation of VTK mesh data. Holds mesh or meshsubset and
-    polyhedral-cell decomposition on it.
-
-SourceFiles
-    vtkMesh.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkMesh_H
-#define vtkMesh_H
-
-#include "fvMeshSubset.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// Forward declaration of classes
-class Time;
-
-/*---------------------------------------------------------------------------*\
-                           Class vtkMesh Declaration
-\*---------------------------------------------------------------------------*/
-
-class vtkMesh
-{
-    // Private data
-
-        //- Reference to mesh
-        fvMesh& baseMesh_;
-
-        //- Subsetting engine + sub-fvMesh
-        fvMeshSubset subsetter_;
-
-        //- Current cellSet (or empty)
-        const word setName_;
-
-//        //- Current decomposition of topology
-//        mutable autoPtr<vtkTopo> topoPtr_;
-
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        vtkMesh(const vtkMesh&);
-
-        //- Disallow default bitwise assignment
-        void operator=(const vtkMesh&);
-
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        vtkMesh(fvMesh& baseMesh, const word& setName = "");
-
-
-    // Member Functions
-
-        // Access
-
-            //- Whole mesh
-            const fvMesh& baseMesh() const
-            {
-                return baseMesh_;
-            }
-
-            const fvMeshSubset& subsetter() const
-            {
-                return subsetter_;
-            }
-
-            //- Check if running subMesh
-            bool useSubMesh() const
-            {
-                return setName_.size();
-            }
-
-//            //- topology
-//            const vtkTopo& topo() const
-//            {
-//                if (topoPtr_.empty())
-//                {
-//                    topoPtr_.reset(new vtkTopo(mesh()));
-//                }
-//                return topoPtr_();
-//            }
-
-            //- Access either mesh or submesh
-            const fvMesh& mesh() const
-            {
-                if (useSubMesh())
-                {
-                    return subsetter_.subMesh();
-                }
-                else
-                {
-                    return baseMesh_;
-                }
-            }
-
-//            //- Number of field cells
-//            label nFieldCells() const
-//            {
-//                return topo().vertLabels().size();
-//            }
-//
-//            //- Number of field points
-//            label nFieldPoints() const
-//            {
-//                return mesh().nPoints() + topo().addPointCellLabels().size();
-//            }
-
-
-        // Edit
-
-            //- Read mesh
-            polyMesh::readUpdateState readUpdate();
-
-
-            //- Map volume field (does in fact do very little interpolation;
-            //  just copied from fvMeshSubset)
-            template<class GeoField>
-            tmp<GeoField> interpolate(const GeoField& fld) const
-            {
-                if (useSubMesh())
-                {
-                    tmp<GeoField> subFld = subsetter_.interpolate(fld);
-                    subFld.ref().rename(fld.name());
-                    return subFld;
-                }
-                else
-                {
-                    return fld;
-                }
-            }
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C
index 4e42b5afbfaa25c7e4275541de7c96e959aad0f7..c2a6f3b29810977ee869310d9c56f5feb2463420 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C
@@ -410,7 +410,6 @@ int main(int argc, char *argv[])
     args.optionReadIfPresent("pointSet", pointSetName);
 
 
-
     instantList timeDirs = timeSelector::select0(runTime, args);
 
     #include "createNamedMesh.H"
@@ -450,7 +449,7 @@ int main(int argc, char *argv[])
 
     mkDir(fvPath);
 
-    // Mesh wrapper; does subsetting and decomposition
+    // Mesh wrapper: does subsetting and decomposition
     vtkMesh vMesh(mesh, cellSetName);
 
     Info<< "VTK mesh topology: "
@@ -503,7 +502,7 @@ int main(int argc, char *argv[])
 
             Info<< "    FaceSet   : " << patchFileName << endl;
 
-            writeFaceSet(binary, vMesh, set, patchFileName);
+            writeFaceSet(binary, vMesh.mesh(), set, patchFileName);
 
             continue;
         }
@@ -526,7 +525,7 @@ int main(int argc, char *argv[])
 
             Info<< "    pointSet   : " << patchFileName << endl;
 
-            writePointSet(binary, vMesh, set, patchFileName);
+            writePointSet(binary, vMesh.mesh(), set, patchFileName);
 
             continue;
         }
@@ -849,7 +848,7 @@ int main(int argc, char *argv[])
                 writeSurfFields
                 (
                     binary,
-                    vMesh,
+                    vMesh.mesh(),
                     surfFileName,
                     svf
                 );
@@ -892,7 +891,7 @@ int main(int argc, char *argv[])
 
             patchWriter writer
             (
-                vMesh,
+                vMesh.mesh(),
                 binary,
                 nearCellValue,
                 patchFileName,
@@ -970,7 +969,7 @@ int main(int argc, char *argv[])
 
                     patchWriter writer
                     (
-                        vMesh,
+                        vMesh.mesh(),
                         binary,
                         nearCellValue,
                         patchFileName,
@@ -1188,7 +1187,7 @@ int main(int argc, char *argv[])
 
                 lagrangianWriter writer
                 (
-                    vMesh,
+                    vMesh.mesh(),
                     binary,
                     lagrFileName,
                     cloudName,
@@ -1218,7 +1217,7 @@ int main(int argc, char *argv[])
             {
                 lagrangianWriter writer
                 (
-                    vMesh,
+                    vMesh.mesh(),
                     binary,
                     lagrFileName,
                     cloudName,
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files
index 4deaaa68f07c4ac1117eb8673149c90d195bc8f2..02de5b47e6254aab58ae3557c2f7e2342b7df753 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/Make/files
@@ -6,7 +6,6 @@ writeFuns.C
 writeFaceSet.C
 writePointSet.C
 writeSurfFields.C
-vtkMesh.C
 vtkTopo.C
 
 writeVTK/writeVTK.C
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H
index b61cfd6377aed05e7d85fe681a648c6ef1c63deb..b1836afb60e16c05542594272367a3ea69fdea25 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/internalWriter.H
@@ -41,8 +41,6 @@ SourceFiles
 #include "pointFields.H"
 #include "vtkMesh.H"
 
-using namespace Foam;
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C
index 6c168a22805b4218ecf89f1366cb15ffb77d3815..6eab8f164666e4767559491354f705df14cc4418 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,23 +32,21 @@ License
 
 Foam::lagrangianWriter::lagrangianWriter
 (
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const bool binary,
     const fileName& fName,
     const word& cloudName,
     const bool dummyCloud
 )
 :
-    vMesh_(vMesh),
+    mesh_(mesh),
     binary_(binary),
     fName_(fName),
     cloudName_(cloudName),
     os_(fName.c_str())
 {
-    const fvMesh& mesh = vMesh_.mesh();
-
     // Write header
-    writeFuns::writeHeader(os_, binary_, mesh.time().caseName());
+    writeFuns::writeHeader(os_, binary_, mesh_.time().caseName());
     os_ << "DATASET POLYDATA" << std::endl;
 
     if (dummyCloud)
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H
index 113bfe43b0a399554f61dd0d1614491554d91d0a..24dd4a322872c92eb6f2dfa32474c7c676e728d3 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,9 +40,6 @@ SourceFiles
 #include "Cloud.H"
 #include "volFields.H"
 #include "pointFields.H"
-#include "vtkMesh.H"
-
-using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -57,7 +54,7 @@ class volPointInterpolation;
 
 class lagrangianWriter
 {
-    const vtkMesh& vMesh_;
+    const fvMesh& mesh_;
 
     const bool binary_;
 
@@ -77,7 +74,7 @@ public:
         //- Construct from components
         lagrangianWriter
         (
-            const vtkMesh&,
+            const fvMesh&,
             const bool binary,
             const fileName&,
             const word&,
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C
index 8d34517dca577652c338114abe8c990fab4816c8..86cec10dc3ee015598988d5ee2b71c5ed036fc0c 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/lagrangianWriterTemplates.C
@@ -39,9 +39,9 @@ void Foam::lagrangianWriter::writeIOField(const wordList& objects)
         IOobject header
         (
             object,
-            vMesh_.mesh().time().timeName(),
+            mesh_.time().timeName(),
             cloud::prefix/cloudName_,
-            vMesh_.mesh(),
+            mesh_,
             IOobject::MUST_READ,
             IOobject::NO_WRITE,
             false
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C
index 4a9840c1e271d18aa0314b75bf6463cdc388abae..d099745aa259b8f59f9029a52af2b1725a8859c3 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,21 +30,20 @@ License
 
 Foam::patchWriter::patchWriter
 (
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const bool binary,
     const bool nearCellValue,
     const fileName& fName,
     const labelList& patchIDs
 )
 :
-    vMesh_(vMesh),
+    mesh_(mesh),
     binary_(binary),
     nearCellValue_(nearCellValue),
     fName_(fName),
     patchIDs_(patchIDs),
     os_(fName.c_str())
 {
-    const fvMesh& mesh = vMesh_.mesh();
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
     // Write header
@@ -115,8 +114,6 @@ Foam::patchWriter::patchWriter
 
 void Foam::patchWriter::writePatchIDs()
 {
-    const fvMesh& mesh = vMesh_.mesh();
-
     DynamicList<floatScalar> fField(nFaces_);
 
     os_ << "patchID 1 " << nFaces_ << " float" << std::endl;
@@ -125,7 +122,7 @@ void Foam::patchWriter::writePatchIDs()
     {
         label patchi = patchIDs_[i];
 
-        const polyPatch& pp = mesh.boundaryMesh()[patchi];
+        const polyPatch& pp = mesh_.boundaryMesh()[patchi];
 
         if (!isA<emptyPolyPatch>(pp))
         {
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H
index e25bbb1122414163f440f685bc5a6688c92b3cef..aab8075da87052a6ebc22fdc00cbf041e8aede05 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/patchWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,12 +40,9 @@ SourceFiles
 #include "OFstream.H"
 #include "volFields.H"
 #include "pointFields.H"
-#include "vtkMesh.H"
 #include "indirectPrimitivePatch.H"
 #include "PrimitivePatchInterpolation.H"
 
-using namespace Foam;
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -59,7 +56,8 @@ class volPointInterpolation;
 
 class patchWriter
 {
-    const vtkMesh& vMesh_;
+    //- Reference to the OpenFOAM mesh (or subset)
+    const fvMesh& mesh_;
 
     const bool binary_;
 
@@ -82,7 +80,7 @@ public:
         //- Construct from components
         patchWriter
         (
-            const vtkMesh&,
+            const fvMesh&,
             const bool binary,
             const bool nearCellValue,
             const fileName&,
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C
index 8d515ab056391eef21df4e8177d942e254eb98a7..172a83cf2399cd5f8d4b8678d6e1531fcc16929a 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,37 +36,32 @@ namespace Foam
 template<class GeoField>
 void readFields
 (
-    const vtkMesh& vMesh,
+    const meshSubsetHelper& helper,
     const typename GeoField::Mesh& mesh,
     const IOobjectList& objects,
     const HashSet<word>& selectedFields,
     PtrList<const GeoField>& fields
 )
 {
-    // Search list of objects for volScalarFields
+    // Search list of objects for fields of type GeomField
     IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
 
-    // Construct the vol scalar fields
+    // Construct the fields
     fields.setSize(fieldObjects.size());
     label nFields = 0;
 
-    forAllIter(IOobjectList, fieldObjects, iter)
+    forAllConstIter(IOobjectList, fieldObjects, iter)
     {
         if (selectedFields.empty() || selectedFields.found(iter()->name()))
         {
             fields.set
             (
-                nFields,
-                vMesh.interpolate
+                nFields++,
+                helper.interpolate
                 (
-                    GeoField
-                    (
-                        *iter(),
-                        mesh
-                    )
+                    GeoField(*iter(), mesh)
                 ).ptr()
             );
-            nFields++;
         }
     }
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H
index 31b7e2632c84a7e493e0f4cd5defd3cf5b0e4c56..510bd11d2536419dea3c29bfce016e2dbd5ddd8e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/readFields.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,7 +34,7 @@ SourceFiles
 #ifndef readFields_H
 #define readFields_H
 
-#include "fvMesh.H"
+#include "meshSubsetHelper.H"
 #include "PtrList.H"
 #include "IOobjectList.H"
 #include "HashSet.H"
@@ -48,7 +48,7 @@ namespace Foam
 template<class GeoField>
 void readFields
 (
-    const vtkMesh& vMesh,
+    const meshSubsetHelper&,
     const typename GeoField::Mesh& mesh,
     const IOobjectList& objects,
     const HashSet<word>& selectedFields,
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H
index f06da45c3f7f94576fb397e326d3596d60d0b65d..0a5589c26e7edbe6866388d9bb55936b45d02d37 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriter.H
@@ -40,11 +40,8 @@ SourceFiles
 #include "OFstream.H"
 #include "volFields.H"
 #include "surfaceFields.H"
-#include "vtkMesh.H"
 #include "indirectPrimitivePatch.H"
 
-using namespace Foam;
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C
index 68fd29d257b538d3b36a789daba2bba931c55d08..92d878f2292b534fe915f2c5e8bae4ed2056fff2 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/surfaceMeshWriterTemplates.C
@@ -29,7 +29,8 @@ License
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::tmp<Field<Type>> Foam::surfaceMeshWriter::getFaceField
+Foam::tmp<Foam::Field<Type>>
+Foam::surfaceMeshWriter::getFaceField
 (
     const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
 ) const
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H
index f536ae04fa2f7e27faa7baf121366ba63e988fc4..f0a80db4ead04f7e4e1c13d77c488225d5acb809 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,46 +36,35 @@ SourceFiles
 #ifndef vtkMesh_H
 #define vtkMesh_H
 
+#include "meshSubsetHelper.H"
 #include "vtkTopo.H"
-#include "fvMeshSubset.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// Forward declaration of classes
-class Time;
-
 /*---------------------------------------------------------------------------*\
                            Class vtkMesh Declaration
 \*---------------------------------------------------------------------------*/
 
 class vtkMesh
+:
+    public meshSubsetHelper
 {
     // Private data
 
-        //- Reference to mesh
-        fvMesh& baseMesh_;
-
-        //- Subsetting engine + sub-fvMesh
-        fvMeshSubset subsetter_;
-
-        //- Current cellSet (or empty)
-        const word setName_;
-
         //- Current decomposition of topology
         mutable autoPtr<vtkTopo> topoPtr_;
 
 
-
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        vtkMesh(const vtkMesh&);
+        vtkMesh(const vtkMesh&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const vtkMesh&);
+        void operator=(const vtkMesh&) = delete;
 
 
 public:
@@ -83,31 +72,17 @@ public:
     // Constructors
 
         //- Construct from components
-        vtkMesh(fvMesh& baseMesh, const word& setName = "");
+        vtkMesh(fvMesh& baseMesh, const word& setName = word::null)
+        :
+            meshSubsetHelper(baseMesh, meshSubsetHelper::SET, setName)
+        {}
 
 
     // Member Functions
 
         // Access
 
-            //- Whole mesh
-            const fvMesh& baseMesh() const
-            {
-                return baseMesh_;
-            }
-
-            const fvMeshSubset& subsetter() const
-            {
-                return subsetter_;
-            }
-
-            //- Check if running subMesh
-            bool useSubMesh() const
-            {
-                return setName_.size();
-            }
-
-            //- topology
+            //- Topology
             const vtkTopo& topo() const
             {
                 if (topoPtr_.empty())
@@ -117,18 +92,6 @@ public:
                 return topoPtr_();
             }
 
-            //- Access either mesh or submesh
-            const fvMesh& mesh() const
-            {
-                if (useSubMesh())
-                {
-                    return subsetter_.subMesh();
-                }
-                else
-                {
-                    return baseMesh_;
-                }
-            }
 
             //- Number of field cells
             label nFieldCells() const
@@ -136,6 +99,7 @@ public:
                 return topo().cellTypes().size();
             }
 
+
             //- Number of field points
             label nFieldPoints() const
             {
@@ -145,26 +109,20 @@ public:
 
         // Edit
 
-            //- Read mesh
-            polyMesh::readUpdateState readUpdate();
-
-
-            //- Map volume field (does in fact do very little interpolation;
-            //  just copied from fvMeshSubset)
-            template<class GeoField>
-            tmp<GeoField> interpolate(const GeoField& fld) const
+            //- Read mesh, forcing topo update if necessary
+            polyMesh::readUpdateState readUpdate()
             {
-                if (useSubMesh())
-                {
-                    tmp<GeoField> subFld = subsetter_.interpolate(fld);
-                    subFld.ref().rename(fld.name());
-                    return subFld;
-                }
-                else
+                polyMesh::readUpdateState meshState
+                    = meshSubsetHelper::readUpdate();
+
+                if (meshState != polyMesh::UNCHANGED)
                 {
-                    return fld;
+                    topoPtr_.clear();
                 }
+
+                return meshState;
             }
+
 };
 
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C
index 4ad78d96a0d7075f16dc73444283fd98729ed4bc..0556b7aaf27e0022b82cbb587dea9f818f9409e3 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,12 +32,12 @@ License
 void Foam::writeFaceSet
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const faceSet& set,
     const fileName& fileName
 )
 {
-    const faceList& faces = vMesh.mesh().faces();
+    const faceList& faces = mesh.faces();
 
     std::ofstream ostr(fileName.c_str());
 
@@ -69,7 +69,7 @@ void Foam::writeFaceSet
         setFaces[setFacei] = faces[iter.key()];
         setFacei++;
     }
-    primitiveFacePatch fp(setFaces, vMesh.mesh().points());
+    primitiveFacePatch fp(setFaces, mesh.points());
 
 
     // Write points and faces as polygons
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H
index eb7c45203169a0a46c43fcd713c5e0cb4609effe..73ca4f07416e6fc9fdfff79350a6ddefdd876160 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeFaceSet.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,7 +36,7 @@ SourceFiles
 #ifndef writeFaceSet_H
 #define writeFaceSet_H
 
-#include "vtkMesh.H"
+#include "fvMesh.H"
 #include "faceSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -48,7 +48,7 @@ namespace Foam
 void writeFaceSet
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh&,
     const faceSet& set,
     const fileName& fileName
 );
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C
index 4cafa01f0a0879ad1e40b5d3039042b18bc37f7d..e5fffb536671144a864004b16ee89eac11416612 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.C
@@ -37,7 +37,7 @@ namespace Foam
 void writePointSet
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const pointSet& set,
     const fileName& fileName
 )
@@ -68,7 +68,7 @@ void writePointSet
 
     writeFuns::insert
     (
-        UIndirectList<point>(vMesh.mesh().points(), set.toc())(),
+        UIndirectList<point>(mesh.points(), set.toc())(),
         ptField
     );
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H
index 32ffd981f6bedc4a3c5b14a92d1986528249a664..d1ad15efe6d7b7b95946f479e695765eebb3aea8 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writePointSet.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,7 +36,7 @@ SourceFiles
 #ifndef writePointSet_H
 #define writePointSet_H
 
-#include "vtkMesh.H"
+#include "fvMesh.H"
 #include "pointSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -48,7 +48,7 @@ namespace Foam
 void writePointSet
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const pointSet& set,
     const fileName& fileName
 );
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C
index 4144a579a5497701b36afd23752a98fca3d65e99..9dc889adf4be77423e75cb965625c3cc7b52c590 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,13 +35,11 @@ License
 void Foam::writeSurfFields
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh& mesh,
     const fileName& fileName,
     const UPtrList<const surfaceVectorField>& surfVectorFields
 )
 {
-    const fvMesh& mesh = vMesh.mesh();
-
     std::ofstream str(fileName.c_str());
 
     writeFuns::writeHeader
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H
index 798e335fd343cf180e7f579919cf44fa58630718..7740e15f78f48c3817ebfca37e8ab65b17eb3f44 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/writeSurfFields.H
@@ -35,7 +35,7 @@ SourceFiles
 #ifndef writeSurfFields_H
 #define writeSurfFields_H
 
-#include "vtkMesh.H"
+#include "fvMesh.H"
 #include "surfaceMesh.H"
 #include "surfaceFieldsFwd.H"
 
@@ -48,7 +48,7 @@ namespace Foam
 void writeSurfFields
 (
     const bool binary,
-    const vtkMesh& vMesh,
+    const fvMesh&,
     const fileName& fileName,
     const UPtrList<const surfaceVectorField>& surfVectorFields
 );
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/Allwclean b/applications/utilities/postProcessing/graphics/PV3Readers/Allwclean
deleted file mode 100755
index 47add82a9869c5cb2b9e8468f7e2c99f9baebc3f..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/Allwclean
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-set -x
-
-wclean libso vtkPV3Readers
-PV3blockMeshReader/Allwclean
-PV3FoamReader/Allwclean
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake
deleted file mode 100755
index c65150e0edff1d660a0887520e4bc681d6609071..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-
-# Optional unit: continue-on-error
-export WM_CONTINUE_ON_ERROR=true
-
-# Parse arguments for library compilation
-. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
-
-#
-# There are several prerequisites for building a plugin
-#
-#set -x
-canBuildPlugin()
-{
-    [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ] || {
-        echo
-        echo "WARNING: cannot build ParaView plugin(s) without paraview directory"
-        echo "    ParaView_DIR=$ParaView_DIR"
-        echo
-        return 1
-    }
-
-    [ -n "$PV_PLUGIN_PATH" ] || {
-        echo
-        echo "${PWD##*/} : invalid PV_PLUGIN_PATH for building ParaView plugin(s)"
-        echo "    PV_PLUGIN_PATH=${PV_PLUGIN_PATH:-unset}"
-        echo
-        return 1
-    }
-
-    type cmake > /dev/null 2>&1 || {
-        echo
-        echo "WARNING: cannot build ParaView plugin(s) without cmake"
-        echo
-        return 1
-    }
-
-    return 0 # success
-}
-
-
-# -----------------------------------------------------------------------------
-# major version as per paraview include directory:
-# Eg, "PREFIX/include/paraview-3.4" -> "3.4"
-major="${ParaView_INCLUDE_DIR##*-}"
-
-case "$major" in
-3.[0-9]*)
-    if canBuildPlugin
-    then
-    (
-        wmake $targetType vtkPV3Readers
-        PV3blockMeshReader/Allwmake $targetType $*
-        PV3FoamReader/Allwmake $targetType $*
-    )
-    fi
-    ;;
-*)
-    echo
-    echo "NOTE: skipping build of ParaView V3 plugin(s)"
-    echo "    include directory was for paraview major version '${major:-none}'"
-    echo
-    ;;
-esac
-
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwclean b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwclean
deleted file mode 100755
index 7d374ba5ec71745d847cf580cb67a8ce1f8c22ca..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwclean
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-set -x
-
-# deal with client/server vs combined plugins
-rm -f $FOAM_LIBBIN/libPV3FoamReader* 2>/dev/null
-
-rm -rf PV3FoamReader/Make
-wclean libso vtkPV3Foam
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake
deleted file mode 100755
index 05d46f149e0722169dcd24a2a81cbd9c2da1aaa4..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-
-# Parse arguments for library compilation
-. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
-set -x
-
-if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
-then
-    wmake $targetType vtkPV3Foam
-
-    if [ "$targetType" != "objects" ]
-    then
-        (
-            cd PV3FoamReader
-            mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
-            cd Make/$WM_OPTIONS
-            cmake ../..
-            make
-        )
-    fi
-fi
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/CMakeLists.txt b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/CMakeLists.txt
deleted file mode 100644
index 4b37871f584216f9d7aedb87d773c1fbbc82ce03..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/CMakeLists.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-# create a plugin that adds a reader to the ParaView GUI
-# it is added in the file dialog when doing opens/saves.
-
-# The qrc file is processed by Qt's resource compiler (rcc)
-# the qrc file must have a resource prefix of "/ParaViewResources"
-# and ParaView will read anything contained under that prefix
-# the pqReader.xml file contains xml defining readers with their
-# file extensions and descriptions.
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-
-FIND_PACKAGE(ParaView REQUIRED)
-INCLUDE(${PARAVIEW_USE_FILE})
-
-LINK_DIRECTORIES(
-    $ENV{FOAM_LIBBIN}
-    $ENV{FOAM_EXT_LIBBIN}
-)
-
-INCLUDE_DIRECTORIES(
-    $ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude
-    $ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude
-    $ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude
-    ${PROJECT_SOURCE_DIR}/../vtkPV3Foam
-)
-
-ADD_DEFINITIONS(
-    -DWM_$ENV{WM_PRECISION_OPTION}
-    -DWM_LABEL_SIZE=$ENV{WM_LABEL_SIZE}
-)
-
-# Set output library destination to plugin directory
-SET(
-    LIBRARY_OUTPUT_PATH $ENV{PV_PLUGIN_PATH}
-    CACHE INTERNAL
-    "Single output directory for building all libraries."
-)
-
-
-#
-# Defined combined plugin
-#
-
-# Extend the auto-generated panel
-QT4_WRAP_CPP(MOC_SRCS pqPV3FoamReaderPanel.h)
-
-ADD_PARAVIEW_OBJECT_PANEL(IFACES IFACE_SRCS
-  CLASS_NAME pqPV3FoamReaderPanel
-  XML_NAME  PV3FoamReader  # name of SourceProxy in *SM.xml
-  XML_GROUP sources
-)
-
-ADD_PARAVIEW_PLUGIN(
-    PV3FoamReader_SM "1.0"
-    SERVER_MANAGER_XML PV3FoamReader_SM.xml
-    SERVER_MANAGER_SOURCES vtkPV3FoamReader.cxx
-    GUI_INTERFACES ${IFACES}
-    GUI_SOURCES pqPV3FoamReaderPanel.cxx
-        ${MOC_SRCS} ${UI_SRCS} ${IFACE_SRCS}
-    GUI_RESOURCE_FILES PV3FoamReader.xml
-)
-
-# #
-# # Define the server-side portion of the reader plugin
-# #
-# ADD_PARAVIEW_PLUGIN(
-#     PV3FoamReader_SM "1.0"
-#     SERVER_MANAGER_XML PV3FoamReader_SM.xml
-#     SERVER_MANAGER_SOURCES vtkPV3FoamReader.cxx
-# )
-# #
-# # Define the client-side portion of the reader plugin
-# #
-# ADD_PARAVIEW_PLUGIN(
-#     PV3FoamReader "1.0"
-#     GUI_RESOURCES PV3FoamReader.qrc
-# )
-#
-
-TARGET_LINK_LIBRARIES(
-    PV3FoamReader_SM
-    OpenFOAM
-    finiteVolume
-    vtkPV3Foam
-)
-#-----------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.qrc b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.qrc
deleted file mode 100644
index 7394bb80dff95fb93edeb7aac24f8c27010cbbbb..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
-    <qresource prefix="/ParaViewResources" >
-        <file>PV3FoamReader.xml</file>
-    </qresource>
-</RCC>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.xml b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.xml
deleted file mode 100644
index 123c736f549cdcfed15b7c9792ef46fdcf1cd940..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<ParaViewReaders>
-  <Reader name="PV3FoamReader"
-          extensions="OpenFOAM"
-          file_description="OpenFOAM Reader">
-  </Reader>
-</ParaViewReaders>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml
deleted file mode 100644
index a798530ce8af11e190f8b842eafbbed141a5d484..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml
+++ /dev/null
@@ -1,306 +0,0 @@
-<ServerManagerConfiguration>
-  <ProxyGroup name="sources">
-  <SourceProxy
-    name="PV3FoamReader"
-    class="vtkPV3FoamReader">
-
-    <!-- File name - compulsory -->
-    <StringVectorProperty
-      name="FileName"
-      command="SetFileName"
-      number_of_elements="1"
-      animateable="0">
-      <FileListDomain name="files"/>
-      <Documentation>
-        Specifies the filename for the OpenFOAM Reader.
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Send discrete time info to the animation panel -->
-    <DoubleVectorProperty
-      name="TimestepValues"
-      repeatable="1"
-      information_only="1">
-      <TimeStepsInformationHelper/>
-      <Documentation>
-        Available timestep values.
-      </Documentation>
-    </DoubleVectorProperty>
-
-    <!-- Cache Mesh check-box -->
-    <IntVectorProperty
-      name="UiCacheMesh"
-      command="SetCacheMesh"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="1"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Cache the fvMesh in memory.
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Refresh button -->
-    <IntVectorProperty
-      name="UiRefresh"
-      command="SetRefresh"
-      number_of_elements="1"
-      is_internal="0"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Rescan for updated timesteps/fields.
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Skip Zero Time check-box -->
-    <IntVectorProperty
-      name="UiZeroTime"
-      command="SetSkipZeroTime"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Skip including the 0/ time directory
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Interpolate Fields check-box -->
-    <IntVectorProperty
-      name="UiInterpolateVolFields"
-      command="SetInterpolateVolFields"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="1"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Interpolate volume fields into point fields
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Extrapolate Patches check-box -->
-    <IntVectorProperty
-      name="UiExtrapolatePatches"
-      command="SetExtrapolatePatches"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Extrapolate internalField to non-constraint patches
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Use VTK Polyhedron check-box -->
-    <IntVectorProperty
-      name="UseVTKPolyhedron"
-      command="SetUseVTKPolyhedron"
-      number_of_elements="1"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Use vtkPolyhedron instead of decomposing polyhedra.
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Include Sets check-box -->
-    <IntVectorProperty
-      name="UiIncludeSets"
-      command="SetIncludeSets"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="0"
-      animateable="0">
-      <Documentation>
-        Search the polyMesh/sets/ directory
-      </Documentation>
-      <BooleanDomain name="bool"/>
-    </IntVectorProperty>
-
-    <!-- Include Zones check-box -->
-    <IntVectorProperty
-      name="UiIncludeZones"
-      command="SetIncludeZones"
-      number_of_elements="1"
-      is_internal="1"
-      default_values="0"
-      animateable="0">
-      <Documentation>
-        ZoneMesh information is used to find {cell,face,point}Zones.
-        The polyMesh/ directory is only checked on startup.
-      </Documentation>
-      <BooleanDomain name="bool"/>
-    </IntVectorProperty>
-
-    <!-- Show Patch Names check-box -->
-    <IntVectorProperty
-      name="UiShowPatchNames"
-      command="SetShowPatchNames"
-      number_of_elements="1"
-      default_values="0"
-      is_internal="1"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Show patch names in render window
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Show Groups Only check-box -->
-    <IntVectorProperty
-      name="UiShowGroupsOnly"
-      command="SetShowGroupsOnly"
-      number_of_elements="1"
-      default_values="0"
-      is_internal="1"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Show groups only
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Force GUI update check box -->
-    <IntVectorProperty
-      name="UpdateGUI"
-      command="SetUpdateGUI"
-      number_of_elements="1"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        A simple way to cause a reader GUI modification.
-      </Documentation>
-    </IntVectorProperty>
-
-    <!--
-       | Selections
-       -->
-
-    <!-- Available Parts (volume, patches, lagrangian) array -->
-    <StringVectorProperty
-      name="PartArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="Part"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="PartStatus"
-      label="Mesh Parts"
-      command="SetPartArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="PartArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="PartArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the mesh parts
-        (patches, groups, sets, zones).
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Available volFields array -->
-    <StringVectorProperty
-      name="VolFieldArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="VolField"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="VolFieldStatus"
-      label="Volume Fields"
-      command="SetVolFieldArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="VolFieldArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="VolFieldArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the volume fields
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Available Lagrangian fields array -->
-    <StringVectorProperty
-      name="LagrangianFieldArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="LagrangianField"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="LagrangianFieldStatus"
-      label="Lagrangian Fields"
-      command="SetLagrangianFieldArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="LagrangianFieldArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="LagrangianFieldArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the lagrangian fields
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Available pointFields array -->
-    <StringVectorProperty
-      name="PointFieldArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="PointField"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="PointFieldStatus"
-      label="Point Fields"
-      command="SetPointFieldArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="PointFieldArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="PointFieldArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the point fields
-      </Documentation>
-    </StringVectorProperty>
-
-  <Hints>
-    <Property name="FileName" show="0"/>
-    <Property name="UiCacheMesh" show="0"/>
-    <Property name="UiZeroTime" show="0"/>
-    <Property name="UiRefresh" show="0"/>
-    <Property name="UiShowPatchNames" show="0"/>
-    <Property name="UiShowGroupsOnly" show="0"/>
-    <Property name="UiIncludeSets" show="0"/>
-    <Property name="UiIncludeZones" show="0"/>
-  </Hints>
-
-
-  </SourceProxy>
-  </ProxyGroup>
-</ServerManagerConfiguration>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.cxx
deleted file mode 100644
index 3b111ff59f079dc42e325a9ff565865c0438246a..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.cxx
+++ /dev/null
@@ -1,464 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-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 "pqPV3FoamReaderPanel.h"
-
-// QT
-#include <QGridLayout>
-#include <QCheckBox>
-#include <QLabel>
-#include <QLayout>
-#include <QString>
-#include <QPushButton>
-#include <QtDebug>
-
-// Paraview <-> QT UI
-#include "pqAnimationScene.h"
-#include "pqApplicationCore.h"
-#include "pqPipelineRepresentation.h"
-#include "pqServerManagerModel.h"
-#include "pqView.h"
-
-// Paraview Server Manager
-#include "vtkSMDoubleVectorProperty.h"
-#include "vtkSMIntVectorProperty.h"
-#include "vtkSMProperty.h"
-#include "vtkSMSourceProxy.h"
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-pqPV3FoamReaderPanel::pqPV3FoamReaderPanel
-(
-    pqProxy *proxy,
-    QWidget *p
-)
-:
-    pqAutoGeneratedObjectPanel(proxy, p)
-{
-    // create first sublayout (at top of the panel)
-    QGridLayout* form = new QGridLayout();
-    this->PanelLayout->addLayout(form, 0, 0, 1, -1);
-
-    // ROW 0
-    // ~~~~~
-
-    vtkSMProperty* prop = 0;
-
-    // refresh button for updating times/fields
-    if ((prop = this->proxy()->GetProperty("UiRefresh")) != 0)
-    {
-        prop->SetImmediateUpdate(1);
-        QPushButton *refresh = new QPushButton("Refresh Times");
-        refresh->setToolTip("Rescan for updated times/fields.");
-
-        form->addWidget(refresh, 0, 0, Qt::AlignLeft);
-        QObject::connect
-        (
-            refresh,
-            SIGNAL(clicked()),
-            this,
-            SLOT(RefreshPressed())
-        );
-    }
-
-    // checkbox for skip zeroTime
-    if ((prop = this->proxy()->GetProperty("UiZeroTime")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        ZeroTime_ = new QCheckBox("Skip Zero Time");
-        ZeroTime_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        ZeroTime_->setToolTip
-        (
-            "Skip including the 0/ time directory."
-        );
-
-        form->addWidget(ZeroTime_, 0, 1, Qt::AlignLeft);
-        connect
-        (
-            ZeroTime_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(ZeroTimeToggled())
-        );
-    }
-
-    // ROW 1
-    // ~~~~~
-
-    QFrame* hline1 = new QFrame(this);
-    hline1->setFrameStyle(QFrame::HLine | QFrame::Sunken);
-    form->addWidget(hline1, 1, 0, 1, 3);
-
-    // ROW 2
-    // ~~~~~
-
-    // checkbox for caching mesh
-    if ((prop = this->proxy()->GetProperty("UiCacheMesh")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        CacheMesh_ = new QCheckBox("Cache Mesh");
-        CacheMesh_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        CacheMesh_->setToolTip
-        (
-            "Cache the fvMesh in memory."
-        );
-
-        form->addWidget(CacheMesh_, 2, 0, Qt::AlignLeft);
-        connect
-        (
-            CacheMesh_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(CacheMeshToggled())
-        );
-    }
-
-    // cell 2,1 empty
-
-    // ROW 3
-    // ~~~~~
-
-    // checkbox for include sets
-    if ((prop = this->proxy()->GetProperty("UiIncludeSets")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        IncludeSets_ = new QCheckBox("Include Sets");
-        IncludeSets_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        IncludeSets_->setToolTip
-        (
-            "Search the polyMesh/sets/ directory."
-        );
-
-        // row/col 1,0
-        form->addWidget(IncludeSets_, 3, 0, Qt::AlignLeft);
-        connect
-        (
-            IncludeSets_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(IncludeSetsToggled())
-        );
-    }
-
-    // checkbox for Groups Only
-    if ((prop = this->proxy()->GetProperty("UiShowGroupsOnly")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        ShowGroupsOnly_ = new QCheckBox("Groups Only");
-        ShowGroupsOnly_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        ShowGroupsOnly_->setToolTip
-        (
-            "Show patchGroups only."
-        );
-
-        // row/col 2, 2
-        form->addWidget(ShowGroupsOnly_, 3, 1, Qt::AlignLeft);
-        connect
-        (
-            ShowGroupsOnly_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(ShowGroupsOnlyToggled())
-        );
-    }
-
-
-    // ROW 4
-    // ~~~~~
-
-    // checkbox for include zones
-    if ((prop = this->proxy()->GetProperty("UiIncludeZones")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        IncludeZones_ = new QCheckBox("Include Zones");
-        IncludeZones_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        IncludeZones_->setToolTip
-        (
-            "ZoneMesh information is used to find {cell,face,point}Zones. "
-            "The polyMesh/ directory is only checked on startup."
-        );
-
-        // row/col 1,1
-        form->addWidget(IncludeZones_, 4, 0, Qt::AlignLeft);
-        connect
-        (
-            IncludeZones_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(IncludeZonesToggled())
-        );
-    }
-
-    // checkbox for patch names
-    if ((prop = this->proxy()->GetProperty("UiShowPatchNames")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        ShowPatchNames_ = new QCheckBox("Patch Names");
-        ShowPatchNames_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        ShowPatchNames_->setToolTip
-        (
-            "Show patch names in render window."
-        );
-
-        // row/col 0,1
-        form->addWidget(ShowPatchNames_, 4, 1, Qt::AlignLeft);
-        connect
-        (
-            ShowPatchNames_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(ShowPatchNamesToggled())
-        );
-    }
-
-    // ROW 5
-    // ~~~~~
-
-    QFrame* hline2 = new QFrame(this);
-    hline2->setFrameStyle(QFrame::HLine | QFrame::Sunken);
-    form->addWidget(hline2, 5, 0, 1, 3);
-
-    // ROW 6
-    // ~~~~~
-
-    // checkbox for vol field interpolation
-    if ((prop = this->proxy()->GetProperty("UiInterpolateVolFields")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        InterpolateVolFields_ = new QCheckBox("Interpolate volFields");
-        InterpolateVolFields_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        InterpolateVolFields_->setToolTip
-        (
-            "Interpolate volFields into pointFields"
-        );
-
-        // row/col 1,1
-        form->addWidget(InterpolateVolFields_, 6, 0, Qt::AlignLeft);
-        connect
-        (
-            InterpolateVolFields_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(InterpolateVolFieldsToggled())
-        );
-    }
-
-    // checkbox for extrapolate patches
-    if ((prop = this->proxy()->GetProperty("UiExtrapolatePatches")) != 0)
-    {
-        // immediate update on the Server Manager side
-        prop->SetImmediateUpdate(true);
-
-        ExtrapolatePatches_ = new QCheckBox("Extrapolate Patches");
-        ExtrapolatePatches_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-        ExtrapolatePatches_->setToolTip
-        (
-            "Extrapolate internalField to non-constraint patches"
-        );
-
-        // row/col 1,1
-        form->addWidget(ExtrapolatePatches_, 6, 1, Qt::AlignLeft);
-        connect
-        (
-            ExtrapolatePatches_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(ExtrapolatePatchesToggled())
-        );
-    }
-
-    // ROW 7
-    // ~~~~~
-
-    QFrame* hline3 = new QFrame(this);
-    hline3->setFrameStyle(QFrame::HLine | QFrame::Sunken);
-    form->addWidget(hline3, 7, 0, 1, 3);
-}
-
-
-// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
-
-void pqPV3FoamReaderPanel::CacheMeshToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiCacheMesh")
-    )->SetElement(0, CacheMesh_->isChecked());
-}
-
-
-void pqPV3FoamReaderPanel::RefreshPressed()
-{
-    // update everything
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiRefresh")
-    )->Modified();
-
-    vtkSMSourceProxy::SafeDownCast(this->proxy())->UpdatePipeline();
-
-    // render all views
-    pqApplicationCore::instance()->render();
-}
-
-
-void pqPV3FoamReaderPanel::ZeroTimeToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiZeroTime")
-    )->SetElement(0, ZeroTime_->isChecked());
-
-    this->setModified();
-}
-
-
-void pqPV3FoamReaderPanel::ShowPatchNamesToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiShowPatchNames")
-    )->SetElement(0, ShowPatchNames_->isChecked());
-
-    // update the active view
-    if (this->view())
-    {
-        this->view()->render();
-    }
-    // OR: update all views
-    // pqApplicationCore::instance()->render();
-}
-
-
-void pqPV3FoamReaderPanel::ShowGroupsOnlyToggled()
-{
-    vtkSMProperty* prop;
-
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiShowGroupsOnly")
-    )->SetElement(0, ShowGroupsOnly_->isChecked());
-
-    if ((prop = this->proxy()->GetProperty("PartArrayStatus")) != 0)
-    {
-        this->proxy()->UpdatePropertyInformation(prop);
-    }
-}
-
-
-void pqPV3FoamReaderPanel::IncludeSetsToggled()
-{
-    vtkSMProperty* prop;
-
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiIncludeSets")
-    )->SetElement(0, IncludeSets_->isChecked());
-
-    if ((prop = this->proxy()->GetProperty("PartArrayStatus")) != 0)
-    {
-        this->proxy()->UpdatePropertyInformation(prop);
-    }
-}
-
-
-void pqPV3FoamReaderPanel::IncludeZonesToggled()
-{
-    vtkSMProperty* prop;
-
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiIncludeZones")
-    )->SetElement(0, IncludeZones_->isChecked());
-
-    if ((prop = this->proxy()->GetProperty("PartArrayStatus")) != 0)
-    {
-        this->proxy()->UpdatePropertyInformation(prop);
-    }
-}
-
-
-void pqPV3FoamReaderPanel::ExtrapolatePatchesToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiExtrapolatePatches")
-    )->SetElement(0, ExtrapolatePatches_->isChecked());
-
-    this->setModified();
-}
-
-
-void pqPV3FoamReaderPanel::InterpolateVolFieldsToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiInterpolateVolFields")
-    )->SetElement(0, InterpolateVolFields_->isChecked());
-
-    this->setModified();
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.h b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.h
deleted file mode 100644
index c4594c257e7cc32e51a1d244f29380a548b131ef..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/pqPV3FoamReaderPanel.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 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
-    pqPV3FoamReaderPanel
-
-Description
-    GUI modifications for the ParaView reader panel
-
-    A custom panel for the PV3FoamReader.
-
-SourceFiles
-    pqPV3FoamReaderPanel.cxx
-
-\*---------------------------------------------------------------------------*/
-#ifndef pqPV3FoamReaderPanel_h
-#define pqPV3FoamReaderPanel_h
-
-
-#include "pqAutoGeneratedObjectPanel.h"
-
-// Forward declaration of QT classes
-
-class QCheckBox;
-class QLineEdit;
-class QTimer;
-class QToolButton;
-
-// Forward declaration of ParaView classes
-class vtkSMSourceProxy;
-
-
-/*---------------------------------------------------------------------------*\
-                  Class pqPV3FoamReaderPanel Declaration
-\*---------------------------------------------------------------------------*/
-
-class pqPV3FoamReaderPanel
-:
-    public pqAutoGeneratedObjectPanel
-{
-    // Private data
-    Q_OBJECT;
-    typedef pqAutoGeneratedObjectPanel Superclass;
-
-    //- ZeroTime checkbox
-    QCheckBox* ZeroTime_;
-
-    //- CacheMesh checkbox
-    QCheckBox* CacheMesh_;
-
-    //- Show Patch Names checkbox
-    QCheckBox* ShowPatchNames_;
-
-    //- Show Groups Only checkbox
-    QCheckBox* ShowGroupsOnly_;
-
-    //- IncludeSets checkbox
-    QCheckBox* IncludeSets_;
-
-    //- IncludeZones checkbox
-    QCheckBox* IncludeZones_;
-
-    //- InterpolateVolFields checkbox
-    QCheckBox* InterpolateVolFields_;
-
-    //- ExtrapolatePatches checkbox
-    QCheckBox* ExtrapolatePatches_;
-
-
-protected slots:
-
-    void CacheMeshToggled();
-    void ZeroTimeToggled();
-    void RefreshPressed();
-    void ShowPatchNamesToggled();
-    void ShowGroupsOnlyToggled();
-    void IncludeSetsToggled();
-    void IncludeZonesToggled();
-    void InterpolateVolFieldsToggled();
-    void ExtrapolatePatchesToggled();
-
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        pqPV3FoamReaderPanel(pqProxy*, QWidget*);
-
-
-    //- Destructor
-    // virtual ~pqPV3FoamReaderPanel();
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
deleted file mode 100644
index 163b63785420640695260f8a287ab4808a3dc285..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
+++ /dev/null
@@ -1,757 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3FoamReader.h"
-
-#include "pqApplicationCore.h"
-#include "pqRenderView.h"
-#include "pqServerManagerModel.h"
-
-// VTK includes
-#include "vtkCallbackCommand.h"
-#include "vtkDataArraySelection.h"
-#include "vtkInformation.h"
-#include "vtkInformationVector.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkObjectFactory.h"
-#include "vtkSMRenderViewProxy.h"
-#include "vtkStreamingDemandDrivenPipeline.h"
-#include "vtkStringArray.h"
-
-// OpenFOAM includes
-#include "vtkPV3Foam.H"
-
-#undef EXPERIMENTAL_TIME_CACHING
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-vtkStandardNewMacro(vtkPV3FoamReader);
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-vtkPV3FoamReader::vtkPV3FoamReader()
-{
-    Debug = 0;
-    vtkDebugMacro(<<"Constructor");
-
-    SetNumberOfInputPorts(0);
-
-    FileName  = nullptr;
-    foamData_ = nullptr;
-
-    output0_  = nullptr;
-
-#ifdef VTKPV3FOAM_DUALPORT
-    // Add second output for the Lagrangian
-    this->SetNumberOfOutputPorts(2);
-    vtkMultiBlockDataSet *lagrangian = vtkMultiBlockDataSet::New();
-    lagrangian->ReleaseData();
-
-    this->GetExecutive()->SetOutputData(1, lagrangian);
-    lagrangian->Delete();
-#endif
-
-    TimeStepRange[0] = 0;
-    TimeStepRange[1] = 0;
-
-    CacheMesh = 1;
-    Refresh = 0;
-
-    SkipZeroTime = 0;
-    ExtrapolatePatches = 0;
-    UseVTKPolyhedron = 0;
-    IncludeSets = 0;
-    IncludeZones = 0;
-    ShowPatchNames = 0;
-    ShowGroupsOnly = 0;
-    InterpolateVolFields = 1;
-
-    UpdateGUI = 0;
-
-    PartSelection = vtkDataArraySelection::New();
-    VolFieldSelection = vtkDataArraySelection::New();
-    PointFieldSelection = vtkDataArraySelection::New();
-    LagrangianFieldSelection = vtkDataArraySelection::New();
-
-    // Setup the selection callback to modify this object when an array
-    // selection is changed.
-    SelectionObserver = vtkCallbackCommand::New();
-    SelectionObserver->SetCallback
-    (
-        &vtkPV3FoamReader::SelectionModifiedCallback
-    );
-    SelectionObserver->SetClientData(this);
-
-    PartSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-    VolFieldSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-    PointFieldSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-    LagrangianFieldSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-vtkPV3FoamReader::~vtkPV3FoamReader()
-{
-    vtkDebugMacro(<<"Deconstructor");
-
-    if (foamData_)
-    {
-        // remove patch names
-        updatePatchNamesView(false);
-        delete foamData_;
-    }
-
-    if (FileName)
-    {
-        delete [] FileName;
-    }
-
-    if (output0_)
-    {
-        output0_->Delete();
-    }
-
-
-    PartSelection->RemoveObserver(this->SelectionObserver);
-    VolFieldSelection->RemoveObserver(this->SelectionObserver);
-    PointFieldSelection->RemoveObserver(this->SelectionObserver);
-    LagrangianFieldSelection->RemoveObserver(this->SelectionObserver);
-
-    SelectionObserver->Delete();
-
-    PartSelection->Delete();
-    VolFieldSelection->Delete();
-    PointFieldSelection->Delete();
-    LagrangianFieldSelection->Delete();
-}
-
-
-// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
-
-// Do everything except set the output info
-int vtkPV3FoamReader::RequestInformation
-(
-    vtkInformation* vtkNotUsed(request),
-    vtkInformationVector** vtkNotUsed(inputVector),
-    vtkInformationVector* outputVector
-)
-{
-    vtkDebugMacro(<<"RequestInformation");
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        cout<<"REQUEST_INFORMATION\n";
-    }
-
-    if (!FileName)
-    {
-        vtkErrorMacro("FileName has to be specified!");
-        return 0;
-    }
-
-    int nInfo = outputVector->GetNumberOfInformationObjects();
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        cout<<"RequestInformation with " << nInfo << " item(s)\n";
-        for (int infoI = 0; infoI < nInfo; ++infoI)
-        {
-            outputVector->GetInformationObject(infoI)->Print(cout);
-        }
-    }
-
-    if (!foamData_)
-    {
-        foamData_ = new Foam::vtkPV3Foam(FileName, this);
-    }
-    else
-    {
-        foamData_->updateInfo();
-    }
-
-    int nTimeSteps = 0;
-    double* timeSteps = foamData_->findTimes(nTimeSteps);
-
-    if (!nTimeSteps)
-    {
-        vtkErrorMacro("could not find valid OpenFOAM mesh");
-
-        // delete foamData and flag it as fatal error
-        delete foamData_;
-        foamData_ = nullptr;
-        return 0;
-    }
-
-    // set identical time steps for all ports
-    for (int infoI = 0; infoI < nInfo; ++infoI)
-    {
-        outputVector->GetInformationObject(infoI)->Set
-        (
-            vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
-            timeSteps,
-            nTimeSteps
-        );
-    }
-
-    if (nTimeSteps)
-    {
-        double timeRange[2];
-        timeRange[0] = timeSteps[0];
-        timeRange[1] = timeSteps[nTimeSteps-1];
-
-        if (Foam::vtkPV3Foam::debug > 1)
-        {
-            cout<<"nTimeSteps " << nTimeSteps << "\n"
-                <<"timeRange " << timeRange[0] << " to " << timeRange[1]
-                << "\n";
-
-            for (int timeI = 0; timeI < nTimeSteps; ++timeI)
-            {
-                cout<< "step[" << timeI << "] = " << timeSteps[timeI] << "\n";
-            }
-        }
-
-        for (int infoI = 0; infoI < nInfo; ++infoI)
-        {
-            outputVector->GetInformationObject(infoI)->Set
-            (
-                vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
-                timeRange,
-                2
-            );
-        }
-    }
-
-    delete timeSteps;
-
-    return 1;
-}
-
-
-// Set the output info
-int vtkPV3FoamReader::RequestData
-(
-    vtkInformation* vtkNotUsed(request),
-    vtkInformationVector** vtkNotUsed(inputVector),
-    vtkInformationVector* outputVector
-)
-{
-    vtkDebugMacro(<<"RequestData");
-
-    if (!FileName)
-    {
-        vtkErrorMacro("FileName has to be specified!");
-        return 0;
-    }
-
-    // catch previous error
-    if (!foamData_)
-    {
-        vtkErrorMacro("Reader failed - perhaps no mesh?");
-        return 0;
-    }
-
-    int nInfo = outputVector->GetNumberOfInformationObjects();
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        cout<<"RequestData with " << nInfo << " item(s)\n";
-        for (int infoI = 0; infoI < nInfo; ++infoI)
-        {
-            outputVector->GetInformationObject(infoI)->Print(cout);
-        }
-    }
-
-    // Get the requested time step.
-    // We only support requests for a single time step
-
-    int nRequestTime = 0;
-    double requestTime[nInfo];
-
-    // taking port0 as the lead for other outputs would be nice, but fails when
-    // a filter is added - we need to check everything
-    // but since PREVIOUS_UPDATE_TIME_STEPS() is protected, relay the logic
-    // to the vtkPV3Foam::setTime() method
-    for (int infoI = 0; infoI < nInfo; ++infoI)
-    {
-        vtkInformation *outInfo = outputVector->GetInformationObject(infoI);
-
-        if
-        (
-            outInfo->Has
-            (
-                vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()
-            )
-         && outInfo->Length
-            (
-                vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()
-            ) >= 1
-        )
-        {
-            requestTime[nRequestTime++] = outInfo->Get
-            (
-                vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()
-            )[0];
-        }
-    }
-
-    if (nRequestTime)
-    {
-        foamData_->setTime(nRequestTime, requestTime);
-    }
-
-    vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
-    (
-        outputVector->GetInformationObject(0)->Get
-        (
-            vtkMultiBlockDataSet::DATA_OBJECT()
-        )
-    );
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        cout<< "update output with "
-            << output->GetNumberOfBlocks() << " blocks\n";
-    }
-
-
-#ifdef EXPERIMENTAL_TIME_CACHING
-    bool needsUpdate = false;
-
-    if (!output0_)
-    {
-        output0_ = vtkMultiBlockDataSet::New();
-        needsUpdate = true;
-    }
-
-    // This experimental bit of code seems to work for the geometry,
-    // but trashes the fields and still triggers the GeometryFilter
-    if (needsUpdate)
-    {
-        foamData_->Update(output);
-        output0_->ShallowCopy(output);
-    }
-    else
-    {
-        output->ShallowCopy(output0_);
-    }
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        if (needsUpdate)
-        {
-            cout<< "full UPDATE ---------\n";
-        }
-        else
-        {
-            cout<< "cached UPDATE ---------\n";
-        }
-
-        cout<< "UPDATED output: ";
-        output->Print(cout);
-
-        cout<< "UPDATED output0_: ";
-        output0_->Print(cout);
-    }
-
-#else
-
-#ifdef VTKPV3FOAM_DUALPORT
-    foamData_->Update
-    (
-        output,
-        vtkMultiBlockDataSet::SafeDownCast
-        (
-            outputVector->GetInformationObject(1)->Get
-            (
-                vtkMultiBlockDataSet::DATA_OBJECT()
-            )
-        );
-    );
-#else
-    foamData_->Update(output, output);
-#endif
-
-    updatePatchNamesView(ShowPatchNames);
-
-#endif
-
-    // Do any cleanup on the OpenFOAM side
-    foamData_->CleanUp();
-
-    return 1;
-}
-
-
-void vtkPV3FoamReader::SetRefresh(int val)
-{
-    Modified();
-}
-
-
-void vtkPV3FoamReader::SetIncludeSets(int val)
-{
-    if (IncludeSets != val)
-    {
-        IncludeSets = val;
-        if (foamData_)
-        {
-            foamData_->updateInfo();
-        }
-    }
-}
-
-
-void vtkPV3FoamReader::SetIncludeZones(int val)
-{
-    if (IncludeZones != val)
-    {
-        IncludeZones = val;
-        if (foamData_)
-        {
-            foamData_->updateInfo();
-        }
-    }
-}
-
-
-void vtkPV3FoamReader::SetShowPatchNames(int val)
-{
-    if (ShowPatchNames != val)
-    {
-        ShowPatchNames = val;
-        updatePatchNamesView(ShowPatchNames);
-    }
-}
-
-
-void vtkPV3FoamReader::SetShowGroupsOnly(int val)
-{
-    if (ShowGroupsOnly != val)
-    {
-        ShowGroupsOnly = val;
-        if (foamData_)
-        {
-            foamData_->updateInfo();
-        }
-    }
-}
-
-
-void vtkPV3FoamReader::updatePatchNamesView(const bool show)
-{
-    pqApplicationCore* appCore = pqApplicationCore::instance();
-
-    // need to check this, since our destructor calls this
-    if (!appCore)
-    {
-        return;
-    }
-
-    // Server manager model for querying items in the server manager
-    pqServerManagerModel* smModel = appCore->getServerManagerModel();
-
-    if (!smModel || !foamData_)
-    {
-        return;
-    }
-
-    // Get all the pqRenderView instances
-    QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>();
-
-    for (int viewI=0; viewI < renderViews.size(); ++viewI)
-    {
-        foamData_->renderPatchNames
-        (
-            renderViews[viewI]->getRenderViewProxy()->GetRenderer(),
-            show
-        );
-    }
-
-    // use refresh here?
-}
-
-
-void vtkPV3FoamReader::PrintSelf(ostream& os, vtkIndent indent)
-{
-    vtkDebugMacro(<<"PrintSelf");
-
-    this->Superclass::PrintSelf(os,indent);
-    os  << indent << "File name: "
-        << (this->FileName ? this->FileName : "(none)") << "\n";
-
-    foamData_->PrintSelf(os, indent);
-
-    os  << indent << "Time step range: "
-        << this->TimeStepRange[0] << " - " << this->TimeStepRange[1] << "\n"
-        << indent << "Time step: " << this->GetTimeStep() << endl;
-}
-
-
-int vtkPV3FoamReader::GetTimeStep()
-{
-    return foamData_ ? foamData_->timeIndex() : -1;
-}
-
-
-// ----------------------------------------------------------------------
-// Parts selection list control
-
-vtkDataArraySelection* vtkPV3FoamReader::GetPartSelection()
-{
-    vtkDebugMacro(<<"GetPartSelection");
-    return PartSelection;
-}
-
-
-int vtkPV3FoamReader::GetNumberOfPartArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfPartArrays");
-    return PartSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3FoamReader::GetPartArrayName(int index)
-{
-    vtkDebugMacro(<<"GetPartArrayName");
-    return PartSelection->GetArrayName(index);
-}
-
-
-int vtkPV3FoamReader::GetPartArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetPartArrayStatus");
-    return PartSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3FoamReader::SetPartArrayStatus(const char* name, int status)
-{
-    vtkDebugMacro("Set mesh part \"" << name << "\" status to: " << status);
-
-    if (status)
-    {
-        PartSelection->EnableArray(name);
-    }
-    else
-    {
-        PartSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-// volField selection list control
-
-vtkDataArraySelection* vtkPV3FoamReader::GetVolFieldSelection()
-{
-    vtkDebugMacro(<<"GetVolFieldSelection");
-    return VolFieldSelection;
-}
-
-
-int vtkPV3FoamReader::GetNumberOfVolFieldArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfVolFieldArrays");
-    return VolFieldSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3FoamReader::GetVolFieldArrayName(int index)
-{
-    vtkDebugMacro(<<"GetVolFieldArrayName");
-    return VolFieldSelection->GetArrayName(index);
-}
-
-
-int vtkPV3FoamReader::GetVolFieldArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetVolFieldArrayStatus");
-    return VolFieldSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3FoamReader::SetVolFieldArrayStatus(const char* name, int status)
-{
-    vtkDebugMacro(<<"SetVolFieldArrayStatus");
-    if (status)
-    {
-        VolFieldSelection->EnableArray(name);
-    }
-    else
-    {
-        VolFieldSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-// pointField selection list control
-
-vtkDataArraySelection* vtkPV3FoamReader::GetPointFieldSelection()
-{
-    vtkDebugMacro(<<"GetPointFieldSelection");
-    return PointFieldSelection;
-}
-
-
-int vtkPV3FoamReader::GetNumberOfPointFieldArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfPointFieldArrays");
-    return PointFieldSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3FoamReader::GetPointFieldArrayName(int index)
-{
-    vtkDebugMacro(<<"GetPointFieldArrayName");
-    return PointFieldSelection->GetArrayName(index);
-}
-
-
-int vtkPV3FoamReader::GetPointFieldArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetPointFieldArrayStatus");
-    return PointFieldSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3FoamReader::SetPointFieldArrayStatus(const char* name, int status)
-{
-    vtkDebugMacro(<<"SetPointFieldArrayStatus");
-    if (status)
-    {
-        PointFieldSelection->EnableArray(name);
-    }
-    else
-    {
-        PointFieldSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-// lagrangianField selection list control
-
-vtkDataArraySelection* vtkPV3FoamReader::GetLagrangianFieldSelection()
-{
-    vtkDebugMacro(<<"GetLagrangianFieldSelection");
-    return LagrangianFieldSelection;
-}
-
-
-int vtkPV3FoamReader::GetNumberOfLagrangianFieldArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfLagrangianFieldArrays");
-    return LagrangianFieldSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3FoamReader::GetLagrangianFieldArrayName(int index)
-{
-    vtkDebugMacro(<<"GetLagrangianFieldArrayName");
-    return LagrangianFieldSelection->GetArrayName(index);
-}
-
-
-int vtkPV3FoamReader::GetLagrangianFieldArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetLagrangianFieldArrayStatus");
-    return LagrangianFieldSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3FoamReader::SetLagrangianFieldArrayStatus
-(
-    const char* name,
-    int status
-)
-{
-    vtkDebugMacro(<<"SetLagrangianFieldArrayStatus");
-    if (status)
-    {
-        LagrangianFieldSelection->EnableArray(name);
-    }
-    else
-    {
-        LagrangianFieldSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-
-void vtkPV3FoamReader::SelectionModifiedCallback
-(
-    vtkObject*,
-    unsigned long,
-    void* clientdata,
-    void*
-)
-{
-    static_cast<vtkPV3FoamReader*>(clientdata)->SelectionModified();
-}
-
-
-void vtkPV3FoamReader::SelectionModified()
-{
-    vtkDebugMacro(<<"SelectionModified");
-    Modified();
-}
-
-
-int vtkPV3FoamReader::FillOutputPortInformation
-(
-    int port,
-    vtkInformation* info
-)
-{
-    if (port == 0)
-    {
-        return this->Superclass::FillOutputPortInformation(port, info);
-    }
-    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
-    return 1;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
deleted file mode 100644
index aa4bec44b691be7f3f24c4b850dfebe2cb7cf126..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 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
-    vtkPV3FoamReader
-
-Description
-    reads a dataset in OpenFOAM format
-
-    vtkPV3blockMeshReader creates an multiblock dataset.
-    It uses the OpenFOAM infrastructure (fvMesh, etc) to handle mesh and
-    field data.
-
-SourceFiles
-    vtkPV3blockMeshReader.cxx
-
-\*---------------------------------------------------------------------------*/
-#ifndef vtkPV3FoamReader_h
-#define vtkPV3FoamReader_h
-
-// VTK includes
-#include "vtkMultiBlockDataSetAlgorithm.h"
-
-// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
-
-// VTK forward declarations
-class vtkDataArraySelection;
-class vtkCallbackCommand;
-
-// OpenFOAM forward declarations
-namespace Foam
-{
-    class vtkPV3Foam;
-}
-
-
-/*---------------------------------------------------------------------------*\
-                      Class vtkPV3FoamReader Declaration
-\*---------------------------------------------------------------------------*/
-
-class VTK_IO_EXPORT vtkPV3FoamReader
-:
-    public vtkMultiBlockDataSetAlgorithm
-{
-public:
-    vtkTypeMacro(vtkPV3FoamReader, vtkMultiBlockDataSetAlgorithm);
-    void PrintSelf(ostream&, vtkIndent);
-
-    static vtkPV3FoamReader* New();
-
-    // Description:
-    // Get the current timestep and the timestep range.
-    vtkGetVector2Macro(TimeStepRange, int);
-
-    // Description:
-    // Set/Get the filename.
-    vtkSetStringMacro(FileName);
-    vtkGetStringMacro(FileName);
-
-    // Description:
-    // OpenFOAM mesh caching control
-    vtkSetMacro(CacheMesh, int);
-    vtkGetMacro(CacheMesh, int);
-
-    // Description:
-    // OpenFOAM refresh times/fields
-    virtual void SetRefresh(int);
-
-    // Description:
-    // OpenFOAM skip/include the 0/ time directory
-    vtkSetMacro(SkipZeroTime, int);
-    vtkGetMacro(SkipZeroTime, int);
-
-    // Description:
-    // GUI update control
-    vtkSetMacro(UpdateGUI, int);
-    vtkGetMacro(UpdateGUI, int);
-
-    // Description:
-    // OpenFOAM extrapolate internal values onto the patches
-    vtkSetMacro(ExtrapolatePatches, int);
-    vtkGetMacro(ExtrapolatePatches, int);
-
-    // Description:
-    // OpenFOAM use vtkPolyhedron instead of decomposing polyhedra
-    vtkSetMacro(UseVTKPolyhedron, int);
-    vtkGetMacro(UseVTKPolyhedron, int);
-
-    // Description:
-    // OpenFOAM read sets control
-    virtual void SetIncludeSets(int);
-    vtkGetMacro(IncludeSets, int);
-
-    // Description:
-    // OpenFOAM read zones control
-    virtual void SetIncludeZones(int);
-    vtkGetMacro(IncludeZones, int);
-
-    // Description:
-    // OpenFOAM display patch names control
-    virtual void SetShowPatchNames(int);
-    vtkGetMacro(ShowPatchNames, int);
-
-    // Description:
-    // OpenFOAM display patchGroups
-    virtual void SetShowGroupsOnly(int);
-    vtkGetMacro(ShowGroupsOnly, int);
-
-    // Description:
-    // OpenFOAM volField interpolation
-    vtkSetMacro(InterpolateVolFields, int);
-    vtkGetMacro(InterpolateVolFields, int);
-
-    // Description:
-    // Get the current timestep
-    int  GetTimeStep();
-
-    // Description:
-    // Parts selection list control
-    virtual vtkDataArraySelection* GetPartSelection();
-    int  GetNumberOfPartArrays();
-    int  GetPartArrayStatus(const char* name);
-    void SetPartArrayStatus(const char* name, int status);
-    const char* GetPartArrayName(int index);
-
-    // Description:
-    // volField selection list control
-    virtual vtkDataArraySelection* GetVolFieldSelection();
-    int  GetNumberOfVolFieldArrays();
-    int  GetVolFieldArrayStatus(const char* name);
-    void SetVolFieldArrayStatus(const char* name, int status);
-    const char* GetVolFieldArrayName(int index);
-
-    // Description:
-    // pointField selection list control
-    virtual vtkDataArraySelection* GetPointFieldSelection();
-    int  GetNumberOfPointFieldArrays();
-    int  GetPointFieldArrayStatus(const char* name);
-    void SetPointFieldArrayStatus(const char* name, int status);
-    const char* GetPointFieldArrayName(int index);
-
-    // Description:
-    // lagrangianField selection list control
-    virtual vtkDataArraySelection* GetLagrangianFieldSelection();
-    int  GetNumberOfLagrangianFieldArrays();
-    int  GetLagrangianFieldArrayStatus(const char* name);
-    void SetLagrangianFieldArrayStatus(const char* name, int status);
-    const char* GetLagrangianFieldArrayName(int index);
-
-    // Description:
-    // Callback registered with the SelectionObserver
-    // for all the selection lists
-    static void SelectionModifiedCallback
-    (
-        vtkObject* caller,
-        unsigned long eid,
-        void* clientdata,
-        void* calldata
-    );
-
-    void SelectionModified();
-
-
-protected:
-
-    //- Construct null
-    vtkPV3FoamReader();
-
-    //- Destructor
-    ~vtkPV3FoamReader();
-
-    //- Return information about mesh, times, etc without loading anything
-    virtual int RequestInformation
-    (
-        vtkInformation*,
-        vtkInformationVector**,
-        vtkInformationVector*
-    );
-
-    //- Get the mesh/fields for a particular time
-    virtual int RequestData
-    (
-        vtkInformation*,
-        vtkInformationVector**,
-        vtkInformationVector*
-    );
-
-    //- Fill in additional port information
-    virtual int FillOutputPortInformation(int, vtkInformation*);
-
-    //- The observer to modify this object when array selections are modified
-    vtkCallbackCommand* SelectionObserver;
-
-    //- The file name for this case
-    char* FileName;
-
-
-private:
-
-    //- Disallow default bitwise copy construct
-    vtkPV3FoamReader(const vtkPV3FoamReader&);
-
-    //- Disallow default bitwise assignment
-    void operator=(const vtkPV3FoamReader&);
-
-    //- Add/remove patch names to/from the view
-    void updatePatchNamesView(const bool show);
-
-    int TimeStepRange[2];
-    int Refresh;
-    int CacheMesh;
-    int SkipZeroTime;
-
-    int ExtrapolatePatches;
-    int UseVTKPolyhedron;
-    int IncludeSets;
-    int IncludeZones;
-    int ShowPatchNames;
-    int ShowGroupsOnly;
-    int InterpolateVolFields;
-
-    //- Dummy variable/switch to invoke a reader update
-    int UpdateGUI;
-
-    vtkDataArraySelection* PartSelection;
-    vtkDataArraySelection* VolFieldSelection;
-    vtkDataArraySelection* PointFieldSelection;
-    vtkDataArraySelection* LagrangianFieldSelection;
-
-    //- Cached data for output port0 (experimental!)
-    vtkMultiBlockDataSet* output0_;
-
-    //BTX
-    Foam::vtkPV3Foam* foamData_;
-    //ETX
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/files b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/files
deleted file mode 100644
index 685ea2e8a025c92fc5498a7e675f31945ed44ed0..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/files
+++ /dev/null
@@ -1,11 +0,0 @@
-vtkPV3Foam.C
-vtkPV3FoamFields.C
-vtkPV3FoamMesh.C
-vtkPV3FoamMeshLagrangian.C
-vtkPV3FoamMeshSet.C
-vtkPV3FoamMeshVolume.C
-vtkPV3FoamMeshZone.C
-vtkPV3FoamUpdateInfo.C
-vtkPV3FoamUtils.C
-
-LIB = $(FOAM_LIBBIN)/libvtkPV3Foam
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options
deleted file mode 100644
index 2e5018852fa0bb80f326bc09142763bc3669bb6c..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Note: enable vtkPolyhedron when available */
-
-EXE_INC = \
-    -I$(LIB_SRC)/meshTools/lnInclude \
-    -I$(LIB_SRC)/finiteVolume/lnInclude \
-    -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-    -I../../vtkPV3Readers/lnInclude \
-    -I../PV3FoamReader \
-    -I$(ParaView_INCLUDE_DIR) \
-    $(shell \
-        test -f $(ParaView_INCLUDE_DIR)/vtkPolyhedron.h && \
-        echo "-DHAS_VTK_POLYHEDRON" || echo "-UHAS_VTK_POLYHEDRON" \
-    )
-
-LIB_LIBS = \
-    -lmeshTools \
-    -lfiniteVolume \
-    -lgenericPatchFields \
-    -llagrangian \
-    -L$(FOAM_LIBBIN) -lvtkPV3Readers \
-    $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
deleted file mode 100644
index 812a8ef6b73c74b554a38e9e84d22177d452bcbe..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
+++ /dev/null
@@ -1,839 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-#include "vtkPV3FoamReader.h"
-
-// OpenFOAM includes
-#include "fvMesh.H"
-#include "Time.H"
-#include "patchZones.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkRenderer.h"
-#include "vtkTextActor.h"
-#include "vtkTextProperty.h"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-defineTypeNameAndDebug(vtkPV3Foam, 0);
-}
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-#include "vtkPV3FoamAddToSelection.H"
-#include "vtkPV3FoamUpdateInfoFields.H"
-
-void Foam::vtkPV3Foam::resetCounters()
-{
-    // Reset array range information (ids and sizes)
-    arrayRangeVolume_.reset();
-    arrayRangePatches_.reset();
-    arrayRangeLagrangian_.reset();
-    arrayRangeCellZones_.reset();
-    arrayRangeFaceZones_.reset();
-    arrayRangePointZones_.reset();
-    arrayRangeCellSets_.reset();
-    arrayRangeFaceSets_.reset();
-    arrayRangePointSets_.reset();
-}
-
-
-void Foam::vtkPV3Foam::reduceMemory()
-{
-    forAll(regionPolyDecomp_, i)
-    {
-        regionPolyDecomp_[i].clear();
-    }
-
-    forAll(zonePolyDecomp_, i)
-    {
-        zonePolyDecomp_[i].clear();
-    }
-
-    forAll(csetPolyDecomp_, i)
-    {
-        csetPolyDecomp_[i].clear();
-    }
-
-    if (!reader_->GetCacheMesh())
-    {
-        delete meshPtr_;
-        meshPtr_ = nullptr;
-    }
-}
-
-
-int Foam::vtkPV3Foam::setTime(int nRequest, const double requestTimes[])
-{
-    Time& runTime = dbPtr_();
-
-    // Get times list
-    instantList Times = runTime.times();
-
-    int nearestIndex = timeIndex_;
-    for (int requestI = 0; requestI < nRequest; ++requestI)
-    {
-        int index = Time::findClosestTimeIndex(Times, requestTimes[requestI]);
-        if (index >= 0 && index != timeIndex_)
-        {
-            nearestIndex = index;
-            break;
-        }
-    }
-
-    if (nearestIndex < 0)
-    {
-        nearestIndex = 0;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::setTime(";
-        for (int requestI = 0; requestI < nRequest; ++requestI)
-        {
-            if (requestI)
-            {
-                Info<< ", ";
-            }
-
-            Info<< requestTimes[requestI];
-        }
-        Info<< ") - previousIndex = " << timeIndex_
-            << ", nearestIndex = " << nearestIndex << endl;
-    }
-
-
-    // see what has changed
-    if (timeIndex_ != nearestIndex)
-    {
-        timeIndex_ = nearestIndex;
-        runTime.setTime(Times[nearestIndex], nearestIndex);
-
-        // the fields change each time
-        fieldsChanged_ = true;
-
-        if (meshPtr_)
-        {
-            if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
-            {
-                meshChanged_ = true;
-            }
-        }
-        else
-        {
-            meshChanged_ = true;
-        }
-
-        reader_->UpdateProgress(0.05);
-
-        // this seems to be needed for catching Lagrangian fields
-        updateInfo();
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::setTime() - selectedTime="
-            << Times[nearestIndex].name() << " index=" << timeIndex_
-            << "/" << Times.size()
-            << " meshChanged=" << Switch(meshChanged_)
-            << " fieldsChanged=" << Switch(fieldsChanged_) << endl;
-    }
-
-    return nearestIndex;
-}
-
-
-void Foam::vtkPV3Foam::updateMeshPartsStatus()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
-    }
-
-    vtkDataArraySelection* selection = reader_->GetPartSelection();
-    label nElem = selection->GetNumberOfArrays();
-
-    if (partStatus_.size() != nElem)
-    {
-        partStatus_.setSize(nElem);
-        partStatus_ = false;
-        meshChanged_ = true;
-    }
-
-    // this needs fixing if we wish to re-use the datasets
-    partDataset_.setSize(nElem);
-    partDataset_ = -1;
-
-    // Read the selected mesh parts (zones, patches ...) and add to list
-    forAll(partStatus_, partId)
-    {
-        const int setting = selection->GetArraySetting(partId);
-
-        if (partStatus_[partId] != setting)
-        {
-            partStatus_[partId] = setting;
-            meshChanged_ = true;
-        }
-
-        if (debug)
-        {
-            Info<< "  part[" << partId << "] = "
-                << partStatus_[partId]
-                << " : " << selection->GetArrayName(partId) << endl;
-        }
-    }
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::vtkPV3Foam::vtkPV3Foam
-(
-    const char* const FileName,
-    vtkPV3FoamReader* reader
-)
-:
-    reader_(reader),
-    dbPtr_(nullptr),
-    meshPtr_(nullptr),
-    meshRegion_(polyMesh::defaultRegion),
-    meshDir_(polyMesh::meshSubDir),
-    timeIndex_(-1),
-    meshChanged_(true),
-    fieldsChanged_(true),
-    arrayRangeVolume_("unzoned"),
-    arrayRangePatches_("patches"),
-    arrayRangeLagrangian_("lagrangian"),
-    arrayRangeCellZones_("cellZone"),
-    arrayRangeFaceZones_("faceZone"),
-    arrayRangePointZones_("pointZone"),
-    arrayRangeCellSets_("cellSet"),
-    arrayRangeFaceSets_("faceSet"),
-    arrayRangePointSets_("pointSet")
-{
-    if (debug)
-    {
-        Info<< "Foam::vtkPV3Foam::vtkPV3Foam - " << FileName << endl;
-        printMemory();
-    }
-
-    // avoid argList and get rootPath/caseName directly from the file
-    fileName fullCasePath(fileName(FileName).path());
-
-    if (!isDir(fullCasePath))
-    {
-        return;
-    }
-    if (fullCasePath == ".")
-    {
-        fullCasePath = cwd();
-    }
-
-    // Set the case as an environment variable - some BCs might use this
-    if (fullCasePath.name().find("processor", 0) == 0)
-    {
-        const fileName globalCase = fullCasePath.path();
-
-        setEnv("FOAM_CASE", globalCase, true);
-        setEnv("FOAM_CASENAME", globalCase.name(), true);
-    }
-    else
-    {
-        setEnv("FOAM_CASE", fullCasePath, true);
-        setEnv("FOAM_CASENAME", fullCasePath.name(), true);
-    }
-
-    // look for 'case{region}.OpenFOAM'
-    // could be stringent and insist the prefix match the directory name...
-    // Note: cannot use fileName::name() due to the embedded '{}'
-    string caseName(fileName(FileName).lessExt());
-    string::size_type beg = caseName.find_last_of("/{");
-    string::size_type end = caseName.find('}', beg);
-
-    if
-    (
-        beg != string::npos && caseName[beg] == '{'
-     && end != string::npos && end == caseName.size()-1
-    )
-    {
-        meshRegion_ = caseName.substr(beg+1, end-beg-1);
-
-        // some safety
-        if (meshRegion_.empty())
-        {
-            meshRegion_ = polyMesh::defaultRegion;
-        }
-
-        if (meshRegion_ != polyMesh::defaultRegion)
-        {
-            meshDir_ = meshRegion_/polyMesh::meshSubDir;
-        }
-    }
-
-    if (debug)
-    {
-        Info<< "fullCasePath=" << fullCasePath << nl
-            << "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
-            << "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
-            << "region=" << meshRegion_ << endl;
-    }
-
-    // Create time object
-    dbPtr_.reset
-    (
-        new Time
-        (
-            Time::controlDictName,
-            fileName(fullCasePath.path()),
-            fileName(fullCasePath.name())
-        )
-    );
-
-    dbPtr_().functionObjects().off();
-
-    updateInfo();
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::vtkPV3Foam::~vtkPV3Foam()
-{
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::~vtkPV3Foam" << endl;
-    }
-
-    delete meshPtr_;
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::vtkPV3Foam::updateInfo()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfo"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "] timeIndex="
-            << timeIndex_ << endl;
-    }
-
-    resetCounters();
-
-    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
-
-    // there are two ways to ensure we have the correct list of parts:
-    // 1. remove everything and then set particular entries 'on'
-    // 2. build a 'char **' list and call SetArraysWithDefault()
-    //
-    // Nr. 2 has the potential advantage of not touching the modification
-    // time of the vtkDataArraySelection, but the qt/paraview proxy
-    // layer doesn't care about that anyhow.
-
-    // enable 'internalMesh' on the first call
-    // or preserve the enabled selections
-    stringList enabledEntries;
-    if (!partSelection->GetNumberOfArrays() && !meshPtr_)
-    {
-        enabledEntries.setSize(1);
-        enabledEntries[0] = "internalMesh";
-    }
-    else
-    {
-        enabledEntries = getSelectedArrayEntries(partSelection);
-    }
-
-    // Clear current mesh parts list
-    partSelection->RemoveAllArrays();
-
-    // Update mesh parts list - add Lagrangian at the bottom
-    updateInfoInternalMesh(partSelection);
-    updateInfoPatches(partSelection, enabledEntries);
-    updateInfoSets(partSelection);
-    updateInfoZones(partSelection);
-    updateInfoLagrangian(partSelection);
-
-    // restore the enabled selections
-    setSelectedArrayEntries(partSelection, enabledEntries);
-
-    if (meshChanged_)
-    {
-        fieldsChanged_ = true;
-    }
-
-    // Update volume, point and lagrangian fields
-    updateInfoFields<fvPatchField, volMesh>
-    (
-        reader_->GetVolFieldSelection()
-    );
-    updateInfoFields<pointPatchField, pointMesh>
-    (
-        reader_->GetPointFieldSelection()
-    );
-    updateInfoLagrangianFields();
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(partSelection);
-        Info<< "<end> Foam::vtkPV3Foam::updateInfo" << endl;
-    }
-
-}
-
-
-void Foam::vtkPV3Foam::updateFoamMesh()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateFoamMesh" << endl;
-        printMemory();
-    }
-
-    if (!reader_->GetCacheMesh())
-    {
-        delete meshPtr_;
-        meshPtr_ = nullptr;
-    }
-
-    // Check to see if the OpenFOAM mesh has been created
-    if (!meshPtr_)
-    {
-        if (debug)
-        {
-            Info<< "Creating OpenFOAM mesh for region " << meshRegion_
-                << " at time=" << dbPtr_().timeName()
-                << endl;
-
-        }
-
-        meshPtr_ = new fvMesh
-        (
-            IOobject
-            (
-                meshRegion_,
-                dbPtr_().timeName(),
-                dbPtr_(),
-                IOobject::MUST_READ
-            )
-        );
-
-        meshChanged_ = true;
-    }
-    else
-    {
-        if (debug)
-        {
-            Info<< "Using existing OpenFOAM mesh" << endl;
-        }
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateFoamMesh" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::Update
-(
-    vtkMultiBlockDataSet* output,
-    vtkMultiBlockDataSet* lagrangianOutput
-)
-{
-    if (debug)
-    {
-        cout<< "<beg> Foam::vtkPV3Foam::Update - output with "
-            << output->GetNumberOfBlocks() << " and "
-            << lagrangianOutput->GetNumberOfBlocks() << " blocks\n";
-        output->Print(cout);
-        lagrangianOutput->Print(cout);
-        printMemory();
-    }
-    reader_->UpdateProgress(0.1);
-
-    // Set up mesh parts selection(s)
-    updateMeshPartsStatus();
-
-    reader_->UpdateProgress(0.15);
-
-    // Update the OpenFOAM mesh
-    updateFoamMesh();
-    reader_->UpdateProgress(0.4);
-
-    // Convert meshes - start port0 at block=0
-    int blockNo = 0;
-
-    convertMeshVolume(output, blockNo);
-    convertMeshPatches(output, blockNo);
-    reader_->UpdateProgress(0.6);
-
-    if (reader_->GetIncludeZones())
-    {
-        convertMeshCellZones(output, blockNo);
-        convertMeshFaceZones(output, blockNo);
-        convertMeshPointZones(output, blockNo);
-        reader_->UpdateProgress(0.65);
-    }
-
-    if (reader_->GetIncludeSets())
-    {
-        convertMeshCellSets(output, blockNo);
-        convertMeshFaceSets(output, blockNo);
-        convertMeshPointSets(output, blockNo);
-        reader_->UpdateProgress(0.7);
-    }
-
-#ifdef VTKPV3FOAM_DUALPORT
-    // restart port1 at block=0
-    blockNo = 0;
-#endif
-    convertMeshLagrangian(lagrangianOutput, blockNo);
-
-    reader_->UpdateProgress(0.8);
-
-    // Update fields
-    convertVolFields(output);
-    convertPointFields(output);
-    convertLagrangianFields(lagrangianOutput);
-    if (debug)
-    {
-        Info<< "done reader part" << endl;
-    }
-    reader_->UpdateProgress(0.95);
-
-    meshChanged_ = fieldsChanged_ = false;
-}
-
-
-void Foam::vtkPV3Foam::CleanUp()
-{
-    // reclaim some memory
-    reduceMemory();
-    reader_->UpdateProgress(1.0);
-}
-
-
-double* Foam::vtkPV3Foam::findTimes(int& nTimeSteps)
-{
-    int nTimes = 0;
-    double* tsteps = nullptr;
-
-    if (dbPtr_.valid())
-    {
-        Time& runTime = dbPtr_();
-        instantList timeLst = runTime.times();
-
-        // find the first time for which this mesh appears to exist
-        label timeI = 0;
-        for (; timeI < timeLst.size(); ++timeI)
-        {
-            const word& timeName = timeLst[timeI].name();
-
-            if
-            (
-                isFile(runTime.path()/timeName/meshDir_/"points")
-             && IOobject
-                (
-                    "points",
-                    timeName,
-                    meshDir_,
-                    runTime
-                ).typeHeaderOk<pointIOField>(true)
-            )
-            {
-                break;
-            }
-        }
-
-        nTimes = timeLst.size() - timeI;
-
-        // skip "constant" time whenever possible
-        if (timeI == 0 && nTimes > 1)
-        {
-            if (timeLst[timeI].name() == runTime.constant())
-            {
-                ++timeI;
-                --nTimes;
-            }
-        }
-
-
-        // skip "0/" time if requested and possible
-        if (nTimes > 1 && reader_->GetSkipZeroTime())
-        {
-            if (mag(timeLst[timeI].value()) < SMALL)
-            {
-                ++timeI;
-                --nTimes;
-            }
-        }
-
-        if (nTimes)
-        {
-            tsteps = new double[nTimes];
-            for (label stepI = 0; stepI < nTimes; ++stepI, ++timeI)
-            {
-                tsteps[stepI] = timeLst[timeI].value();
-            }
-        }
-    }
-    else
-    {
-        if (debug)
-        {
-            cout<< "no valid dbPtr:\n";
-        }
-    }
-
-    // vector length returned via the parameter
-    nTimeSteps = nTimes;
-
-    return tsteps;
-}
-
-
-void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
-{
-    if (!meshPtr_)
-    {
-        return;
-    }
-
-    // always remove old actors first
-
-    forAll(patchTextActorsPtrs_, patchi)
-    {
-        renderer->RemoveViewProp(patchTextActorsPtrs_[patchi]);
-        patchTextActorsPtrs_[patchi]->Delete();
-    }
-    patchTextActorsPtrs_.clear();
-
-    if (show)
-    {
-        // get the display patches, strip off any suffix
-        wordHashSet selectedPatches = getSelected
-        (
-            reader_->GetPartSelection(),
-            arrayRangePatches_
-        );
-
-        if (selectedPatches.empty())
-        {
-            return;
-        }
-
-        const polyBoundaryMesh& pbMesh = meshPtr_->boundaryMesh();
-
-        // Find the total number of zones
-        // Each zone will take the patch name
-        // Number of zones per patch ... zero zones should be skipped
-        labelList nZones(pbMesh.size(), 0);
-
-        // Per global zone number the average face centre position
-        List<DynamicList<point>> zoneCentre(pbMesh.size());
-
-
-        // Loop through all patches to determine zones, and centre of each zone
-        forAll(pbMesh, patchi)
-        {
-            const polyPatch& pp = pbMesh[patchi];
-
-            // Only include the patch if it is selected
-            if (!selectedPatches.found(pp.name()))
-            {
-                continue;
-            }
-
-            const labelListList& edgeFaces = pp.edgeFaces();
-            const vectorField& n = pp.faceNormals();
-
-            boolList featEdge(pp.nEdges(), false);
-
-            forAll(edgeFaces, edgeI)
-            {
-                const labelList& eFaces = edgeFaces[edgeI];
-
-                if (eFaces.size() == 1)
-                {
-                    // Note: could also do ones with > 2 faces but this gives
-                    // too many zones for baffles
-                    featEdge[edgeI] = true;
-                }
-                else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
-                {
-                    featEdge[edgeI] = true;
-                }
-            }
-
-            // Do topological analysis of patch, find disconnected regions
-            patchZones pZones(pp, featEdge);
-
-            nZones[patchi] = pZones.nZones();
-
-            labelList zoneNFaces(pZones.nZones(), 0);
-
-            // Create storage for additional zone centres
-            forAll(zoneNFaces, zoneI)
-            {
-                zoneCentre[patchi].append(Zero);
-            }
-
-            // Do averaging per individual zone
-            forAll(pp, facei)
-            {
-                label zoneI = pZones[facei];
-                zoneCentre[patchi][zoneI] += pp[facei].centre(pp.points());
-                zoneNFaces[zoneI]++;
-            }
-
-            forAll(zoneCentre[patchi], zoneI)
-            {
-                zoneCentre[patchi][zoneI] /= zoneNFaces[zoneI];
-            }
-        }
-
-        // Count number of zones we're actually going to display.
-        // This is truncated to a max per patch
-
-        const label MAXPATCHZONES = 20;
-
-        label displayZoneI = 0;
-
-        forAll(pbMesh, patchi)
-        {
-            displayZoneI += min(MAXPATCHZONES, nZones[patchi]);
-        }
-
-        if (debug)
-        {
-            Info<< "displayed zone centres = " << displayZoneI << nl
-                << "zones per patch = " << nZones << endl;
-        }
-
-        // Set the size of the patch labels to max number of zones
-        patchTextActorsPtrs_.setSize(displayZoneI);
-
-        if (debug)
-        {
-            Info<< "constructing patch labels" << endl;
-        }
-
-        // Actor index
-        displayZoneI = 0;
-
-        forAll(pbMesh, patchi)
-        {
-            const polyPatch& pp = pbMesh[patchi];
-
-            label globalZoneI = 0;
-
-            // Only selected patches will have a non-zero number of zones
-            label nDisplayZones = min(MAXPATCHZONES, nZones[patchi]);
-            label increment = 1;
-            if (nZones[patchi] >= MAXPATCHZONES)
-            {
-                increment = nZones[patchi]/MAXPATCHZONES;
-            }
-
-            for (label i = 0; i < nDisplayZones; i++)
-            {
-                if (debug)
-                {
-                    Info<< "patch name = " << pp.name() << nl
-                        << "anchor = " << zoneCentre[patchi][globalZoneI] << nl
-                        << "globalZoneI = " << globalZoneI << endl;
-                }
-
-                vtkTextActor* txt = vtkTextActor::New();
-
-                txt->SetInput(pp.name().c_str());
-
-                // Set text properties
-                vtkTextProperty* tprop = txt->GetTextProperty();
-                tprop->SetFontFamilyToArial();
-                tprop->BoldOff();
-                tprop->ShadowOff();
-                tprop->SetLineSpacing(1.0);
-                tprop->SetFontSize(12);
-                tprop->SetColor(1.0, 0.0, 0.0);
-                tprop->SetJustificationToCentered();
-
-                // Set text to use 3-D world co-ordinates
-                txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
-
-                txt->GetPositionCoordinate()->SetValue
-                (
-                    zoneCentre[patchi][globalZoneI].x(),
-                    zoneCentre[patchi][globalZoneI].y(),
-                    zoneCentre[patchi][globalZoneI].z()
-                );
-
-                // Add text to each renderer
-                renderer->AddViewProp(txt);
-
-                // Maintain a list of text labels added so that they can be
-                // removed later
-                patchTextActorsPtrs_[displayZoneI] = txt;
-
-                globalZoneI += increment;
-                displayZoneI++;
-            }
-        }
-
-        // Resize the patch names list to the actual number of patch names added
-        patchTextActorsPtrs_.setSize(displayZoneI);
-    }
-}
-
-
-void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
-{
-    os  << indent << "Number of nodes: "
-        << (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
-
-    os  << indent << "Number of cells: "
-        << (meshPtr_ ? meshPtr_->nCells() : 0) << "\n";
-
-    os  << indent << "Number of available time steps: "
-        << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << "\n";
-
-    os  << indent << "mesh region: " << meshRegion_ << "\n";
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
deleted file mode 100644
index ab6dc05c831eff0c486708622036c9c1dbc60c4c..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
+++ /dev/null
@@ -1,741 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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::vtkPV3Foam
-
-Description
-    Provides a reader interface for OpenFOAM to VTK interaction.
-
-SourceFiles
-    vtkPV3Foam.C
-    vtkPV3Foam.H
-    vtkPV3FoamFields.C
-    vtkPV3FoamMesh.C
-    vtkPV3FoamMeshLagrangian.C
-    vtkPV3FoamTemplates.C
-    vtkPV3FoamMeshSet.C
-    vtkPV3FoamMeshVolume.C
-    vtkPV3FoamMeshZone.C
-    vtkPV3FoamFaceField.H
-    vtkPV3FoamLagrangianFields.H
-    vtkPV3FoamPatchField.H
-    vtkPV3FoamPointFields.H
-    vtkPV3FoamPoints.H
-    vtkPV3FoamUpdateInfo.C
-    vtkPV3FoamUpdateInfoFields.H
-    vtkPV3FoamUtils.C
-    vtkPV3FoamVolFields.H
-    vtkPV3FoamAddToSelection.H
-
-    // Needed by VTK:
-    vtkDataArrayTemplateImplicit.txx
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3Foam_H
-#define vtkPV3Foam_H
-
-// do not include legacy strstream headers
-#ifndef  VTK_EXCLUDE_STRSTREAM_HEADERS
-# define VTK_EXCLUDE_STRSTREAM_HEADERS
-#endif
-
-#include "className.H"
-#include "fileName.H"
-#include "stringList.H"
-#include "wordList.H"
-#include "primitivePatch.H"
-#include "PrimitivePatchInterpolation.H"
-#include "volPointInterpolation.H"
-
-#undef VTKPV3FOAM_DUALPORT
-
-// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
-
-class vtkDataArraySelection;
-class vtkDataSet;
-class vtkPoints;
-class vtkPV3FoamReader;
-class vtkRenderer;
-class vtkTextActor;
-class vtkMultiBlockDataSet;
-class vtkPolyData;
-class vtkUnstructuredGrid;
-class vtkIndent;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// OpenFOAM class forward declarations
-class argList;
-class Time;
-class fvMesh;
-class IOobjectList;
-class polyPatch;
-class faceSet;
-class pointSet;
-
-template<class Type> class IOField;
-template<class Type> class List;
-
-/*---------------------------------------------------------------------------*\
-                        Class vtkPV3Foam Declaration
-\*---------------------------------------------------------------------------*/
-
-class vtkPV3Foam
-{
-    // Private classes
-
-        //- Bookkeeping for GUI checklists and the multi-block organization
-        class arrayRange
-        {
-            const char *name_;
-            int block_;
-            int start_;
-            int size_;
-
-        public:
-
-            arrayRange(const char *name, const int blockNo=0)
-            :
-                name_(name),
-                block_(blockNo),
-                start_(0),
-                size_(0)
-            {}
-
-            //- Return the block holding these datasets
-            int block() const
-            {
-                return block_;
-            }
-
-            //- Assign block number, return previous value
-            int block(int blockNo)
-            {
-                int prev = block_;
-                block_ = blockNo;
-                return prev;
-            }
-
-            //- Return block name
-            const char* name() const
-            {
-                return name_;
-            }
-
-            //- Return array start index
-            int start() const
-            {
-                return start_;
-            }
-
-            //- Return array end index
-            int end() const
-            {
-                return start_ + size_;
-            }
-
-            //- Return sublist size
-            int size() const
-            {
-                return size_;
-            }
-
-            bool empty() const
-            {
-                return !size_;
-            }
-
-            //- Reset the size to zero and optionally assign a new start
-            void reset(const int startAt = 0)
-            {
-                start_ = startAt;
-                size_ = 0;
-            }
-
-            //- Increment the size
-            void operator+=(const int n)
-            {
-                size_ += n;
-            }
-        };
-
-        //- Bookkeeping for polyhedral cell decomposition
-        //  hide in extra pointMap (cellSet/cellZone) for now
-        class polyDecomp
-        {
-            labelList superCells_;
-            labelList addPointCellLabels_;
-            labelList pointMap_;
-
-        public:
-
-            polyDecomp()
-            {}
-
-            //- Label of original cell for decomposed cells
-            labelList& superCells()
-            {
-                return superCells_;
-            }
-
-            //- Label of original cell for decomposed cells
-            const labelList& superCells() const
-            {
-                return superCells_;
-            }
-
-            //- Cell-centre labels for additional points of decomposed cells
-            labelList& addPointCellLabels()
-            {
-                return addPointCellLabels_;
-            }
-
-            //- Cell-centre labels for additional points of decomposed cells
-            const labelList& addPointCellLabels() const
-            {
-                return addPointCellLabels_;
-            }
-
-            //- Point labels for subsetted meshes
-            labelList& pointMap()
-            {
-                return pointMap_;
-            }
-
-            //- Point labels for subsetted meshes
-            const labelList& pointMap() const
-            {
-                return pointMap_;
-            }
-
-
-            //- Clear
-            void clear()
-            {
-                superCells_.clear();
-                addPointCellLabels_.clear();
-                pointMap_.clear();
-            }
-        };
-
-
-    // Private Data
-
-        //- Access to the controlling vtkPV3FoamReader
-        vtkPV3FoamReader* reader_;
-
-        //- OpenFOAM time control
-        autoPtr<Time> dbPtr_;
-
-        //- OpenFOAM mesh
-        fvMesh* meshPtr_;
-
-        //- The mesh region
-        word meshRegion_;
-
-        //- The mesh directory for the region
-        fileName meshDir_;
-
-        //- The time index
-        int timeIndex_;
-
-        //- Track changes in mesh geometry
-        bool meshChanged_;
-
-        //- Track changes in fields
-        bool fieldsChanged_;
-
-        //- Selected geometrical parts (internalMesh, patches, ...)
-        boolList partStatus_;
-
-        //- Datasets corresponding to selected geometrical pieces
-        //  a negative number indicates that no vtkmesh exists for this piece
-        labelList partDataset_;
-
-        //- First instance and size of various mesh parts
-        //  used to index into partStatus_ and partDataset_
-        arrayRange arrayRangeVolume_;
-        arrayRange arrayRangePatches_;
-        arrayRange arrayRangeLagrangian_;
-        arrayRange arrayRangeCellZones_;
-        arrayRange arrayRangeFaceZones_;
-        arrayRange arrayRangePointZones_;
-        arrayRange arrayRangeCellSets_;
-        arrayRange arrayRangeFaceSets_;
-        arrayRange arrayRangePointSets_;
-
-        //- Decomposed cells information (mesh regions)
-        //  TODO: regions
-        List<polyDecomp> regionPolyDecomp_;
-
-        //- Decomposed cells information (cellZone meshes)
-        List<polyDecomp> zonePolyDecomp_;
-
-        //- Decomposed cells information (cellSet meshes)
-        List<polyDecomp> csetPolyDecomp_;
-
-        //- List of patch names for rendering to window
-        List<vtkTextActor*> patchTextActorsPtrs_;
-
-    // Private Member Functions
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static void AddToBlock
-        (
-            vtkMultiBlockDataSet* output,
-            vtkDataSet* dataset,
-            const arrayRange&,
-            const label datasetNo,
-            const std::string& datasetName
-        );
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static vtkDataSet* GetDataSetFromBlock
-        (
-            vtkMultiBlockDataSet* output,
-            const arrayRange&,
-            const label datasetNo
-        );
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static label GetNumberOfDataSets
-        (
-            vtkMultiBlockDataSet* output,
-            const arrayRange&
-        );
-
-        //- Reset data counters
-        void resetCounters();
-
-        // Update information helper functions
-
-            //- Update the mesh parts selected in the GUI
-            void updateMeshPartsStatus();
-
-            //- Internal mesh info
-            void updateInfoInternalMesh(vtkDataArraySelection*);
-
-            //- Lagrangian info
-            void updateInfoLagrangian(vtkDataArraySelection*);
-
-            //- Patch info
-            void updateInfoPatches(vtkDataArraySelection*, stringList&);
-
-            //- Set info
-            void updateInfoSets(vtkDataArraySelection*);
-
-            //- Zone info
-            void updateInfoZones(vtkDataArraySelection*);
-
-            //- Get non-empty zone names for zoneType from file
-            wordList getZoneNames(const word& zoneType) const;
-
-            //- Get non-empty zone names from mesh info
-            template<class ZoneType>
-            wordList getZoneNames
-            (
-                const ZoneMesh<ZoneType, polyMesh>&
-            ) const;
-
-            //- Add objects of Type to paraview array selection
-            template<class Type>
-            label addToSelection
-            (
-                vtkDataArraySelection*,
-                const IOobjectList&,
-                const string& suffix=string::null
-            );
-
-            //- Field info
-            template<template<class> class patchType, class meshType>
-            void updateInfoFields(vtkDataArraySelection*);
-
-            //- Lagrangian field info
-            void updateInfoLagrangianFields();
-
-
-        // Update helper functions
-
-            //- OpenFOAM mesh
-            void updateFoamMesh();
-
-            //- Reduce memory footprint after conversion
-            void reduceMemory();
-
-            //- Volume fields
-            void updateVolFields(vtkMultiBlockDataSet*);
-
-            //- Point fields
-            void updatePointFields(vtkMultiBlockDataSet*);
-
-            //- Lagrangian fields
-            void updateLagrangianFields(vtkMultiBlockDataSet*);
-
-
-        // Mesh conversion functions
-
-            //- Volume mesh
-            void convertMeshVolume(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Lagrangian mesh
-            void convertMeshLagrangian(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Patch meshes
-            void convertMeshPatches(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Cell zone meshes
-            void convertMeshCellZones(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Face zone meshes
-            void convertMeshFaceZones(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Point zone meshes
-            void convertMeshPointZones(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Cell set meshes
-            void convertMeshCellSets(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Face set meshes
-            void convertMeshFaceSets(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Point set meshes
-            void convertMeshPointSets(vtkMultiBlockDataSet*, int& blockNo);
-
-
-        // Add mesh functions
-
-            //- Add internal mesh/cell set meshes
-            vtkUnstructuredGrid* volumeVTKMesh(const fvMesh&, polyDecomp&);
-
-            //- Add Lagrangian mesh
-            vtkPolyData* lagrangianVTKMesh
-            (
-                const fvMesh&,
-                const word& cloudName
-            );
-
-            //- Add patch mesh
-            template<class PatchType>
-            vtkPolyData* patchVTKMesh(const word& name, const PatchType&);
-
-            //- Add point zone
-            vtkPolyData* pointZoneVTKMesh
-            (
-                const fvMesh&,
-                const labelList& pointLabels
-            );
-
-            //- Add face set mesh
-            vtkPolyData* faceSetVTKMesh
-            (
-                const fvMesh&,
-                const faceSet&
-            );
-
-            //- Add point mesh
-            vtkPolyData* pointSetVTKMesh
-            (
-                const fvMesh&,
-                const pointSet&
-            );
-
-        // Field conversion functions
-
-            //- Convert volume fields
-            void convertVolFields(vtkMultiBlockDataSet*);
-
-            //- Convert point fields
-            void convertPointFields(vtkMultiBlockDataSet*);
-
-            //- Convert Lagrangian fields
-            void convertLagrangianFields(vtkMultiBlockDataSet*);
-
-
-        //- Add the fields in the selected time directory to the selection
-        //  lists
-        template<class GeoField>
-        label addObjectsToSelection
-        (
-            vtkDataArraySelection*,
-            const IOobjectList&,
-            const string& suffix=string::null
-        );
-
-
-        // Convert OpenFOAM fields
-
-            //- Volume fields - all types
-            template<class Type>
-            void convertVolFields
-            (
-                const fvMesh&,
-                const PtrList<PrimitivePatchInterpolation<primitivePatch>>&,
-                const IOobjectList&,
-                const bool interpFields,
-                vtkMultiBlockDataSet* output
-            );
-
-            //- Volume field - all selected parts
-            template<class Type>
-            void convertVolFieldBlock
-            (
-                const GeometricField<Type, fvPatchField, volMesh>&,
-                autoPtr<GeometricField<Type, pointPatchField, pointMesh>>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const List<polyDecomp>& decompLst
-            );
-
-            //- Volume field
-            template<class Type>
-            void convertVolField
-            (
-                const GeometricField<Type, fvPatchField, volMesh>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo,
-                const polyDecomp&
-            );
-
-            //- Patch field
-            template<class Type>
-            void convertPatchField
-            (
-                const word& name,
-                const Field<Type>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo
-            );
-
-            //- Face set/zone field
-            template<class Type>
-            void convertFaceField
-            (
-                const GeometricField<Type, fvPatchField, volMesh>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo,
-                const fvMesh&,
-                const labelList& faceLabels
-            );
-
-            //- Lagrangian fields - all types
-            template<class Type>
-            void convertLagrangianFields
-            (
-                const IOobjectList&,
-                vtkMultiBlockDataSet* output,
-                const label datasetNo
-            );
-
-            //- Lagrangian field
-            template<class Type>
-            void convertLagrangianField
-            (
-                const IOField<Type>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo
-            );
-
-            //- Point fields - all types
-            template<class Type>
-            void convertPointFields
-            (
-                const fvMesh&,
-                const pointMesh&,
-                const IOobjectList&,
-                vtkMultiBlockDataSet* output
-            );
-
-            //- Point field - all selected parts
-            template<class Type>
-            void convertPointFieldBlock
-            (
-                const GeometricField<Type, pointPatchField, pointMesh>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const List<polyDecomp>&
-            );
-
-            //- Point fields
-            template<class Type>
-            void convertPointField
-            (
-                const GeometricField<Type, pointPatchField, pointMesh>&,
-                const GeometricField<Type, fvPatchField, volMesh>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo,
-                const polyDecomp&
-            );
-
-            //- Patch point field
-            template<class Type>
-            void convertPatchPointField
-            (
-                const word& name,
-                const Field<Type>&,
-                vtkMultiBlockDataSet* output,
-                const arrayRange&,
-                const label datasetNo
-            );
-
-
-       // GUI selection helper functions
-
-            //- Only keep what is listed in hashSet
-            static void pruneObjectList
-            (
-                IOobjectList&,
-                const wordHashSet&
-            );
-
-            //- Retrieve the current selections
-            static wordHashSet getSelected(vtkDataArraySelection*);
-
-            //- Retrieve a sub-list of the current selections
-            static wordHashSet getSelected
-            (
-                vtkDataArraySelection*,
-                const arrayRange&
-            );
-
-            //- Retrieve the current selections
-            static stringList getSelectedArrayEntries(vtkDataArraySelection*);
-
-            //- Retrieve a sub-list of the current selections
-            static stringList getSelectedArrayEntries
-            (
-                vtkDataArraySelection*,
-                const arrayRange&
-            );
-
-            //- Set selection(s)
-            static void setSelectedArrayEntries
-            (
-                vtkDataArraySelection*,
-                const stringList&
-            );
-
-            //- Get the first word from the mesh parts selection
-            word getPartName(const int);
-
-
-        //- Disallow default bitwise copy construct
-        vtkPV3Foam(const vtkPV3Foam&);
-
-        //- Disallow default bitwise assignment
-        void operator=(const vtkPV3Foam&);
-
-
-public:
-
-    //- Static data members
-
-        ClassName("vtkPV3Foam");
-
-
-    // Constructors
-
-        //- Construct from components
-        vtkPV3Foam
-        (
-            const char* const FileName,
-            vtkPV3FoamReader* reader
-        );
-
-
-    //- Destructor
-    ~vtkPV3Foam();
-
-
-    // Member Functions
-
-        //- Update
-        void updateInfo();
-
-        void Update
-        (
-            vtkMultiBlockDataSet* output,
-            vtkMultiBlockDataSet* lagrangianOutput
-        );
-
-        //- Clean any storage
-        void CleanUp();
-
-        //- Allocate and return a list of selected times
-        //  returns the count via the parameter
-        double* findTimes(int& nTimeSteps);
-
-        //- Add/remove patch names to/from the view
-        void renderPatchNames(vtkRenderer*, const bool show);
-
-        //- Set the runTime to the first plausible request time,
-        //  returns the timeIndex
-        //  sets to "constant" on error
-        int setTime(int count, const double requestTimes[]);
-
-
-        //- The current time index
-        int timeIndex() const
-        {
-           return timeIndex_;
-        }
-
-
-     // Access
-
-        //- Debug information
-        void PrintSelf(ostream&, vtkIndent) const;
-
-        //- Simple memory used debugging information
-        static void printMemory();
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-    #include "vtkPV3FoamTemplates.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H
deleted file mode 100644
index 1324b84ea98a731388f2b446ddeb8e9e3de2fa64..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H
+++ /dev/null
@@ -1,117 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamFaceField_H
-#define vtkPV3FoamFaceField_H
-
-// VTK includes
-#include "vtkCellData.h"
-#include "vtkFloatArray.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkPolyData.h"
-
-#include "vtkOpenFOAMTupleRemap.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::vtkPV3Foam::convertFaceField
-(
-    const GeometricField<Type, fvPatchField, volMesh>& tf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo,
-    const fvMesh& mesh,
-    const labelList& faceLabels
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-    const label nInternalFaces = mesh.nInternalFaces();
-    const labelList& faceOwner = mesh.faceOwner();
-    const labelList& faceNeigh = mesh.faceNeighbour();
-
-    vtkFloatArray* cellData = vtkFloatArray::New();
-    cellData->SetNumberOfTuples(faceLabels.size());
-    cellData->SetNumberOfComponents(nComp);
-    cellData->Allocate(nComp*faceLabels.size());
-    cellData->SetName(tf.name().c_str());
-
-    if (debug)
-    {
-        Info<< "convert convertFaceField: "
-            << tf.name()
-            << " size = " << tf.size()
-            << " nComp=" << nComp
-            << " nTuples = " << faceLabels.size() <<  endl;
-    }
-
-    float vec[nComp];
-
-    // for interior faces: average owner/neighbour
-    // for boundary faces: owner
-    forAll(faceLabels, facei)
-    {
-        const label faceNo = faceLabels[facei];
-        if (faceNo < nInternalFaces)
-        {
-            Type t = 0.5*(tf[faceOwner[faceNo]] + tf[faceNeigh[faceNo]]);
-
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-        }
-        else
-        {
-            const Type& t = tf[faceOwner[faceNo]];
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-        }
-        vtkOpenFOAMTupleRemap<Type>(vec);
-
-        cellData->InsertTuple(facei, vec);
-    }
-
-
-    vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetCellData()
-        ->AddArray(cellData);
-
-    cellData->Delete();
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C
deleted file mode 100644
index 0c0fa41c739dedc1fb93ec5ade71510bb2c4b1c5..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C
+++ /dev/null
@@ -1,325 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "IOobjectList.H"
-#include "vtkPV3FoamReader.h"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkPolyData.h"
-#include "vtkUnstructuredGrid.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-#include "vtkPV3FoamVolFields.H"
-#include "vtkPV3FoamPointFields.H"
-#include "vtkPV3FoamLagrangianFields.H"
-
-
-void Foam::vtkPV3Foam::pruneObjectList
-(
-    IOobjectList& objects,
-    const wordHashSet& selected
-)
-{
-    // hash all the selected field names
-    if (selected.empty())
-    {
-        objects.clear();
-    }
-
-    // only keep selected fields
-    forAllIter(IOobjectList, objects, iter)
-    {
-        if (!selected.found(iter()->name()))
-        {
-            objects.erase(iter);
-        }
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertVolFields
-(
-    vtkMultiBlockDataSet* output
-)
-{
-    const fvMesh& mesh = *meshPtr_;
-
-    wordHashSet selectedFields = getSelected
-    (
-        reader_->GetVolFieldSelection()
-    );
-
-    if (selectedFields.empty())
-    {
-        return;
-    }
-
-    // Get objects (fields) for this time - only keep selected fields
-    // the region name is already in the mesh db
-    IOobjectList objects(mesh, dbPtr_().timeName());
-    pruneObjectList(objects, selectedFields);
-
-    if (objects.empty())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertVolFields" << nl
-            << "converting OpenFOAM volume fields" << endl;
-        forAllConstIter(IOobjectList, objects, iter)
-        {
-            Info<< "  " << iter()->name()
-                << " == " << iter()->objectPath() << nl;
-        }
-        printMemory();
-    }
-
-
-    PtrList<PrimitivePatchInterpolation<primitivePatch>>
-        ppInterpList(mesh.boundaryMesh().size());
-
-    forAll(ppInterpList, i)
-    {
-        ppInterpList.set
-        (
-            i,
-            new PrimitivePatchInterpolation<primitivePatch>
-            (
-                mesh.boundaryMesh()[i]
-            )
-        );
-    }
-
-
-    bool interpFields = reader_->GetInterpolateVolFields();
-
-    convertVolFields<scalar>
-    (
-        mesh, ppInterpList, objects, interpFields, output
-    );
-    convertVolFields<vector>
-    (
-        mesh, ppInterpList, objects, interpFields, output
-    );
-    convertVolFields<sphericalTensor>
-    (
-        mesh, ppInterpList, objects, interpFields, output
-    );
-    convertVolFields<symmTensor>
-    (
-        mesh, ppInterpList, objects, interpFields, output
-    );
-    convertVolFields<tensor>
-    (
-        mesh, ppInterpList, objects, interpFields, output
-    );
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertVolFields" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertPointFields
-(
-    vtkMultiBlockDataSet* output
-)
-{
-    const fvMesh& mesh = *meshPtr_;
-
-    wordHashSet selectedFields = getSelected
-    (
-        reader_->GetPointFieldSelection()
-    );
-
-    if (selectedFields.empty())
-    {
-        if (debug)
-        {
-            Info<< "no point fields selected" << endl;
-        }
-        return;
-    }
-
-    // Get objects (fields) for this time - only keep selected fields
-    // the region name is already in the mesh db
-    IOobjectList objects(mesh, dbPtr_().timeName());
-    pruneObjectList(objects, selectedFields);
-
-    if (objects.empty())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertPointFields" << nl
-            << "converting OpenFOAM volume fields -> point fields" << endl;
-        forAllConstIter(IOobjectList, objects, iter)
-        {
-            Info<< "  " << iter()->name()
-                << " == " << iter()->objectPath() << nl;
-        }
-        printMemory();
-    }
-
-    // Construct interpolation on the raw mesh
-    const pointMesh& pMesh = pointMesh::New(mesh);
-
-
-    convertPointFields<scalar>
-    (
-        mesh, pMesh, objects, output
-    );
-    convertPointFields<vector>
-    (
-        mesh, pMesh, objects, output
-    );
-    convertPointFields<sphericalTensor>
-    (
-        mesh, pMesh, objects, output
-    );
-    convertPointFields<symmTensor>
-    (
-        mesh, pMesh, objects, output
-    );
-    convertPointFields<tensor>
-    (
-        mesh, pMesh, objects, output
-    );
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertPointFields" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertLagrangianFields
-(
-    vtkMultiBlockDataSet* output
-)
-{
-    arrayRange& range = arrayRangeLagrangian_;
-    const fvMesh& mesh = *meshPtr_;
-
-    wordHashSet selectedFields = getSelected
-    (
-        reader_->GetLagrangianFieldSelection()
-    );
-
-    if (selectedFields.empty())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertLagrangianFields" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word  cloudName = getPartName(partId);
-        const label datasetNo = partDataset_[partId];
-
-        if (!partStatus_[partId] || datasetNo < 0)
-        {
-            continue;
-        }
-
-
-        // Get the Lagrangian fields for this time and this cloud
-        // but only keep selected fields
-        // the region name is already in the mesh db
-        IOobjectList objects
-        (
-            mesh,
-            dbPtr_().timeName(),
-            cloud::prefix/cloudName
-        );
-        pruneObjectList(objects, selectedFields);
-
-        if (objects.empty())
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "converting OpenFOAM lagrangian fields" << nl;
-            forAllConstIter(IOobjectList, objects, iter)
-            {
-                Info<< "  " << iter()->name()
-                    << " == " << iter()->objectPath() << nl;
-            }
-        }
-
-        convertLagrangianFields<label>
-        (
-            objects, output, datasetNo
-        );
-        convertLagrangianFields<scalar>
-        (
-            objects, output, datasetNo
-        );
-        convertLagrangianFields<vector>
-        (
-            objects, output, datasetNo
-        );
-        convertLagrangianFields<sphericalTensor>
-        (
-            objects, output, datasetNo
-        );
-        convertLagrangianFields<symmTensor>
-        (
-            objects, output, datasetNo
-        );
-        convertLagrangianFields<tensor>
-        (
-            objects, output, datasetNo
-        );
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertLagrangianFields" << endl;
-        printMemory();
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H
deleted file mode 100644
index 53d209dbffa60d69a8010eb6ee89dbaaf719d6db..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H
+++ /dev/null
@@ -1,113 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamLagrangianFields_H
-#define vtkPV3FoamLagrangianFields_H
-
-#include "Cloud.H"
-
-#include "vtkOpenFOAMTupleRemap.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::vtkPV3Foam::convertLagrangianFields
-(
-    const IOobjectList& objects,
-    vtkMultiBlockDataSet* output,
-    const label datasetNo
-)
-{
-    const arrayRange& range = arrayRangeLagrangian_;
-
-    forAllConstIter(IOobjectList, objects, iter)
-    {
-        // restrict to this IOField<Type>
-        if (iter()->headerClassName() == IOField<Type>::typeName)
-        {
-            IOField<Type> tf(*iter());
-            convertLagrangianField(tf, output, range, datasetNo);
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::vtkPV3Foam::convertLagrangianField
-(
-    const IOField<Type>& tf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-
-    vtkFloatArray* pointData = vtkFloatArray::New();
-    pointData->SetNumberOfTuples(tf.size());
-    pointData->SetNumberOfComponents(nComp);
-    pointData->Allocate(nComp*tf.size());
-    pointData->SetName(tf.name().c_str());
-
-    if (debug)
-    {
-        Info<< "convert LagrangianField: "
-            << tf.name()
-            << " size = " << tf.size()
-            << " nComp=" << nComp
-            << " nTuples = " << tf.size() <<  endl;
-    }
-
-    float vec[nComp];
-    forAll(tf, i)
-    {
-        const Type& t = tf[i];
-        for (direction d=0; d<nComp; ++d)
-        {
-            vec[d] = component(t, d);
-        }
-        vtkOpenFOAMTupleRemap<Type>(vec);
-
-        pointData->InsertTuple(i, vec);
-    }
-
-
-    vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetPointData()
-        ->AddArray(pointData);
-
-    pointData->Delete();
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C
deleted file mode 100644
index 5ffcffbeb10e197f01d9ff02557fa06e7f4b6ac7..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C
+++ /dev/null
@@ -1,651 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "cellSet.H"
-#include "faceSet.H"
-#include "pointSet.H"
-#include "fvMeshSubset.H"
-#include "vtkPV3FoamReader.h"
-#include "uindirectPrimitivePatch.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkPolyData.h"
-#include "vtkUnstructuredGrid.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::vtkPV3Foam::convertMeshVolume
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeVolume_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    // resize for decomposed polyhedra
-    regionPolyDecomp_.setSize(range.size());
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshVolume" << endl;
-        printMemory();
-    }
-
-    // Convert the internalMesh
-    // this looks like more than one part, but it isn't
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word partName = "internalMesh";
-
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
-        (
-            mesh,
-            regionPolyDecomp_[datasetNo]
-        );
-
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, partName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshVolume" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshLagrangian
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeLagrangian_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshLagrangian" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word cloudName = getPartName(partId);
-
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        vtkPolyData* vtkmesh = lagrangianVTKMesh(mesh, cloudName);
-
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, cloudName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshLagrangian" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshPatches
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangePatches_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshPatches" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        const word patchName = getPartName(partId);
-
-        labelHashSet patchIds
-        (
-            patches.patchSet(List<wordRe>(1, wordRe(patchName)))
-        );
-
-        if (debug)
-        {
-            Info<< "Creating VTK mesh for patches [" << patchIds <<"] "
-                << patchName  << endl;
-        }
-
-        vtkPolyData* vtkmesh = nullptr;
-        if (patchIds.size() == 1)
-        {
-            vtkmesh = patchVTKMesh(patchName, patches[patchIds.begin().key()]);
-        }
-        else
-        {
-            // Patch group. Collect patch faces.
-            label sz = 0;
-            forAllConstIter(labelHashSet, patchIds, iter)
-            {
-                sz += patches[iter.key()].size();
-            }
-            labelList meshFaceLabels(sz);
-            sz = 0;
-            forAllConstIter(labelHashSet, patchIds, iter)
-            {
-                const polyPatch& pp = patches[iter.key()];
-                forAll(pp, i)
-                {
-                    meshFaceLabels[sz++] = pp.start()+i;
-                }
-            }
-            UIndirectList<face> fcs(mesh.faces(), meshFaceLabels);
-            uindirectPrimitivePatch pp(fcs, mesh.points());
-
-            vtkmesh = patchVTKMesh(patchName, pp);
-        }
-
-
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, patchName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshPatches" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshCellZones
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeCellZones_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    // resize for decomposed polyhedra
-    zonePolyDecomp_.setSize(range.size());
-
-    if (range.empty())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshCellZones" << endl;
-        printMemory();
-    }
-
-    const cellZoneMesh& zMesh = mesh.cellZones();
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word zoneName = getPartName(partId);
-        const label  zoneId = zMesh.findZoneID(zoneName);
-
-        if (!partStatus_[partId] || zoneId < 0)
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Creating VTK mesh for cellZone[" << zoneId << "] "
-                << zoneName << endl;
-        }
-
-        fvMeshSubset subsetter(mesh);
-        subsetter.setLargeCellSubset(zMesh[zoneId]);
-
-        vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
-        (
-            subsetter.subMesh(),
-            zonePolyDecomp_[datasetNo]
-        );
-
-        if (vtkmesh)
-        {
-            // superCells + addPointCellLabels must contain global cell ids
-            inplaceRenumber
-            (
-                subsetter.cellMap(),
-                zonePolyDecomp_[datasetNo].superCells()
-            );
-            inplaceRenumber
-            (
-                subsetter.cellMap(),
-                zonePolyDecomp_[datasetNo].addPointCellLabels()
-            );
-
-            // copy pointMap as well, otherwise pointFields fail
-            zonePolyDecomp_[datasetNo].pointMap() = subsetter.pointMap();
-
-            AddToBlock(output, vtkmesh, range, datasetNo, zoneName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshCellZones" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshCellSets
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeCellSets_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    // resize for decomposed polyhedra
-    csetPolyDecomp_.setSize(range.size());
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshCellSets" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word partName = getPartName(partId);
-
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Creating VTK mesh for cellSet=" << partName << endl;
-        }
-
-        const cellSet cSet(mesh, partName);
-        fvMeshSubset subsetter(mesh);
-        subsetter.setLargeCellSubset(cSet);
-
-        vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
-        (
-            subsetter.subMesh(),
-            csetPolyDecomp_[datasetNo]
-        );
-
-        if (vtkmesh)
-        {
-            // superCells + addPointCellLabels must contain global cell ids
-            inplaceRenumber
-            (
-                subsetter.cellMap(),
-                csetPolyDecomp_[datasetNo].superCells()
-            );
-            inplaceRenumber
-            (
-                subsetter.cellMap(),
-                csetPolyDecomp_[datasetNo].addPointCellLabels()
-            );
-
-            // copy pointMap as well, otherwise pointFields fail
-            csetPolyDecomp_[datasetNo].pointMap() = subsetter.pointMap();
-
-            AddToBlock(output, vtkmesh, range, datasetNo, partName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshCellSets" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshFaceZones
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeFaceZones_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    if (range.empty())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshFaceZones" << endl;
-        printMemory();
-    }
-
-    const faceZoneMesh& zMesh = mesh.faceZones();
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word zoneName = getPartName(partId);
-        const label  zoneId = zMesh.findZoneID(zoneName);
-
-        if (!partStatus_[partId] || zoneId < 0)
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Creating VTKmesh for faceZone[" << zoneId << "] "
-                << zoneName << endl;
-        }
-
-        vtkPolyData* vtkmesh = patchVTKMesh(zoneName, zMesh[zoneId]());
-
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, zoneName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshFaceZones" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshFaceSets
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeFaceSets_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshFaceSets" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const word partName = getPartName(partId);
-
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Creating VTK mesh for faceSet=" << partName << endl;
-        }
-
-        const faceSet fSet(mesh, partName);
-
-        vtkPolyData* vtkmesh = faceSetVTKMesh(mesh, fSet);
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, partName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshFaceSets" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::convertMeshPointZones
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangePointZones_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshPointZones" << endl;
-        printMemory();
-    }
-
-    if (range.size())
-    {
-        const pointZoneMesh& zMesh = mesh.pointZones();
-        for (int partId = range.start(); partId < range.end(); ++partId)
-        {
-            word zoneName = getPartName(partId);
-            label zoneId = zMesh.findZoneID(zoneName);
-
-            if (!partStatus_[partId] || zoneId < 0)
-            {
-                continue;
-            }
-
-            vtkPolyData* vtkmesh = pointZoneVTKMesh(mesh, zMesh[zoneId]);
-            if (vtkmesh)
-            {
-                AddToBlock(output, vtkmesh, range, datasetNo, zoneName);
-                vtkmesh->Delete();
-
-                partDataset_[partId] = datasetNo++;
-            }
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshPointZones" << endl;
-        printMemory();
-    }
-}
-
-
-
-void Foam::vtkPV3Foam::convertMeshPointSets
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangePointSets_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-    const fvMesh& mesh = *meshPtr_;
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::convertMeshPointSets" << endl;
-        printMemory();
-    }
-
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        word partName = getPartName(partId);
-
-        if (!partStatus_[partId])
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Creating VTK mesh for pointSet=" << partName << endl;
-        }
-
-        const pointSet pSet(mesh, partName);
-
-        vtkPolyData* vtkmesh = pointSetVTKMesh(mesh, pSet);
-        if (vtkmesh)
-        {
-            AddToBlock(output, vtkmesh, range, datasetNo, partName);
-            vtkmesh->Delete();
-
-            partDataset_[partId] = datasetNo++;
-        }
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::convertMeshPointSets" << endl;
-        printMemory();
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshLagrangian.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshLagrangian.C
deleted file mode 100644
index 9b112a21bbb319a7683cba64d3a5a79755fd7c93..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshLagrangian.C
+++ /dev/null
@@ -1,109 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "Cloud.H"
-#include "fvMesh.H"
-#include "IOobjectList.H"
-#include "passiveParticle.H"
-#include "vtkOpenFOAMPoints.H"
-
-// VTK includes
-#include "vtkCellArray.h"
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-vtkPolyData* Foam::vtkPV3Foam::lagrangianVTKMesh
-(
-    const fvMesh& mesh,
-    const word& cloudName
-)
-{
-    vtkPolyData* vtkmesh = nullptr;
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::lagrangianVTKMesh - timePath "
-            << mesh.time().timePath()/cloud::prefix/cloudName << endl;
-        printMemory();
-    }
-
-
-    // the region name is already in the mesh db
-    IOobjectList sprayObjs
-    (
-        mesh,
-        mesh.time().timeName(),
-        cloud::prefix/cloudName
-    );
-
-    IOobject* positionsPtr = sprayObjs.lookup(word("positions"));
-    if (positionsPtr)
-    {
-        Cloud<passiveParticle> parcels(mesh, cloudName, false);
-
-        if (debug)
-        {
-            Info<< "cloud with " << parcels.size() << " parcels" << endl;
-        }
-
-        vtkmesh = vtkPolyData::New();
-        vtkPoints* vtkpoints = vtkPoints::New();
-        vtkCellArray* vtkcells = vtkCellArray::New();
-
-        vtkpoints->Allocate(parcels.size());
-        vtkcells->Allocate(parcels.size());
-
-        vtkIdType particleId = 0;
-        forAllConstIter(Cloud<passiveParticle>, parcels, iter)
-        {
-            vtkInsertNextOpenFOAMPoint(vtkpoints, iter().position());
-
-            vtkcells->InsertNextCell(1, &particleId);
-            particleId++;
-        }
-
-        vtkmesh->SetPoints(vtkpoints);
-        vtkpoints->Delete();
-
-        vtkmesh->SetVerts(vtkcells);
-        vtkcells->Delete();
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::lagrangianVTKMesh" << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshSet.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshSet.C
deleted file mode 100644
index 7eba743458bfc8aed55ab4b819a304c9c34cbd7a..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshSet.C
+++ /dev/null
@@ -1,148 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "faceSet.H"
-#include "pointSet.H"
-#include "vtkOpenFOAMPoints.H"
-
-// VTK includes
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-#include "vtkCellArray.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-vtkPolyData* Foam::vtkPV3Foam::faceSetVTKMesh
-(
-    const fvMesh& mesh,
-    const faceSet& fSet
-)
-{
-    vtkPolyData* vtkmesh = vtkPolyData::New();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::faceSetVTKMesh" << endl;
-        printMemory();
-    }
-
-    // Construct primitivePatch of faces in fSet.
-
-    const faceList& meshFaces = mesh.faces();
-    faceList patchFaces(fSet.size());
-    label facei = 0;
-    forAllConstIter(faceSet, fSet, iter)
-    {
-        patchFaces[facei++] = meshFaces[iter.key()];
-    }
-    primitiveFacePatch p(patchFaces, mesh.points());
-
-
-    // The balance of this routine should be identical to patchVTKMesh
-
-    // Convert OpenFOAM mesh vertices to VTK
-    const pointField& points = p.localPoints();
-
-    vtkPoints* vtkpoints = vtkPoints::New();
-    vtkpoints->Allocate(points.size());
-    forAll(points, i)
-    {
-        vtkInsertNextOpenFOAMPoint(vtkpoints, points[i]);
-    }
-    vtkmesh->SetPoints(vtkpoints);
-    vtkpoints->Delete();
-
-    // Add faces as polygons
-    const faceList& faces = p.localFaces();
-
-    vtkCellArray* vtkcells = vtkCellArray::New();
-    vtkcells->Allocate(faces.size());
-
-    forAll(faces, facei)
-    {
-        const face& f = faces[facei];
-        vtkIdType nodeIds[f.size()];
-
-        forAll(f, fp)
-        {
-            nodeIds[fp] = f[fp];
-        }
-        vtkcells->InsertNextCell(f.size(), nodeIds);
-    }
-
-    vtkmesh->SetPolys(vtkcells);
-    vtkcells->Delete();
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::faceSetVTKMesh" << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-vtkPolyData* Foam::vtkPV3Foam::pointSetVTKMesh
-(
-    const fvMesh& mesh,
-    const pointSet& pSet
-)
-{
-    vtkPolyData* vtkmesh = vtkPolyData::New();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::pointSetVTKMesh" << endl;
-        printMemory();
-    }
-
-    const pointField& meshPoints = mesh.points();
-
-    vtkPoints* vtkpoints = vtkPoints::New();
-    vtkpoints->Allocate(pSet.size());
-
-    forAllConstIter(pointSet, pSet, iter)
-    {
-        vtkInsertNextOpenFOAMPoint(vtkpoints, meshPoints[iter.key()]);
-    }
-
-    vtkmesh->SetPoints(vtkpoints);
-    vtkpoints->Delete();
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::pointSetVTKMesh" << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
deleted file mode 100644
index 825ff9dc5a0bf9e5145940cc4136a632f90ef9e2..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
+++ /dev/null
@@ -1,480 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-#include "vtkPV3FoamReader.h"
-
-// OpenFOAM includes
-#include "fvMesh.H"
-#include "cellModeller.H"
-#include "vtkOpenFOAMPoints.H"
-#include "Swap.H"
-
-// VTK includes
-#include "vtkCellArray.h"
-#include "vtkIdTypeArray.h"
-#include "vtkUnstructuredGrid.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
-(
-    const fvMesh& mesh,
-    polyDecomp& decompInfo
-)
-{
-    const cellModel& tet = *(cellModeller::lookup("tet"));
-    const cellModel& pyr = *(cellModeller::lookup("pyr"));
-    const cellModel& prism = *(cellModeller::lookup("prism"));
-    const cellModel& wedge = *(cellModeller::lookup("wedge"));
-    const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
-    const cellModel& hex = *(cellModeller::lookup("hex"));
-
-    vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
-        printMemory();
-    }
-
-    const cellShapeList& cellShapes = mesh.cellShapes();
-
-    // Number of additional points needed by the decomposition of polyhedra
-    label nAddPoints = 0;
-
-    // Number of additional cells generated by the decomposition of polyhedra
-    label nAddCells = 0;
-
-    // face owner is needed to determine the face orientation
-    const labelList& owner = mesh.faceOwner();
-
-    labelList& superCells = decompInfo.superCells();
-    labelList& addPointCellLabels = decompInfo.addPointCellLabels();
-
-    // Scan for cells which need to be decomposed and count additional points
-    // and cells
-    if (!reader_->GetUseVTKPolyhedron())
-    {
-        if (debug)
-        {
-            Info<< "... scanning for polyhedra" << endl;
-        }
-
-        forAll(cellShapes, celli)
-        {
-            const cellModel& model = cellShapes[celli].model();
-
-            if
-            (
-                model != hex
-             && model != wedge
-             && model != prism
-             && model != pyr
-             && model != tet
-             && model != tetWedge
-            )
-            {
-                const cell& cFaces = mesh.cells()[celli];
-
-                forAll(cFaces, cFacei)
-                {
-                    const face& f = mesh.faces()[cFaces[cFacei]];
-
-                    label nQuads = 0;
-                    label nTris = 0;
-                    f.nTrianglesQuads(mesh.points(), nTris, nQuads);
-
-                    nAddCells += nQuads + nTris;
-                }
-
-                nAddCells--;
-                nAddPoints++;
-            }
-        }
-    }
-
-    // Set size of additional point addressing array
-    // (from added point to original cell)
-    addPointCellLabels.setSize(nAddPoints);
-
-    // Set size of additional cells mapping array
-    // (from added cell to original cell)
-
-    if (debug)
-    {
-        Info<<" mesh nCells     = " << mesh.nCells() << nl
-            <<"      nPoints    = " << mesh.nPoints() << nl
-            <<"      nAddCells  = " << nAddCells << nl
-            <<"      nAddPoints = " << nAddPoints << endl;
-    }
-
-    superCells.setSize(mesh.nCells() + nAddCells);
-
-    if (debug)
-    {
-        Info<< "... converting points" << endl;
-    }
-
-    // Convert OpenFOAM mesh vertices to VTK
-    vtkPoints* vtkpoints = vtkPoints::New();
-    vtkpoints->Allocate(mesh.nPoints() + nAddPoints);
-
-    const Foam::pointField& points = mesh.points();
-
-    forAll(points, i)
-    {
-        vtkInsertNextOpenFOAMPoint(vtkpoints, points[i]);
-    }
-
-
-    if (debug)
-    {
-        Info<< "... converting cells" << endl;
-    }
-
-    vtkmesh->Allocate(mesh.nCells() + nAddCells);
-
-    // Set counters for additional points and additional cells
-    label addPointi = 0, addCelli = 0;
-
-    // Create storage for points - needed for mapping from OpenFOAM to VTK
-    // data types - max 'order' = hex = 8 points
-    vtkIdType nodeIds[8];
-
-    // face-stream for a polyhedral cell
-    // [numFace0Pts, id1, id2, id3, numFace1Pts, id1, id2, id3, ...]
-    DynamicList<vtkIdType> faceStream(256);
-
-    forAll(cellShapes, celli)
-    {
-        const cellShape& cellShape = cellShapes[celli];
-        const cellModel& cellModel = cellShape.model();
-
-        superCells[addCelli++] = celli;
-
-        if (cellModel == tet)
-        {
-            for (int j = 0; j < 4; j++)
-            {
-                nodeIds[j] = cellShape[j];
-            }
-            vtkmesh->InsertNextCell
-            (
-                VTK_TETRA,
-                4,
-                nodeIds
-            );
-        }
-        else if (cellModel == pyr)
-        {
-            for (int j = 0; j < 5; j++)
-            {
-                nodeIds[j] = cellShape[j];
-            }
-            vtkmesh->InsertNextCell
-            (
-                VTK_PYRAMID,
-                5,
-                nodeIds
-            );
-        }
-        else if (cellModel == prism)
-        {
-            // VTK has a different node order for VTK_WEDGE
-            // their triangles point outwards!
-            nodeIds[0] = cellShape[0];
-            nodeIds[1] = cellShape[2];
-            nodeIds[2] = cellShape[1];
-            nodeIds[3] = cellShape[3];
-            nodeIds[4] = cellShape[5];
-            nodeIds[5] = cellShape[4];
-
-            vtkmesh->InsertNextCell
-            (
-                VTK_WEDGE,
-                6,
-                nodeIds
-            );
-        }
-        else if (cellModel == tetWedge && !reader_->GetUseVTKPolyhedron())
-        {
-            // Treat as squeezed prism (VTK_WEDGE)
-
-            nodeIds[0] = cellShape[0];
-            nodeIds[1] = cellShape[2];
-            nodeIds[2] = cellShape[1];
-            nodeIds[3] = cellShape[3];
-            nodeIds[4] = cellShape[4];
-            nodeIds[5] = cellShape[3];
-
-            vtkmesh->InsertNextCell
-            (
-                VTK_WEDGE,
-                6,
-                nodeIds
-            );
-        }
-        else if (cellModel == wedge)
-        {
-            // Treat as squeezed hex
-
-            nodeIds[0] = cellShape[0];
-            nodeIds[1] = cellShape[1];
-            nodeIds[2] = cellShape[2];
-            nodeIds[3] = cellShape[2];
-            nodeIds[4] = cellShape[3];
-            nodeIds[5] = cellShape[4];
-            nodeIds[6] = cellShape[5];
-            nodeIds[7] = cellShape[6];
-
-            vtkmesh->InsertNextCell
-            (
-                VTK_HEXAHEDRON,
-                8,
-                nodeIds
-            );
-        }
-        else if (cellModel == hex)
-        {
-            for (int j = 0; j < 8; j++)
-            {
-                nodeIds[j] = cellShape[j];
-            }
-            vtkmesh->InsertNextCell
-            (
-                VTK_HEXAHEDRON,
-                8,
-                nodeIds
-            );
-        }
-        else if (reader_->GetUseVTKPolyhedron())
-        {
-            // Polyhedral cell - use VTK_POLYHEDRON
-            const labelList& cFaces = mesh.cells()[celli];
-
-#ifdef HAS_VTK_POLYHEDRON
-            vtkIdType nFaces = cFaces.size();
-            vtkIdType nLabels = nFaces;
-
-            // count size for face stream
-            forAll(cFaces, cFacei)
-            {
-                const face& f = mesh.faces()[cFaces[cFacei]];
-                nLabels += f.size();
-            }
-
-            // build face-stream
-            // [numFace0Pts, id1, id2, id3, numFace1Pts, id1, id2, id3, ...]
-            // point Ids are global
-            faceStream.clear();
-            faceStream.reserve(nLabels + nFaces);
-
-            forAll(cFaces, cFacei)
-            {
-                const face& f = mesh.faces()[cFaces[cFacei]];
-                const bool isOwner = (owner[cFaces[cFacei]] == celli);
-                const label nFacePoints = f.size();
-
-                // number of labels for this face
-                faceStream.append(nFacePoints);
-
-                if (isOwner)
-                {
-                    forAll(f, fp)
-                    {
-                        faceStream.append(f[fp]);
-                    }
-                }
-                else
-                {
-                    // fairly immaterial if we reverse the list
-                    // or use face::reverseFace()
-                    forAllReverse(f, fp)
-                    {
-                        faceStream.append(f[fp]);
-                    }
-                }
-            }
-
-            vtkmesh->InsertNextCell(VTK_POLYHEDRON, nFaces, faceStream.data());
-#else
-            // this is a horrible substitute
-            // but avoids crashes when there is no vtkPolyhedron support
-
-            // establish unique node ids used
-            HashSet<vtkIdType, Hash<label>> hashUniqId(2*256);
-
-            forAll(cFaces, cFacei)
-            {
-                const face& f = mesh.faces()[cFaces[cFacei]];
-
-                forAll(f, fp)
-                {
-                    hashUniqId.insert(f[fp]);
-                }
-            }
-
-            // use face stream to store unique node ids:
-            faceStream = hashUniqId.sortedToc();
-
-            vtkmesh->InsertNextCell
-            (
-                VTK_CONVEX_POINT_SET,
-                vtkIdType(faceStream.size()),
-                faceStream.data()
-            );
-#endif
-        }
-        else
-        {
-            // Polyhedral cell. Decompose into tets + prisms.
-
-            // Mapping from additional point to cell
-            addPointCellLabels[addPointi] = celli;
-
-            // The new vertex from the cell-centre
-            const label newVertexLabel = mesh.nPoints() + addPointi;
-            vtkInsertNextOpenFOAMPoint(vtkpoints, mesh.C()[celli]);
-
-            // Whether to insert cell in place of original or not.
-            bool substituteCell = true;
-
-            const labelList& cFaces = mesh.cells()[celli];
-            forAll(cFaces, cFacei)
-            {
-                const face& f = mesh.faces()[cFaces[cFacei]];
-                const bool isOwner = (owner[cFaces[cFacei]] == celli);
-
-                // Number of triangles and quads in decomposition
-                label nTris = 0;
-                label nQuads = 0;
-                f.nTrianglesQuads(mesh.points(), nTris, nQuads);
-
-                // Do actual decomposition into triFcs and quadFcs.
-                faceList triFcs(nTris);
-                faceList quadFcs(nQuads);
-                label trii = 0;
-                label quadi = 0;
-                f.trianglesQuads(mesh.points(), trii, quadi, triFcs, quadFcs);
-
-                forAll(quadFcs, quadI)
-                {
-                    if (substituteCell)
-                    {
-                        substituteCell = false;
-                    }
-                    else
-                    {
-                        superCells[addCelli++] = celli;
-                    }
-
-                    const face& quad = quadFcs[quadI];
-
-                    // Ensure we have the correct orientation for the
-                    // base of the primitive cell shape.
-                    // If the cell is face owner, the orientation needs to be
-                    // flipped.
-                    // At the moment, VTK doesn't actually seem to care if
-                    // negative cells are defined, but we'll do it anyhow
-                    // (for safety).
-                    if (isOwner)
-                    {
-                        nodeIds[0] = quad[3];
-                        nodeIds[1] = quad[2];
-                        nodeIds[2] = quad[1];
-                        nodeIds[3] = quad[0];
-                    }
-                    else
-                    {
-                        nodeIds[0] = quad[0];
-                        nodeIds[1] = quad[1];
-                        nodeIds[2] = quad[2];
-                        nodeIds[3] = quad[3];
-                    }
-                    nodeIds[4] = newVertexLabel;
-                    vtkmesh->InsertNextCell
-                    (
-                        VTK_PYRAMID,
-                        5,
-                        nodeIds
-                    );
-                }
-
-                forAll(triFcs, triI)
-                {
-                    if (substituteCell)
-                    {
-                        substituteCell = false;
-                    }
-                    else
-                    {
-                        superCells[addCelli++] = celli;
-                    }
-
-                    const face& tri = triFcs[triI];
-
-                    // See note above about the orientation.
-                    if (isOwner)
-                    {
-                        nodeIds[0] = tri[2];
-                        nodeIds[1] = tri[1];
-                        nodeIds[2] = tri[0];
-                    }
-                    else
-                    {
-                        nodeIds[0] = tri[0];
-                        nodeIds[1] = tri[1];
-                        nodeIds[2] = tri[2];
-                    }
-                    nodeIds[3] = newVertexLabel;
-
-                    vtkmesh->InsertNextCell
-                    (
-                        VTK_TETRA,
-                        4,
-                        nodeIds
-                    );
-                }
-            }
-
-            addPointi++;
-        }
-    }
-
-    vtkmesh->SetPoints(vtkpoints);
-    vtkpoints->Delete();
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::volumeVTKMesh" << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshZone.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshZone.C
deleted file mode 100644
index 437c6be9ca16a29d07ea0d5f67084c84751cb398..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshZone.C
+++ /dev/null
@@ -1,75 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "vtkOpenFOAMPoints.H"
-
-// VTK includes
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-#include "vtkCellArray.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-vtkPolyData* Foam::vtkPV3Foam::pointZoneVTKMesh
-(
-    const fvMesh& mesh,
-    const labelList& pointLabels
-)
-{
-    vtkPolyData* vtkmesh = vtkPolyData::New();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::pointZoneVTKMesh" << endl;
-        printMemory();
-    }
-
-    const pointField& meshPoints = mesh.points();
-
-    vtkPoints* vtkpoints = vtkPoints::New();
-    vtkpoints->Allocate(pointLabels.size());
-
-    forAll(pointLabels, pointi)
-    {
-        vtkInsertNextOpenFOAMPoint(vtkpoints, meshPoints[pointLabels[pointi]]);
-    }
-
-    vtkmesh->SetPoints(vtkpoints);
-    vtkpoints->Delete();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::pointZoneVTKMesh" << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H
deleted file mode 100644
index 09e67db610ee975eb9b6c67ee894d638799c1edc..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H
+++ /dev/null
@@ -1,129 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamPatchField_H
-#define vtkPV3FoamPatchField_H
-
-// VTK includes
-#include "vtkCellData.h"
-#include "vtkFloatArray.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkPointData.h"
-#include "vtkPolyData.h"
-
-#include "vtkOpenFOAMTupleRemap.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::vtkPV3Foam::convertPatchField
-(
-    const word& name,
-    const Field<Type>& ptf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-
-    vtkFloatArray* cellData = vtkFloatArray::New();
-    cellData->SetNumberOfTuples(ptf.size());
-    cellData->SetNumberOfComponents(nComp);
-    cellData->Allocate(nComp*ptf.size());
-    cellData->SetName(name.c_str());
-
-    float vec[nComp];
-    forAll(ptf, i)
-    {
-        const Type& t = ptf[i];
-        for (direction d=0; d<nComp; ++d)
-        {
-            vec[d] = component(t, d);
-        }
-        vtkOpenFOAMTupleRemap<Type>(vec);
-
-        cellData->InsertTuple(i, vec);
-    }
-
-    vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetCellData()
-        ->AddArray(cellData);
-
-    cellData->Delete();
-}
-
-
-// as above, but with PointData()
-template<class Type>
-void Foam::vtkPV3Foam::convertPatchPointField
-(
-    const word& name,
-    const Field<Type>& pptf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-
-    vtkFloatArray* pointData = vtkFloatArray::New();
-    pointData->SetNumberOfTuples(pptf.size());
-    pointData->SetNumberOfComponents(nComp);
-    pointData->Allocate(nComp*pptf.size());
-    pointData->SetName(name.c_str());
-
-    float vec[nComp];
-    forAll(pptf, i)
-    {
-        const Type& t = pptf[i];
-        for (direction d=0; d<nComp; ++d)
-        {
-            vec[d] = component(t, d);
-        }
-        vtkOpenFOAMTupleRemap<Type>(vec);
-
-        pointData->InsertTuple(i, vec);
-    }
-
-    vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetPointData()
-        ->AddArray(pointData);
-
-    pointData->Delete();
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
deleted file mode 100644
index 17017920e604e3595d71974ce345d936f1b425ac..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
+++ /dev/null
@@ -1,331 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamPointFields_H
-#define vtkPV3FoamPointFields_H
-
-// OpenFOAM includes
-#include "interpolatePointToCell.H"
-
-#include "vtkOpenFOAMTupleRemap.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::vtkPV3Foam::convertPointFields
-(
-    const fvMesh& mesh,
-    const pointMesh& pMesh,
-    const IOobjectList& objects,
-    vtkMultiBlockDataSet* output
-)
-{
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    forAllConstIter(IOobjectList, objects, iter)
-    {
-        const word& fieldName = iter()->name();
-        // restrict to this GeometricField<Type, ...>
-        if
-        (
-            iter()->headerClassName()
-         != GeometricField<Type, pointPatchField, pointMesh>::typeName
-        )
-        {
-            continue;
-        }
-
-        if (debug)
-        {
-            Info<< "Foam::vtkPV3Foam::convertPointFields : "
-                << fieldName << endl;
-        }
-
-        GeometricField<Type, pointPatchField, pointMesh> ptf
-        (
-            *iter(),
-            pMesh
-        );
-
-
-        // Convert activated internalMesh regions
-        convertPointFieldBlock
-        (
-            ptf,
-            output,
-            arrayRangeVolume_,
-            regionPolyDecomp_
-        );
-
-        // Convert activated cellZones
-        convertPointFieldBlock
-        (
-            ptf,
-            output,
-            arrayRangeCellZones_,
-            zonePolyDecomp_
-        );
-
-        // Convert activated cellSets
-        convertPointFieldBlock
-        (
-            ptf,
-            output,
-            arrayRangeCellSets_,
-            csetPolyDecomp_
-        );
-
-
-        //
-        // Convert patches - if activated
-        //
-        for
-        (
-            int partId = arrayRangePatches_.start();
-            partId < arrayRangePatches_.end();
-            ++partId
-        )
-        {
-            const word patchName = getPartName(partId);
-            const label datasetNo = partDataset_[partId];
-            const label patchId = patches.findPatchID(patchName);
-
-            if (!partStatus_[partId] || datasetNo < 0 || patchId < 0)
-            {
-                continue;
-            }
-
-            convertPatchPointField
-            (
-                fieldName,
-                ptf.boundaryField()[patchId].patchInternalField()(),
-                output,
-                arrayRangePatches_,
-                datasetNo
-            );
-        }
-
-        //
-        // Convert faceZones - if activated
-        //
-        for
-        (
-            int partId = arrayRangeFaceZones_.start();
-            partId < arrayRangeFaceZones_.end();
-            ++partId
-        )
-        {
-            const word zoneName = getPartName(partId);
-            const label datasetNo = partDataset_[partId];
-            const label zoneId = mesh.faceZones().findZoneID(zoneName);
-
-            if (!partStatus_[partId] || datasetNo < 0 || zoneId < 0)
-            {
-                continue;
-            }
-
-            // Extract the field on the zone
-            Field<Type> fld
-            (
-                ptf.primitiveField(),
-                mesh.faceZones()[zoneId]().meshPoints()
-            );
-
-            convertPatchPointField
-            (
-                fieldName,
-                fld,
-                output,
-                arrayRangeFaceZones_,
-                datasetNo
-            );
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::vtkPV3Foam::convertPointFieldBlock
-(
-    const GeometricField<Type, pointPatchField, pointMesh>& ptf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const List<polyDecomp>& decompLst
-)
-{
-   for (int partId = range.start(); partId < range.end(); ++partId)
-   {
-       const label datasetNo = partDataset_[partId];
-
-       if (datasetNo >= 0 && partStatus_[partId])
-       {
-           convertPointField
-           (
-               ptf,
-               GeometricField<Type, fvPatchField, volMesh>::null(),
-               output,
-               range,
-               datasetNo,
-               decompLst[datasetNo]
-           );
-       }
-   }
-}
-
-
-template<class Type>
-void Foam::vtkPV3Foam::convertPointField
-(
-    const GeometricField<Type, pointPatchField, pointMesh>& ptf,
-    const GeometricField<Type, fvPatchField, volMesh>& tf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo,
-    const polyDecomp& decomp
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-    const labelList& addPointCellLabels = decomp.addPointCellLabels();
-    const labelList& pointMap = decomp.pointMap();
-
-    // use a pointMap or address directly into mesh
-    label nPoints;
-    if (pointMap.size())
-    {
-        nPoints = pointMap.size();
-    }
-    else
-    {
-        nPoints = ptf.size();
-    }
-
-    vtkFloatArray* pointData = vtkFloatArray::New();
-    pointData->SetNumberOfTuples(nPoints + addPointCellLabels.size());
-    pointData->SetNumberOfComponents(nComp);
-    pointData->Allocate(nComp*(nPoints + addPointCellLabels.size()));
-
-    // Note: using the name of the original volField
-    // not the name generated by the interpolation "volPointInterpolate(<name>)"
-
-    if (&tf != &GeometricField<Type, fvPatchField, volMesh>::null())
-    {
-        pointData->SetName(tf.name().c_str());
-    }
-    else
-    {
-        pointData->SetName(ptf.name().c_str());
-    }
-
-    if (debug)
-    {
-        Info<< "convert convertPointField: "
-            << ptf.name()
-            << " size = " << nPoints
-            << " nComp=" << nComp
-            << " nTuples = " << (nPoints + addPointCellLabels.size())
-            <<  endl;
-    }
-
-    float vec[nComp];
-
-    if (pointMap.size())
-    {
-        forAll(pointMap, i)
-        {
-            const Type& t = ptf[pointMap[i]];
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-            vtkOpenFOAMTupleRemap<Type>(vec);
-
-            pointData->InsertTuple(i, vec);
-        }
-    }
-    else
-    {
-        forAll(ptf, i)
-        {
-            const Type& t = ptf[i];
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-            vtkOpenFOAMTupleRemap<Type>(vec);
-
-            pointData->InsertTuple(i, vec);
-        }
-    }
-
-    // continue insertion from here
-    label i = nPoints;
-
-    if (&tf != &GeometricField<Type, fvPatchField, volMesh>::null())
-    {
-        forAll(addPointCellLabels, apI)
-        {
-            const Type& t = tf[addPointCellLabels[apI]];
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-            vtkOpenFOAMTupleRemap<Type>(vec);
-
-            pointData->InsertTuple(i++, vec);
-        }
-    }
-    else
-    {
-        forAll(addPointCellLabels, apI)
-        {
-            Type t = interpolatePointToCell(ptf, addPointCellLabels[apI]);
-            for (direction d=0; d<nComp; ++d)
-            {
-                vec[d] = component(t, d);
-            }
-            vtkOpenFOAMTupleRemap<Type>(vec);
-
-            pointData->InsertTuple(i++, vec);
-        }
-    }
-
-    vtkUnstructuredGrid::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetPointData()
-        ->AddArray(pointData);
-
-    pointData->Delete();
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamTemplates.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamTemplates.C
deleted file mode 100644
index 8a5c16c87fe0f08885cbc61352b44fe1aa9bbf72..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamTemplates.C
+++ /dev/null
@@ -1,99 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "polyPatch.H"
-#include "primitivePatch.H"
-#include "vtkOpenFOAMPoints.H"
-
-// VTK includes
-#include "vtkCellArray.h"
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class PatchType>
-vtkPolyData* Foam::vtkPV3Foam::patchVTKMesh
-(
-    const word& name,
-    const PatchType& p
-)
-{
-    vtkPolyData* vtkmesh = vtkPolyData::New();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::patchVTKMesh - " << name << endl;
-        printMemory();
-    }
-
-    // Convert OpenFOAM mesh vertices to VTK
-    const Foam::pointField& points = p.localPoints();
-
-    vtkPoints* vtkpoints = vtkPoints::New();
-    vtkpoints->Allocate(points.size());
-    forAll(points, i)
-    {
-        vtkInsertNextOpenFOAMPoint(vtkpoints, points[i]);
-    }
-
-    vtkmesh->SetPoints(vtkpoints);
-    vtkpoints->Delete();
-
-
-    // Add faces as polygons
-    const faceList& faces = p.localFaces();
-
-    vtkCellArray* vtkcells = vtkCellArray::New();
-    vtkcells->Allocate(faces.size());
-    forAll(faces, facei)
-    {
-        const face& f = faces[facei];
-        vtkIdType nodeIds[f.size()];
-
-        forAll(f, fp)
-        {
-            nodeIds[fp] = f[fp];
-        }
-        vtkcells->InsertNextCell(f.size(), nodeIds);
-    }
-
-    vtkmesh->SetPolys(vtkcells);
-    vtkcells->Delete();
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::patchVTKMesh - " << name << endl;
-        printMemory();
-    }
-
-    return vtkmesh;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C
deleted file mode 100644
index bfb86436e4ebe4354d06ae03327850889cb004c6..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C
+++ /dev/null
@@ -1,724 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3Foam.H"
-
-// OpenFOAM includes
-#include "cellSet.H"
-#include "faceSet.H"
-#include "pointSet.H"
-#include "IOobjectList.H"
-#include "IOPtrList.H"
-#include "polyBoundaryMeshEntries.H"
-#include "entry.H"
-#include "Cloud.H"
-#include "vtkPV3FoamReader.h"
-
-// local headers
-#include "vtkPV3FoamAddToSelection.H"
-#include "vtkPV3FoamUpdateInfoFields.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-
-
-// * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-//- A class for reading zone information without requiring a mesh
-class zonesEntries
-:
-    public regIOobject,
-    public PtrList<entry>
-{
-
-public:
-
-    // Constructors
-
-        explicit zonesEntries(const IOobject& io)
-        :
-            regIOobject(io),
-            PtrList<entry>(readStream("regIOobject"))
-        {
-            close();
-        }
-
-   // Member functions
-
-        bool writeData(Ostream&) const
-        {
-            NotImplemented;
-            return false;
-        }
-};
-
-}
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-template<class ZoneType>
-Foam::wordList Foam::vtkPV3Foam::getZoneNames
-(
-    const ZoneMesh<ZoneType, polyMesh>& zmesh
-) const
-{
-    wordList names(zmesh.size());
-    label nZone = 0;
-
-    forAll(zmesh, zoneI)
-    {
-        if (zmesh[zoneI].size())
-        {
-            names[nZone++] = zmesh[zoneI].name();
-        }
-    }
-    names.setSize(nZone);
-
-    return names;
-}
-
-
-Foam::wordList Foam::vtkPV3Foam::getZoneNames(const word& zoneType) const
-{
-    wordList names;
-
-    // mesh not loaded - read from file
-    IOobject ioObj
-    (
-        zoneType,
-        dbPtr_().findInstance
-        (
-            meshDir_,
-            zoneType,
-            IOobject::READ_IF_PRESENT
-        ),
-        meshDir_,
-        dbPtr_(),
-        IOobject::READ_IF_PRESENT,
-        IOobject::NO_WRITE,
-        false
-    );
-
-    if (ioObj.typeHeaderOk<cellZoneMesh>(false))
-    {
-        zonesEntries zones(ioObj);
-
-        names.setSize(zones.size());
-        forAll(zones, zoneI)
-        {
-            names[zoneI] = zones[zoneI].keyword();
-        }
-    }
-
-    return names;
-}
-
-
-void Foam::vtkPV3Foam::updateInfoInternalMesh
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoInternalMesh" << endl;
-    }
-
-    // Determine mesh parts (internalMesh, patches...)
-    //- Add internal mesh as first entry
-    arrayRangeVolume_.reset(arraySelection->GetNumberOfArrays());
-    arraySelection->AddArray
-    (
-        "internalMesh"
-    );
-    arrayRangeVolume_ += 1;
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoInternalMesh" << endl;
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateInfoLagrangian
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoLagrangian" << nl
-            << "    " << dbPtr_->timePath()/cloud::prefix << endl;
-    }
-
-
-    // use the db directly since this might be called without a mesh,
-    // but the region must get added back in
-    fileName lagrangianPrefix(cloud::prefix);
-    if (meshRegion_ != polyMesh::defaultRegion)
-    {
-        lagrangianPrefix = meshRegion_/cloud::prefix;
-    }
-
-    // Search for list of lagrangian objects for this time
-    fileNameList cloudDirs
-    (
-        readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
-    );
-
-    arrayRangeLagrangian_.reset(arraySelection->GetNumberOfArrays());
-
-    int nClouds = 0;
-    forAll(cloudDirs, cloudI)
-    {
-        // Add cloud to GUI list
-        arraySelection->AddArray
-        (
-            (cloudDirs[cloudI] + " - lagrangian").c_str()
-        );
-
-        ++nClouds;
-    }
-    arrayRangeLagrangian_ += nClouds;
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoLagrangian" << endl;
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateInfoPatches
-(
-    vtkDataArraySelection* arraySelection,
-    stringList& enabledEntries
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoPatches"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "]" << endl;
-    }
-
-
-    HashSet<string> enabledEntriesSet(enabledEntries);
-
-    arrayRangePatches_.reset(arraySelection->GetNumberOfArrays());
-
-    int nPatches = 0;
-    if (meshPtr_)
-    {
-        const polyBoundaryMesh& patches = meshPtr_->boundaryMesh();
-        const HashTable<labelList, word>& groups = patches.groupPatchIDs();
-        const wordList allPatchNames = patches.names();
-
-        // Add patch groups
-        // ~~~~~~~~~~~~~~~~
-
-        for
-        (
-            HashTable<labelList, word>::const_iterator iter = groups.begin();
-            iter != groups.end();
-            ++iter
-        )
-        {
-            const word& groupName = iter.key();
-            const labelList& patchIDs = iter();
-
-            label nFaces = 0;
-            forAll(patchIDs, i)
-            {
-                nFaces += patches[patchIDs[i]].size();
-            }
-
-            // Valid patch if nFace > 0 - add patch to GUI list
-            if (nFaces)
-            {
-                string vtkGrpName = groupName + " - group";
-                arraySelection->AddArray(vtkGrpName.c_str());
-
-                ++nPatches;
-
-                if (enabledEntriesSet.found(vtkGrpName))
-                {
-                    if (!reader_->GetShowGroupsOnly())
-                    {
-                        enabledEntriesSet.erase(vtkGrpName);
-                        forAll(patchIDs, i)
-                        {
-                            const polyPatch& pp = patches[patchIDs[i]];
-                            if (pp.size())
-                            {
-                                string vtkPatchName = pp.name() + " - patch";
-                                enabledEntriesSet.insert(vtkPatchName);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-
-        // Add patches
-        // ~~~~~~~~~~~
-
-        if (!reader_->GetShowGroupsOnly())
-        {
-            forAll(patches, patchi)
-            {
-                const polyPatch& pp = patches[patchi];
-
-                if (pp.size())
-                {
-                    // Add patch to GUI list
-                    arraySelection->AddArray
-                    (
-                        (pp.name() + " - patch").c_str()
-                    );
-
-                    ++nPatches;
-                }
-            }
-        }
-    }
-    else
-    {
-        // mesh not loaded - read from file
-        // but this could fail if we've supplied a bad region name
-        IOobject ioObj
-        (
-            "boundary",
-            dbPtr_().findInstance
-            (
-                meshDir_,
-                "boundary",
-                IOobject::READ_IF_PRESENT
-            ),
-            meshDir_,
-            dbPtr_(),
-            IOobject::READ_IF_PRESENT,
-            IOobject::NO_WRITE,
-            false
-        );
-
-        // this should only ever fail if the mesh region doesn't exist
-        if (ioObj.typeHeaderOk<polyBoundaryMesh>(true))
-        {
-            polyBoundaryMeshEntries patchEntries(ioObj);
-
-
-            // Read patches and determine sizes
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            wordList names(patchEntries.size());
-            labelList sizes(patchEntries.size());
-
-            forAll(patchEntries, patchi)
-            {
-                const dictionary& patchDict = patchEntries[patchi].dict();
-
-                sizes[patchi] = readLabel(patchDict.lookup("nFaces"));
-                names[patchi] = patchEntries[patchi].keyword();
-            }
-
-
-            // Add (non-zero) patch groups to the list of mesh parts
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            HashTable<labelList, word> groups(patchEntries.size());
-
-            forAll(patchEntries, patchi)
-            {
-                const dictionary& patchDict = patchEntries[patchi].dict();
-
-                wordList groupNames;
-                patchDict.readIfPresent("inGroups", groupNames);
-
-                forAll(groupNames, groupI)
-                {
-                    HashTable<labelList, word>::iterator iter = groups.find
-                    (
-                        groupNames[groupI]
-                    );
-                    if (iter != groups.end())
-                    {
-                        iter().append(patchi);
-                    }
-                    else
-                    {
-                        groups.insert(groupNames[groupI], labelList(1, patchi));
-                    }
-                }
-            }
-
-            for
-            (
-                HashTable<labelList, word>::const_iterator iter =
-                    groups.begin();
-                iter != groups.end();
-                ++iter
-            )
-            {
-                const word& groupName = iter.key();
-                const labelList& patchIDs = iter();
-
-                label nFaces = 0;
-                forAll(patchIDs, i)
-                {
-                    nFaces += sizes[patchIDs[i]];
-                }
-
-                // Valid patch if nFace > 0 - add patch to GUI list
-                if (nFaces)
-                {
-                    string vtkGrpName = groupName + " - group";
-                    arraySelection->AddArray(vtkGrpName.c_str());
-
-                    ++nPatches;
-
-                    if (enabledEntriesSet.found(vtkGrpName))
-                    {
-                        if (!reader_->GetShowGroupsOnly())
-                        {
-                            enabledEntriesSet.erase(vtkGrpName);
-                            forAll(patchIDs, i)
-                            {
-                                if (sizes[patchIDs[i]])
-                                {
-                                    string vtkPatchName =
-                                        names[patchIDs[i]] + " - patch";
-                                    enabledEntriesSet.insert(vtkPatchName);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-
-            // Add (non-zero) patches to the list of mesh parts
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            if (!reader_->GetShowGroupsOnly())
-            {
-                forAll(names, patchi)
-                {
-                    // Valid patch if nFace > 0 - add patch to GUI list
-                    if (sizes[patchi])
-                    {
-                        arraySelection->AddArray
-                        (
-                            (names[patchi] + " - patch").c_str()
-                        );
-
-                        ++nPatches;
-                    }
-                }
-            }
-        }
-    }
-    arrayRangePatches_ += nPatches;
-
-    // Update enabled entries in case of group selection
-    enabledEntries = enabledEntriesSet.toc();
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoPatches" << endl;
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateInfoZones
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (!reader_->GetIncludeZones())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoZones"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "]" << endl;
-    }
-
-    wordList namesLst;
-
-    //
-    // cellZones information
-    // ~~~~~~~~~~~~~~~~~~~~~
-    if (meshPtr_)
-    {
-        namesLst = getZoneNames(meshPtr_->cellZones());
-    }
-    else
-    {
-        namesLst = getZoneNames("cellZones");
-    }
-
-    arrayRangeCellZones_.reset(arraySelection->GetNumberOfArrays());
-    forAll(namesLst, elemI)
-    {
-        arraySelection->AddArray
-        (
-            (namesLst[elemI] + " - cellZone").c_str()
-        );
-    }
-    arrayRangeCellZones_ += namesLst.size();
-
-
-    //
-    // faceZones information
-    // ~~~~~~~~~~~~~~~~~~~~~
-    if (meshPtr_)
-    {
-        namesLst = getZoneNames(meshPtr_->faceZones());
-    }
-    else
-    {
-        namesLst = getZoneNames("faceZones");
-    }
-
-    arrayRangeFaceZones_.reset(arraySelection->GetNumberOfArrays());
-    forAll(namesLst, elemI)
-    {
-        arraySelection->AddArray
-        (
-            (namesLst[elemI] + " - faceZone").c_str()
-        );
-    }
-    arrayRangeFaceZones_ += namesLst.size();
-
-
-    //
-    // pointZones information
-    // ~~~~~~~~~~~~~~~~~~~~~~
-    if (meshPtr_)
-    {
-        namesLst = getZoneNames(meshPtr_->pointZones());
-    }
-    else
-    {
-        namesLst = getZoneNames("pointZones");
-    }
-
-    arrayRangePointZones_.reset(arraySelection->GetNumberOfArrays());
-    forAll(namesLst, elemI)
-    {
-        arraySelection->AddArray
-        (
-            (namesLst[elemI] + " - pointZone").c_str()
-        );
-    }
-    arrayRangePointZones_ += namesLst.size();
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoZones" << endl;
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateInfoSets
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (!reader_->GetIncludeSets())
-    {
-        return;
-    }
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoSets" << endl;
-    }
-
-    // Add names of sets. Search for last time directory with a sets
-    // subdirectory. Take care not to search beyond the last mesh.
-
-    word facesInstance = dbPtr_().findInstance
-    (
-        meshDir_,
-        "faces",
-        IOobject::READ_IF_PRESENT
-    );
-
-    word setsInstance = dbPtr_().findInstance
-    (
-        meshDir_/"sets",
-        word::null,
-        IOobject::READ_IF_PRESENT,
-        facesInstance
-    );
-
-    IOobjectList objects(dbPtr_(), setsInstance, meshDir_/"sets");
-
-    if (debug)
-    {
-        Info<< "     Foam::vtkPV3Foam::updateInfoSets read "
-            << objects.names() << " from " << setsInstance << endl;
-    }
-
-
-    arrayRangeCellSets_.reset(arraySelection->GetNumberOfArrays());
-    arrayRangeCellSets_ += addToSelection<cellSet>
-    (
-        arraySelection,
-        objects,
-        " - cellSet"
-    );
-
-    arrayRangeFaceSets_.reset(arraySelection->GetNumberOfArrays());
-    arrayRangeFaceSets_ += addToSelection<faceSet>
-    (
-        arraySelection,
-        objects,
-        " - faceSet"
-    );
-
-    arrayRangePointSets_.reset(arraySelection->GetNumberOfArrays());
-    arrayRangePointSets_ += addToSelection<pointSet>
-    (
-        arraySelection,
-        objects,
-        " - pointSet"
-    );
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoSets" << endl;
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateInfoLagrangianFields()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoLagrangianFields"
-            << endl;
-    }
-
-    vtkDataArraySelection* fieldSelection =
-        reader_->GetLagrangianFieldSelection();
-
-    // preserve the enabled selections
-    stringList enabledEntries = getSelectedArrayEntries(fieldSelection);
-    fieldSelection->RemoveAllArrays();
-
-    // TODO - currently only get fields from ONE cloud
-    // have to decide if the second set of fields get mixed in
-    // or dealt with separately
-
-    const arrayRange& range = arrayRangeLagrangian_;
-    if (range.empty())
-    {
-        return;
-    }
-
-    int partId = range.start();
-    word cloudName = getPartName(partId);
-
-    // use the db directly since this might be called without a mesh,
-    // but the region must get added back in
-    fileName lagrangianPrefix(cloud::prefix);
-    if (meshRegion_ != polyMesh::defaultRegion)
-    {
-        lagrangianPrefix = meshRegion_/cloud::prefix;
-    }
-
-    IOobjectList objects
-    (
-        dbPtr_(),
-        dbPtr_().timeName(),
-        lagrangianPrefix/cloudName
-    );
-
-    addToSelection<IOField<label>>
-    (
-        fieldSelection,
-        objects
-    );
-    addToSelection<IOField<scalar>>
-    (
-        fieldSelection,
-        objects
-    );
-    addToSelection<IOField<vector>>
-    (
-        fieldSelection,
-        objects
-    );
-    addToSelection<IOField<sphericalTensor>>
-    (
-        fieldSelection,
-
-        objects
-    );
-    addToSelection<IOField<symmTensor>>
-    (
-        fieldSelection,
-        objects
-    );
-    addToSelection<IOField<tensor>>
-    (
-        fieldSelection,
-        objects
-    );
-
-    // restore the enabled selections
-    setSelectedArrayEntries(fieldSelection, enabledEntries);
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoLagrangianFields - "
-            << "lagrangian objects.size() = " << objects.size() << endl;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H
deleted file mode 100644
index dd2c98c7240437b6bd166774d24f182c04b3fd5d..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H
+++ /dev/null
@@ -1,115 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamUpdateInfoFields_H
-#define vtkPV3FoamUpdateInfoFields_H
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<template<class> class patchType, class meshType>
-void Foam::vtkPV3Foam::updateInfoFields
-(
-    vtkDataArraySelection* select
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateInfoFields <"
-            << meshType::Mesh::typeName
-            << "> [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "]"
-            << endl;
-    }
-
-    stringList enabledEntries;
-    // enable 'p' and 'U' on the first call
-    if (select->GetNumberOfArrays() == 0 && !meshPtr_)
-    {
-        enabledEntries.setSize(2);
-        enabledEntries[0] = "p";
-        enabledEntries[1] = "U";
-    }
-    else
-    {
-        // preserve the enabled selections
-        enabledEntries = getSelectedArrayEntries(select);
-    }
-
-    select->RemoveAllArrays();
-
-    // use the db directly since this might be called without a mesh,
-    // but the region must get added back in
-    word regionPrefix;
-    if (meshRegion_ != polyMesh::defaultRegion)
-    {
-        regionPrefix = meshRegion_;
-    }
-
-    // Search for list of objects for this time and mesh region
-    IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
-
-    //- Add volume fields to GUI
-    addToSelection<GeometricField<scalar, patchType, meshType>>
-    (
-        select,
-        objects
-    );
-    addToSelection<GeometricField<vector, patchType, meshType>>
-    (
-        select,
-        objects
-    );
-    addToSelection<GeometricField<sphericalTensor, patchType, meshType>>
-    (
-        select,
-        objects
-    );
-    addToSelection<GeometricField<symmTensor, patchType, meshType>>
-    (
-        select,
-        objects
-    );
-    addToSelection<GeometricField<tensor, patchType, meshType>>
-    (
-        select,
-        objects
-    );
-
-    // restore the enabled selections
-    setSelectedArrayEntries(select, enabledEntries);
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateInfoFields" << endl;
-    }
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtils.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtils.C
deleted file mode 100644
index 00430a614456fcee3fef5dfbcf5f8b3955539af1..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtils.C
+++ /dev/null
@@ -1,340 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-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/>.
-
-Description
-    Misc helper methods and utilities
-
-\*---------------------------------------------------------------------------*/
-
-#include "vtkPV3Foam.H"
-#include "vtkPV3FoamReader.h"
-
-// OpenFOAM includes
-#include "fvMesh.H"
-#include "Time.H"
-#include "IFstream.H"
-#include "memInfo.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkDataSet.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkInformation.h"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    //! \cond fileScope
-    //  Extract up to the first non-word characters
-    inline word getFirstWord(const char* str)
-    {
-        if (str)
-        {
-            label n = 0;
-            while (str[n] && word::valid(str[n]))
-            {
-                ++n;
-            }
-            return word(str, n, true);
-        }
-        else
-        {
-            return word::null;
-        }
-
-    }
-    //! \endcond
-
-} // End namespace Foam
-
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::vtkPV3Foam::AddToBlock
-(
-    vtkMultiBlockDataSet* output,
-    vtkDataSet* dataset,
-    const arrayRange& range,
-    const label datasetNo,
-    const std::string& datasetName
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (!block)
-    {
-        if (blockDO)
-        {
-            FatalErrorInFunction
-                << "Block already has a vtkDataSet assigned to it"
-                << endl;
-            return;
-        }
-
-        block = vtkMultiBlockDataSet::New();
-        output->SetBlock(blockNo, block);
-        block->Delete();
-    }
-
-    if (debug)
-    {
-        Info<< "block[" << blockNo << "] has "
-            << block->GetNumberOfBlocks()
-            <<  " datasets prior to adding set " << datasetNo
-            <<  " with name: " << datasetName << endl;
-    }
-
-    block->SetBlock(datasetNo, dataset);
-
-    // name the block when assigning dataset 0
-    if (datasetNo == 0)
-    {
-        output->GetMetaData(blockNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            range.name()
-        );
-    }
-
-    if (datasetName.size())
-    {
-        block->GetMetaData(datasetNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            datasetName.c_str()
-        );
-    }
-}
-
-
-vtkDataSet* Foam::vtkPV3Foam::GetDataSetFromBlock
-(
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (block)
-    {
-        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
-    }
-
-    return 0;
-}
-
-
-// ununsed at the moment
-Foam::label Foam::vtkPV3Foam::GetNumberOfDataSets
-(
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (block)
-    {
-        return block->GetNumberOfBlocks();
-    }
-
-    return 0;
-}
-
-
-Foam::word Foam::vtkPV3Foam::getPartName(const int partId)
-{
-    return getFirstWord(reader_->GetPartArrayName(partId));
-}
-
-
-Foam::wordHashSet Foam::vtkPV3Foam::getSelected
-(
-    vtkDataArraySelection* select
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::wordHashSet Foam::vtkPV3Foam::getSelected
-(
-    vtkDataArraySelection* select,
-    const arrayRange& range
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI = range.start(); elemI < range.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select
-)
-{
-    stringList selections(select->GetNumberOfArrays());
-    label nElem = 0;
-
-    forAll(selections, elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        label nElem = select->GetNumberOfArrays();
-        Info<< "available(";
-        for (int elemI = 0; elemI < nElem; ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const arrayRange& range
-)
-{
-    stringList selections(range.size());
-    label nElem = 0;
-
-    for (int elemI = range.start(); elemI < range.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        Info<< "available(";
-        for (int elemI = range.start(); elemI < range.end(); ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-void Foam::vtkPV3Foam::setSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const stringList& selections
-)
-{
-    const int nElem = select->GetNumberOfArrays();
-    select->DisableAllArrays();
-
-    // Loop through entries, setting values from selectedEntries
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        string arrayName(select->GetArrayName(elemI));
-
-        forAll(selections, elemI)
-        {
-            if (selections[elemI] == arrayName)
-            {
-                select->EnableArray(arrayName.c_str());
-                break;
-            }
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::vtkPV3Foam::printMemory()
-{
-    memInfo mem;
-
-    if (mem.valid())
-    {
-        Info<< "mem peak/size/rss: " << mem << "\n";
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H
deleted file mode 100644
index 9e11686f205ca1971810774676f441fd2fb9b2fa..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H
+++ /dev/null
@@ -1,380 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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/>.
-
-InClass
-    vtkPV3Foam
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3FoamVolFields_H
-#define vtkPV3FoamVolFields_H
-
-// OpenFOAM includes
-#include "emptyFvPatchField.H"
-#include "wallPolyPatch.H"
-#include "faceSet.H"
-#include "volPointInterpolation.H"
-
-#include "vtkPV3FoamFaceField.H"
-#include "vtkPV3FoamPatchField.H"
-
-#include "vtkOpenFOAMTupleRemap.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template<class Type>
-void Foam::vtkPV3Foam::convertVolFields
-(
-    const fvMesh& mesh,
-    const PtrList<PrimitivePatchInterpolation<primitivePatch>>& ppInterpList,
-    const IOobjectList& objects,
-    const bool interpFields,
-    vtkMultiBlockDataSet* output
-)
-{
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    forAllConstIter(IOobjectList, objects, iter)
-    {
-        // restrict to GeometricField<Type, ...>
-        if
-        (
-            iter()->headerClassName()
-         != GeometricField<Type, fvPatchField, volMesh>::typeName
-        )
-        {
-            continue;
-        }
-
-        // Load field
-        GeometricField<Type, fvPatchField, volMesh> tf
-        (
-            *iter(),
-            mesh
-        );
-
-        // Interpolated field (demand driven)
-        autoPtr<GeometricField<Type, pointPatchField, pointMesh>> ptfPtr;
-        if (interpFields)
-        {
-            if (debug)
-            {
-                Info<< "convertVolFieldBlock interpolating:" << tf.name()
-                    << endl;
-            }
-
-            ptfPtr.reset
-            (
-                volPointInterpolation::New(tf.mesh()).interpolate(tf).ptr()
-            );
-        }
-
-
-        // Convert activated internalMesh regions
-        convertVolFieldBlock
-        (
-            tf,
-            ptfPtr,
-            output,
-            arrayRangeVolume_,
-            regionPolyDecomp_
-        );
-
-        // Convert activated cellZones
-        convertVolFieldBlock
-        (
-            tf,
-            ptfPtr,
-            output,
-            arrayRangeCellZones_,
-            zonePolyDecomp_
-        );
-
-        // Convert activated cellSets
-        convertVolFieldBlock
-        (
-            tf,
-            ptfPtr,
-            output,
-            arrayRangeCellSets_,
-            csetPolyDecomp_
-        );
-
-
-        //
-        // Convert patches - if activated
-        //
-        for
-        (
-            int partId = arrayRangePatches_.start();
-            partId < arrayRangePatches_.end();
-            ++partId
-        )
-        {
-            const word patchName = getPartName(partId);
-            const label datasetNo = partDataset_[partId];
-            const label patchId = patches.findPatchID(patchName);
-
-            if (!partStatus_[partId] || datasetNo < 0 || patchId < 0)
-            {
-                continue;
-            }
-
-            const fvPatchField<Type>& ptf = tf.boundaryField()[patchId];
-
-            if
-            (
-                isType<emptyFvPatchField<Type>>(ptf)
-             ||
-                (
-                    reader_->GetExtrapolatePatches()
-                && !polyPatch::constraintType(patches[patchId].type())
-                )
-            )
-            {
-                fvPatch p(ptf.patch().patch(), tf.mesh().boundary());
-
-                tmp<Field<Type>> tpptf
-                (
-                    fvPatchField<Type>(p, tf).patchInternalField()
-                );
-
-                convertPatchField
-                (
-                    tf.name(),
-                    tpptf(),
-                    output,
-                    arrayRangePatches_,
-                    datasetNo
-                );
-
-                if (interpFields)
-                {
-                    convertPatchPointField
-                    (
-                        tf.name(),
-                        ppInterpList[patchId].faceToPointInterpolate(tpptf)(),
-                        output,
-                        arrayRangePatches_,
-                        datasetNo
-                    );
-                }
-            }
-            else
-            {
-                convertPatchField
-                (
-                    tf.name(),
-                    ptf,
-                    output,
-                    arrayRangePatches_,
-                    datasetNo
-                );
-
-                if (interpFields)
-                {
-                    convertPatchPointField
-                    (
-                        tf.name(),
-                        ppInterpList[patchId].faceToPointInterpolate(ptf)(),
-                        output,
-                        arrayRangePatches_,
-                        datasetNo
-                    );
-                }
-            }
-        }
-
-        //
-        // Convert face zones - if activated
-        //
-        for
-        (
-            int partId = arrayRangeFaceZones_.start();
-            partId < arrayRangeFaceZones_.end();
-            ++partId
-        )
-        {
-            const word zoneName = getPartName(partId);
-            const label datasetNo = partDataset_[partId];
-
-            if (!partStatus_[partId] || datasetNo < 0)
-            {
-                continue;
-            }
-
-            const faceZoneMesh& zMesh = mesh.faceZones();
-            const label zoneId = zMesh.findZoneID(zoneName);
-
-            if (zoneId < 0)
-            {
-                continue;
-            }
-
-            convertFaceField
-            (
-                tf,
-                output,
-                arrayRangeFaceZones_,
-                datasetNo,
-                mesh,
-                zMesh[zoneId]
-            );
-
-            // TODO: points
-        }
-
-        //
-        // Convert face sets - if activated
-        //
-        for
-        (
-            int partId = arrayRangeFaceSets_.start();
-            partId < arrayRangeFaceSets_.end();
-            ++partId
-        )
-        {
-            const word selectName = getPartName(partId);
-            const label datasetNo = partDataset_[partId];
-
-            if (!partStatus_[partId] || datasetNo < 0)
-            {
-                continue;
-            }
-
-            const faceSet fSet(mesh, selectName);
-
-            convertFaceField
-            (
-                tf,
-                output,
-                arrayRangeFaceSets_,
-                datasetNo,
-                mesh,
-                fSet.toc()
-            );
-
-            // TODO: points
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::vtkPV3Foam::convertVolFieldBlock
-(
-    const GeometricField<Type, fvPatchField, volMesh>& tf,
-    autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const List<polyDecomp>& decompLst
-)
-{
-    for (int partId = range.start(); partId < range.end(); ++partId)
-    {
-        const label datasetNo = partDataset_[partId];
-
-        if (datasetNo >= 0 && partStatus_[partId])
-        {
-            convertVolField
-            (
-                tf,
-                output,
-                range,
-                datasetNo,
-                decompLst[datasetNo]
-            );
-
-            if (ptfPtr.valid())
-            {
-                convertPointField
-                (
-                    ptfPtr(),
-                    tf,
-                    output,
-                    range,
-                    datasetNo,
-                    decompLst[datasetNo]
-                );
-            }
-        }
-    }
-}
-
-
-template<class Type>
-void Foam::vtkPV3Foam::convertVolField
-(
-    const GeometricField<Type, fvPatchField, volMesh>& tf,
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo,
-    const polyDecomp& decompInfo
-)
-{
-    const label nComp = pTraits<Type>::nComponents;
-    const labelList& superCells = decompInfo.superCells();
-
-    vtkFloatArray* celldata = vtkFloatArray::New();
-    celldata->SetNumberOfTuples(superCells.size());
-    celldata->SetNumberOfComponents(nComp);
-    celldata->Allocate(nComp*superCells.size());
-    celldata->SetName(tf.name().c_str());
-
-    if (debug)
-    {
-        Info<< "convert volField: "
-            << tf.name()
-            << " size = " << tf.size()
-            << " nComp=" << nComp
-            << " nTuples = " << superCells.size() <<  endl;
-    }
-
-    float vec[nComp];
-    forAll(superCells, i)
-    {
-        const Type& t = tf[superCells[i]];
-        for (direction d=0; d<nComp; ++d)
-        {
-            vec[d] = component(t, d);
-        }
-        vtkOpenFOAMTupleRemap<Type>(vec);
-
-        celldata->InsertTuple(i, vec);
-    }
-
-    vtkUnstructuredGrid::SafeDownCast
-    (
-        GetDataSetFromBlock(output, range, datasetNo)
-    )   ->GetCellData()
-        ->AddArray(celldata);
-
-    celldata->Delete();
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwclean b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwclean
deleted file mode 100755
index 1e6cdb695c56e99d184b6262891bc9c605bc5f1a..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwclean
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-set -x
-
-# deal with client/server vs combined plugins
-rm -f $FOAM_LIBBIN/libPV3blockMeshReader*  2>/dev/null
-
-rm -rf PV3blockMeshReader/Make
-wclean libso vtkPV3blockMesh
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake
deleted file mode 100755
index 241091e0c5fc0b394f4489eb3022efbcaf2ff346..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-
-# Parse arguments for library compilation
-. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
-set -x
-
-if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
-then
-    wmake $targetType vtkPV3blockMesh
-
-    if [ "$targetType" != "objects" ]
-    then
-        (
-            cd PV3blockMeshReader
-            mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
-            cd Make/$WM_OPTIONS
-            cmake ../..
-            make
-        )
-    fi
-fi
-
-#------------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/CMakeLists.txt b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/CMakeLists.txt
deleted file mode 100644
index 60aaad3f625dc6666fd25534190202123b9446bf..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/CMakeLists.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-# create a plugin that adds a reader to the ParaView GUI
-# it is added in the file dialog when doing opens/saves.
-
-# The qrc file is processed by Qt's resource compiler (rcc)
-# the qrc file must have a resource prefix of "/ParaViewResources"
-# and ParaView will read anything contained under that prefix
-# the pqReader.xml file contains xml defining readers with their
-# file extensions and descriptions.
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-
-FIND_PACKAGE(ParaView REQUIRED)
-INCLUDE(${PARAVIEW_USE_FILE})
-
-LINK_DIRECTORIES(
-    $ENV{FOAM_LIBBIN}
-    $ENV{FOAM_EXT_LIBBIN}
-)
-
-INCLUDE_DIRECTORIES(
-    $ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude
-    $ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude
-    $ENV{WM_PROJECT_DIR}/src/meshing/blockMesh/lnInclude
-    ${PROJECT_SOURCE_DIR}/../vtkPV3blockMesh
-)
-
-ADD_DEFINITIONS(
-    -DWM_$ENV{WM_PRECISION_OPTION}
-    -DWM_LABEL_SIZE=$ENV{WM_LABEL_SIZE}
-)
-
-# Set output library destination to plugin directory
-SET(
-    LIBRARY_OUTPUT_PATH $ENV{PV_PLUGIN_PATH}
-    CACHE INTERNAL
-    "Single output directory for building all libraries."
-)
-
-#
-# Define combined plugin
-#
-
-# Extend the auto-generated panel
-QT4_WRAP_CPP(MOC_SRCS pqPV3blockMeshReaderPanel.h)
-
-ADD_PARAVIEW_OBJECT_PANEL(IFACES IFACE_SRCS
-  CLASS_NAME pqPV3blockMeshReaderPanel
-  XML_NAME  PV3blockMeshReader # name of SourceProxy in *SM.xml
-  XML_GROUP sources
-)
-
-ADD_PARAVIEW_PLUGIN(
-    PV3blockMeshReader_SM "1.0"
-    SERVER_MANAGER_XML PV3blockMeshReader_SM.xml
-    SERVER_MANAGER_SOURCES  vtkPV3blockMeshReader.cxx
-    GUI_INTERFACES ${IFACES}
-    GUI_SOURCES pqPV3blockMeshReaderPanel.cxx
-        ${MOC_SRCS} ${UI_SRCS} ${IFACE_SRCS}
-    GUI_RESOURCE_FILES PV3blockMeshReader.xml
-)
-
-
-# #
-# # Define the server-side portion of the reader plugin
-# #
-# ADD_PARAVIEW_PLUGIN(PV3blockMeshReader_SM "1.0"
-#   SERVER_MANAGER_XML PV3blockMeshReader_SM.xml
-#   SERVER_MANAGER_SOURCES vtkPV3blockMeshReader.cxx
-# )
-# #
-# # Define the client-side portion of the reader plugin
-# #
-# ADD_PARAVIEW_PLUGIN(
-#     PV3blockMeshReader "1.0"
-#     GUI_RESOURCES PV3blockMeshReader.qrc
-# )
-
-
-# Build the client-side plugin
-
-TARGET_LINK_LIBRARIES(
-    PV3blockMeshReader_SM
-    OpenFOAM
-    blockMesh
-    vtkPV3blockMesh
-)
-#-----------------------------------------------------------------------------
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.qrc b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.qrc
deleted file mode 100644
index 5a3d74d0b06982021135362a2b01047409a04f20..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
-  <qresource prefix="/ParaViewResources" >
-      <file>PV3blockMeshReader.xml</file>
-  </qresource>
-</RCC>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.xml b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.xml
deleted file mode 100644
index 8b97801148105176fe530eb8dd6118235624329d..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<ParaViewReaders>
-  <Reader name="PV3blockMeshReader"
-      extensions="blockMesh"
-      file_description="OpenFOAM blockMesh reader">
-  </Reader>
-</ParaViewReaders>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader_SM.xml b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader_SM.xml
deleted file mode 100644
index b5bb304a652ff1eabd93d15c25a6e6e48ab270f1..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/PV3blockMeshReader_SM.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<ServerManagerConfiguration>
-  <ProxyGroup name="sources">
-  <SourceProxy
-    name="PV3blockMeshReader"
-    class="vtkPV3blockMeshReader">
-
-    <!-- File name - compulsory -->
-    <StringVectorProperty
-      name="FileName"
-      command="SetFileName"
-      number_of_elements="1"
-      animateable="0">
-      <FileListDomain name="files"/>
-      <Documentation>
-        Specifies the filename for the OpenFOAM blockMesh Reader.
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Show Point Numbers check-box -->
-    <IntVectorProperty
-      name="UiShowPointNumbers"
-      command="SetShowPointNumbers"
-      number_of_elements="1"
-      default_values="1"
-      is_internal="1"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        Show point numbers in render window.
-      </Documentation>
-    </IntVectorProperty>
-
-    <!-- Update GUI check box -->
-    <IntVectorProperty
-      name="UpdateGUI"
-      command="SetUpdateGUI"
-      number_of_elements="1"
-      default_values="0"
-      animateable="0">
-      <BooleanDomain name="bool"/>
-      <Documentation>
-        A simple way to cause a reader GUI modification.
-      </Documentation>
-    </IntVectorProperty>
-
-
-    <!--
-       | Selections
-       -->
-
-    <!-- Available Blocks array -->
-    <StringVectorProperty
-      name="BlockArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="Block"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="BlockStatus"
-      label="Blocks"
-      command="SetBlockArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="BlockArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="BlockArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the blocks
-      </Documentation>
-    </StringVectorProperty>
-
-    <!-- Available CurvedEdges array -->
-    <StringVectorProperty
-      name="CurvedEdgesArrayStatus"
-      information_only="1">
-      <ArraySelectionInformationHelper attribute_name="CurvedEdges"/>
-    </StringVectorProperty>
-    <StringVectorProperty
-      name="CurvedEdgesStatus"
-      label="Curved Edges"
-      command="SetCurvedEdgesArrayStatus"
-      number_of_elements="0"
-      repeat_command="1"
-      number_of_elements_per_command="2"
-      element_types="2 0"
-      information_property="CurvedEdgesArrayStatus"
-      animateable="0">
-      <ArraySelectionDomain name="array_list">
-        <RequiredProperties>
-          <Property name="CurvedEdgesArrayStatus" function="ArrayList"/>
-        </RequiredProperties>
-      </ArraySelectionDomain>
-      <Documentation>
-        This property contains a list of the curved edges
-      </Documentation>
-    </StringVectorProperty>
-
-  <Hints>
-    <Property name="FileName" show="0"/>
-    <Property name="UiShowPointNumbers" show="0"/>
-  </Hints>
-
-  </SourceProxy>
-  </ProxyGroup>
-</ServerManagerConfiguration>
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.cxx
deleted file mode 100644
index 961d4f51273b7078e25c20b1ae5c23e9e6ca7bfe..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.cxx
+++ /dev/null
@@ -1,110 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "pqPV3blockMeshReaderPanel.h"
-
-// QT
-#include <QGridLayout>
-#include <QCheckBox>
-#include <QLabel>
-#include <QLayout>
-#include <QString>
-#include <QPushButton>
-#include <QtDebug>
-
-// Paraview <-> QT UI
-#include "pqAnimationScene.h"
-#include "pqApplicationCore.h"
-#include "pqPipelineRepresentation.h"
-#include "pqServerManagerModel.h"
-#include "pqView.h"
-
-// Paraview Server Manager
-#include "vtkSMDoubleVectorProperty.h"
-#include "vtkSMIntVectorProperty.h"
-#include "vtkSMProperty.h"
-#include "vtkSMSourceProxy.h"
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-pqPV3blockMeshReaderPanel::pqPV3blockMeshReaderPanel
-(
-    pqProxy *proxy,
-    QWidget *p
-)
-:
-    pqAutoGeneratedObjectPanel(proxy, p)
-{
-    // create first sublayout (at top of the panel)
-    QGridLayout *form = new QGridLayout();
-    this->PanelLayout->addLayout(form, 0, 0, 1, -1);
-
-    vtkSMProperty* prop = 0;
-    // checkbox for showing point numbers
-    if ((prop = this->proxy()->GetProperty("UiShowPointNumbers")) != 0)
-    {
-        prop->SetImmediateUpdate(true);
-
-        ShowPointNumbers_ = new QCheckBox("Show Point Numbers");
-        ShowPointNumbers_->setToolTip("Show point numbers in render window.");
-        ShowPointNumbers_->setChecked
-        (
-            vtkSMIntVectorProperty::SafeDownCast(prop)->GetElement(0)
-        );
-
-        form->addWidget(ShowPointNumbers_);
-
-        connect
-        (
-            ShowPointNumbers_,
-            SIGNAL(stateChanged(int)),
-            this,
-            SLOT(ShowPointNumbersToggled())
-        );
-    }
-
-}
-
-// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
-
-void pqPV3blockMeshReaderPanel::ShowPointNumbersToggled()
-{
-    vtkSMIntVectorProperty::SafeDownCast
-    (
-        this->proxy()->GetProperty("UiShowPointNumbers")
-    )->SetElement(0, ShowPointNumbers_->isChecked());
-
-    // update the active view
-    if (this->view())
-    {
-        this->view()->render();
-    }
-    // OR: update all views
-    // pqApplicationCore::instance()->render();
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.h b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.h
deleted file mode 100644
index 9f555198594b77d9b411df494965d6e41b779d4d..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/pqPV3blockMeshReaderPanel.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    pqPV3blockMeshReaderPanel
-
-Description
-    GUI modifications for the ParaView reader panel
-
-    A custom panel for the PV3blockMeshReader.
-
-SourceFiles
-    pqPV3blockMeshReaderPanel.cxx
-
-\*---------------------------------------------------------------------------*/
-#ifndef pqPV3blockMeshReaderPanel_h
-#define pqPV3blockMeshReaderPanel_h
-
-#include "pqAutoGeneratedObjectPanel.h"
-
-// Forward declaration of QT classes
-
-class QCheckBox;
-class QLineEdit;
-class QTimer;
-class QToolButton;
-
-// Forward declaration of ParaView classes
-class vtkSMSourceProxy;
-
-
-/*---------------------------------------------------------------------------*\
-                  Class pqPV3blockMeshReaderPanel Declaration
-\*---------------------------------------------------------------------------*/
-
-class pqPV3blockMeshReaderPanel
-:
-    public pqAutoGeneratedObjectPanel
-{
-    // Private data
-    Q_OBJECT;
-    typedef pqAutoGeneratedObjectPanel Superclass;
-
-    //- Show Point Numbers checkbox
-    QCheckBox* ShowPointNumbers_;
-
-protected slots:
-
-    void ShowPointNumbersToggled();
-
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        pqPV3blockMeshReaderPanel(pqProxy*, QWidget*);
-
-
-    //- Destructor
-    // virtual ~pqPV3blockMeshReaderPanel();
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx
deleted file mode 100644
index 707e055c636dfd11de476381c858a914bbf18ce8..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx
+++ /dev/null
@@ -1,419 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3blockMeshReader.h"
-
-#include "pqApplicationCore.h"
-#include "pqRenderView.h"
-#include "pqServerManagerModel.h"
-
-// VTK includes
-#include "vtkCallbackCommand.h"
-#include "vtkDataArraySelection.h"
-#include "vtkInformation.h"
-#include "vtkInformationVector.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkObjectFactory.h"
-#include "vtkSMRenderViewProxy.h"
-#include "vtkStreamingDemandDrivenPipeline.h"
-#include "vtkStringArray.h"
-
-// OpenFOAM includes
-#include "vtkPV3blockMesh.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-vtkStandardNewMacro(vtkPV3blockMeshReader);
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-vtkPV3blockMeshReader::vtkPV3blockMeshReader()
-{
-    Debug = 0;
-    vtkDebugMacro(<<"Constructor");
-
-    SetNumberOfInputPorts(0);
-
-    FileName  = nullptr;
-    foamData_ = nullptr;
-
-    ShowPointNumbers = 1;
-    UpdateGUI = 0;
-
-    BlockSelection = vtkDataArraySelection::New();
-    CurvedEdgesSelection = vtkDataArraySelection::New();
-
-    // Setup the selection callback to modify this object when an array
-    // selection is changed.
-    SelectionObserver = vtkCallbackCommand::New();
-    SelectionObserver->SetCallback
-    (
-        &vtkPV3blockMeshReader::SelectionModifiedCallback
-    );
-    SelectionObserver->SetClientData(this);
-
-
-    BlockSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-
-    CurvedEdgesSelection->AddObserver
-    (
-        vtkCommand::ModifiedEvent,
-        this->SelectionObserver
-    );
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-vtkPV3blockMeshReader::~vtkPV3blockMeshReader()
-{
-    vtkDebugMacro(<<"Deconstructor");
-
-    if (foamData_)
-    {
-        // remove point numbers
-        updatePointNumbersView(false);
-        delete foamData_;
-    }
-
-    if (FileName)
-    {
-        delete [] FileName;
-    }
-
-    BlockSelection->RemoveObserver(this->SelectionObserver);
-    CurvedEdgesSelection->RemoveObserver(this->SelectionObserver);
-
-    SelectionObserver->Delete();
-    BlockSelection->Delete();
-}
-
-
-// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
-
-// Do everything except set the output info
-int vtkPV3blockMeshReader::RequestInformation
-(
-    vtkInformation* vtkNotUsed(request),
-    vtkInformationVector** vtkNotUsed(inputVector),
-    vtkInformationVector* outputVector
-)
-{
-    vtkDebugMacro(<<"RequestInformation");
-
-    if (Foam::vtkPV3blockMesh::debug)
-    {
-        cout<<"REQUEST_INFORMATION\n";
-    }
-
-    if (!FileName)
-    {
-        vtkErrorMacro("FileName has to be specified!");
-        return 0;
-    }
-
-    int nInfo = outputVector->GetNumberOfInformationObjects();
-
-    if (Foam::vtkPV3blockMesh::debug)
-    {
-        cout<<"RequestInformation with " << nInfo << " item(s)\n";
-        for (int infoI = 0; infoI < nInfo; ++infoI)
-        {
-            outputVector->GetInformationObject(infoI)->Print(cout);
-        }
-    }
-
-    if (!foamData_)
-    {
-        foamData_ = new Foam::vtkPV3blockMesh(FileName, this);
-    }
-    else
-    {
-        foamData_->updateInfo();
-    }
-
-    // might need some other type of error handling
-
-//    {
-//        vtkErrorMacro("could not find valid OpenFOAM blockMesh");
-//
-//        // delete foamData and flag it as fatal error
-//        delete foamData_;
-//        foamData_ = nullptr;
-//        return 0;
-//    }
-
-
-    return 1;
-}
-
-
-// Set the output info
-int vtkPV3blockMeshReader::RequestData
-(
-    vtkInformation* vtkNotUsed(request),
-    vtkInformationVector** vtkNotUsed(inputVector),
-    vtkInformationVector* outputVector
-)
-{
-    vtkDebugMacro(<<"RequestData");
-
-    if (!FileName)
-    {
-        vtkErrorMacro("FileName has to be specified!");
-        return 0;
-    }
-
-    // catch previous error
-    if (!foamData_)
-    {
-        vtkErrorMacro("Reader failed - perhaps no mesh?");
-        return 0;
-    }
-
-    int nInfo = outputVector->GetNumberOfInformationObjects();
-
-    if (Foam::vtkPV3blockMesh::debug)
-    {
-        cout<<"RequestData with " << nInfo << " item(s)\n";
-        for (int infoI = 0; infoI < nInfo; ++infoI)
-        {
-            outputVector->GetInformationObject(infoI)->Print(cout);
-        }
-    }
-
-    vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
-    (
-        outputVector->GetInformationObject(0)->Get
-        (
-            vtkMultiBlockDataSet::DATA_OBJECT()
-        )
-    );
-
-    if (Foam::vtkPV3blockMesh::debug)
-    {
-        cout<< "update output with "
-            << output->GetNumberOfBlocks() << " blocks\n";
-    }
-
-
-    foamData_->Update(output);
-    updatePointNumbersView(ShowPointNumbers);
-
-    // Do any cleanup on the OpenFOAM side
-    foamData_->CleanUp();
-
-    return 1;
-}
-
-
-
-void vtkPV3blockMeshReader::SetShowPointNumbers(const int val)
-{
-    if (ShowPointNumbers != val)
-    {
-        ShowPointNumbers = val;
-        updatePointNumbersView(ShowPointNumbers);
-    }
-}
-
-
-void vtkPV3blockMeshReader::updatePointNumbersView(const bool show)
-{
-    pqApplicationCore* appCore = pqApplicationCore::instance();
-
-    // need to check this, since our destructor calls this
-    if (!appCore)
-    {
-        return;
-    }
-
-    // Server manager model for querying items in the server manager
-    pqServerManagerModel* smModel = appCore->getServerManagerModel();
-    if (!smModel || !foamData_)
-    {
-        return;
-    }
-
-
-    // Get all the pqRenderView instances
-    QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>();
-    for (int viewI=0; viewI<renderViews.size(); ++viewI)
-    {
-        foamData_->renderPointNumbers
-        (
-            renderViews[viewI]->getRenderViewProxy()->GetRenderer(),
-            show
-        );
-    }
-
-    // use refresh here?
-}
-
-
-void vtkPV3blockMeshReader::PrintSelf(ostream& os, vtkIndent indent)
-{
-    vtkDebugMacro(<<"PrintSelf");
-
-    this->Superclass::PrintSelf(os,indent);
-    os  << indent << "File name: "
-        << (this->FileName ? this->FileName : "(none)") << "\n";
-
-    foamData_->PrintSelf(os, indent);
-}
-
-
-// ----------------------------------------------------------------------
-// Block selection list control
-
-vtkDataArraySelection* vtkPV3blockMeshReader::GetBlockSelection()
-{
-    vtkDebugMacro(<<"GetBlockSelection");
-    return BlockSelection;
-}
-
-
-int vtkPV3blockMeshReader::GetNumberOfBlockArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfBlockArrays");
-    return BlockSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3blockMeshReader::GetBlockArrayName(int index)
-{
-    vtkDebugMacro(<<"GetBlockArrayName");
-    return BlockSelection->GetArrayName(index);
-}
-
-
-int vtkPV3blockMeshReader::GetBlockArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetBlockArrayStatus");
-    return BlockSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3blockMeshReader::SetBlockArrayStatus
-(
-    const char* name,
-    int status
-)
-{
-    vtkDebugMacro(<<"SetBlockArrayStatus");
-    if (status)
-    {
-        BlockSelection->EnableArray(name);
-    }
-    else
-    {
-        BlockSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-// CurvedEdges selection list control
-
-vtkDataArraySelection* vtkPV3blockMeshReader::GetCurvedEdgesSelection()
-{
-    vtkDebugMacro(<<"GetCurvedEdgesSelection");
-    return CurvedEdgesSelection;
-}
-
-
-int vtkPV3blockMeshReader::GetNumberOfCurvedEdgesArrays()
-{
-    vtkDebugMacro(<<"GetNumberOfCurvedEdgesArrays");
-    return CurvedEdgesSelection->GetNumberOfArrays();
-}
-
-
-const char* vtkPV3blockMeshReader::GetCurvedEdgesArrayName(int index)
-{
-    vtkDebugMacro(<<"GetCurvedEdgesArrayName");
-    return CurvedEdgesSelection->GetArrayName(index);
-}
-
-
-int vtkPV3blockMeshReader::GetCurvedEdgesArrayStatus(const char* name)
-{
-    vtkDebugMacro(<<"GetCurvedEdgesArrayStatus");
-    return CurvedEdgesSelection->ArrayIsEnabled(name);
-}
-
-
-void vtkPV3blockMeshReader::SetCurvedEdgesArrayStatus
-(
-    const char* name,
-    int status
-)
-{
-    vtkDebugMacro(<<"SetCurvedEdgesArrayStatus");
-    if (status)
-    {
-        CurvedEdgesSelection->EnableArray(name);
-    }
-    else
-    {
-        CurvedEdgesSelection->DisableArray(name);
-    }
-}
-
-
-// ----------------------------------------------------------------------
-
-void vtkPV3blockMeshReader::SelectionModifiedCallback
-(
-    vtkObject*,
-    unsigned long,
-    void* clientdata,
-    void*
-)
-{
-    static_cast<vtkPV3blockMeshReader*>(clientdata)->Modified();
-}
-
-
-int vtkPV3blockMeshReader::FillOutputPortInformation
-(
-    int port,
-    vtkInformation* info
-)
-{
-    if (port == 0)
-    {
-        return this->Superclass::FillOutputPortInformation(port, info);
-    }
-    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
-    return 1;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.h b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.h
deleted file mode 100644
index 40e900c1b445239c2ab186217993db3c7d39755d..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    vtkPV3blockMeshReader
-
-Description
-    reads a dataset in OpenFOAM bockMesh format
-
-    vtkPV3blockMeshReader creates an multiblock dataset.
-    It uses the OpenFOAM infrastructure (blockMesh).
-
-SourceFiles
-    vtkPV3blockMeshReader.cxx
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3blockMeshReader_h
-#define vtkPV3blockMeshReader_h
-
-// VTK includes
-#include "vtkMultiBlockDataSetAlgorithm.h"
-
-// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
-
-// VTK forward declarations
-class vtkDataArraySelection;
-class vtkCallbackCommand;
-
-namespace Foam
-{
-    class vtkPV3blockMesh;
-}
-
-/*---------------------------------------------------------------------------*\
-                   Class vtkPV3blockMeshReader Declaration
-\*---------------------------------------------------------------------------*/
-
-class VTK_IO_EXPORT vtkPV3blockMeshReader
-:
-    public vtkMultiBlockDataSetAlgorithm
-{
-public:
-    vtkTypeMacro(vtkPV3blockMeshReader, vtkMultiBlockDataSetAlgorithm);
-    void PrintSelf(ostream&, vtkIndent);
-
-    static vtkPV3blockMeshReader* New();
-
-    // Description:
-    // Set/Get the filename.
-    vtkSetStringMacro(FileName);
-    vtkGetStringMacro(FileName);
-
-    // Description:
-    // Display corner point labels
-    virtual void SetShowPointNumbers(int);
-    vtkGetMacro(ShowPointNumbers, int);
-
-    // Description:
-    // GUI update control
-    vtkSetMacro(UpdateGUI, int);
-    vtkGetMacro(UpdateGUI, int);
-
-
-    // Description:
-    // Blocks selection list control
-    vtkDataArraySelection* GetBlockSelection();
-    int  GetNumberOfBlockArrays();
-    int  GetBlockArrayStatus(const char*);
-    void SetBlockArrayStatus(const char*, int status);
-    const char* GetBlockArrayName(int index);
-
-    // Description:
-    // CurvedEdges selection list control
-    vtkDataArraySelection* GetCurvedEdgesSelection();
-    int  GetNumberOfCurvedEdgesArrays();
-    int  GetCurvedEdgesArrayStatus(const char*);
-    void SetCurvedEdgesArrayStatus(const char*, int status);
-    const char* GetCurvedEdgesArrayName(int index);
-
-    // Description:
-    // Callback registered with the SelectionObserver
-    // for all the selection lists
-    static void SelectionModifiedCallback
-    (
-        vtkObject* caller,
-        unsigned long eid,
-        void* clientdata,
-        void* calldata
-    );
-
-
-protected:
-
-    //- Construct null
-    vtkPV3blockMeshReader();
-
-    //- Destructor
-    ~vtkPV3blockMeshReader();
-
-    //- Return information about mesh, times, etc without loading anything
-    virtual int RequestInformation
-    (
-        vtkInformation*,
-        vtkInformationVector**,
-        vtkInformationVector*
-    );
-
-    //- Get the mesh/fields for a particular time
-    virtual int RequestData
-    (
-        vtkInformation*,
-        vtkInformationVector**,
-        vtkInformationVector*
-    );
-
-    //- Fill in additional port information
-    virtual int FillOutputPortInformation(int, vtkInformation*);
-
-    // The observer to modify this object when array selections are modified
-    vtkCallbackCommand* SelectionObserver;
-
-    char* FileName;
-
-
-private:
-
-    //- Disallow default bitwise copy construct
-    vtkPV3blockMeshReader(const vtkPV3blockMeshReader&);
-
-    //- Disallow default bitwise assignment
-    void operator=(const vtkPV3blockMeshReader&);
-
-    //- Add/remove point numbers to/from the view
-    void updatePointNumbersView(const bool show);
-
-
-    //- Show Point Numbers
-    int ShowPointNumbers;
-
-    //- Dummy variable/switch to invoke a reader update
-    int UpdateGUI;
-
-    vtkDataArraySelection* BlockSelection;
-
-    vtkDataArraySelection* CurvedEdgesSelection;
-
-    //BTX
-    Foam::vtkPV3blockMesh* foamData_;
-    //ETX
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/files b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/files
deleted file mode 100644
index f084cc9f28fbc5faa5d02b2a857a9e4fc7f5eaf5..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/files
+++ /dev/null
@@ -1,5 +0,0 @@
-vtkPV3blockMesh.C
-vtkPV3blockMeshConvert.C
-vtkPV3blockMeshUtils.C
-
-LIB = $(FOAM_LIBBIN)/libvtkPV3blockMesh
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options
deleted file mode 100644
index dfab6b6630cfd31224b82bb0f8cb5d35fb59609c..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options
+++ /dev/null
@@ -1,12 +0,0 @@
-EXE_INC = \
-    -I$(LIB_SRC)/meshTools/lnInclude \
-    -I$(LIB_SRC)/mesh/blockMesh/lnInclude \
-    -I$(ParaView_INCLUDE_DIR) \
-    -I../../vtkPV3Readers/lnInclude \
-    -I../PV3blockMeshReader
-
-LIB_LIBS = \
-    -lmeshTools \
-    -lblockMesh \
-    -L$(FOAM_LIBBIN) -lvtkPV3Readers \
-    $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C
deleted file mode 100644
index 3aea81a88740e47a296d52090421c8572bf8eec6..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C
+++ /dev/null
@@ -1,488 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3blockMesh.H"
-#include "vtkPV3blockMeshReader.h"
-
-// OpenFOAM includes
-#include "blockMesh.H"
-#include "Time.H"
-#include "patchZones.H"
-#include "OStringStream.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkRenderer.h"
-#include "vtkTextActor.h"
-#include "vtkTextProperty.h"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    defineTypeNameAndDebug(vtkPV3blockMesh, 0);
-}
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::vtkPV3blockMesh::resetCounters()
-{
-    // Reset mesh part ids and sizes
-    arrayRangeBlocks_.reset();
-    arrayRangeEdges_.reset();
-    arrayRangeCorners_.reset();
-}
-
-
-void Foam::vtkPV3blockMesh::updateInfoBlocks
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::updateInfoBlocks"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "]" << endl;
-    }
-
-    arrayRangeBlocks_.reset( arraySelection->GetNumberOfArrays() );
-
-    const blockMesh& blkMesh = *meshPtr_;
-    const int nBlocks = blkMesh.size();
-    for (int blockI = 0; blockI < nBlocks; ++blockI)
-    {
-        const blockDescriptor& blockDef = blkMesh[blockI];
-
-        word partName = Foam::name(blockI);
-
-        // append the (optional) zone name
-        if (!blockDef.zoneName().empty())
-        {
-            partName += " - " + blockDef.zoneName();
-        }
-
-        // Add blockId and zoneName to GUI list
-        arraySelection->AddArray(partName.c_str());
-    }
-
-    arrayRangeBlocks_ += nBlocks;
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3blockMesh::updateInfoBlocks" << endl;
-    }
-}
-
-
-void Foam::vtkPV3blockMesh::updateInfoEdges
-(
-    vtkDataArraySelection* arraySelection
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::updateInfoEdges"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "]" << endl;
-    }
-
-    arrayRangeEdges_.reset( arraySelection->GetNumberOfArrays() );
-
-    const blockMesh& blkMesh = *meshPtr_;
-    const blockEdgeList& edges = blkMesh.edges();
-
-    const int nEdges = edges.size();
-    forAll(edges, edgeI)
-    {
-        OStringStream ostr;
-
-        ostr<< edges[edgeI].start() << ":" << edges[edgeI].end() << " - "
-            << edges[edgeI].type();
-
-        // Add "beg:end - type" to GUI list
-        arraySelection->AddArray(ostr.str().c_str());
-    }
-
-    arrayRangeEdges_ += nEdges;
-
-    if (debug)
-    {
-        // just for debug info
-        getSelectedArrayEntries(arraySelection);
-
-        Info<< "<end> Foam::vtkPV3blockMesh::updateInfoEdges" << endl;
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::vtkPV3blockMesh::vtkPV3blockMesh
-(
-    const char* const FileName,
-    vtkPV3blockMeshReader* reader
-)
-:
-    reader_(reader),
-    dbPtr_(nullptr),
-    meshPtr_(nullptr),
-    meshRegion_(polyMesh::defaultRegion),
-    meshDir_(polyMesh::meshSubDir),
-    arrayRangeBlocks_("block"),
-    arrayRangeEdges_("edges"),
-    arrayRangeCorners_("corners")
-{
-    if (debug)
-    {
-        Info<< "Foam::vtkPV3blockMesh::vtkPV3blockMesh - "
-            << FileName << endl;
-    }
-
-    // avoid argList and get rootPath/caseName directly from the file
-    fileName fullCasePath(fileName(FileName).path());
-
-    if (!isDir(fullCasePath))
-    {
-        return;
-    }
-    if (fullCasePath == ".")
-    {
-        fullCasePath = cwd();
-    }
-
-    // Set the case as an environment variable - some BCs might use this
-    if (fullCasePath.name().find("processor", 0) == 0)
-    {
-        const fileName globalCase = fullCasePath.path();
-
-        setEnv("FOAM_CASE", globalCase, true);
-        setEnv("FOAM_CASENAME", globalCase.name(), true);
-    }
-    else
-    {
-        setEnv("FOAM_CASE", fullCasePath, true);
-        setEnv("FOAM_CASENAME", fullCasePath.name(), true);
-    }
-
-    // look for 'case{region}.OpenFOAM'
-    // could be stringent and insist the prefix match the directory name...
-    // Note: cannot use fileName::name() due to the embedded '{}'
-    string caseName(fileName(FileName).lessExt());
-    string::size_type beg = caseName.find_last_of("/{");
-    string::size_type end = caseName.find('}', beg);
-
-    if
-    (
-        beg != string::npos && caseName[beg] == '{'
-     && end != string::npos && end == caseName.size()-1
-    )
-    {
-        meshRegion_ = caseName.substr(beg+1, end-beg-1);
-
-        // some safety
-        if (meshRegion_.empty())
-        {
-            meshRegion_ = polyMesh::defaultRegion;
-        }
-
-        if (meshRegion_ != polyMesh::defaultRegion)
-        {
-            meshDir_ = meshRegion_/polyMesh::meshSubDir;
-        }
-    }
-
-    if (debug)
-    {
-        Info<< "fullCasePath=" << fullCasePath << nl
-            << "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
-            << "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << endl;
-    }
-
-    // Create time object
-    dbPtr_.reset
-    (
-        new Time
-        (
-            Time::controlDictName,
-            fileName(fullCasePath.path()),
-            fileName(fullCasePath.name())
-        )
-    );
-
-    dbPtr_().functionObjects().off();
-
-    updateInfo();
-}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::vtkPV3blockMesh::~vtkPV3blockMesh()
-{
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::~vtkPV3blockMesh" << endl;
-    }
-
-    // Hmm. pointNumberTextActors are not getting removed
-    //
-    forAll(pointNumberTextActorsPtrs_, pointi)
-    {
-        pointNumberTextActorsPtrs_[pointi]->Delete();
-    }
-    pointNumberTextActorsPtrs_.clear();
-
-    delete meshPtr_;
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::vtkPV3blockMesh::updateInfo()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::updateInfo"
-            << " [meshPtr=" << (meshPtr_ ? "set" : "nullptr") << "] " << endl;
-    }
-
-    resetCounters();
-
-    vtkDataArraySelection* blockSelection = reader_->GetBlockSelection();
-    vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection();
-
-    // enable 'internalMesh' on the first call
-    // or preserve the enabled selections
-    stringList enabledParts;
-    stringList enabledEdges;
-    bool firstTime = false;
-    if (!blockSelection->GetNumberOfArrays() && !meshPtr_)
-    {
-        firstTime = true;
-    }
-    else
-    {
-        enabledParts = getSelectedArrayEntries(blockSelection);
-        enabledEdges = getSelectedArrayEntries(edgeSelection);
-    }
-
-    // Clear current mesh parts list
-    blockSelection->RemoveAllArrays();
-    edgeSelection->RemoveAllArrays();
-
-    // need a blockMesh
-    updateFoamMesh();
-
-    // Update mesh parts list
-    updateInfoBlocks( blockSelection );
-
-    // Update curved edges list
-    updateInfoEdges( edgeSelection );
-
-    // restore the enabled selections
-    if (!firstTime)
-    {
-        setSelectedArrayEntries(blockSelection, enabledParts);
-        setSelectedArrayEntries(edgeSelection, enabledEdges);
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::updateInfo" << endl;
-    }
-}
-
-
-void Foam::vtkPV3blockMesh::updateFoamMesh()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::updateFoamMesh" << endl;
-    }
-
-    // Check to see if the OpenFOAM mesh has been created
-    if (!meshPtr_)
-    {
-        if (debug)
-        {
-            Info<< "Creating blockMesh at time=" << dbPtr_().timeName()
-                << endl;
-        }
-
-        // Set path for the blockMeshDict
-        const word dictName("blockMeshDict");
-        fileName dictPath(dbPtr_().system()/dictName);
-
-        // Check if dictionary is present in the constant directory
-        if
-        (
-            exists
-            (
-                dbPtr_().path()/dbPtr_().constant()
-               /polyMesh::meshSubDir/dictName
-            )
-        )
-        {
-            dictPath = dbPtr_().constant()/polyMesh::meshSubDir/dictName;
-        }
-
-        IOdictionary meshDict
-        (
-            IOobject
-            (
-                dictPath,
-                dbPtr_(),
-                IOobject::MUST_READ_IF_MODIFIED,
-                IOobject::NO_WRITE,
-                false
-            )
-        );
-
-        meshPtr_ = new blockMesh(meshDict, meshRegion_);
-    }
-
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::updateFoamMesh" << endl;
-    }
-}
-
-
-void Foam::vtkPV3blockMesh::Update
-(
-    vtkMultiBlockDataSet* output
-)
-{
-    reader_->UpdateProgress(0.1);
-
-    // Set up mesh parts selection(s)
-    updateBoolListStatus(blockStatus_, reader_->GetBlockSelection());
-
-    // Set up curved edges selection(s)
-    updateBoolListStatus(edgeStatus_, reader_->GetCurvedEdgesSelection());
-
-    reader_->UpdateProgress(0.2);
-
-    // Update the OpenFOAM mesh
-    updateFoamMesh();
-    reader_->UpdateProgress(0.5);
-
-    // Convert mesh elemente
-    int blockNo = 0;
-
-    convertMeshCorners(output, blockNo);
-    convertMeshBlocks(output, blockNo);
-    convertMeshEdges(output, blockNo);
-
-    reader_->UpdateProgress(0.8);
-
-}
-
-
-void Foam::vtkPV3blockMesh::CleanUp()
-{
-    reader_->UpdateProgress(1.0);
-}
-
-
-void Foam::vtkPV3blockMesh::renderPointNumbers
-(
-    vtkRenderer* renderer,
-    const bool show
-)
-{
-    // always remove old actors first
-
-    forAll(pointNumberTextActorsPtrs_, pointi)
-    {
-        renderer->RemoveViewProp(pointNumberTextActorsPtrs_[pointi]);
-        pointNumberTextActorsPtrs_[pointi]->Delete();
-    }
-    pointNumberTextActorsPtrs_.clear();
-
-    if (show && meshPtr_)
-    {
-        const pointField& cornerPts = meshPtr_->vertices();
-        const scalar scaleFactor = meshPtr_->scaleFactor();
-
-        pointNumberTextActorsPtrs_.setSize(cornerPts.size());
-        forAll(cornerPts, pointi)
-        {
-            vtkTextActor* txt = vtkTextActor::New();
-
-            txt->SetInput(Foam::name(pointi).c_str());
-
-            // Set text properties
-            vtkTextProperty* tprop = txt->GetTextProperty();
-            tprop->SetFontFamilyToArial();
-            tprop->BoldOn();
-            tprop->ShadowOff();
-            tprop->SetLineSpacing(1.0);
-            tprop->SetFontSize(14);
-            tprop->SetColor(1.0, 0.0, 1.0);
-            tprop->SetJustificationToCentered();
-
-            // Set text to use 3-D world co-ordinates
-            txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
-
-            txt->GetPositionCoordinate()->SetValue
-            (
-                cornerPts[pointi].x()*scaleFactor,
-                cornerPts[pointi].y()*scaleFactor,
-                cornerPts[pointi].z()*scaleFactor
-            );
-
-            // Add text to each renderer
-            renderer->AddViewProp(txt);
-
-            // Maintain a list of text labels added so that they can be
-            // removed later
-            pointNumberTextActorsPtrs_[pointi] = txt;
-        }
-    }
-}
-
-
-
-void Foam::vtkPV3blockMesh::PrintSelf(ostream& os, vtkIndent indent) const
-{
-#if 0
-    os  << indent << "Number of nodes: "
-        << (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
-
-    os  << indent << "Number of cells: "
-        << (meshPtr_ ? meshPtr_->nCells() : 0) << "\n";
-
-    os  << indent << "Number of available time steps: "
-        << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
-#endif
-}
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.H
deleted file mode 100644
index cf5c25f3071ea006df5b7529fe6a3413c45069a6..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.H
+++ /dev/null
@@ -1,353 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-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::vtkPV3blockMesh
-
-Description
-    Provides a reader interface for OpenFOAM blockMesh to VTK interaction
-
-SourceFiles
-    vtkPV3blockMesh.C
-    vtkPV3blockMeshConvert.C
-    vtkPV3blockMeshUpdate.C
-    vtkPV3blockMeshUtils.C
-
-    // Needed by VTK:
-    vtkDataArrayTemplateImplicit.txx
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3blockMesh_H
-#define vtkPV3blockMesh_H
-
-// do not include legacy strstream headers
-#ifndef  VTK_EXCLUDE_STRSTREAM_HEADERS
-# define VTK_EXCLUDE_STRSTREAM_HEADERS
-#endif
-
-#include "className.H"
-#include "fileName.H"
-#include "stringList.H"
-#include "wordList.H"
-
-#include "primitivePatch.H"
-
-// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
-
-class vtkDataArraySelection;
-class vtkDataSet;
-class vtkPoints;
-class vtkPV3blockMeshReader;
-class vtkRenderer;
-class vtkTextActor;
-class vtkMultiBlockDataSet;
-class vtkPolyData;
-class vtkUnstructuredGrid;
-class vtkIndent;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// OpenFOAM class forward declarations
-class argList;
-class Time;
-class blockMesh;
-
-template<class Type> class List;
-
-/*---------------------------------------------------------------------------*\
-                     Class vtkPV3blockMesh Declaration
-\*---------------------------------------------------------------------------*/
-
-class vtkPV3blockMesh
-{
-    // Private classes
-
-        //- Bookkeeping for GUI checklists and the multi-block organization
-        class arrayRange
-        {
-            const char *name_;
-            int block_;
-            int start_;
-            int size_;
-
-        public:
-
-            arrayRange(const char *name, const int blockNo=0)
-            :
-                name_(name),
-                block_(blockNo),
-                start_(0),
-                size_(0)
-            {}
-
-            //- Return the block holding these datasets
-            int block() const
-            {
-                return block_;
-            }
-
-            //- Assign block number, return previous value
-            int block(int blockNo)
-            {
-                int prev = block_;
-                block_ = blockNo;
-                return prev;
-            }
-
-            //- Return block name
-            const char* name() const
-            {
-                return name_;
-            }
-
-            //- Return array start index
-            int start() const
-            {
-                return start_;
-            }
-
-            //- Return array end index
-            int end() const
-            {
-                return start_ + size_;
-            }
-
-            //- Return sublist size
-            int size() const
-            {
-                return size_;
-            }
-
-            bool empty() const
-            {
-                return !size_;
-            }
-
-            //- Reset the size to zero and optionally assign a new start
-            void reset(const int startAt = 0)
-            {
-                start_ = startAt;
-                size_ = 0;
-            }
-
-            //- Increment the size
-            void operator+=(const int n)
-            {
-                size_ += n;
-            }
-        };
-
-
-    // Private Data
-
-        //- Access to the controlling vtkPV3blockMeshReader
-        vtkPV3blockMeshReader* reader_;
-
-        //- OpenFOAM time control
-        autoPtr<Time> dbPtr_;
-
-        //- OpenFOAM mesh
-        blockMesh* meshPtr_;
-
-        //- The mesh region
-        word meshRegion_;
-
-        //- The mesh directory for the region
-        fileName meshDir_;
-
-        //- Selected geometrical parts
-        boolList blockStatus_;
-
-        //- Selected curved edges
-        boolList edgeStatus_;
-
-        //- First instance and size of bleckMesh blocks
-        //  used to index into blockStatus_
-        arrayRange arrayRangeBlocks_;
-
-        //- First instance and size of CurvedEdges (only partially used)
-        arrayRange arrayRangeEdges_;
-
-        //- First instance and size of block corners (only partially used)
-        arrayRange arrayRangeCorners_;
-
-        //- List of point numbers for rendering to window
-        List<vtkTextActor*> pointNumberTextActorsPtrs_;
-
-    // Private Member Functions
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static void AddToBlock
-        (
-            vtkMultiBlockDataSet* output,
-            vtkDataSet* dataset,
-            const arrayRange&,
-            const label datasetNo,
-            const std::string& datasetName
-        );
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static vtkDataSet* GetDataSetFromBlock
-        (
-            vtkMultiBlockDataSet* output,
-            const arrayRange&,
-            const label datasetNo
-        );
-
-        // Convenience method use to convert the readers from VTK 5
-        // multiblock API to the current composite data infrastructure
-        static label GetNumberOfDataSets
-        (
-            vtkMultiBlockDataSet* output,
-            const arrayRange&
-        );
-
-        //- Update boolList from GUI selection
-        static void updateBoolListStatus
-        (
-            boolList&,
-            vtkDataArraySelection*
-        );
-
-        //- Reset data counters
-        void resetCounters();
-
-        // Update information helper functions
-
-            //- Internal block info
-            void updateInfoBlocks(vtkDataArraySelection*);
-
-            //- Block curved edges info
-            void updateInfoEdges(vtkDataArraySelection*);
-
-        // Update helper functions
-
-            //- OpenFOAM mesh
-            void updateFoamMesh();
-
-        // Mesh conversion functions
-
-            //- Mesh blocks
-            void convertMeshBlocks(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Mesh curved edges
-            void convertMeshEdges(vtkMultiBlockDataSet*, int& blockNo);
-
-            //- Mesh corners
-            void convertMeshCorners(vtkMultiBlockDataSet*, int& blockNo);
-
-
-       // GUI selection helper functions
-
-            //- Retrieve the current selections
-            static wordHashSet getSelected(vtkDataArraySelection*);
-
-            //- Retrieve a sub-list of the current selections
-            static wordHashSet getSelected
-            (
-                vtkDataArraySelection*,
-                const arrayRange&
-            );
-
-            //- Retrieve the current selections
-            static stringList getSelectedArrayEntries(vtkDataArraySelection*);
-
-            //- Retrieve a sub-list of the current selections
-            static stringList getSelectedArrayEntries
-            (
-                vtkDataArraySelection*,
-                const arrayRange&
-            );
-
-            //- Set selection(s)
-            static void setSelectedArrayEntries
-            (
-                vtkDataArraySelection*,
-                const stringList&
-            );
-
-
-        //- Disallow default bitwise copy construct
-        vtkPV3blockMesh(const vtkPV3blockMesh&);
-
-        //- Disallow default bitwise assignment
-        void operator=(const vtkPV3blockMesh&);
-
-
-public:
-
-    //- Static data members
-
-        ClassName("vtkPV3blockMesh");
-
-
-    // Constructors
-
-        //- Construct from components
-        vtkPV3blockMesh
-        (
-            const char* const FileName,
-            vtkPV3blockMeshReader* reader
-        );
-
-
-    //- Destructor
-    ~vtkPV3blockMesh();
-
-
-    // Member Functions
-
-        //- Update
-        void updateInfo();
-
-        void Update(vtkMultiBlockDataSet* output);
-
-        //- Clean any storage
-        void CleanUp();
-
-        //- Add/remove point numbers to/from the view
-        void renderPointNumbers(vtkRenderer*, const bool show);
-
-     // Access
-
-        //- Debug information
-        void PrintSelf(ostream&, vtkIndent) const;
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C
deleted file mode 100644
index 8dce33a9826fe844ff273f7e4a9ea5b8cba4c6ba..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C
+++ /dev/null
@@ -1,319 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "vtkPV3blockMesh.H"
-#include "vtkPV3blockMeshReader.h"
-
-// OpenFOAM includes
-#include "blockMesh.H"
-#include "Time.H"
-
-#include "vtkOpenFOAMPoints.H"
-
-// VTK includes
-#include "vtkCellArray.h"
-#include "vtkDataArraySelection.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkPoints.h"
-#include "vtkPolyData.h"
-#include "vtkUnstructuredGrid.h"
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::vtkPV3blockMesh::convertMeshBlocks
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    vtkDataArraySelection* selection = reader_->GetBlockSelection();
-    arrayRange& range = arrayRangeBlocks_;
-    range.block(blockNo);   // set output block
-    label datasetNo = 0;       // restart at dataset 0
-
-    const blockMesh& blkMesh = *meshPtr_;
-    const Foam::pointField& blockPoints = blkMesh.vertices();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::convertMeshBlocks" << endl;
-    }
-
-    int blockI = 0;
-    const scalar scaleFactor = blkMesh.scaleFactor();
-
-    for
-    (
-        int partId = range.start();
-        partId < range.end();
-        ++partId, ++blockI
-    )
-    {
-        if (!blockStatus_[partId])
-        {
-            continue;
-        }
-
-        const blockDescriptor& blockDef = blkMesh[blockI];
-
-        vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();
-
-        // Convert OpenFOAM mesh vertices to VTK
-        vtkPoints *vtkpoints = vtkPoints::New();
-        vtkpoints->Allocate( blockDef.nPoints() );
-        const labelList& blockLabels = blockDef.blockShape();
-
-        vtkmesh->Allocate(1);
-        vtkIdType nodeIds[8];
-
-        forAll(blockLabels, ptI)
-        {
-            vtkInsertNextOpenFOAMPoint
-            (
-                vtkpoints,
-                blockPoints[blockLabels[ptI]],
-                scaleFactor
-            );
-
-            nodeIds[ptI] = ptI;
-        }
-
-        vtkmesh->InsertNextCell
-        (
-            VTK_HEXAHEDRON,
-            8,
-            nodeIds
-        );
-
-        vtkmesh->SetPoints(vtkpoints);
-        vtkpoints->Delete();
-
-        AddToBlock
-        (
-            output, vtkmesh, range, datasetNo,
-            selection->GetArrayName(partId)
-        );
-
-        vtkmesh->Delete();
-        datasetNo++;
-    }
-
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::convertMeshBlocks" << endl;
-    }
-}
-
-
-void Foam::vtkPV3blockMesh::convertMeshEdges
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    vtkDataArraySelection* selection = reader_->GetCurvedEdgesSelection();
-    arrayRange& range = arrayRangeEdges_;
-
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-
-    const blockMesh& blkMesh = *meshPtr_;
-    const blockEdgeList& edges = blkMesh.edges();
-
-    int edgeI = 0;
-    const scalar scaleFactor = blkMesh.scaleFactor();
-
-    for
-    (
-        int partId = range.start();
-        partId < range.end();
-        ++partId, ++edgeI
-    )
-    {
-        if (!edgeStatus_[partId])
-        {
-            continue;
-        }
-
-        // search each block
-        forAll(blkMesh, blockI)
-        {
-            const blockDescriptor& blockDef = blkMesh[blockI];
-
-            edgeList blkEdges = blockDef.blockShape().edges();
-
-            // find the corresponding edge within the block
-            label foundEdgeI = -1;
-            forAll(blkEdges, blkEdgeI)
-            {
-                if (edges[edgeI].compare(blkEdges[blkEdgeI]))
-                {
-                    foundEdgeI = blkEdgeI;
-                    break;
-                }
-            }
-
-            if (foundEdgeI != -1)
-            {
-                const List<point>& edgePoints =
-                    blockDef.blockEdgePoints()[foundEdgeI];
-
-
-                vtkPolyData* vtkmesh = vtkPolyData::New();
-                vtkPoints* vtkpoints = vtkPoints::New();
-
-                vtkpoints->Allocate( edgePoints.size() );
-                vtkmesh->Allocate(1);
-
-                vtkIdType pointIds[edgePoints.size()];
-                forAll(edgePoints, ptI)
-                {
-                    vtkInsertNextOpenFOAMPoint
-                    (
-                        vtkpoints,
-                        edgePoints[ptI],
-                        scaleFactor
-                    );
-                    pointIds[ptI] = ptI;
-                }
-
-                vtkmesh->InsertNextCell
-                (
-                    VTK_POLY_LINE,
-                    edgePoints.size(),
-                    pointIds
-                );
-
-                vtkmesh->SetPoints(vtkpoints);
-                vtkpoints->Delete();
-
-                AddToBlock
-                (
-                    output, vtkmesh, range, datasetNo,
-                    selection->GetArrayName(partId)
-                );
-
-                vtkmesh->Delete();
-                datasetNo++;
-
-                break;
-            }
-        }
-    }
-
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::convertMeshEdges" << endl;
-    }
-
-}
-
-
-void Foam::vtkPV3blockMesh::convertMeshCorners
-(
-    vtkMultiBlockDataSet* output,
-    int& blockNo
-)
-{
-    arrayRange& range = arrayRangeCorners_;
-    range.block(blockNo);      // set output block
-    label datasetNo = 0;       // restart at dataset 0
-
-    const pointField& blockPoints = meshPtr_->vertices();
-    const scalar& scaleFactor = meshPtr_->scaleFactor();
-
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::convertMeshCorners" << endl;
-    }
-
-    if (true)  // or some flag or other condition
-    {
-        vtkPolyData* vtkmesh = vtkPolyData::New();
-        vtkPoints* vtkpoints = vtkPoints::New();
-        vtkCellArray* vtkcells = vtkCellArray::New();
-
-        vtkpoints->Allocate( blockPoints.size() );
-        vtkcells->Allocate( blockPoints.size() );
-
-        vtkIdType pointId = 0;
-        forAll(blockPoints, ptI)
-        {
-            vtkInsertNextOpenFOAMPoint
-            (
-                vtkpoints,
-                blockPoints[ptI],
-                scaleFactor
-            );
-
-            vtkcells->InsertNextCell(1, &pointId);
-            pointId++;
-        }
-
-        vtkmesh->SetPoints(vtkpoints);
-        vtkpoints->Delete();
-
-        vtkmesh->SetVerts(vtkcells);
-        vtkcells->Delete();
-
-        AddToBlock
-        (
-            output, vtkmesh, range, datasetNo,
-            arrayRangeCorners_.name()
-        );
-        vtkmesh->Delete();
-
-        datasetNo++;
-    }
-
-    // anything added?
-    if (datasetNo)
-    {
-        ++blockNo;
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::convertMeshCorners" << endl;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshUtils.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshUtils.C
deleted file mode 100644
index fb26fceba1bbe3abba15336cf82b6867da5617a9..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshUtils.C
+++ /dev/null
@@ -1,357 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-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/>.
-
-Description
-    Misc helper methods and utilities
-
-\*---------------------------------------------------------------------------*/
-
-#include "vtkPV3blockMesh.H"
-#include "vtkPV3blockMeshReader.h"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkDataSet.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkInformation.h"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    //! \cond fileScope
-    //  Extract up to the first non-word characters
-    inline word getFirstWord(const char* str)
-    {
-        if (str)
-        {
-            label n = 0;
-            while (str[n] && word::valid(str[n]))
-            {
-                ++n;
-            }
-            return word(str, n, true);
-        }
-        else
-        {
-            return word::null;
-        }
-
-    }
-    //! \endcond
-
-} // End namespace Foam
-
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::vtkPV3blockMesh::AddToBlock
-(
-    vtkMultiBlockDataSet* output,
-    vtkDataSet* dataset,
-    const arrayRange& range,
-    const label datasetNo,
-    const std::string& datasetName
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (!block)
-    {
-        if (blockDO)
-        {
-            FatalErrorInFunction
-                << "Block already has a vtkDataSet assigned to it"
-                << endl;
-            return;
-        }
-
-        block = vtkMultiBlockDataSet::New();
-        output->SetBlock(blockNo, block);
-        block->Delete();
-    }
-
-    if (debug)
-    {
-        Info<< "block[" << blockNo << "] has "
-            << block->GetNumberOfBlocks()
-            <<  " datasets prior to adding set " << datasetNo
-            <<  " with name: " << datasetName << endl;
-    }
-
-    block->SetBlock(datasetNo, dataset);
-
-    // name the block when assigning dataset 0
-    if (datasetNo == 0)
-    {
-        output->GetMetaData(blockNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            range.name()
-        );
-    }
-
-    if (datasetName.size())
-    {
-        block->GetMetaData(datasetNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            datasetName.c_str()
-        );
-    }
-}
-
-
-vtkDataSet* Foam::vtkPV3blockMesh::GetDataSetFromBlock
-(
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range,
-    const label datasetNo
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (block)
-    {
-        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
-    }
-
-    return 0;
-}
-
-
-// ununsed at the moment
-Foam::label Foam::vtkPV3blockMesh::GetNumberOfDataSets
-(
-    vtkMultiBlockDataSet* output,
-    const arrayRange& range
-)
-{
-    const int blockNo = range.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (block)
-    {
-        return block->GetNumberOfBlocks();
-    }
-
-    return 0;
-}
-
-
-Foam::wordHashSet Foam::vtkPV3blockMesh::getSelected
-(
-    vtkDataArraySelection* select
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::wordHashSet Foam::vtkPV3blockMesh::getSelected
-(
-    vtkDataArraySelection* select,
-    const arrayRange& range
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI = range.start(); elemI < range.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3blockMesh::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select
-)
-{
-    stringList selections(select->GetNumberOfArrays());
-    label nElem = 0;
-
-    forAll(selections, elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        label nElem = select->GetNumberOfArrays();
-        Info<< "available(";
-        for (int elemI = 0; elemI < nElem; ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3blockMesh::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const arrayRange& range
-)
-{
-    stringList selections(range.size());
-    label nElem = 0;
-
-    for (int elemI = range.start(); elemI < range.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        Info<< "available(";
-        for (int elemI = range.start(); elemI < range.end(); ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-void Foam::vtkPV3blockMesh::setSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const stringList& selections
-)
-{
-    const int nElem = select->GetNumberOfArrays();
-    select->DisableAllArrays();
-
-    // Loop through entries, setting values from selectedEntries
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        string arrayName(select->GetArrayName(elemI));
-
-        forAll(selections, elemI)
-        {
-            if (selections[elemI] == arrayName)
-            {
-                select->EnableArray(arrayName.c_str());
-                break;
-            }
-        }
-    }
-}
-
-
-void Foam::vtkPV3blockMesh::updateBoolListStatus
-(
-    boolList& status,
-    vtkDataArraySelection* selection
-)
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3blockMesh::updateBoolListStatus" << endl;
-    }
-
-    const label nElem = selection->GetNumberOfArrays();
-    if (status.size() != nElem)
-    {
-        status.setSize(nElem);
-        status = false;
-    }
-
-    forAll(status, elemI)
-    {
-        const int setting = selection->GetArraySetting(elemI);
-
-        status[elemI] = setting;
-
-        if (debug)
-        {
-            Info<< "  part[" << elemI << "] = "
-                << status[elemI]
-                << " : " << selection->GetArrayName(elemI) << endl;
-        }
-    }
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3blockMesh::updateBoolListStatus" << endl;
-    }
-}
-
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files
deleted file mode 100644
index 134b8de963e813e2955fdac51ea10d5e684e6c94..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files
+++ /dev/null
@@ -1,3 +0,0 @@
-vtkPV3Readers.C
-
-LIB = $(FOAM_LIBBIN)/libvtkPV3Readers
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options
deleted file mode 100644
index 11c006c3bea328b82dc705da5f4b29e830c23635..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options
+++ /dev/null
@@ -1,5 +0,0 @@
-EXE_INC = \
-    -I$(ParaView_INCLUDE_DIR)
-
-LIB_LIBS = \
-    $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C
deleted file mode 100644
index 5740476e665dd9eb37fa82608f1769b0b96fa434..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C
+++ /dev/null
@@ -1,333 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-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/>.
-
-Description
-    Misc helper methods and utilities
-
-\*---------------------------------------------------------------------------*/
-
-#include "vtkPV3Readers.H"
-
-// OpenFOAM includes
-#include "IFstream.H"
-
-// VTK includes
-#include "vtkDataArraySelection.h"
-#include "vtkDataSet.h"
-#include "vtkMultiBlockDataSet.h"
-#include "vtkInformation.h"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-defineTypeNameAndDebug(vtkPV3Readers, 0);
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    //! \cond fileScope
-    //  Extract up to the first non-word characters
-    inline word getFirstWord(const char* str)
-    {
-        if (str)
-        {
-            label n = 0;
-            while (str[n] && word::valid(str[n]))
-            {
-                ++n;
-            }
-            return word(str, n, true);
-        }
-        else
-        {
-            return word::null;
-        }
-
-    }
-    //! \endcond
-
-} // End namespace Foam
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::vtkPV3Readers::AddToBlock
-(
-    vtkMultiBlockDataSet* output,
-    vtkDataSet* dataset,
-    const partInfo& selector,
-    const label datasetNo,
-    const std::string& datasetName
-)
-{
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (!block)
-    {
-        if (blockDO)
-        {
-            FatalErrorInFunction
-                << "Block already has a vtkDataSet assigned to it"
-                << endl;
-            return;
-        }
-
-        block = vtkMultiBlockDataSet::New();
-        output->SetBlock(blockNo, block);
-        block->Delete();
-    }
-
-    if (debug)
-    {
-        Info<< "block[" << blockNo << "] has "
-            << block->GetNumberOfBlocks()
-            <<  " datasets prior to adding set " << datasetNo
-            <<  " with name: " << datasetName << endl;
-    }
-
-    block->SetBlock(datasetNo, dataset);
-
-    // name the block when assigning dataset 0
-    if (datasetNo == 0)
-    {
-        output->GetMetaData(blockNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            selector.name()
-        );
-    }
-
-    if (datasetName.size())
-    {
-        block->GetMetaData(datasetNo)->Set
-        (
-            vtkCompositeDataSet::NAME(),
-            datasetName.c_str()
-        );
-    }
-}
-
-
-vtkDataSet* Foam::vtkPV3Readers::GetDataSetFromBlock
-(
-    vtkMultiBlockDataSet* output,
-    const partInfo& selector,
-    const label datasetNo
-)
-{
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-
-    if (block)
-    {
-        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
-    }
-
-    return 0;
-}
-
-
-// ununsed at the moment
-Foam::label Foam::vtkPV3Readers::GetNumberOfDataSets
-(
-    vtkMultiBlockDataSet* output,
-    const partInfo& selector
-)
-{
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (block)
-    {
-        return block->GetNumberOfBlocks();
-    }
-
-    return 0;
-}
-
-
-// Foam::word Foam::vtkPV3Readers::getPartName(int partId)
-// {
-//     return getFirstWord(reader_->GetPartArrayName(partId));
-// }
-
-
-Foam::wordHashSet Foam::vtkPV3Readers::getSelected
-(
-    vtkDataArraySelection* select
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::wordHashSet Foam::vtkPV3Readers::getSelected
-(
-    vtkDataArraySelection* select,
-    const partInfo& selector
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections.insert(getFirstWord(select->GetArrayName(elemI)));
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Readers::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select
-)
-{
-    stringList selections(select->GetNumberOfArrays());
-    label nElem = 0;
-
-    forAll(selections, elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        label nElem = select->GetNumberOfArrays();
-        Info<< "available(";
-        for (int elemI = 0; elemI < nElem; ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Readers::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const partInfo& selector
-)
-{
-    stringList selections(selector.size());
-    label nElem = 0;
-
-    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            selections[nElem++] = select->GetArrayName(elemI);
-        }
-    }
-    selections.setSize(nElem);
-
-
-    if (debug)
-    {
-        Info<< "available(";
-        for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\nselected(";
-
-        forAll(selections, elemI)
-        {
-            Info<< " " << selections[elemI];
-        }
-        Info<< " )\n";
-    }
-
-    return selections;
-}
-
-
-void Foam::vtkPV3Readers::setSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const stringList& selections
-)
-{
-    const int nElem = select->GetNumberOfArrays();
-    select->DisableAllArrays();
-
-    // Loop through entries, setting values from selectedEntries
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        string arrayName(select->GetArrayName(elemI));
-
-        forAll(selections, elemI)
-        {
-            if (selections[elemI] == arrayName)
-            {
-                select->EnableArray(arrayName.c_str());
-                break;
-            }
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H
deleted file mode 100644
index e955be79fc86aacd6e39486c94a3dae6c0477748..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H
+++ /dev/null
@@ -1,228 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Namespace
-    Foam::vtkPV3Readers
-
-Description
-    A collection of helper functions when building a reader interface in
-    ParaView3.
-
-SourceFiles
-    vtkPV3Readers.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkPV3Readers_H
-#define vtkPV3Readers_H
-
-// do not include legacy strstream headers
-#ifndef  VTK_EXCLUDE_STRSTREAM_HEADERS
-# define VTK_EXCLUDE_STRSTREAM_HEADERS
-#endif
-
-#include "className.H"
-#include "fileName.H"
-#include "stringList.H"
-#include "wordList.H"
-#include "HashSet.H"
-
-
-// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
-
-class vtkDataArraySelection;
-class vtkDataSet;
-class vtkPoints;
-class vtkPV3FoamReader;
-class vtkRenderer;
-class vtkTextActor;
-class vtkMultiBlockDataSet;
-class vtkPolyData;
-class vtkUnstructuredGrid;
-class vtkIndent;
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-namespace vtkPV3Readers
-{
-    //- Declare name of the class and its debug switch
-    NamespaceName("vtkPV3Readers");
-
-    //- Bookkeeping for GUI checklists and the multi-block organization
-    class partInfo
-    {
-        const char *name_;
-        int block_;
-        int start_;
-        int size_;
-
-    public:
-
-        partInfo(const char *name, const int blockNo=0)
-        :
-            name_(name),
-            block_(blockNo),
-            start_(-1),
-            size_(0)
-        {}
-
-        //- Return the block holding these datasets
-        int block() const
-        {
-            return block_;
-        }
-
-        //- Assign block number, return previous value
-        int block(int blockNo)
-        {
-            int prev = block_;
-            block_ = blockNo;
-            return prev;
-        }
-
-        const char* name() const
-        {
-            return name_;
-        }
-
-        int start() const
-        {
-            return start_;
-        }
-
-        int end() const
-        {
-            return start_ + size_;
-        }
-
-        int size() const
-        {
-            return size_;
-        }
-
-        bool empty() const
-        {
-            return !size_;
-        }
-
-        void reset()
-        {
-            start_ = -1;
-            size_ = 0;
-        }
-
-        //- Assign new start and reset the size
-        void operator=(const int i)
-        {
-            start_ = i;
-            size_ = 0;
-        }
-
-        //- Increment the size
-        void operator+=(const int n)
-        {
-            size_ += n;
-        }
-    };
-
-
-    //- Convenience method use to convert the readers from VTK 5
-    //  multiblock API to the current composite data infrastructure
-    void AddToBlock
-    (
-        vtkMultiBlockDataSet* output,
-        vtkDataSet* dataset,
-        const partInfo& selector,
-        const label datasetNo,
-        const std::string& datasetName
-    );
-
-
-    //- Convenience method use to convert the readers from VTK 5
-    // multiblock API to the current composite data infrastructure
-    vtkDataSet* GetDataSetFromBlock
-    (
-        vtkMultiBlockDataSet* output,
-        const partInfo& selector,
-        const label datasetNo
-    );
-
-    //- Convenience method use to convert the readers from VTK 5
-    // multiblock API to the current composite data infrastructure
-    // ununsed at the moment
-    label GetNumberOfDataSets
-    (
-        vtkMultiBlockDataSet* output,
-        const partInfo& selector
-    );
-
-
-    //- Retrieve the current selections as a wordHashSet
-    wordHashSet getSelected
-    (
-        vtkDataArraySelection* select
-    );
-
-
-    //- Retrieve a sub-list of the current selections
-    wordHashSet getSelected
-    (
-        vtkDataArraySelection*,
-        const partInfo&
-    );
-
-
-    //- Retrieve the current selections
-    stringList getSelectedArrayEntries(vtkDataArraySelection*);
-
-    //- Retrieve a sub-list of the current selections
-    stringList getSelectedArrayEntries
-    (
-        vtkDataArraySelection* select,
-        const partInfo& selector
-    );
-
-
-    //- Set selection(s)
-    void setSelectedArrayEntries
-    (
-        vtkDataArraySelection*,
-        const stringList&
-    );
-
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace vtkPV3
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/Make/options b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/Make/options
index d0cdd781d764d8d978df42aa7bd999d0ce185106..9f63402d646402607cc5a547da62abbdbfabfd68 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/Make/options
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/Make/options
@@ -3,6 +3,8 @@ EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
     -I$(ParaView_INCLUDE_DIR) \
     -I$(ParaView_INCLUDE_DIR)/vtkkwiml \
     -I../../vtkPVReaders/lnInclude \
@@ -10,7 +12,7 @@ EXE_INC = \
 
 LIB_LIBS = \
     -ldynamicMesh \
-    -ldynamicMesh \
+    -lconversion \
     -lgenericPatchFields \
     -llagrangian \
     -L$(FOAM_LIBBIN) -lvtkPVReaders \
diff --git a/applications/utilities/postProcessing/noise/createFields.H b/applications/utilities/postProcessing/noise/createFields.H
deleted file mode 100644
index 53598de047b8b65eb068794ac01794a6959c1425..0000000000000000000000000000000000000000
--- a/applications/utilities/postProcessing/noise/createFields.H
+++ /dev/null
@@ -1,34 +0,0 @@
-    word dictName("noiseDict");
-    if (args.optionFound("dict"))
-    {
-        dictName = args["dict"];
-    }
-
-    IOdictionary dict
-    (
-        IOobject
-        (
-            dictName,
-            runTime.system(),
-            runTime,
-            IOobject::MUST_READ
-        )
-    );
-
-    // reference pressure
-    scalar pRef = dict.lookupOrDefault("pRef", 0.0);
-
-    // number of samples in sampling window
-    label N = dict.lookupOrDefault("N", 65536);
-
-    // number of sampling windows
-    label nw = dict.lookupOrDefault("nw", 100);
-
-    // lower frequency of frequency band
-    scalar f1 = dict.lookupOrDefault("f1", 25.0);
-
-    // upper frequency of frequency band
-    scalar fU = dict.lookupOrDefault("fU", 10000.0);
-
-    // graph format
-    word graphFormat = dict.lookupOrDefault<word>("graphFormat", "raw");
diff --git a/applications/utilities/postProcessing/noise/noise.C b/applications/utilities/postProcessing/noise/noise.C
index ac294d4dc1a72c313faf14250c31c653f1f88321..88ef922589d5f80f51bfd1592c753af392b150b0 100644
--- a/applications/utilities/postProcessing/noise/noise.C
+++ b/applications/utilities/postProcessing/noise/noise.C
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
     (
         IOobject
         (
-            dictName,
+            dictName.expand(),
             runTime,
             IOobject::MUST_READ
         )
diff --git a/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C b/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C
index ffeef922f4202fac7fe19d78496113e3c29e82c2..851f018c8b58b28b49275b1d99a3f76df9f98d8f 100644
--- a/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C
+++ b/applications/utilities/preProcessing/applyBoundaryLayer/applyBoundaryLayer.C
@@ -57,57 +57,37 @@ static const scalar Cmu(0.09);
 static const scalar kappa(0.41);
 
 
-Foam::tmp<Foam::volVectorField> createSimplifiedU(const volVectorField& U)
-{
-    tmp<volVectorField> tU
-    (
-        new volVectorField
-        (
-            IOobject
-            (
-                "Udash",
-                U.mesh().time().timeName(),
-                U.mesh(),
-                IOobject::NO_READ
-            ),
-            U.mesh(),
-            dimensionedVector("0", dimVelocity, vector::zero),
-            zeroGradientFvPatchField<vector>::typeName
-        )
-    );
-
-    // Assign the internal value to the original field
-    tU.ref() = U;
-
-    return tU;
-}
-
-
-void correctProcessorPatches(volScalarField& vf)
+template<class Type>
+void correctProcessorPatches
+(
+    GeometricField<Type, fvPatchField, volMesh>& vf
+)
 {
     if (!Pstream::parRun())
     {
         return;
     }
 
+    typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
+
     // Not possible to use correctBoundaryConditions on fields as they may
     // use local info as opposed to the constraint values employed here,
     // but still need to update processor patches
-    volScalarField::Boundary& bf = vf.boundaryFieldRef();
+    typename volFieldType::Boundary& bf = vf.boundaryFieldRef();
 
-    forAll(bf, patchI)
+    forAll(bf, patchi)
     {
-        if (isA<processorFvPatchField<scalar>>(bf[patchI]))
+        if (isA<processorFvPatchField<Type>>(bf[patchi]))
         {
-            bf[patchI].initEvaluate();
+            bf[patchi].initEvaluate();
         }
     }
 
-    forAll(bf, patchI)
+    forAll(bf, patchi)
     {
-        if (isA<processorFvPatchField<scalar>>(bf[patchI]))
+        if (isA<processorFvPatchField<Type>>(bf[patchi]))
         {
-            bf[patchI].evaluate();
+            bf[patchi].evaluate();
         }
     }
 }
@@ -142,7 +122,7 @@ void blendField
         // - operation may use inconsistent fields wrt these local
         //   manipulations
         //fld.correctBoundaryConditions();
-        correctProcessorPatches(fld);
+        correctProcessorPatches<scalar>(fld);
 
         Info<< "Writing " << fieldName << nl << endl;
         fld.write();
@@ -181,7 +161,7 @@ void calcOmegaField
         // - operation may use inconsistent fields wrt these local
         //   manipulations
         // omega.correctBoundaryConditions();
-        correctProcessorPatches(omega);
+        correctProcessorPatches<scalar>(omega);
 
         Info<< "Writing omega\n" << endl;
         omega.write();
@@ -215,7 +195,7 @@ void setField
         // - operation may use inconsistent fields wrt these local
         //   manipulations
         // fld.correctBoundaryConditions();
-        correctProcessorPatches(fld);
+        correctProcessorPatches<scalar>(fld);
 
         Info<< "Writing " << fieldName << nl << endl;
         fld.write();
@@ -267,7 +247,8 @@ tmp<volScalarField> calcNut
         //       case for the Templated Turbulence models.  The call to correct
         //       below will evolve the turbulence model equations and update nut,
         //       whereas only nut update is required.  Need to revisit.
-        turbulence->correct();
+//        turbulence->correct();
+        turbulence->correctEnergyTransport();
 
         return tmp<volScalarField>(new volScalarField(turbulence->nut()));
     }
@@ -290,8 +271,8 @@ tmp<volScalarField> calcNut
         // Note: in previous versions of the code, nut was initialised on
         //       construction of the turbulence model.  This is no longer the
         //       case for the Templated Turbulence models.  The call to correct
-        //       below will evolve the turbulence model equations and update nut,
-        //       whereas only nut update is required.  Need to revisit.
+        //       below will evolve the turbulence model equations and update
+        //       nut, whereas only nut update is required.  Need to revisit.
         turbulence->correct();
 
         return tmp<volScalarField>(new volScalarField(turbulence->nut()));
@@ -347,38 +328,32 @@ int main(int argc, char *argv[])
 
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-    // Create a copy of the U field where BCs are simplified to  zeroGradient
-    // to enable boundary condition update without requiring other fields,
-    // e.g. phi.  We can then call correctBoundaryConditions on this field to
-    // enable appropriate behaviour for processor patches.
-    volVectorField Udash(createSimplifiedU(U));
-
     // Modify velocity by applying a 1/7th power law boundary-layer
     // u/U0 = (y/ybl)^(1/7)
     // assumes U0 is the same as the current cell velocity
     Info<< "Setting boundary layer velocity" << nl << endl;
     scalar yblv = ybl.value();
-    forAll(Udash, celli)
+    forAll(U, celli)
     {
         if (y[celli] <= yblv)
         {
             mask[celli] = 1;
-            Udash[celli] *= ::pow(y[celli]/yblv, (1.0/7.0));
+            U[celli] *= ::pow(y[celli]/yblv, (1.0/7.0));
         }
     }
     mask.correctBoundaryConditions();
-    Udash.correctBoundaryConditions();
+    correctProcessorPatches<vector>(U);
 
     // Retrieve nut from turbulence model
-    volScalarField nut(calcNut(mesh, Udash));
+    volScalarField nut(calcNut(mesh, U));
 
     // Blend nut using boundary layer profile
-    volScalarField S("S", mag(dev(symm(fvc::grad(Udash)))));
+    volScalarField S("S", mag(dev(symm(fvc::grad(U)))));
     nut = (1 - mask)*nut + mask*sqr(kappa*min(y, ybl))*::sqrt(2)*S;
 
     // Do not correct BC - wall functions will 'undo' manipulation above
     // by using nut from turbulence model
-    correctProcessorPatches(nut);
+    correctProcessorPatches<scalar>(nut);
     nut.write();
 
     // Boundary layer turbulence kinetic energy
@@ -395,10 +370,8 @@ int main(int argc, char *argv[])
     calcOmegaField(mesh, mask, kBL, epsilonBL);
     setField(mesh, "nuTilda", nut);
 
-
-    // Copy internal field Udash into U before writing
+    // Write the updated U field
     Info<< "Writing U\n" << endl;
-    U = Udash;
     U.write();
 
     Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
diff --git a/applications/utilities/surface/surfaceAdd/surfaceAdd.C b/applications/utilities/surface/surfaceAdd/surfaceAdd.C
index 615f14e61b64be27aab9cdafb8a5ed7a43b9b8af..5caa3e070316edabcc7f8747fe1277673d9a7ea0 100644
--- a/applications/utilities/surface/surfaceAdd/surfaceAdd.C
+++ b/applications/utilities/surface/surfaceAdd/surfaceAdd.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -178,21 +178,82 @@ int main(int argc, char *argv[])
 
         label trianglei = 0;
 
-        // Copy triangles1 into trianglesAll
-        forAll(surface1, facei)
+
+
+        // Determine map for both regions
+        label nNewPatches = 0;
+        labelList patch1Map(surface1.patches().size());
+        labelList patch2Map(surface2.patches().size());
+
+        if (mergeRegions)
         {
-            facesAll[trianglei++] = surface1[facei];
-        }
-        label nRegions1 = surface1.patches().size();
+            HashTable<label> nameToPatch;
 
+            forAll(surface1.patches(), i)
+            {
+                const word& name = surface1.patches()[i].name();
+                HashTable<label>::iterator iter = nameToPatch.find(name);
+
+                label combinedi;
+                if (iter == nameToPatch.end())
+                {
+                    combinedi = nameToPatch.size();
+                    nameToPatch.insert(name, combinedi);
+                }
+                else
+                {
+                    combinedi = iter();
+                }
+                patch1Map[i] = combinedi;
+            }
+
+            // Determine map for surface2 regions
+
+            forAll(surface2.patches(), i)
+            {
+                const word& name = surface2.patches()[i].name();
+                HashTable<label>::iterator iter = nameToPatch.find(name);
+
+                label combinedi;
+                if (iter == nameToPatch.end())
+                {
+                    combinedi = nameToPatch.size();
+                    nameToPatch.insert(name, combinedi);
+                }
+                else
+                {
+                    combinedi = iter();
+                }
+                patch2Map[i] = combinedi;
+            }
 
-        if (!mergeRegions)
+            nNewPatches = nameToPatch.size();
+        }
+        else
         {
-            Info<< "Surface " << inFileName1 << " has " << nRegions1
+            Info<< "Surface " << inFileName1
+                << " has " << surface1.patches().size()
                 << " regions"
                 << nl
                 << "All region numbers in " << inFileName2 << " will be offset"
                 << " by this amount" << nl << endl;
+
+            patch1Map = identity(surface1.patches().size());
+            patch2Map = identity(surface2.patches().size()) + patch1Map.size();
+
+            nNewPatches = surface1.patches().size()+surface2.patches().size();
+        }
+
+
+
+        // Copy triangles1 into trianglesAll
+        forAll(surface1, facei)
+        {
+            const labelledTri& tri = surface1[facei];
+            labelledTri& destTri = facesAll[trianglei++];
+
+            destTri.triFace::operator=(tri);
+            destTri.region() = patch1Map[tri.region()];
         }
 
         // Add (renumbered) surface2 triangles
@@ -204,63 +265,20 @@ int main(int argc, char *argv[])
             destTri[0] = tri[0] + points1.size();
             destTri[1] = tri[1] + points1.size();
             destTri[2] = tri[2] + points1.size();
-            if (mergeRegions)
-            {
-                destTri.region() = tri.region();
-            }
-            else
-            {
-                destTri.region() = tri.region() + nRegions1;
-            }
+            destTri.region() = patch2Map[tri.region()];
         }
 
-        label nRegions2 = surface2.patches().size();
 
-        geometricSurfacePatchList newPatches;
-
-        if (mergeRegions)
+        geometricSurfacePatchList newPatches(nNewPatches);
+        forAll(surface1.patches(), patchi)
         {
-            // Overwrite
-            newPatches.setSize(max(nRegions1, nRegions2));
-
-            forAll(surface1.patches(), patchi)
-            {
-                newPatches[patchi] = surface1.patches()[patchi];
-            }
-            forAll(surface2.patches(), patchi)
-            {
-                newPatches[patchi] = surface2.patches()[patchi];
-            }
+            newPatches[patch1Map[patchi]] = surface1.patches()[patchi];
         }
-        else
+        forAll(surface2.patches(), patchi)
         {
-            Info<< "Regions from " << inFileName2 << " have been renumbered:"
-                << nl
-                << "    old\tnew" << nl;
-
-            for (label regionI = 0; regionI < nRegions2; regionI++)
-            {
-                Info<< "    " << regionI << '\t' << regionI+nRegions1
-                    << nl;
-            }
-            Info<< nl;
-
-            newPatches.setSize(nRegions1 + nRegions2);
-
-            label newPatchi = 0;
-
-            forAll(surface1.patches(), patchi)
-            {
-                newPatches[newPatchi++] = surface1.patches()[patchi];
-            }
-
-            forAll(surface2.patches(), patchi)
-            {
-                newPatches[newPatchi++] = surface2.patches()[patchi];
-            }
+            newPatches[patch2Map[patchi]] = surface2.patches()[patchi];
         }
 
-
         Info<< "New patches:" << nl;
         forAll(newPatches, patchi)
         {
@@ -284,8 +302,8 @@ int main(int argc, char *argv[])
 
     Info<< "Writing : " << outFileName << endl;
 
-    // No need to 'group' while writing since all in correct order anyway.
-    combinedSurf.write(outFileName);
+    // If merging regions also sort
+    combinedSurf.write(outFileName, mergeRegions);
 
     Info<< "End\n" << endl;
 
diff --git a/applications/utilities/surface/surfaceBooleanFeatures/Allwmake b/applications/utilities/surface/surfaceBooleanFeatures/Allwmake
index 98d3d2035c07f8b2ae3ffe6dd6e4169edc4a4a4c..660a2e59b52039d526cc498cfab408d32a4cc953 100755
--- a/applications/utilities/surface/surfaceBooleanFeatures/Allwmake
+++ b/applications/utilities/surface/surfaceBooleanFeatures/Allwmake
@@ -4,8 +4,8 @@ set -x
 
 unset COMPILE_FLAGS LINK_FLAGS
 
-if [ -d "$CGAL_ARCH_PATH/include/CGAL" ] || \
-   [ "${CGAL_ARCH_PATH##*-}" = system -a -d /usr/include/CGAL ]
+if [ -f "$CGAL_ARCH_PATH/include/CGAL/version.h" ] || \
+   [ "${CGAL_ARCH_PATH##*-}" = system -a -f /usr/include/CGAL/version.h ]
 then
     wmake PolyhedronReader
     export COMPILE_FLAGS='-IPolyhedronReader'
diff --git a/applications/utilities/surface/surfaceBooleanFeatures/PolyhedronReader/Make/options b/applications/utilities/surface/surfaceBooleanFeatures/PolyhedronReader/Make/options
index 6603adda0ff4df4762f57ce04094904a0f32664b..424f89a8aba98e7eae709757dcc68d0a3471ec1e 100644
--- a/applications/utilities/surface/surfaceBooleanFeatures/PolyhedronReader/Make/options
+++ b/applications/utilities/surface/surfaceBooleanFeatures/PolyhedronReader/Make/options
@@ -1,7 +1,6 @@
 EXE_NDEBUG = -DNDEBUG
 /* EXE_NDEBUG = -g -O0 -DFULLDEBUG */
 
-
 c++CGALWARN = -Wno-old-style-cast
 
 /*-- Define CGAL_INEXACT to use inexact CGAL constructions */
@@ -21,5 +20,5 @@ EXE_INC = \
     -I/usr/include/Qt
 
 LIB_LIBS = \
-    -L${CGAL_ARCH_PATH}/lib \
+    -L$(CGAL_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
     -ltriSurface
diff --git a/applications/utilities/surface/surfaceCheck/Make/options b/applications/utilities/surface/surfaceCheck/Make/options
index ef204ab685abd76efe285c169f1597226b475441..28fb9f2ccebe4e9e245cb1c66ea6e677d567751c 100644
--- a/applications/utilities/surface/surfaceCheck/Make/options
+++ b/applications/utilities/surface/surfaceCheck/Make/options
@@ -7,5 +7,4 @@ EXE_INC = \
 EXE_LIBS = \
     -lsampling \
     -ltriSurface \
-    -lsurfMesh \
     -lmeshTools
diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C
index e1aca6c42d99699ee5358be0ffd08bf0e90fbd7c..dcbf38b8708f2a5f0e2bfbba09ffe56fff32a94f 100644
--- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C
+++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C
@@ -228,8 +228,11 @@ void writeZoning
     (
         surfFilePath,
         surfFileNameBase,
-        surf.points(),
-        faces,
+        meshedSurfRef
+        (
+            surf.points(),
+            faces
+        ),
         fieldName,
         scalarFaceZone,
         false               // face based data
@@ -795,6 +798,12 @@ int main(int argc, char *argv[])
             Info<< "Splitting surface into parts ..." << endl << endl;
 
             writeZoning(surf, faceZone, "zone", surfFilePath, surfFileNameBase);
+
+            if (numZones > outputThreshold)
+            {
+                Info<< "Limiting number of files to " << outputThreshold
+                    << endl;
+            }
             writeParts
             (
                 surf,
@@ -849,6 +858,12 @@ int main(int argc, char *argv[])
                 surfFilePath,
                 surfFileNameBase
             );
+
+            if (numNormalZones > outputThreshold)
+            {
+                Info<< "Limiting number of files to " << outputThreshold
+                    << endl;
+            }
             writeParts
             (
                 surf,
@@ -885,28 +900,78 @@ int main(int argc, char *argv[])
         forAll(surf.edges(), edgei)
         {
             const edge& e = surf.edges()[edgei];
+            const point& start = surf.points()[surf.meshPoints()[e[0]]];
+            const point& end = surf.points()[surf.meshPoints()[e[1]]];
 
-            pointIndexHit hitInfo
-            (
-                tree.findLine
-                (
-                    surf.points()[surf.meshPoints()[e[0]]],
-                    surf.points()[surf.meshPoints()[e[1]]],
-                    treeDataTriSurface::findSelfIntersectOp
-                    (
-                        tree,
-                        edgei
-                    )
-                )
-            );
+            // Exclude hits of connected triangles
+            treeDataTriSurface::findSelfIntersectOp exclOp(tree, edgei);
+
+            pointIndexHit hitInfo(tree.findLineAny(start, end, exclOp));
 
-            if (hitInfo.hit() && intStreamPtr.valid())
+            if (hitInfo.hit())
             {
-                intStreamPtr().write(hitInfo.hitPoint());
                 nInt++;
+
+                if (intStreamPtr.valid())
+                {
+                    intStreamPtr().write(hitInfo.hitPoint());
+                }
+
+                // Try and find from other side.
+                pointIndexHit hitInfo2(tree.findLineAny(end, start, exclOp));
+
+                if (hitInfo2.hit() && hitInfo.index() != hitInfo2.index())
+                {
+                    nInt++;
+
+                    if (intStreamPtr.valid())
+                    {
+                        intStreamPtr().write(hitInfo2.hitPoint());
+                    }
+                }
             }
         }
 
+        //// Check very near triangles
+        //{
+        //    const pointField& localPoints = surf.localPoints();
+        //
+        //    const boundBox bb(localPoints);
+        //    scalar smallDim = 1e-6 * bb.mag();
+        //    scalar smallDimSqr = Foam::sqr(smallDim);
+        //
+        //    const pointField& faceCentres = surf.faceCentres();
+        //    forAll(faceCentres, faceI)
+        //    {
+        //        const point& fc = faceCentres[faceI];
+        //        pointIndexHit hitInfo
+        //        (
+        //            tree.findNearest
+        //            (
+        //                fc,
+        //                smallDimSqr,
+        //                findSelfNearOp(tree, faceI)
+        //            )
+        //        );
+        //
+        //        if (hitInfo.hit() && intStreamPtr.valid())
+        //        {
+        //            intStreamPtr().write(hitInfo.hitPoint());
+        //
+        //            label nearFaceI = hitInfo.index();
+        //            triPointRef nearTri(surf[nearFaceI].tri(surf.points()));
+        //            triStreamPtr().write
+        //            (
+        //                surf[faceI].tri(surf.points()),
+        //                false
+        //            );
+        //            triStreamPtr().write(nearTri, false);
+        //            nInt++;
+        //        }
+        //    }
+        //}
+
+
         if (nInt == 0)
         {
             Info<< "Surface is not self-intersecting" << endl;
diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C
index 3b0a9bdebde742f08251590f6be6947b145f0510..86bfe9a22e7c0b4df8f6dd05ed965be854d73454 100644
--- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C
+++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -1643,8 +1643,11 @@ int main(int argc, char *argv[])
                 (
                     runTime.constantPath()/"triSurface",// outputDir
                     sFeatFileName,                      // surfaceName
-                    surf.points(),
-                    faces,
+                    meshedSurfRef
+                    (
+                        surf.points(),
+                        faces
+                    ),
                     "internalCloseness",                // fieldName
                     internalCloseness,
                     false,                              // isNodeValues
@@ -1655,8 +1658,11 @@ int main(int argc, char *argv[])
                 (
                     runTime.constantPath()/"triSurface",// outputDir
                     sFeatFileName,                      // surfaceName
-                    surf.points(),
-                    faces,
+                    meshedSurfRef
+                    (
+                        surf.points(),
+                        faces
+                    ),
                     "externalCloseness",                // fieldName
                     externalCloseness,
                     false,                              // isNodeValues
@@ -1691,8 +1697,11 @@ int main(int argc, char *argv[])
                 (
                     runTime.constantPath()/"triSurface",// outputDir
                     sFeatFileName,                      // surfaceName
-                    surf.points(),
-                    faces,
+                    meshedSurfRef
+                    (
+                        surf.points(),
+                        faces
+                    ),
                     "curvature",                        // fieldName
                     k,
                     true,                               // isNodeValues
@@ -1769,8 +1778,11 @@ int main(int argc, char *argv[])
                 (
                     runTime.constantPath()/"triSurface",// outputDir
                     sFeatFileName,                      // surfaceName
-                    surf.points(),
-                    faces,
+                    meshedSurfRef
+                    (
+                        surf.points(),
+                        faces
+                    ),
                     "featureProximity",                 // fieldName
                     featureProximity,
                     false,                              // isNodeValues
diff --git a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
index e0dcfcf0cc334cf5d1bca1510bfc9d02ce2eaf3c..bc7d50f495e3a4b3fe807d7946e84c4b9bc85615 100644
--- a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
+++ b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
@@ -41,6 +41,9 @@ Usage
       - \par -orient
         Check face orientation on the input surface
 
+      - \par -testModify
+        Test modification mechanism
+
       - \par -scale \<scale\>
         Specify a scaling factor for writing the files
 
@@ -65,6 +68,7 @@ Note
 #include "PackedBoolList.H"
 
 #include "MeshedSurfaces.H"
+#include "ModifiableMeshedSurface.H"
 #include "UnsortedMeshedSurfaces.H"
 
 #include "IStringStream.H"
@@ -93,6 +97,13 @@ int main(int argc, char *argv[])
         "orient",
         "check surface orientation"
     );
+
+    argList::addBoolOption
+    (
+        "testModify",
+        "Test modification mechanism (MeshedSurface)"
+    );
+
     argList::addBoolOption
     (
         "surfMesh",
@@ -161,7 +172,8 @@ int main(int argc, char *argv[])
 
         Info<< "Read surface:" << endl;
         surf.writeStats(Info);
-        Info<< endl;
+        Info<< "Area         : " << sum(surf.magSf()) << nl
+            << endl;
 
         // check: output to ostream, construct from istream
         {
@@ -205,7 +217,8 @@ int main(int argc, char *argv[])
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
             surf.writeStats(Info);
-            Info<< endl;
+            Info<< "Area         : " << sum(surf.magSf()) << nl
+                << endl;
         }
 
         if (optStdout)
@@ -224,7 +237,8 @@ int main(int argc, char *argv[])
 
         Info<< "Read surface:" << endl;
         surf.writeStats(Info);
-        Info<< endl;
+        Info<< "Area         : " << sum(surf.magSf()) << nl
+            << endl;
 
         // check: output to ostream, construct from istream
         {
@@ -268,7 +282,8 @@ int main(int argc, char *argv[])
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
             surf.writeStats(Info);
-            Info<< endl;
+            Info<< "Area         : " << sum(surf.magSf()) << nl
+                << endl;
         }
 
         if (optStdout)
@@ -286,7 +301,8 @@ int main(int argc, char *argv[])
 
         Info<< "Read surface:" << endl;
         surf.writeStats(Info);
-        Info<< endl;
+        Info<< "Area         : " << sum(surf.magSf()) << nl
+            << endl;
 
         // check: output to ostream, construct from istream
         {
@@ -330,7 +346,8 @@ int main(int argc, char *argv[])
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
             surf.writeStats(Info);
-            Info<< endl;
+            Info<< "Area         : " << sum(surf.magSf()) << nl
+                << endl;
         }
 
         if (optStdout)
@@ -348,7 +365,8 @@ int main(int argc, char *argv[])
 
         Info<< "Read surface:" << endl;
         surf.writeStats(Info);
-        Info<< endl;
+        Info<< "Area         : " << sum(surf.magSf()) << nl
+            << endl;
 
         // check: output to ostream, construct from istream
         {
@@ -382,6 +400,34 @@ int main(int argc, char *argv[])
             Info<< endl;
         }
 
+        if (args.optionFound("testModify"))
+        {
+            Info<< "Use ModifiableMeshedSurface to shift (1, 0, 0)" << endl;
+            Info<< "original" << nl;
+            surf.writeStats(Info);
+            Info<< endl;
+
+            ModifiableMeshedSurface<face> tsurf(surf.xfer());
+            // ModifiableMeshedSurface<face> tsurf;
+            // tsurf.reset(surf.xfer());
+
+            Info<< "in-progress" << nl;
+            surf.writeStats(Info);
+            Info<< endl;
+
+            tsurf.storedPoints() += vector(1, 0, 0);
+
+            surf.transfer(tsurf);
+
+            Info<< "updated" << nl;
+            surf.writeStats(Info);
+            Info<< endl;
+
+            Info<< "modifier" << nl;
+            tsurf.writeStats(Info);
+            Info<< endl;
+        }
+
         Info<< "writing " << exportName;
         if (scaleFactor <= 0)
         {
@@ -392,7 +438,8 @@ int main(int argc, char *argv[])
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
             surf.writeStats(Info);
-            Info<< endl;
+            Info<< "Area         : " << sum(surf.magSf()) << nl
+                << endl;
         }
 
         if (optStdout)
diff --git a/bin/tools/foamConfigurePaths b/bin/tools/foamConfigurePaths
index 6d77141d90ec11637763638f276d298f45330d73..a85cff83f8b3f68d20dd7ea2c4e7995fdcd326a9 100755
--- a/bin/tools/foamConfigurePaths
+++ b/bin/tools/foamConfigurePaths
@@ -4,7 +4,7 @@
 # \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
 #  \\    /   O peration     |
 #   \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-#    \\/     M anipulation  |
+#    \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
 #     This file is part of OpenFOAM.
@@ -26,7 +26,7 @@
 #     foamConfigurePaths
 #
 # Description
-#     hardcode installation directory
+#     Adjust hardcoded installation paths and versions
 #
 #------------------------------------------------------------------------------
 usage() {
@@ -35,53 +35,103 @@ usage() {
     cat<<USAGE
 
 usage: ${0##*/}
-  --foamInstall dir         specify installation directory (e.g. /opt)
-  --projectName name        specify project name (e.g. openfoam220)
-  --projectVersion ver      specify project version (e.g. 2.2.0)
-  --archOption arch         specify architecture option (only 32 or 64 applicable)
-  --paraviewInstall dir     specify ParaView_DIR (e.g. /opt/paraviewopenfoam3120)
-  --paraviewVersion ver     specify ParaView_VERSION (e.g. 3.12.0)
-  --scotchArchPath dir      specify SCOTCH_ARCH_PATH (e.g. /opt/OpenFOAM-scotch-6.0.0/)
-  --scotchVersion ver       specify SCOTCH_VERSION (e.g. 6.0.0)
+  -foamInstall dir        specify installation directory (e.g. /opt)
+  -projectName name       specify project name (e.g. openfoam220)
+  -projectVersion ver     specify project version (e.g. 2.2.0)
+  -archOption 32|64       specify architecture option
+  -label 32|64            specify label size
+  -system name            specify 'system' compiler to be used
+  -thirdParty name        specify 'ThirdParty' compiler to be used
 
-* hardcode paths to installation
+  -boost ver              specify boost_version
+  -boostArchPath dir      specify BOOST_ARCH_PATH
+  -cgal ver               specify cgal_version
+  -cgalArchPath dir       specify CGAL_ARCH_PATH
+  -clang ver              specify clang_version for ThirdParty Clang
+  -cmake ver              specify cmake_version
+  -fftw ver               specify fffw_version
+  -fftwArchPath dir       specify FFTW_ARCH_PATH
+  -metis ver              specify METIS_VERSION
+  -metisArchPath dir      specify METIS_ARCH_PATH
+  -paraview ver           specify ParaView_VERSION (e.g. 3.12.0)
+  -paraviewInstall dir    specify ParaView_DIR (e.g. /opt/paraviewopenfoam3120)
+  -scotch ver             specify SCOTCH_VERSION (e.g. 6.0.0)
+  -scotchArchPath dir     specify SCOTCH_ARCH_PATH (e.g. /opt/OpenFOAM-scotch-6.0.0/)
+
+* Adjust hardcoded installation paths and versions
 
 USAGE
     exit 1
 }
 
+# Report error and exit
+die()
+{
+    exec 1>&2
+    echo
+    echo "Error: see '${0##*/} -help' for usage"
+    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
+    echo
+    exit 1
+}
+
 
 # Function to do replacement on file. Checks if any replacement has been done.
 # _inlineSed <file> <regexp> <replacement> <msg>
 _inlineSed()
 {
-    file="$1"
+    local file="$1"
+    local regexp="$2"
+    local replacement="$3"
+    local msg="$4"
+    local cmd='/^[^#]/s@'"$regexp"'@'"$replacement"'@'
 
     [ -f "$file" ] || {
         echo "Missing file: $file"
-        exit 1
+        exit 2 # Fatal
     }
 
-    regexp="$2"
-    replacement="$3"
-    msg="$4"
+    grep -q "$regexp" "$file" && sed -i -e "$cmd" "$file" || { \
+        echo "Failed: $msg in $file"
+        return 1
+    }
 
-    cmd='/^[^#]/s@'"$regexp"'@'"$replacement"'@'
+    echo "Okay: $msg in $file"
+    return 0
+}
 
-    grep -q "$regexp" "$file" && sed -i -e "$cmd" "$file" || \
-        (echo "Failed: $msg in $file" && exit 1)
 
-    echo "Okay: $msg in $file"
+# Standard <key> <val> type of replacements.
+# replace <file> <key1> <val1> .. <keyN> <valN>
+# looks for KEYWORD=.*
+replace()
+{
+    local file="$1"
+    shift
 
-    return 0
+    local key
+    local val
+
+    while [ "$#" -ge 2 ]
+    do
+        key=$1
+        val=$2
+        shift 2
+
+        _inlineSed \
+            $file \
+            "$key=.*" \
+            "$key=$val" \
+            "Replacing $key setting by '$val'"
+    done
 }
 
 
 [ -f etc/bashrc ] || usage "Please run from top-level directory of installation"
 
-unset foamInstDir projectName projectVersion archOption
-unset paraviewInstall scotchArchPath
+#------------------------------------------------------------------------------
 
+unset adjusted
 # Parse options
 while [ "$#" -gt 0 ]
 do
@@ -89,131 +139,213 @@ do
     -h | -help | --help)
         usage
         ;;
+
     -foamInstall | --foamInstall)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        foamInstDir="$2"
         # Replace FOAM_INST_DIR=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        foamInstDir="$2"
         _inlineSed \
             etc/bashrc \
             '\(.*BASH_SOURCE.*\)' \
-            '#\1' \
+            '##\1' \
             "Removing default FOAM_INST_DIR setting"
         _inlineSed \
             etc/bashrc \
-            '^export FOAM_INST_DIR=.*' \
-            'export FOAM_INST_DIR='"$foamInstDir" \
+            '^ *FOAM_INST_DIR=.*' \
+            'FOAM_INST_DIR='"$foamInstDir" \
             "Setting FOAM_INST_DIR to '$foamInstDir'"
-        shift 2
+
+        adjusted=true
+        shift
         ;;
+
    -projectName | --projectName)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+        # Replace WM_PROJECT_DIR=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
         projectName="$2"
-        # replace WM_PROJECT_DIR=...
         _inlineSed \
             etc/bashrc \
             'WM_PROJECT_DIR=.*' \
             'WM_PROJECT_DIR=$WM_PROJECT_INST_DIR/'"$projectName" \
             "Replacing WM_PROJECT_DIR setting by $projectName"
-        shift 2
+
+        adjusted=true
+        shift
         ;;
-   --projectVersion)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        projectVersion="$2"
-        # replace WM_PROJECT_VERSION=...
-        echo "Replacing WM_PROJECT_VERSION setting by $projectVersion"
-        _inlineSed \
-            etc/bashrc \
-            'WM_PROJECT_VERSION=.*' \
-            'WM_PROJECT_VERSION='"$projectVersion" \
-            "Replacing WM_PROJECT_VERSION setting by $projectVersion"
 
-        shift 2
+   -projectVersion | --projectVersion)
+        # Replace WM_PROJECT_VERSION=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/bashrc  WM_PROJECT_VERSION "$2"
+        adjusted=true
+        shift
         ;;
+
     -archOption | --archOption)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+        # Replace WM_ARCH_OPTION=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
         archOption="$2"
-        current_archOption=`grep WM_ARCH_OPTION= etc/bashrc | sed "s/export WM_ARCH_OPTION=//"`
-        if [ "$archOption" != "$current_archOption" ]
+        current="$(sed -ne '/^[^#]/s/^.* WM_ARCH_OPTION=//p' etc/bashrc)"
+        if [ "$archOption" = "$current" ]
         then
-            # replace WM_ARCH_OPTION=...
-            _inlineSed \
-                etc/bashrc \
-                'WM_ARCH_OPTION=.*' \
-                'WM_ARCH_OPTION='"$archOption" \
-                "Replacing WM_ARCH_OPTION setting by '$archOption'"
-        else
             echo "WM_ARCH_OPTION already set to $archOption"
+        else
+            replace etc/bashrc  WM_ARCH_OPTION "$2"
         fi
-        shift 2
+        adjusted=true
+        shift
         ;;
+
+    -label)
+        # Replace WM_LABEL_SIZE=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/bashrc  WM_LABEL_SIZE "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -system)
+        # Replace WM_COMPILER_TYPE=... and WM_COMPILER=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/bashrc  WM_COMPILER_TYPE system  WM_COMPILER "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -third[Pp]arty)
+        # Replace WM_COMPILER_TYPE=... and WM_COMPILER=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/bashrc  WM_COMPILER_TYPE ThirdParty  WM_COMPILER "$2"
+        adjusted=true
+        shift
+        ;;
+
+
+    -boost)
+        # Replace boost_version=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/CGAL  boost_version "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -boostArchPath)
+        # Replace BOOST_ARCH_PATH=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/CGAL  BOOST_ARCH_PATH "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -cgal)
+        # Replace cgal_version=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/CGAL  cgal_version "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -cgalArchPath)
+        # Replace CGAL_ARCH_PATH=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/CGAL  CGAL_ARCH_PATH "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -fftw)
+        # Replace fftw_version=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/FFTW  fftw_version "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -fftwArchPath)
+        # Replace FFTW_ARCH_PATH=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/FFTW  FFTW_ARCH_PATH "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -clang)
+        # Replace clang_version=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/compiler  clang_version "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -cmake)
+        # Replace cmake_version=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/paraview  cmake_version "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -paraview | -paraviewVersion | --paraviewVersion)
+        # Replace ParaView_VERSION=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/paraview  ParaView_VERSION "$2"
+        adjusted=true
+        shift
+        ;;
+
     -paraviewInstall | --paraviewInstall)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        paraviewInstall="$2"
-        # replace ParaView_DIR=...
-        _inlineSed \
-            etc/config.sh/paraview \
-            'ParaView_DIR=.*' \
-            'ParaView_DIR='"$paraviewInstall" \
-            "Replacing ParaView_DIR setting by '$paraviewInstall'"
-        shift 2
+        # Replace ParaView_DIR=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/paraview  ParaView_DIR "$2"
+        adjusted=true
+        shift
         ;;
-    -paraviewVersion | --paraviewVersion)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        paraviewVersion="$2"
-        # replace ParaView_VERSION=...
-        _inlineSed \
-            etc/config.sh/paraview \
-            'ParaView_VERSION=.*' \
-            'ParaView_VERSION='"$paraviewVersion" \
-            "Replacing ParaView_VERSION setting by '$paraviewVersion'"
-        shift 2
+
+    -metis)
+        # Replace METIS_VERSION=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/metis  METIS_VERSION "$2"
+        adjusted=true
+        shift
         ;;
-    -scotchVersion | --scotchVersion)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        scotchVersion="$2"
-        _inlineSed \
-            etc/config.sh/scotch \
-            'SCOTCH_VERSION=.*' \
-            'SCOTCH_VERSION='"$scotchVersion" \
-            "Replacing SCOTCH_VERSION setting by '$scotchVersion'"
-        shift 2
+
+    -metisArchPath)
+        # Replace METIS_ARCH_PATH=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/metis  METIS_ARCH_PATH "$2"
+        adjusted=true
+        shift
+        ;;
+
+    -scotch | -scotchVersion | --scotchVersion)
+        # Replace SCOTCH_VERSION=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/scotch  SCOTCH_VERSION "$2"
+        adjusted=true
+        shift
         ;;
+
     -scotchArchPath | --scotchArchPath)
-        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
-        scotchArchPath="$2"
-        _inlineSed \
-            etc/config.sh/scotch \
-            'SCOTCH_ARCH_PATH=.*' \
-            'SCOTCH_ARCH_PATH='"$scotchArchPath" \
-            "Replacing SCOTCH_ARCH_PATH setting by '$scotchArchPath'"
-        shift 2
+        # Replace SCOTCH_ARCH_PATH=...
+        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+        replace etc/config.sh/scotch  SCOTCH_ARCH_PATH "$2"
+        adjusted=true
+        shift
         ;;
+
     *)
-        usage "unknown option/argument: '$*'"
+        die "unknown option/argument: '$1'"
         ;;
     esac
+    shift
 done
 
-[ -n "$foamInstDir" -o -n "$projectName" -o -n "$projectVersion" -o -n "$archOption" \
--o -n "$paraviewInstall" -o -n "$paraviewVersion" \
--o -n "$scotchVersion" -o -n "$scotchArchPath" \
-] || usage "Please specify at least one configure option"
-
-#echo "Replacing WM_PROJECT setting by '$projectName'"
-#sed -i -e 's@WM_PROJECT=.*@WM_PROJECT='"$projectName@" etc/bashrc
+[ -n "$adjusted" ] || die "Please specify at least one configure option"
 
 # Set WM_MPLIB=SYSTEMOPENMPI always
-_inlineSed \
-    etc/bashrc \
-    'export WM_MPLIB=.*' \
-    'export WM_MPLIB=SYSTEMOPENMPI' \
-    "Replacing WM_MPLIB setting by 'SYSTEMOPENMPI'"
-
-## set WM_COMPILER_TYPE=system always
-#_inlineSed \
-#    etc/bashrc \
-#    'WM_COMPILER_TYPE=.*' \
-#    'WM_COMPILER_TYPE=system' \
-#    "Replacing WM_COMPILER_TYPE setting by 'system'"
+replace etc/bashrc  WM_MPLIB SYSTEMOPENMPI
+
+## Set WM_COMPILER_TYPE=system always
+# replace etc/bashrc  WM_COMPILER_TYPE system
 
 #------------------------------------------------------------------------------
diff --git a/etc/config.csh/CGAL b/etc/config.csh/CGAL
index 2fd06120eb67550b22e6a5ad752a89238c22abc8..84bc71bda6099e176d517c47763a95398a6d51d4 100644
--- a/etc/config.csh/CGAL
+++ b/etc/config.csh/CGAL
@@ -68,12 +68,12 @@ endif
 
 set ending="${BOOST_ARCH_PATH:t}"
 if ( "$ending" != "boost-none" && "$ending" != "boost-system" ) then
-    _foamAddLib $BOOST_ARCH_PATH/lib
+    _foamAddLib $BOOST_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH
 endif
 
 set ending="${CGAL_ARCH_PATH:t}"
 if ( "$ending" != "cgal-none" && "$ending" != "cgal-system" ) then
-    _foamAddLib $CGAL_ARCH_PATH/lib
+    _foamAddLib $CGAL_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH
 endif
 
 unset boost_version cgal_version ending
diff --git a/etc/config.csh/compiler b/etc/config.csh/compiler
index 7d8f757b23eb13680a5545b489e7ef40e55fa657..bc19a6ce2a52b9b1749dc15eedb6fa35e9fa213e 100644
--- a/etc/config.csh/compiler
+++ b/etc/config.csh/compiler
@@ -90,6 +90,10 @@ case Clang:
     setenv WM_CC 'clang'
     setenv WM_CXX 'clang++'
     breaksw
+case Icc:
+    setenv WM_CC 'icc'
+    setenv WM_CXX 'icpc'
+    breaksw
 endsw
 
 #------------------------------------------------------------------------------
diff --git a/etc/config.csh/example/paraview b/etc/config.csh/example/paraview
index 63d2e2668233647ad2b86866d07488b696312db5..47747cafad74bf6ce0f67f6eefa5bea1331a33dc 100644
--- a/etc/config.csh/example/paraview
+++ b/etc/config.csh/example/paraview
@@ -39,7 +39,7 @@
 #
 
 set foamFile=`$WM_PROJECT_DIR/bin/foamEtcFile -mode o config.csh/paraview`
-if ( $status == 0 ) source $foamFile ParaView_VERSION=3.12.0
+if ( $status == 0 ) source $foamFile ParaView_VERSION=5.0.1
 
 unset foamFile
 
diff --git a/etc/config.csh/paraview b/etc/config.csh/paraview
index ef697365a1be89eccd61919575bc79b15fcc9fcb..0fea6e0c07a1ff1fde18e450095c8452cf37a6cd 100644
--- a/etc/config.csh/paraview
+++ b/etc/config.csh/paraview
@@ -41,18 +41,18 @@
 #     If using a central installation not located under ThirdParty, you will
 #     need to set some environment values directly. For example,
 #
-#         setenv ParaView_DIR /opt/paraview/paraview-5.0.1
-#         setenv ParaView_INCLUDE_DIR $ParaView_DIR/include/paraview-5.0
-#         setenv PV_PLUGIN_PATH $FOAM_LIBBIN/paraview-5.0
+#         setenv ParaView_DIR /opt/paraview/paraview-5.2.0
+#         setenv ParaView_INCLUDE_DIR $ParaView_DIR/include/paraview-5.2
+#         setenv PV_PLUGIN_PATH $FOAM_LIBBIN/paraview-5.2
 #
 #         setenv PATH ${ParaView_DIR}/bin:${PATH}
-#         setenv LD_LIBRARY_PATH ${ParaView_DIR}/lib/paraview-5.0:${LD_LIBRARY_PATH}
+#         setenv LD_LIBRARY_PATH ${ParaView_DIR}/lib/paraview-5.2:${LD_LIBRARY_PATH}
 #         unsetenv ParaView_VERSION     # avoid using ThirdParty settings
 #
 #------------------------------------------------------------------------------
 
-setenv ParaView_VERSION 5.0.1
-setenv ParaView_MAJOR   detect          # Automatically determine major version
+setenv ParaView_VERSION 5.1.2
+setenv ParaView_MAJOR detect            # Automatically determine major version
 
 set cmake_version=cmake-system
 
diff --git a/etc/config.sh/CGAL b/etc/config.sh/CGAL
index e23164d2c920402a636f6921a2500c5f89461434..044327109f64ec5c4762546ff1214e3c04b2c2fb 100644
--- a/etc/config.sh/CGAL
+++ b/etc/config.sh/CGAL
@@ -72,13 +72,13 @@ then
     ending="${BOOST_ARCH_PATH##*-}"
     if [ "$ending" != none -a "$ending" != system ]
     then
-        _foamAddLib $BOOST_ARCH_PATH/lib
+        _foamAddLib $BOOST_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH
     fi
 
     ending="${CGAL_ARCH_PATH##*-}"
     if [ "$ending" != none -a "$ending" != system ]
     then
-        _foamAddLib $CGAL_ARCH_PATH/lib
+        _foamAddLib $CGAL_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH
     fi
 
     unset boost_version cgal_version ending
diff --git a/etc/config.sh/compiler b/etc/config.sh/compiler
index 0f27fab8a68bc7fb8dc3475ad4e9b79b78b7b020..f49f2857460a5f52835421a3ccfe98ac4f0c0a34 100644
--- a/etc/config.sh/compiler
+++ b/etc/config.sh/compiler
@@ -87,6 +87,10 @@ Clang)
     export WM_CC='clang'
     export WM_CXX='clang++'
     ;;
+Icc)
+    export WM_CC='icc'
+    export WM_CXX='icpc'
+    ;;
 esac
 
 #------------------------------------------------------------------------------
diff --git a/etc/config.sh/example/paraview b/etc/config.sh/example/paraview
index 704c209dac7319b410fce1f154b271affd1a88ec..ed02d12082f14d58f26b2d7d738e9bee9ea6f9de 100644
--- a/etc/config.sh/example/paraview
+++ b/etc/config.sh/example/paraview
@@ -39,7 +39,7 @@
 #
 
 foamFile=$($WM_PROJECT_DIR/bin/foamEtcFile -mode o config.sh/paraview 2>/dev/null)
-[ $? -eq 0 ] && . $foamFile ParaView_VERSION=3.12.0
+[ $? -eq 0 ] && . $foamFile ParaView_VERSION=5.0.1
 
 unset foamFile
 
diff --git a/etc/config.sh/metis b/etc/config.sh/metis
index 70260f97f06ffd0b6ffc24288569863cf2ba3eff..54ecba0466f1ca42f435a30cac6953f9c2e52d9d 100644
--- a/etc/config.sh/metis
+++ b/etc/config.sh/metis
@@ -28,13 +28,33 @@
 #     Setup file for metis include/libraries.
 #     Sourced during wmake process only.
 #
+#     Normally used to specify the metis version and location for a
+#     ThirdParty installation.
+#
+#     If using system-wide installations, use the following setting:
+#
+#         METIS_VERSION=metis-system
+#
+#     If the system metis is unusable (eg, too old) and you don't
+#     have or want a ThirdParty installation:
+#
+#         METIS_VERSION=metis-none
+#
+#     If using a central installation, but not located under ThirdParty:
+#         - specify metis-system
+#         - provide full paths for METIS_ARCH_PATH
+#
 # Note
 #     A csh version is not needed, since the values here are only sourced
-#     during the wmake process
+#     during the wmake process.
+#
+#     Metis can also be entirely disabled, by either renaming this file or
+#     by creating an empty one with the same name at a user or site location.
 #
 #------------------------------------------------------------------------------
 
-export METIS_VERSION=metis-5.1.0
+METIS_VERSION=metis-5.1.0
+
 export METIS_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/$METIS_VERSION
 
 #------------------------------------------------------------------------------
diff --git a/etc/config.sh/paraview b/etc/config.sh/paraview
index 0438aa132391eb4f9fd6db789034a30a6c0a5207..c9b8621d5251c93124f5882d38b12e87a33cc2f5 100644
--- a/etc/config.sh/paraview
+++ b/etc/config.sh/paraview
@@ -41,17 +41,17 @@
 #     If using a central installation not located under ThirdParty, you will
 #     need to set some environment values directly. For example,
 #
-#         export ParaView_DIR=/opt/paraview/paraview-5.0.1
-#         export ParaView_INCLUDE_DIR=$ParaView_DIR/include/paraview-5.0
-#         export PV_PLUGIN_PATH=$FOAM_LIBBIN/paraview-5.0
+#         export ParaView_DIR=/opt/paraview/paraview-5.2.0
+#         export ParaView_INCLUDE_DIR=$ParaView_DIR/include/paraview-5.2
+#         export PV_PLUGIN_PATH=$FOAM_LIBBIN/paraview-5.2
 #
 #         export PATH=$ParaView_DIR/bin:$PATH
-#         export LD_LIBRARY_PATH=$ParaView_DIR/lib/paraview-5.0:$LD_LIBRARY_PATH
+#         export LD_LIBRARY_PATH=$ParaView_DIR/lib/paraview-5.2:$LD_LIBRARY_PATH
 #         unset ParaView_VERSION        # avoid using ThirdParty settings
 #
 #------------------------------------------------------------------------------
 
-ParaView_VERSION=5.0.1
+ParaView_VERSION=5.1.2
 ParaView_MAJOR=detect                   # Automatically determine major version
 
 cmake_version=cmake-system
diff --git a/etc/config.sh/scotch b/etc/config.sh/scotch
index 7f9800965d8bbe9734700c74c5459bad503cf4a1..bb5e12bced0e2d6b18a9d01ef5bd2668936305c3 100644
--- a/etc/config.sh/scotch
+++ b/etc/config.sh/scotch
@@ -28,16 +28,33 @@
 #     Setup file for scotch include/libraries.
 #     Sourced during wmake process only.
 #
+#     Normally used to specify the scotch version and location for a
+#     ThirdParty installation.
+#
+#     If using system-wide installations, use the following setting:
+#
+#         SCOTCH_VERSION=scotch-system
+#
+#     If the system scotch is unusable (eg, too old) and you don't
+#     have or want a ThirdParty installation:
+#
+#         SCOTCH_VERSION=scotch-none
+#
+#     If using a central installation, but not located under ThirdParty:
+#         - specify scotch-system
+#         - provide full path for SCOTCH_ARCH_PATH
+#
 # Note
 #     A csh version is not needed, since the values here are only sourced
-#     during the wmake process
+#     during the wmake process.
 #
-#     If Scotch is to be entirely disabled, either rename this file or create
-#     an empty one with the same name at a user or site location.
+#     Scotch can also be entirely disabled, by either renaming this file or
+#     by creating an empty one with the same name at a user or site location.
 #
 #------------------------------------------------------------------------------
 
-export SCOTCH_VERSION=scotch_6.0.3
+SCOTCH_VERSION=scotch_6.0.3
+
 export SCOTCH_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/$SCOTCH_VERSION
 
 #------------------------------------------------------------------------------
diff --git a/etc/controlDict b/etc/controlDict
index 9726a8b1aee441676576c4dc91498f080795287a..1334cc1bb1e1e6128f998ecff0a75bb1f92797c1 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -794,7 +794,6 @@ DebugSwitches
     surfaceIntersection 0;
     surfaceNormalFixedValue 0;
     surfacePatch        0;
-    surfacePatchIOList  0;
     surfaceScalarField  0;
     surfaceScalarField::Internal 0;
     surfaceSlipDisplacement 0;
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 8b6be8d8953b09a095c296d0d0a65ede9f909136..a1650b7ee38443087671cf717dc2facb0d5b20c8 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -418,6 +418,7 @@ $(cellShape)/cellShapeIOList.C
 
 meshes/Identifiers/patch/patchIdentifier.C
 meshes/Identifiers/patch/coupleGroupIdentifier.C
+meshes/Identifiers/surface/surfZoneIdentifier.C
 
 meshes/MeshObject/meshObject.C
 
diff --git a/src/OpenFOAM/db/IOobject/IOobjectTemplates.C b/src/OpenFOAM/db/IOobject/IOobjectTemplates.C
index b1e39564a5b8136fcfe8b8fda76cf87eb6c3661e..1ef06e3415e7902bfc452126f4c54fe71c339701 100644
--- a/src/OpenFOAM/db/IOobject/IOobjectTemplates.C
+++ b/src/OpenFOAM/db/IOobject/IOobjectTemplates.C
@@ -69,9 +69,12 @@ bool Foam::IOobject::typeHeaderOk(const bool checkType)
             {
                 if (checkType && headerClassName_ != Type::typeName)
                 {
-                    IOWarningInFunction(*isPtr)
-                        << "unexpected class name " << headerClassName_
-                        << " expected " << Type::typeName << endl;
+                    if (debug)
+                    {
+                        IOWarningInFunction(*isPtr)
+                            << "unexpected class name " << headerClassName_
+                            << " expected " << Type::typeName << endl;
+                    }
 
                     ok = false;
                 }
diff --git a/src/OpenFOAM/db/functionObjects/writeFile/writeFile.C b/src/OpenFOAM/db/functionObjects/writeFile/writeFile.C
index f6fefcdab25a466429b445085a240a1f9711e97e..3d7b6d707a3d4e80189d7588f12450435a635ef1 100644
--- a/src/OpenFOAM/db/functionObjects/writeFile/writeFile.C
+++ b/src/OpenFOAM/db/functionObjects/writeFile/writeFile.C
@@ -160,6 +160,7 @@ Foam::functionObjects::writeFile::writeFile
 :
     fileObr_(obr),
     prefix_(prefix),
+    fileName_(fileName),
     filePtr_(),
     writePrecision_(IOstream::defaultPrecision()),
     writeToFile_(true)
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
index 092ae85bd329e6bccb12730d1382cf8d2aab9c81..178dff7c256f132cd4ff069abbaaf355c20148e0 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -114,6 +114,9 @@ public:
         //- Construct by transferring the parameter contents
         explicit inline DynamicField(const Xfer<List<T>>&);
 
+        //- Construct by transferring the parameter contents
+        explicit inline DynamicField(const Xfer<Field<T>>&);
+
         //- Construct by 1 to 1 mapping from the given field
         inline DynamicField
         (
diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
index 8db855af5353f7f695d2599a4a76e049dd0a0394..b29af8958e3357ccb7cc44f69c0c37af8bd9af26 100644
--- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
+++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -69,6 +69,17 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
 {}
 
 
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
+(
+    const Xfer<Field<T>>& lst
+)
+:
+    Field<T>(lst),
+    capacity_(Field<T>::size())
+{}
+
+
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
 (
diff --git a/src/OpenFOAM/fields/Fields/Field/Field.C b/src/OpenFOAM/fields/Fields/Field/Field.C
index 997135bc34d84fa693a4cc712dee1e6a82b62e5d..f60ed5047b5ad7b94800058aa22e4470de4224bd 100644
--- a/src/OpenFOAM/fields/Fields/Field/Field.C
+++ b/src/OpenFOAM/fields/Fields/Field/Field.C
@@ -233,8 +233,10 @@ Foam::Field<Type>::Field(const Xfer<List<Type>>& f)
 template<class Type>
 Foam::Field<Type>::Field(const Xfer<Field<Type>>& f)
 :
-    List<Type>(f)
-{}
+    List<Type>()
+{
+    List<Type>::transfer(f());
+}
 
 
 template<class Type>
diff --git a/src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.C b/src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.C
similarity index 90%
rename from src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.C
rename to src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.C
index 049559865785f811a81f6c66ea1909fe0543f272..88c3f2d788f98a66ef09b0fd7cddf07694a01c77 100644
--- a/src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.C
+++ b/src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.C
@@ -97,14 +97,11 @@ Foam::surfZoneIdentifier::~surfZoneIdentifier()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-
 void Foam::surfZoneIdentifier::write(Ostream& os) const
 {
     if (geometricType_.size())
     {
-        os.writeKeyword("geometricType")
-            << geometricType_
-            << token::END_STATEMENT << nl;
+        os.writeEntry("geometricType", geometricType_);
     }
 }
 
@@ -112,7 +109,6 @@ void Foam::surfZoneIdentifier::write(Ostream& os) const
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 // needed for list output
-
 bool Foam::surfZoneIdentifier::operator!=
 (
     const surfZoneIdentifier& rhs
@@ -129,8 +125,9 @@ bool Foam::surfZoneIdentifier::operator==
 {
     return
     (
-        name() == rhs.name()
-     && geometricType() == rhs.geometricType()
+        (index() == rhs.index())
+     && (name()  == rhs.name())
+     && (geometricType() == rhs.geometricType())
     );
 }
 
@@ -139,8 +136,7 @@ bool Foam::surfZoneIdentifier::operator==
 
 Foam::Istream& Foam::operator>>(Istream& is, surfZoneIdentifier& obj)
 {
-    is  >> obj.name_
-        >> obj.geometricType_;
+    is >> obj.name_ >> obj.geometricType_;
 
     return is;
 }
@@ -148,7 +144,8 @@ Foam::Istream& Foam::operator>>(Istream& is, surfZoneIdentifier& obj)
 
 Foam::Ostream& Foam::operator<<(Ostream& os, const surfZoneIdentifier& obj)
 {
-    os  << obj.name_ << ' ' << obj.geometricType_;
+    // newlines to separate, since that is what triSurface currently expects
+    os  << nl << obj.name_ << nl << obj.geometricType_;
 
     os.check("Ostream& operator<<(Ostream&, const surfZoneIdentifier&)");
     return os;
diff --git a/src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.H b/src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.H
similarity index 98%
rename from src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.H
rename to src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.H
index 3f6a1b9a7790a19dba9126616c744eae92e05b2c..ff75b56afa566d0935d1cf25be468deb2c81b560 100644
--- a/src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifier.H
+++ b/src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifier.H
@@ -40,7 +40,6 @@ SourceFiles
 
 #include "word.H"
 #include "label.H"
-#include "typeInfo.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -56,7 +55,7 @@ Istream& operator>>(Istream&, surfZoneIdentifier&);
 Ostream& operator<<(Ostream&, const surfZoneIdentifier&);
 
 /*---------------------------------------------------------------------------*\
-                    Class surfZoneIdentifier Declaration
+                     Class surfZoneIdentifier Declaration
 \*---------------------------------------------------------------------------*/
 
 class surfZoneIdentifier
diff --git a/src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifierList.H b/src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifierList.H
similarity index 100%
rename from src/surfMesh/surfZone/surfZoneIdentifier/surfZoneIdentifierList.H
rename to src/OpenFOAM/meshes/Identifiers/surface/surfZoneIdentifierList.H
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 0504145adeb815a6887408d9421d23b218dba99b..62ae47b3d078d5907346571684059c775891cdc5 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.H
@@ -155,8 +155,8 @@ public:
         //- Construct from list of labels
         explicit inline face(const labelUList&);
 
-        //- Construct from list of labels
-        explicit inline face(const labelList&);
+        //- Construct from an initializer list of labels
+        explicit inline face(std::initializer_list<label>);
 
         //- Construct by transferring the parameter contents
         explicit inline face(const Xfer<labelList>&);
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
index 7dfc9ef7ea7a43ffc28ab0ed6d741e41ce54f213..0dc5e035a60819fc80236ba51d8935041dc27fec 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
@@ -57,7 +57,7 @@ inline Foam::face::face(const labelUList& lst)
 {}
 
 
-inline Foam::face::face(const labelList& lst)
+inline Foam::face::face(std::initializer_list<label> lst)
 :
     labelList(lst)
 {}
@@ -79,7 +79,7 @@ inline Foam::face::face(Istream& is)
 
 inline Foam::pointField Foam::face::points(const pointField& meshPoints) const
 {
-    // There are as many points as there labels for them
+    // There are as many points as there are labels for them
     pointField p(size());
 
     // For each point in list, set it to the point in 'pnts' addressed
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceListFwd.H b/src/OpenFOAM/meshes/meshShapes/face/faceListFwd.H
index d268b0ccbc291119dd0b63b7270cbed46b83c6c4..0caf8a454a2d93c03ad9e66ada975b8d86d20ab9 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceListFwd.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceListFwd.H
@@ -43,8 +43,6 @@ namespace Foam
     typedef List<face> faceList;
     typedef SubList<face> faceSubList;
     typedef List<faceList> faceListList;
-    // same as faceUList:
-    typedef UList<face> unallocFaceList;
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/triSurface/tools/labelledTri/labelledTri.H b/src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTri.H
similarity index 81%
rename from src/triSurface/tools/labelledTri/labelledTri.H
rename to src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTri.H
index a0fd5a90dd0a371aaedb6364ac7a1fca4318e851..f9feafa610a78004d5a68142cafd9734b2d4fc8e 100644
--- a/src/triSurface/tools/labelledTri/labelledTri.H
+++ b/src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTri.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -64,29 +64,44 @@ class labelledTri
         label region_;
 
 
+    // Private Member Functions
+
+        //- Assign from a list of 3 or 4 labels.
+        //  Default region is 0.
+        inline void assign(const labelUList&);
+
 public:
 
     // Constructors
 
-        //- Construct null
+        //- Construct null with invalid point labels and region (-1).
         inline labelledTri();
 
-        //- Construct from triFace and a region label
+        //- Construct from triFace and region label.
+        //  Default region is 0 if not specified.
         inline labelledTri
         (
             const triFace&,
-            const label region
+            const label region = 0
         );
 
-        //- Construct from three point labels and a region label
+        //- Construct from three point labels and a region label.
+        //  Default region is 0 if not specified.
         inline labelledTri
         (
             const label a,
             const label b,
             const label c,
-            const label region
+            const label region = 0
         );
 
+        //- Construct from a list of 3 or 4 labels.
+        //  Default region is 0.
+        explicit inline labelledTri(const labelUList&);
+
+        //- Construct from an initializer list of 3 or 4 labels.
+        explicit inline labelledTri(std::initializer_list<label>);
+
         //- Construct from Istream
         inline labelledTri(Istream&);
 
@@ -102,17 +117,6 @@ public:
             inline label& region();
 
 
-        // Check
-
-        // Edit
-
-        // Write
-
-
-    // Friend Functions
-
-    // Friend Operators
-
     // IOstream Operators
 
         inline friend Istream& operator>>(Istream&, labelledTri&);
diff --git a/src/triSurface/tools/labelledTri/labelledTriI.H b/src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTriI.H
similarity index 79%
rename from src/triSurface/tools/labelledTri/labelledTriI.H
rename to src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTriI.H
index 0d86d6cee9086ed6bb67a6245ab6c587a8d46f36..0e0c72af77c9836d9c175c22a297dc3063be0b4e 100644
--- a/src/triSurface/tools/labelledTri/labelledTriI.H
+++ b/src/OpenFOAM/meshes/meshShapes/labelledTri/labelledTriI.H
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,10 +25,34 @@ License
 
 #include "IOstreams.H"
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+inline void Foam::labelledTri::assign(const labelUList& lst)
+{
+    const label sz = lst.size();
+
+    // checkSize
+    if (sz < 3 || sz > 4)
+    {
+         FatalErrorInFunction
+            << "size " << sz << " != (3 or 4)"
+            << abort(FatalError);
+    }
+
+    for (label i=0; i<3; ++i)
+    {
+        operator[](i) = lst[i];
+    }
+
+    region_ = (sz > 3 ? lst[3] : 0);
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 inline Foam::labelledTri::labelledTri()
 :
+    triFace(),
     region_(-1)
 {}
 
@@ -57,6 +81,24 @@ inline Foam::labelledTri::labelledTri
 {}
 
 
+inline Foam::labelledTri::labelledTri(const labelUList& lst)
+:
+    triFace(),
+    region_(0)
+{
+    assign(lst);
+}
+
+
+inline Foam::labelledTri::labelledTri(std::initializer_list<label> initLst)
+:
+    triFace(),
+    region_(0)
+{
+    assign(labelList(initLst));
+}
+
+
 inline Foam::labelledTri::labelledTri(Istream& is)
 {
     operator>>(is, *this);
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
index 2e7a730228adbf9999521160ee364611d0ba9a5d..0b2d5170ad04bc0808addb15776e47ab0a83d095 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
@@ -75,7 +75,7 @@ public:
 
     // Constructors
 
-        //- Construct null
+        //- Construct null with invalid point labels (-1)
         inline triFace();
 
         //- Construct from three point labels
@@ -86,9 +86,12 @@ public:
             const label c
         );
 
-        //- Construct from a list of labels
+        //- Construct from a list of 3 labels.
         explicit inline triFace(const labelUList&);
 
+        //- Construct from an initializer list of 3 labels
+        explicit inline triFace(std::initializer_list<label>);
+
         //- Construct from Istream
         inline triFace(Istream&);
 
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
index b956780df4138ec0f0c4c8b7c52154bc292cdfd1..8d8bcaba99af925979b26f12ab2ea33c6ef7e7d0 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
@@ -62,6 +62,8 @@ inline int Foam::triFace::compare(const triFace& a, const triFace& b)
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 inline Foam::triFace::triFace()
+:
+    FixedList<label, 3>(-1)
 {}
 
 
@@ -84,6 +86,12 @@ inline Foam::triFace::triFace(const labelUList& lst)
 {}
 
 
+inline Foam::triFace::triFace(std::initializer_list<label> lst)
+:
+    FixedList<label, 3>(lst)
+{}
+
+
 inline Foam::triFace::triFace(Istream& is)
 :
     FixedList<label, 3>(is)
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
index 04c3f9e62a5630bdb4ca800b5ecbedb2f30d1835..fdff5f05c3a198a06b588a1ba043dd4456b5d69b 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
@@ -58,6 +58,8 @@ PrimitivePatch
     localPointsPtr_(nullptr),
     localPointOrderPtr_(nullptr),
     faceCentresPtr_(nullptr),
+    faceAreasPtr_(nullptr),
+    magFaceAreasPtr_(nullptr),
     faceNormalsPtr_(nullptr),
     pointNormalsPtr_(nullptr)
 {}
@@ -94,6 +96,8 @@ PrimitivePatch
     localPointsPtr_(nullptr),
     localPointOrderPtr_(nullptr),
     faceCentresPtr_(nullptr),
+    faceAreasPtr_(nullptr),
+    magFaceAreasPtr_(nullptr),
     faceNormalsPtr_(nullptr),
     pointNormalsPtr_(nullptr)
 {}
@@ -131,6 +135,8 @@ PrimitivePatch
     localPointsPtr_(nullptr),
     localPointOrderPtr_(nullptr),
     faceCentresPtr_(nullptr),
+    faceAreasPtr_(nullptr),
+    magFaceAreasPtr_(nullptr),
     faceNormalsPtr_(nullptr),
     pointNormalsPtr_(nullptr)
 {}
@@ -167,6 +173,8 @@ PrimitivePatch
     localPointsPtr_(nullptr),
     localPointOrderPtr_(nullptr),
     faceCentresPtr_(nullptr),
+    faceAreasPtr_(nullptr),
+    magFaceAreasPtr_(nullptr),
     faceNormalsPtr_(nullptr),
     pointNormalsPtr_(nullptr)
 {}
@@ -524,6 +532,46 @@ faceCentres() const
 }
 
 
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+const Foam::Field<PointType>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+faceAreas() const
+{
+    if (!faceAreasPtr_)
+    {
+        calcFaceAreas();
+    }
+
+    return *faceAreasPtr_;
+}
+
+
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+const Foam::Field<Foam::scalar>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+magFaceAreas() const
+{
+    if (!magFaceAreasPtr_)
+    {
+        calcMagFaceAreas();
+    }
+
+    return *magFaceAreasPtr_;
+}
+
+
 template
 <
     class Face,
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
index 5668e8f064ef665ae418ab67925078767031376a..6e732b9fd824f72b34273fc0100e983f214e3dc5 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
@@ -168,6 +168,12 @@ private:
         //- Face centres
         mutable Field<PointType>* faceCentresPtr_;
 
+        //- Face area vectors
+        mutable Field<PointType>* faceAreasPtr_;
+
+        //- Mag face area
+        mutable Field<scalar>* magFaceAreasPtr_;
+
         //- Face unit normals
         mutable Field<PointType>* faceNormalsPtr_;
 
@@ -210,6 +216,12 @@ private:
         //- Calculate face centres
         void calcFaceCentres() const;
 
+        //- Calculate face area vectors
+        void calcFaceAreas() const;
+
+        //- Calculate face area magnitudes
+        void calcMagFaceAreas() const;
+
         //- Calculate unit face normals
         void calcFaceNormals() const;
 
@@ -381,7 +393,13 @@ public:
             //- Return face centres for patch
             const Field<PointType>& faceCentres() const;
 
-            //- Return face normals for patch
+            //- Return face area vectors for patch
+            const Field<PointType>& faceAreas() const;
+
+            //- Return face area magnitudes for patch
+            const Field<scalar>& magFaceAreas() const;
+
+            //- Return face unit normals for patch
             const Field<PointType>& faceNormals() const;
 
             //- Return point normals for patch
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
index 3ac89f2c61e6a493481e34584917b0402033d1f9..3a226c385d53b1f11c6ce3344324e1c60c8a5a60 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
@@ -47,6 +47,8 @@ clearGeom()
 
     deleteDemandDrivenData(localPointsPtr_);
     deleteDemandDrivenData(faceCentresPtr_);
+    deleteDemandDrivenData(faceAreasPtr_);
+    deleteDemandDrivenData(magFaceAreasPtr_);
     deleteDemandDrivenData(faceNormalsPtr_);
     deleteDemandDrivenData(pointNormalsPtr_);
 }
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C
index 10f758c6485ec0c40eea2d701c241148f553f30f..50e4222be0a54fee5b911ae385cacf592d34ce6f 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.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  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,7 +52,7 @@ calcMeshData() const
     if (meshPointsPtr_ || localFacesPtr_)
     {
         FatalErrorInFunction
-            << "meshPointsPtr_ or localFacesPtr_already allocated"
+            << "meshPointsPtr_ or localFacesPtr_ already allocated"
             << abort(FatalError);
     }
 
@@ -210,7 +210,7 @@ calcLocalPoints() const
     if (localPointsPtr_)
     {
         FatalErrorInFunction
-            << "localPointsPtr_already allocated"
+            << "localPointsPtr_ already allocated"
             << abort(FatalError);
     }
 
@@ -259,7 +259,7 @@ calcPointNormals() const
     if (pointNormalsPtr_)
     {
         FatalErrorInFunction
-            << "pointNormalsPtr_already allocated"
+            << "pointNormalsPtr_ already allocated"
             << abort(FatalError);
     }
 
@@ -323,7 +323,7 @@ calcFaceCentres() const
     if (faceCentresPtr_)
     {
         FatalErrorInFunction
-            << "faceCentresPtr_already allocated"
+            << "faceCentresPtr_ already allocated"
             << abort(FatalError);
     }
 
@@ -346,6 +346,98 @@ calcFaceCentres() const
 }
 
 
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcMagFaceAreas() const
+{
+    if (debug)
+    {
+        Pout<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
+               "calcMagFaceAreas() : "
+               "calculating magFaceAreas in PrimitivePatch"
+            << endl;
+    }
+
+    // It is an error to calculate these more than once.
+    if (magFaceAreasPtr_)
+    {
+        FatalErrorInFunction
+            << "magFaceAreasPtr_ already allocated"
+            << abort(FatalError);
+    }
+
+    magFaceAreasPtr_ = new Field<scalar>(this->size());
+    Field<scalar>& a = *magFaceAreasPtr_;
+
+    forAll(a, facei)
+    {
+        a[facei] = this->operator[](facei).mag(points_);
+    }
+
+    if (debug)
+    {
+        Pout<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
+               "calcMagFaceAreas() : "
+               "finished calculating magFaceAreas in PrimitivePatch"
+            << endl;
+    }
+}
+
+
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcFaceAreas() const
+{
+    if (debug)
+    {
+        Pout<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
+               "calcFaceAreas() : "
+               "calculating faceAreas in PrimitivePatch"
+            << endl;
+    }
+
+    // It is considered an error to attempt to recalculate faceNormals
+    // if they have already been calculated.
+    if (faceAreasPtr_)
+    {
+        FatalErrorInFunction
+            << "faceAreasPtr_ already allocated"
+            << abort(FatalError);
+    }
+
+    faceAreasPtr_ = new Field<PointType>(this->size());
+
+    Field<PointType>& n = *faceAreasPtr_;
+
+    forAll(n, facei)
+    {
+        n[facei] = this->operator[](facei).normal(points_);
+    }
+
+    if (debug)
+    {
+        Pout<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
+               "calcFaceAreas() : "
+               "finished calculating faceAreas in PrimitivePatch"
+            << endl;
+    }
+}
+
+
 template
 <
     class Face,
@@ -370,7 +462,7 @@ calcFaceNormals() const
     if (faceNormalsPtr_)
     {
         FatalErrorInFunction
-            << "faceNormalsPtr_already allocated"
+            << "faceNormalsPtr_ already allocated"
             << abort(FatalError);
     }
 
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
index 3488217e0778b8f77e8d178f09528717a29fe745..9fb6f3f1dcea6cfeeaf5df9dd468d690cae4c750 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
@@ -239,11 +239,11 @@ inline const Cmpt&
 VectorSpace<Form, Cmpt, Ncmpts>::
 ConstBlock<SubVector, BStart>::operator[]
 (
-    const direction i
+    const direction d
 ) const
 {
     #ifdef FULLDEBUG
-    if (i >= Ncmpts)
+    if (d >= Ncmpts)
     {
         FatalErrorInFunction
             << "index " << d << " out of range"
@@ -251,7 +251,7 @@ ConstBlock<SubVector, BStart>::operator[]
     }
     #endif
 
-    return vs_[BStart + i];
+    return vs_[BStart + d];
 }
 
 
@@ -269,7 +269,7 @@ ConstBlock<SubVector, BStart>::operator()
     if (i >= Ncmpts)
     {
         FatalErrorInFunction
-            << "index " << d << " out of range"
+            << "index " << i << " out of range"
             << abort(FatalError);
     }
 
diff --git a/src/Pstream/Allwmake b/src/Pstream/Allwmake
index a73b43cf0328962877b75544545502cf5683e634..d32bc5503d76e5013e50e96930b5a869903e7714 100755
--- a/src/Pstream/Allwmake
+++ b/src/Pstream/Allwmake
@@ -10,27 +10,26 @@ cd ${0%/*} || exit 1    # Run from this directory
 # use sentinel file to handle version changes
 wmakeMpiLib()
 {
-    set +x
     for libName
     do
     (
         WM_OPTIONS="$WM_OPTIONS$WM_MPLIB"
-        whichmpi="$WM_PROJECT_DIR/platforms/$WM_OPTIONS/src/Pstream/$libName/using:$FOAM_MPI"
+        libDir="$WM_PROJECT_DIR/platforms/$WM_OPTIONS/src/Pstream/$libName"
+        whichmpi="$libDir/using:$FOAM_MPI"
         [ -e "$whichmpi" ] || wclean $libName
         echo "wmake $targetType $libName"
         wmake $targetType $libName
+        mkdir -p "$libDir"
         touch "$whichmpi"
     )
     done
-    set -x
 }
 
-set -x
+echo "wmake $targetType dummy"
 wmake $targetType dummy
 
 case "$WM_MPLIB" in
 *MPI*)
-    set +x
     wmakeMpiLib mpi
     ;;
 esac
diff --git a/src/TurbulenceModels/schemes/DEShybrid/DEShybrid.H b/src/TurbulenceModels/schemes/DEShybrid/DEShybrid.H
index 8d90432566ab064eb4cf187d0164ea2e55f7d04b..b6e2ea466f049f32037ffdce942f9a5d7e8864b8 100644
--- a/src/TurbulenceModels/schemes/DEShybrid/DEShybrid.H
+++ b/src/TurbulenceModels/schemes/DEShybrid/DEShybrid.H
@@ -82,7 +82,8 @@ Description
             30                            // Reference velocity scale
             2                             // Reference length scale
             0                             // Minimum sigma limit (0-1)
-            1;                            // Maximum sigma limit (0-1)
+            1                             // Maximum sigma limit (0-1)
+            1.0e-03;                      // Limiter of B function, typically 1.0e-03
         .
         .
     }
@@ -153,6 +154,9 @@ class DEShybrid
         //- Maximum bound for sigma (0 <= sigmaMax <= 1)
         scalar sigmaMax_;
 
+        //- Limiter of B function
+        scalar OmegaLim_;
+
         //- Scheme constants
         scalar CH1_;
         scalar CH2_;
@@ -184,7 +188,7 @@ class DEShybrid
             const volScalarField B
             (
                 CH3_*Omega*max(S, Omega)
-               /max(0.5*(sqr(S) + sqr(Omega)), sqr(1.0e-3/tau0_))
+               /max(0.5*(sqr(S) + sqr(Omega)), sqr(OmegaLim_/tau0_))
             );
             const volScalarField K
             (
@@ -254,6 +258,7 @@ public:
             L0_("L0", dimLength, readScalar(is)),
             sigmaMin_(readScalar(is)),
             sigmaMax_(readScalar(is)),
+            OmegaLim_(readScalar(is)),
             CH1_(3.0),
             CH2_(1.0),
             CH3_(2.0)
@@ -318,6 +323,7 @@ public:
             L0_("L0", dimLength, readScalar(is)),
             sigmaMin_(readScalar(is)),
             sigmaMax_(readScalar(is)),
+            OmegaLim_(readScalar(is)),
             CH1_(3.0),
             CH2_(1.0),
             CH3_(2.0)
diff --git a/src/conversion/Allwmake b/src/conversion/Allwmake
index 4b81d4b8c1ae4055194d3a4cc096607f750683a1..3187320a6796462cce366fa3845a669791b2042c 100755
--- a/src/conversion/Allwmake
+++ b/src/conversion/Allwmake
@@ -3,8 +3,15 @@ cd ${0%/*} || exit 1    # Run from this directory
 
 # Parse arguments for library compilation
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
 set -x
 
 wmake $targetType
 
+ccm/Allwmake || {
+    echo
+    echo "WARNING: skipped optional conversion component (build issues detected)"
+    echo
+}
+
 #------------------------------------------------------------------------------
diff --git a/src/conversion/Make/files b/src/conversion/Make/files
index bbf86cf8591cf5de9273507b3dbc32432d7e7c95..3f2c0a0c98c7e6ccb2679829519124f5f4fadf6b 100644
--- a/src/conversion/Make/files
+++ b/src/conversion/Make/files
@@ -7,19 +7,24 @@ common/writer/meshWriter.C
 common/tables/boundaryRegion.C
 common/tables/cellTable.C
 
-ensight/file/ensightFile.C
-ensight/file/ensightGeoFile.C
-ensight/readFile/ensightReadFile.C
+ensight/mesh/ensightMesh.C
+ensight/mesh/ensightMeshIO.C
+ensight/mesh/ensightMeshOptions.C
 ensight/part/ensightPart.C
-ensight/part/ensightPartIO.C
 ensight/part/ensightPartCells.C
 ensight/part/ensightPartFaces.C
 ensight/part/ensightParts.C
 
+fire/FIREMeshReader.C
+fire/FIREMeshWriter.C
+fire/checkFireEdges.C
 
 starcd/STARCDMeshReader.C
 starcd/STARCDMeshWriter.C
 
 polyDualMesh/polyDualMesh.C
 
+vtk/part/foamVtkCells.C
+vtk/output/foamVtkOutput.C
+
 LIB = $(FOAM_LIBBIN)/libconversion
diff --git a/src/conversion/ccm/Allwmake b/src/conversion/ccm/Allwmake
new file mode 100755
index 0000000000000000000000000000000000000000..a3e067e1dc0b9cdef6e24986923e5cdcd85a866a
--- /dev/null
+++ b/src/conversion/ccm/Allwmake
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Build optional components (eg, may depend on third-party libraries)
+#------------------------------------------------------------------------------
+cd ${0%/*} || exit 1    # Run from this directory
+
+# Parse arguments for compilation (at least for error catching)
+. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
+. $WM_PROJECT_DIR/etc/config.sh/functions
+_foamSource $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/ccmio)
+
+# Link with static libccmio only (possibly fewer issues)
+if [ "$WM_LABEL_SIZE" = 64 ]
+then
+    # The libccmio uses int32_t.
+    # The OpenFOAM adapter thus requires additional work for 64-bit labels.
+    echo "Skipping optional component libccm"
+    echo "    does not support 64-bit labels"
+elif [ -e $CCMIO_ARCH_PATH/include/libccmio/ccmio.h \
+    -a -e $CCMIO_ARCH_PATH/lib/libccmio.a ]
+then
+    wmake libso
+else
+    echo "Skipping optional component libccm"
+fi
+
+#------------------------------------------------------------------------------
diff --git a/src/conversion/ccm/Make/files b/src/conversion/ccm/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..89ec20a1db35f1404009aea7b0e367eff3d00a9a
--- /dev/null
+++ b/src/conversion/ccm/Make/files
@@ -0,0 +1,16 @@
+common/ccmBase.C
+common/ccmInternal.C
+
+reader/ccmReader.C
+reader/ccmReaderAux.C
+reader/ccmReaderMesh.C
+reader/ccmReaderSolution.C
+reader/ccmReaderOptions.C
+
+writer/ccmWriter.C
+writer/ccmWriterMesh.C
+writer/ccmWriterSolution.C
+
+/* misc/mergePoints1.C */
+
+LIB = $(FOAM_LIBBIN)/libccm
diff --git a/src/conversion/ccm/Make/options b/src/conversion/ccm/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..ef4b6bb2798726d4b87bff3808ec8807b560a1c0
--- /dev/null
+++ b/src/conversion/ccm/Make/options
@@ -0,0 +1,14 @@
+EXE_INC = \
+    /* -DWITH_MONITORING -DDEBUG_MONITORING */ \
+    /* -DDEBUG_BAFFLES */ \
+    /* -DDEBUG_CCMIOREAD */ \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude \
+    -I$(CCMIO_ARCH_PATH)/include
+
+LIB_LIBS = \
+    -lfiniteVolume \
+    -lconversion \
+    -L$(CCMIO_ARCH_PATH)/lib -lccmio
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H b/src/conversion/ccm/common/ccm.H
similarity index 60%
rename from applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H
rename to src/conversion/ccm/common/ccm.H
index e4d8a3e21c2619b1c157e27022d359af64553f5c..639b6127cb87086bc4d522f37acce276739f7b71 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H
+++ b/src/conversion/ccm/common/ccm.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,44 +21,16 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-InClass
-    vtkPV3blockMesh
+Description
+    Reader/writer for handling ccm files.
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef vtkOpenFOAMPoints_H
-#define vtkOpenFOAMPoints_H
+#ifndef ccm_H
+#define ccm_H
 
-// VTK includes
-#include "vtkPoints.h"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-inline void vtkInsertNextOpenFOAMPoint
-(
-    vtkPoints *points,
-    const Foam::point& p
-)
-{
-    points->InsertNextPoint(p.x(), p.y(), p.z());
-}
-
-inline void vtkInsertNextOpenFOAMPoint
-(
-    vtkPoints *points,
-    const Foam::point& p,
-    const Foam::scalar scaleFactor
-)
-{
-    points->InsertNextPoint
-    (
-        p.x()*scaleFactor,
-        p.y()*scaleFactor,
-        p.z()*scaleFactor
-    );
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+#include "ccmReader.H"
+#include "ccmWriter.H"
 
 #endif
 
diff --git a/src/triSurface/tools/labelledTri/sortLabelledTri.C b/src/conversion/ccm/common/ccmBase.C
similarity index 53%
rename from src/triSurface/tools/labelledTri/sortLabelledTri.C
rename to src/conversion/ccm/common/ccmBase.C
index 8ee98169f40f9a901d413edb82927e332ebc5f99..14efe10a5e22fb30a3becd0df48ba238eb16eb52 100644
--- a/src/triSurface/tools/labelledTri/sortLabelledTri.C
+++ b/src/conversion/ccm/common/ccmBase.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,72 +21,82 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-\*---------------------------------------------------------------------------*/
+\*----------------------------------------------------------------------------*/
 
-#include "sortLabelledTri.H"
-#include "labelledTri.H"
-#include "triSurface.H"
+#include "ccmBase.H"
+#include "ccmInternal.H"  // include last to avoid any strange interactions
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-namespace Foam
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+bool Foam::ccm::base::assertNoError
+(
+    int err,
+    const char* msg
+)
 {
+    return ccmGlobalState::assertNoError(static_cast<CCMIOError>(err), msg);
+}
 
-// * * * * * * * * * * * * * * * Private Classes * * * * * * * * * * * * * * //
 
-inline bool surfAndLabel::less::operator()
+bool Foam::ccm::base::assertNoError
 (
-    const surfAndLabel& one,
-    const surfAndLabel& two
-) const
+    int err,
+    const std::string& msg
+)
 {
-    const triSurface& surf = *one.surfPtr_;
-    return surf[one.index_].region() < surf[two.index_].region();
+    return ccmGlobalState::assertNoError(static_cast<CCMIOError>(err), msg);
 }
 
 
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-// Construct from components
-sortLabelledTri::sortLabelledTri(const triSurface& surf)
-:
-    List<surfAndLabel>(surf.size(), surfAndLabel(surf, -1))
+bool Foam::ccm::base::assertNoError(const char* msg) const
 {
+    return globalState_->assertNoError(msg);
+}
 
-    // Set the face label
-    forAll(surf, facei)
-    {
-        operator[](facei).index_ = facei;
-    }
 
-    // Sort according to region number.
-    sort(*this, surfAndLabel::less());
+bool Foam::ccm::base::assertNoError(const std::string& msg) const
+{
+    return globalState_->assertNoError(msg);
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-void sortLabelledTri::indices(labelList& newIndices) const
-{
-    newIndices.setSize(size());
+Foam::ccm::base::base()
+:
+    globalState_(new ccmGlobalState)
+{}
 
-    forAll(newIndices, i)
-    {
-        newIndices[i] = operator[](i).index_;
-    }
-}
 
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
-labelList sortLabelledTri::indices() const
+Foam::ccm::base::~base()
 {
-    labelList newIndices(size());
-    indices(newIndices);
-    return newIndices;
+    close();
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::ccm::base::close()
+{
+    if (globalState_)
+    {
+        if (CCMIOIsValidEntity(globalState_->root))
+        {
+            CCMIOCloseFile(NULL, globalState_->root);
+        }
+        delete globalState_;
+        globalState_ = 0;
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
 
-} // End namespace Foam
 
 // ************************************************************************* //
diff --git a/src/conversion/ccm/common/ccmBase.H b/src/conversion/ccm/common/ccmBase.H
new file mode 100644
index 0000000000000000000000000000000000000000..5f789eadd0aaa100ae07ad4952d7ecc19b627aad
--- /dev/null
+++ b/src/conversion/ccm/common/ccmBase.H
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ccm::base
+
+Description
+    Base functionality common to reader and writer classes
+
+Note
+    this class is in development
+    - any/all of the class names and members may change
+
+SourceFiles
+    ccmBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ccmBase_H
+#define ccmBase_H
+
+#include <string>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ccm
+{
+
+// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
+
+class ccmGlobalState;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+/*---------------------------------------------------------------------------*\
+                          Class ccm::base Declaration
+\*---------------------------------------------------------------------------*/
+
+class base
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        base(const base&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const base&) = delete;
+
+
+protected:
+
+    // Protected Data
+
+        //- Maintain overall global states (error, root-node)
+        ccmGlobalState* globalState_;
+
+
+    // Protected Member Functions
+
+        //- Die with msg if there is an error
+        //  Return true if there is no error
+        static bool assertNoError(int err, const char *msg);
+
+        //- Die with msg if there is an error
+        //  Return true if there is no error
+        static bool assertNoError(int err, const std::string& msg);
+
+
+        //- check global state for errors and die as required
+        //  Return true if there is no error
+        bool assertNoError(const char* msg) const;
+
+        //- check global state for errors and die as required
+        //  Return true if there is no error
+        bool assertNoError(const std::string& msg) const;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        base();
+
+
+    //- Destructor: close file
+    ~base();
+
+
+    // Member Functions
+
+        // Access
+
+        //- Explicity close the file and terminate ccmio access.
+        //  Return false if it was already closed.
+        bool close();
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/common/ccmInternal.C b/src/conversion/ccm/common/ccmInternal.C
new file mode 100644
index 0000000000000000000000000000000000000000..47dd0c393397577c56db7e2702c663f1b27fcb54
--- /dev/null
+++ b/src/conversion/ccm/common/ccmInternal.C
@@ -0,0 +1,171 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "Pstream.H"
+#include "ccmInternal.H" // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+defineTypeNameAndDebug(ccm, 0);
+}
+
+
+// * * * * * * * * * * * * * * Static Functions  * * * * * * * * * * * * * * //
+
+// \cond file-scope
+// Return the string corresponding to the error
+static const char* errorMsg(CCMIOError err)
+{
+    switch (err)
+    {
+        case kCCMIONoErr:
+            return "";
+            break;
+        case kCCMIONoFileErr:
+            return "No File Error";
+            break;
+        case kCCMIOPermissionErr:
+            return "Permission Error";
+            break;
+        case kCCMIOCorruptFileErr:
+            return "Corrupt File Error";
+            break;
+        case kCCMIOBadLinkErr:
+            return "Bad Link Error";
+            break;
+        case kCCMIONoNodeErr:
+            return "No Node Error";
+            break;
+        case kCCMIODuplicateNodeErr:
+            return "Duplicate Node Error";
+            break;
+        case kCCMIOWrongDataTypeErr:
+            return "Wrong Data Type Error";
+            break;
+        case kCCMIONoDataErr:
+            return "NoData Error";
+            break;
+        case kCCMIOWrongParentErr:
+            return "Wrong Parent Error";
+            break;
+        case kCCMIOBadParameterErr:
+            return "Bad Parameter Error";
+            break;
+        case kCCMIONoMemoryErr:
+            return "No Memory Error";
+            break;
+        case kCCMIOIOErr:
+            return "IO Error";
+            break;
+        case kCCMIOTooManyFacesErr:
+            return "Too Many Faces Error";
+            break;
+        case kCCMIOVersionErr:
+            return "Version Error";
+            break;
+        case kCCMIOArrayDimensionToLargeErr:
+            return "Array Dimension To Large Error";
+            break;
+        case kCCMIOInternalErr:
+            return "Internal Error";
+            break;
+        default:
+            return "unclassified error";
+            break;
+    }
+}
+//! \endcond
+
+
+// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+bool Foam::ccm::ccmGlobalState::assertNoError
+(
+    CCMIOError err,
+    const char* msg
+)
+{
+    if (err != kCCMIONoErr)
+    {
+        Perr<< endl
+            << "--> FATAL ERROR:"
+            << "\n    " << msg
+            << "\n    libccmio reports -> " << errorMsg(err) << " <-\n"
+            << endl;
+
+        ::exit(1);
+    }
+
+    return (err == kCCMIONoErr);
+}
+
+
+bool Foam::ccm::ccmGlobalState::assertNoError
+(
+    CCMIOError err,
+    const std::string& msg
+)
+{
+    if (err != kCCMIONoErr)
+    {
+        assertNoError(err, msg.c_str());
+    }
+
+    return (err == kCCMIONoErr);
+}
+
+
+bool Foam::ccm::ccmGlobalState::assertNoError
+(
+    const char* msg
+) const
+{
+    return assertNoError(error, msg);
+}
+
+
+bool Foam::ccm::ccmGlobalState::assertNoError
+(
+    const std::string& msg
+) const
+{
+    return assertNoError(error, msg);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ccm::ccmGlobalState::ccmGlobalState()
+:
+    error(kCCMIONoErr)
+{
+    CCMIOInvalidateEntity(&root);
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/common/ccmInternal.H b/src/conversion/ccm/common/ccmInternal.H
new file mode 100644
index 0000000000000000000000000000000000000000..f528438dbea01c9f52e950dbba3774ad4b66ccab
--- /dev/null
+++ b/src/conversion/ccm/common/ccmInternal.H
@@ -0,0 +1,170 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Description
+    Internal bits for wrapping libccmio - do not use directly
+
+\*---------------------------------------------------------------------------*/
+#ifndef ccmInternal_H
+#define ccmInternal_H
+
+#include "className.H"
+#include "List.H"
+
+// headers and definitions for using libccmio
+#include "libccmio/ccmio.h"
+
+// low-level routines are also needed
+#include "libccmio/ccmiocore.h"
+#include "libccmio/ccmioutility.h"
+
+// don't want these defines to leak through
+#undef TRUE
+#undef FALSE
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// @cond
+// internal use only - skip doxygen documentation
+namespace Foam
+{
+namespace ccm
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Declare namespace and debug information.
+NamespaceName("ccm");
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+//- A C++ wrapper for the C struct
+class ccmID
+:
+    public CCMIOID
+{};
+
+//- A C++ wrapper for the C struct
+class ccmNODE
+:
+    public CCMIONode
+{
+public:
+
+    //- Recast constructor
+    ccmNODE(CCMIONode node)
+    :
+       CCMIONode(node)
+    {}
+};
+
+
+//- A C++ wrapper for the enum
+class ccmDimension
+{
+    CCMIODimensionality dims_;
+
+public:
+
+    //- Construct from components
+    ccmDimension(CCMIODimensionality dims)
+    :
+        dims_(dims)
+    {}
+
+    //- Return underlying enum
+    CCMIODimensionality operator()() const
+    {
+        return dims_;
+    }
+};
+
+
+//- Maintain overall global states (error, rootNode)
+class ccmGlobalState
+{
+public:
+
+    //- Maintain error state between calls
+    CCMIOError error;
+
+    //- Root node in the CCM file
+    ccmID root;
+
+    //- Null constructor. Start with no error, but root in invalid state.
+    ccmGlobalState();
+
+    //- True if there is an error
+    bool hasError() const
+    {
+        return (error != kCCMIONoErr);
+    }
+
+    //- Die with msg if there is an error
+    //  Return true if there is no error
+    static bool assertNoError(CCMIOError err, const char *msg);
+
+    //- Die with msg if there is an error
+    //  Return true if there is no error
+    static bool assertNoError(CCMIOError err, const std::string& msg);
+
+    //- Die with msg if there is an error
+    //  Return true if there is no error
+    bool assertNoError(const char *msg) const;
+
+    //- Die with msg if there is an error
+    //  Return true if there is no error
+    bool assertNoError(const std::string& msg) const;
+
+};
+
+
+//- MapIds for various parts
+class ccmMaps
+{
+public:
+    //- The cell map
+    ccmID cells;
+
+    //- The internalFaces map
+    ccmID internalFaces;
+
+    //- Boundary region maps
+    List<ccmID> boundary;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// @endcond
+// internal use only - skip doxygen documentation
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/misc/ListOps1.H b/src/conversion/ccm/misc/ListOps1.H
new file mode 100644
index 0000000000000000000000000000000000000000..7e8490240c748b82493c871ad3b625225c118f32
--- /dev/null
+++ b/src/conversion/ccm/misc/ListOps1.H
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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/>.
+
+InNamspace
+    Foam
+
+Description
+    Various functions to operate on Lists.
+
+SourceFiles
+    ListOps.C
+    ListOpsTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ListOps1_H
+#define ListOps1_H
+
+#include "ListOps.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+//- Reorder the elements (indices, not values) of a list.
+//  Negative ListType elements are untouched, unless pruning has been selected.
+//  With pruning, these elements are skipped and the list shrinks accordingly.
+template<class ListType>
+ListType reorder
+(
+    const labelUList& oldToNew,
+    const ListType&,
+    const bool prune
+);
+
+//- Inplace reorder the elements of a list.
+//  Negative ListType elements are untouched, unless pruning has been selected.
+//  With pruning, these elements are skipped and the list shrinks accordingly.
+template<class ListType>
+void inplaceReorder
+(
+    const labelUList& oldToNew,
+    ListType&,
+    const bool prune
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ListOps1Templates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
+
diff --git a/src/conversion/ccm/misc/ListOps1Templates.C b/src/conversion/ccm/misc/ListOps1Templates.C
new file mode 100644
index 0000000000000000000000000000000000000000..14a9ac38c9284f3e017187a76b188c73d8391d72
--- /dev/null
+++ b/src/conversion/ccm/misc/ListOps1Templates.C
@@ -0,0 +1,117 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015-2016 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 "ListOps1.H"
+
+// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
+
+template<class ListType>
+ListType Foam::reorder
+(
+    const labelUList& oldToNew,
+    const ListType& lst,
+    const bool prune
+)
+{
+    const label sz = lst.size();
+
+    // Create copy
+    ListType newLst(sz);
+
+    // Ensure consistent addressable size (eg, DynamicList)
+    newLst.setSize(sz);
+
+
+    label maxIdx = 0;
+    forAll(lst, elemI)
+    {
+        const label newIdx = oldToNew[elemI];
+        if (newIdx >= 0) // could also require newIdx < sz
+        {
+            newLst[newIdx] = lst[elemI];
+            if (prune && maxIdx < newIdx)
+            {
+                maxIdx = newIdx;
+            }
+        }
+        else if (!prune)
+        {
+            newLst[elemI] = lst[elemI];
+        }
+    }
+
+    if (prune && maxIdx < sz)
+    {
+        newLst.setSize(maxIdx);
+    }
+
+    return newLst;
+}
+
+
+template<class ListType>
+void Foam::inplaceReorder
+(
+    const labelUList& oldToNew,
+    ListType& lst,
+    const bool prune
+)
+{
+    const label sz = lst.size();
+
+    // Create copy
+    ListType newLst(sz);
+
+    // Ensure consistent addressable size (eg, DynamicList)
+    newLst.setSize(sz);
+
+    label maxIdx = 0;
+    forAll(lst, elemI)
+    {
+        const label newIdx = oldToNew[elemI];
+        if (newIdx >= 0) // could also require newIdx < sz
+        {
+            newLst[newIdx] = lst[elemI];
+            if (prune && maxIdx < newIdx)
+            {
+                maxIdx = newIdx;
+            }
+        }
+        else if (!prune)
+        {
+            newLst[elemI] = lst[elemI];
+        }
+    }
+
+    if (prune && maxIdx < sz)
+    {
+        newLst.setSize(maxIdx);
+    }
+
+    lst.transfer(newLst);
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/misc/mergePoints1.C b/src/conversion/ccm/misc/mergePoints1.C
new file mode 100644
index 0000000000000000000000000000000000000000..c1114df3ca0b6850af134dc77df5358e9bca9359
--- /dev/null
+++ b/src/conversion/ccm/misc/mergePoints1.C
@@ -0,0 +1,177 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "ListOps.H"
+#include "point.H"
+#include "Field.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+// template<class Type, template<class> class ListType=UList>
+template<class Type>
+Foam::label Foam::mergePoints
+(
+    const bool dummy,
+    const UIndirectList<Type>& points,
+    const scalar mergeTol,
+    const bool verbose,
+    labelList& pointMap,
+    const Type& origin
+)
+{
+    // Create a old to new point mapping array
+    pointMap.setSize(points.size());
+    pointMap = -1;
+
+    if (points.empty())
+    {
+        return 0;
+    }
+
+    // No normal field operations on UIndirectList.
+    // Use a tmp pointField instead.
+    tmp<Field<Type>> tPoints(new pointField(points));
+
+    Type compareOrigin = origin;
+    if (origin == Type::max)
+    {
+        compareOrigin = sum(tPoints())/points.size();
+    }
+
+    // We're comparing distance squared to origin first.
+    // Say if starting from two close points:
+    //     x, y, z
+    //     x+mergeTol, y+mergeTol, z+mergeTol
+    // Then the magSqr of both will be
+    //     x^2+y^2+z^2
+    //     x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*...
+    // so the difference will be 2*mergeTol*(x+y+z)
+
+    const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol));
+
+    // Sort points by magSqr
+    const Field<Type> d(tPoints - compareOrigin);
+
+    List<scalar> magSqrD(d.size());
+    forAll(d, pointI)
+    {
+        magSqrD[pointI] = magSqr(d[pointI]);
+    }
+    labelList order;
+    sortedOrder(magSqrD, order);
+
+
+    Field<scalar> sortedTol(points.size());
+    forAll(order, sortI)
+    {
+        label pointI = order[sortI];
+
+        // Convert to scalar precision
+        const point pt
+        (
+            scalar(d[pointI].x()),
+            scalar(d[pointI].y()),
+            scalar(d[pointI].z())
+        );
+        sortedTol[sortI] = 2*mergeTol*(mag(pt.x())+mag(pt.y())+mag(pt.z()));
+    }
+
+    label newPointI = 0;
+
+    // Handle 0th point separately (is always unique)
+    label pointI = order[0];
+    pointMap[pointI] = newPointI++;
+
+
+    for (label sortI = 1; sortI < order.size(); sortI++)
+    {
+        // Get original point index
+        label pointI = order[sortI];
+        const scalar mag2 = magSqrD[order[sortI]];
+        // Convert to scalar precision
+        const point pt
+        (
+            scalar(points[pointI].x()),
+            scalar(points[pointI].y()),
+            scalar(points[pointI].z())
+        );
+
+
+        // Compare to previous points to find equal one.
+        label equalPointI = -1;
+
+        for
+        (
+            label prevSortI = sortI - 1;
+            prevSortI >= 0
+         && (mag(magSqrD[order[prevSortI]] - mag2) <= sortedTol[sortI]);
+            prevSortI--
+        )
+        {
+            label prevPointI = order[prevSortI];
+            const point prevPt
+            (
+                scalar(points[prevPointI].x()),
+                scalar(points[prevPointI].y()),
+                scalar(points[prevPointI].z())
+            );
+
+            if (magSqr(pt - prevPt) <= mergeTolSqr)
+            {
+                // Found match.
+                equalPointI = prevPointI;
+
+                break;
+            }
+        }
+
+
+        if (equalPointI != -1)
+        {
+            // Same coordinate as equalPointI. Map to same new point.
+            pointMap[pointI] = pointMap[equalPointI];
+
+            if (verbose)
+            {
+                Pout<< "Foam::mergePoints : Merging points "
+                    << pointI << " and " << equalPointI
+                    << " with coordinates:" << points[pointI]
+                    << " and " << points[equalPointI]
+                    << endl;
+            }
+        }
+        else
+        {
+            // Differs. Store new point.
+            pointMap[pointI] = newPointI++;
+        }
+    }
+
+    return newPointI;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.H b/src/conversion/ccm/misc/mergePoints1.H
similarity index 66%
rename from src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.H
rename to src/conversion/ccm/misc/mergePoints1.H
index dd37ca049c1332b85e4a67022478a4b39154d89f..85fc56210a289be0d488e89985d0edaab10e13dc 100644
--- a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.H
+++ b/src/conversion/ccm/misc/mergePoints1.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -21,60 +21,50 @@ License
     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::fileFormats::WRLsurfaceFormatCore
-
 Description
-    Internal class used by the WRLsurfaceFormat
+    Merge points. See below.
 
 SourceFiles
-    WRLsurfaceFormatCore.C
+    mergePoints.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef WRLsurfaceFormatCore_H
-#define WRLsurfaceFormatCore_H
+#ifndef mergePoints1_H
+#define mergePoints1_H
 
-#include "Ostream.H"
-#include "OFstream.H"
-#include "MeshedSurface.H"
+#include "scalar.H"
+#include "labelList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-namespace fileFormats
-{
 
 /*---------------------------------------------------------------------------*\
-                    Class WRLsurfaceFormatCore Declaration
+                           Function mergePoints Declaration
 \*---------------------------------------------------------------------------*/
 
-class WRLsurfaceFormatCore
-{
-protected:
-    // Protected Member Functions
-
-    //- Write file header
-    static void writeHeader
-    (
-        Ostream&,
-        const pointField&,
-        const label nFaces,
-        const UList<surfZone>&
-    );
-
-
-    //- Write appearance node
-    static void writeAppearance(Ostream&);
-
-};
+//- Sorts and merges points. All points closer than/equal mergeTol get merged.
+//  Returns the number of unique points and a map from old to new.
+//template<class Type, template<class> class ListType=UList>
+template<class Type>
+label mergePoints
+(
+    const bool dummy,
+    const UIndirectList<Type>& points,
+    const scalar mergeTol,
+    const bool verbose,
+    labelList& pointMap,
+    const Type& origin = Type::zero
+);
 
+} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace fileFormats
-} // End namespace Foam
+#ifdef NoRepository
+    #include "mergePoints1.C"
+#endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/conversion/ccm/reader/ccmBoundaryInfo.H b/src/conversion/ccm/reader/ccmBoundaryInfo.H
new file mode 100644
index 0000000000000000000000000000000000000000..967c6f51e1071f28df17294daa011fb78d22bc59
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmBoundaryInfo.H
@@ -0,0 +1,126 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Description
+    Containers for holding STARCCM boundary information
+
+\*---------------------------------------------------------------------------*/
+#ifndef ccmBoundaryInfo_H
+#define ccmBoundaryInfo_H
+
+#include "word.H"
+#include "Ostream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//! \cond internal-use
+// internal use only - skip doxygen documentation
+namespace Foam
+{
+namespace ccm
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class ccm::ccmBoundaryInfo Declaration
+\*---------------------------------------------------------------------------*/
+
+//- Helper when reading raw boundary information
+class ccmBoundaryInfo
+{
+public:
+    //- The ccm region
+    int ccmIndex;
+
+    //- Number of faces
+    label size;
+
+    //- The openfoam patch id to map to
+    label patchId;
+
+    //- The patch name, as per the BoundaryRegion "Label" entry
+    std::string patchName;
+
+    //- The patch type, as per the BoundaryRegion "BoundaryType" entry
+    std::string patchType;
+
+
+    //- Construct null
+    ccmBoundaryInfo()
+    :
+        ccmIndex(0),
+        size(0),
+        patchId(-1),
+        patchName(),
+        patchType("patch")
+    {}
+
+
+    //- Set patch name, default to "patch_CCMID" for an empty string
+    void setPatchName(const std::string& str)
+    {
+        if (str.empty())
+        {
+            patchName = "patch_" + ::Foam::name(ccmIndex);
+        }
+        else
+        {
+            patchName = str;
+        }
+    }
+
+
+    //- Info doesn't match if the ccm boundaries are different
+    bool operator!=(const ccmBoundaryInfo& rhs) const
+    {
+        return ccmIndex != rhs.ccmIndex;
+    }
+
+   // IOstream Operators
+
+    friend Ostream& operator<<(Ostream& os, const ccmBoundaryInfo& entry)
+    {
+        os  << "BoundaryFaces-" << entry.ccmIndex;
+        os  << " size=" << entry.size;
+        os  << " name=" << entry.patchName;
+        os  << " type=" << entry.patchType;
+        os  << " foam-patch=" << entry.patchId;
+
+        return os;
+    }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+//! \endcond
+// internal use only - skip doxygen documentation
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmInterfaceDefinitions.H b/src/conversion/ccm/reader/ccmInterfaceDefinitions.H
new file mode 100644
index 0000000000000000000000000000000000000000..1c9ea2c8e55da3b5ee3642f1afc118a0f339a984
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmInterfaceDefinitions.H
@@ -0,0 +1,252 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Description
+    Containers for holding STARCCM interface definitions
+
+\*---------------------------------------------------------------------------*/
+#ifndef ccmInterfaceDefinitions_H
+#define ccmInterfaceDefinitions_H
+
+#include "Map.H"
+#include "Ostream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ccm
+{
+
+/*---------------------------------------------------------------------------*\
+                     Class ccm::interfaceEntry Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A STARCCM interface definition is a pair of boundary ids
+class interfaceEntry
+{
+public:
+    // Public Data
+
+        //- The internal interface id
+        label id;
+
+        //- The first boundary
+        label bnd0;
+
+        //- The second boundary
+        label bnd1;
+
+    // Constructors
+
+        //- Construct null
+        interfaceEntry()
+        :
+            id(-1),
+            bnd0(-1),
+            bnd1(-1)
+        {}
+
+
+        //- Construct empty interface definition
+        interfaceEntry(const label index)
+        :
+            id(index),
+            bnd0(-1),
+            bnd1(-1)
+        {}
+
+
+        //- Construct from components
+        interfaceEntry
+        (
+            const label index,
+            const label boundary0,
+            const label boundary1
+        )
+        :
+            id(index),
+            bnd0(boundary0),
+            bnd1(boundary1)
+        {}
+
+
+    // Access
+
+        //- Check for in-place interfaces
+        static bool isInPlace(const std::string& configurationType)
+        {
+            return configurationType == "IN_PLACE";
+        }
+
+
+        //- True if the boundary id is in this interface
+        bool inInterface(label bndId) const
+        {
+            return bndId == bnd0 || bndId == bnd1;
+        }
+
+
+        //- Canonical name for boundary 0
+        word canonicalName0() const
+        {
+            return "Interface" + ::Foam::name(id) + "_0";
+        }
+
+        //- Canonical name for boundary 1
+        word canonicalName1() const
+        {
+            return "Interface" + ::Foam::name(id) + "_1";
+        }
+
+        //- Canonical name for boundary
+        word canonicalName(label bndId) const
+        {
+            if (bndId == bnd0)
+            {
+                return canonicalName0();
+            }
+            else if (bndId == bnd1)
+            {
+                return canonicalName1();
+            }
+            else
+            {
+                return word::null;
+            }
+        }
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const interfaceEntry& entry
+        )
+        {
+            os  << "(" << entry.bnd0 << " " << entry.bnd1 << ")";
+            return os;
+        }
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                  Class ccm::interfaceDefinitions Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A list of available interface definitions
+class interfaceDefinitions
+:
+    public Map<interfaceEntry>
+{
+public:
+    // Constructor
+
+        //- Null construct
+        interfaceDefinitions()
+        :
+            Map<interfaceEntry>()
+        {}
+
+
+        //- Scan available interface entries for one matching this boundary id
+        bool add(interfaceEntry entry)
+        {
+            if
+            (
+                entry.id >= 0
+             && entry.bnd0 >= 0 && entry.bnd1 >= 0
+             && entry.bnd0 != entry.bnd1
+            )
+            {
+                this->set(entry.id, entry);
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+
+        //- Scan available interface entries for one matching this boundary id
+        bool isInterface(label bndId)
+        {
+            forAllConstIter(Map<interfaceEntry>, *this, iter)
+            {
+                if (iter().inInterface(bndId))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+
+        //- Scan interface entries for one matching this boundary id
+        //  return the canonical name
+        word interfaceName(label bndId)
+        {
+            word ifname;
+            forAllConstIter(Map<interfaceEntry>, *this, iter)
+            {
+                ifname = iter().canonicalName(bndId);
+                if (!ifname.empty())
+                {
+                    break;
+                }
+            }
+
+            return ifname;
+        }
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const interfaceDefinitions& defs
+        )
+        {
+            os  << static_cast<const Map<interfaceEntry>& >(defs)
+                << nl;
+
+            return os;
+        }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReader.C b/src/conversion/ccm/reader/ccmReader.C
new file mode 100644
index 0000000000000000000000000000000000000000..5d0c6f11579837bdaf874a34af474e6949a316c8
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReader.C
@@ -0,0 +1,801 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmReader.H"
+#include "IFstream.H"
+#include "IOdictionary.H"
+#include "demandDrivenData.H"
+
+#include "ccmInternal.H"  // include last to avoid any strange interactions
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// The cellTable integer options
+const char* Foam::ccm::reader::cellTableOpti[] =
+{
+    "MaterialId", "PorosityId", "SpinId", "GroupId", "ColorIdx", nullptr
+};
+
+// The cellTable string options - "Label" handled separately
+const char* Foam::ccm::reader::cellTableOptstr[] =
+{
+    "MaterialType", nullptr
+};
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// Simulate GetEntityIndex
+// CCMIOGetEntityIndex(nullptr, nodeId, &internalId);
+int Foam::ccm::reader::ccmGetEntityIndex(ccmNODE node)
+{
+    int intval = 0;
+    char name[kCCMIOMaxStringLength + 1];
+
+    if
+    (
+        CCMIOGetName
+        (
+            nullptr,
+            node,
+            name
+        )
+        == kCCMIONoErr
+    )
+    {
+        char const *pos = strrchr(name, '-');
+
+        if (!pos)
+        {
+            intval = 0;
+        }
+        else
+        {
+            // Negative ID number
+            if (pos != name && (*(pos - 1) == '-'))
+                --pos;
+
+            intval = atoi(++pos);
+        }
+    }
+
+    return intval;
+}
+
+
+std::string Foam::ccm::reader::ccmReadNodestr
+(
+    const char* opt,
+    ccmNODE node
+)
+{
+    char *strval = 0;
+    std::string str;
+
+    if
+    (
+        CCMIOReadNodestr
+        (
+            nullptr,
+            node,
+            opt,
+            &strval
+        )
+     == kCCMIONoErr
+     && strval
+    )
+    {
+        str = strval;
+    }
+
+    // allocated by CCMIOReadNodestr
+    if (strval)
+    {
+        free(strval);
+    }
+
+    return str;
+}
+
+
+std::string Foam::ccm::reader::ccmReadOptstr
+(
+    const char* opt,
+    ccmID node
+)
+{
+    std::string str;
+    int len = 0;
+
+    if
+    (
+        CCMIOReadOptstr
+        (
+            nullptr,
+            node,
+            opt,
+            &len,
+            nullptr
+        )
+     == kCCMIONoErr
+     && len
+    )
+    {
+        char* strval = new char[len + 1];
+        if
+        (
+            CCMIOReadOptstr
+            (
+                nullptr,
+                node,
+                opt,
+                &len,
+                strval
+            )
+         == kCCMIONoErr
+        )
+        {
+            strval[len] = '\0';
+            str = strval;
+        }
+        delete[] strval;
+    }
+
+    return str;
+}
+
+
+Foam::word Foam::ccm::reader::validateWord
+(
+    const std::string& str
+)
+{
+    std::string::size_type ngood = 0;
+    bool prefix = false;
+    bool first  = true;
+
+    for
+    (
+        std::string::const_iterator iter = str.begin();
+        iter != str.end();
+        ++iter
+    )
+    {
+        if (word::valid(*iter))
+        {
+            ++ngood;
+            if (first)
+            {
+                first = false;
+
+                // start with a digit? need to prefix with '_'
+                if (isdigit(*iter))
+                {
+                    prefix = true;
+                    ++ngood;
+                }
+            }
+        }
+    }
+
+    if (ngood == str.size() && !prefix)
+    {
+        return str;
+    }
+
+    Foam::word out;
+    out.resize(ngood);
+    ngood = 0;
+
+    Foam::word::iterator iter2 = out.begin();
+    for
+    (
+        std::string::const_iterator iter1 = str.begin();
+        iter1 != str.end();
+        ++iter1
+    )
+    {
+        register char c = *iter1;
+
+        if (Foam::word::valid(c))
+        {
+            if (prefix)
+            {
+                prefix = false;
+                *(iter2++) = '_';
+                ++ngood;
+            }
+            *(iter2++) = c;
+            ++ngood;
+        }
+    }
+
+    out.resize(ngood);
+
+    return out;
+}
+
+
+// read map data and check error
+void Foam::ccm::reader::readMap
+(
+    const ccmID& mapId,
+    labelList& data
+)
+{
+    if (globalState_->hasError())
+    {
+        return;
+    }
+
+    CCMIOReadMap
+    (
+        &(globalState_->error),
+        mapId,
+        data.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("error reading map");
+}
+
+
+// readProblemDescription:
+// - get cellTable and boundaryRegion information
+// - some regions defined here may be unused by our mesh
+void Foam::ccm::reader::readProblemDescription
+(
+    const ccmID& probNode
+)
+{
+    readInterfaceDefinitions();
+    readProblemDescription_boundaryRegion(probNode);
+    readProblemDescription_cellTable(probNode);
+
+#ifdef DEBUG_CCMIOREAD
+    Info<< "InterfaceDefinitions: " << interfaceDefinitions_ << nl
+        << "cellTable" << cellTable_ << nl
+        << "boundaryRegion" << boundaryRegion_ << endl;
+#endif
+}
+
+
+// readInterfaceDefinitions:
+// - get /InterfaceDefinitions. used by STARCCM to define in-place interfaces, etc
+// - only handle in-place one here
+void Foam::ccm::reader::readInterfaceDefinitions()
+{
+    interfaceDefinitions_.clear();
+
+    // /InterfaceDefinitions
+    // ---------------------
+
+    CCMIONode rootNode;
+    CCMIONode interfaceDefNode;
+
+    // CCMIOID -> CCMIONODE
+    if
+    (
+        CCMIOGetEntityNode
+        (
+            nullptr,
+            (globalState_->root),
+            &rootNode
+        )
+     == kCCMIONoErr
+
+        // get "/InterfaceDefinitions"
+     &&
+        CCMIOGetNode
+        (
+            nullptr,
+            rootNode,
+            "InterfaceDefinitions",
+            &interfaceDefNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        CCMIONode interfaceNode;
+
+        // simulate CCMIONextEntity
+        for
+        (
+            int index = 0;
+            CCMIOGetNextChildWithLabel
+            (
+                nullptr,
+                interfaceDefNode,
+                "Interface",
+                &index,
+                &interfaceNode
+            ) == kCCMIONoErr;
+            /* nop */
+        )
+        {
+            interfaceEntry ifentry(ccmGetEntityIndex(interfaceNode));
+
+            if
+            (
+                CCMIOReadNodei
+                (
+                    nullptr,
+                    interfaceNode,
+                    "Boundary0",
+                    &(ifentry.bnd0)
+                )
+             == kCCMIONoErr
+
+             && CCMIOReadNodei
+                (
+                    nullptr,
+                    interfaceNode,
+                    "Boundary1",
+                    &(ifentry.bnd1)
+                )
+             == kCCMIONoErr
+
+                // only handle 'IN_PLACE' interfaces
+             && interfaceEntry::isInPlace
+                (
+                    ccmReadNodestr("Configuration", interfaceNode)
+                )
+            )
+            {
+                interfaceDefinitions_.add(ifentry);
+            }
+        }
+    }
+}
+
+
+// readProblemDescription - get boundaryRegion information
+//
+// CCM Node: /ProblemDescriptions/ProblemDescription-N/BoundaryRegion-N
+//
+// Requires InterfaceDefinitions first
+void Foam::ccm::reader::readProblemDescription_boundaryRegion
+(
+    const ccmID& probNode
+)
+{
+    if (option().useNumberedNames())
+    {
+        Info<< "using numbered patch/zone names" << endl;
+    }
+
+    boundaryRegion_.clear();
+
+    ccmID node;
+
+    // boundaryRegion information
+    // --------------------------
+    for
+    (
+        int nodeI = 0;
+        CCMIONextEntity
+        (
+            nullptr,
+            probNode,
+            kCCMIOBoundaryRegion,
+            &nodeI,
+            &node
+        ) == kCCMIONoErr;
+        /* nop */
+    )
+    {
+        // read boundaryRegionId
+        int Id = 0;
+        CCMIOGetEntityIndex
+        (
+            &(globalState_->error),
+            node,
+            &Id
+        );
+        assertNoError("error reading boundaryRegion index");
+
+        dictionary dict;
+
+        // Read boundary type
+        // (inlet|outlet|symmetry|wall|
+        //   cyclic|stagnation|pressure|baffle|freestream)
+        {
+            const char* opt = "BoundaryType";
+            std::string str = ccmReadOptstr(opt, node);
+
+            if (str.empty())
+            {
+                dict.add(opt, "empty");
+            }
+            else if (str == "internal")
+            {
+                // old PROSTAR bug: "monitoring" mislabeled as "internal"
+                dict.add(opt, "monitoring");
+            }
+            else
+            {
+                dict.add(opt, validateWord(str));
+            }
+        }
+
+
+        // Read boundary name:
+        // - from 'Label' field (STARCCM+)
+        // - from 'BoundaryName' field (PROSTAR and/or STARCCM+)
+        // - fallback: generate one from boundary type and boundaryRegionId
+        {
+            const char* opt = "Label";
+            std::string str;
+
+            if (option().useNumberedNames())
+            {
+                str = "patch_" + ::Foam::name(Id);
+            }
+            else if
+            (
+                option().renameInterfaces()
+             && interfaceDefinitions_.isInterface(Id)
+            )
+            {
+#ifdef DEBUG_CCMIOREAD
+                Info<< "boundary is on an interface: remap name for  " << Id << endl;
+#endif
+                // substitute immediately with interface name
+                str = interfaceDefinitions_.interfaceName(Id);
+            }
+            else if
+            (
+                (str = ccmReadOptstr(opt, node)).empty()
+             && (str = ccmReadOptstr("BoundaryName", node)).empty()
+            )
+            {
+                // fallback
+                str = word(dict["BoundaryType"]) + "_" + ::Foam::name(Id);
+            }
+
+            if (!str.empty())
+            {
+                dict.add(opt, validateWord(str));
+            }
+        }
+
+        boundaryRegion_.insert(Id, dict);
+    }
+}
+
+
+// readProblemDescription - get cellTable information
+//
+// CCM Node: /ProblemDescriptions/ProblemDescription-N/CellType-N
+//
+void Foam::ccm::reader::readProblemDescription_cellTable
+(
+    const ccmID& probNode
+)
+{
+    cellTable_.clear();
+
+    ccmID node;
+
+    // cellTable information
+    // ---------------------
+    for
+    (
+        int nodeI = 0;
+        CCMIONextEntity
+        (
+            nullptr,
+            probNode,
+            kCCMIOCellType,
+            &nodeI,
+            &node
+        ) == kCCMIONoErr;
+        /* nop */
+    )
+    {
+        // Read cellTableId (CellType)
+        int Id = 0;
+        CCMIOGetEntityIndex
+        (
+            &(globalState_->error),
+            node,
+            &Id
+        );
+        assertNoError("error reading cellTable index");
+
+        dictionary dict;
+
+        // Special treatment for "Label"
+        {
+            const char* opt = "Label";
+            std::string str;
+
+            if (!option().useNumberedNames())
+            {
+                str = ccmReadOptstr(opt, node);
+            }
+
+            if (str.empty())
+            {
+                str = "zone_" + ::Foam::name(Id);
+            }
+
+            dict.add(opt, validateWord(str));
+        }
+
+
+        // Other string options
+        for (int i=0; cellTableOptstr[i]; ++i)
+        {
+            const char* opt = cellTableOptstr[i];
+            std::string str = ccmReadOptstr(opt, node);
+
+            if (!str.empty())
+            {
+                dict.add(opt, validateWord(str));
+            }
+        }
+
+        // Add non-zero integer options
+        for (int i=0; cellTableOpti[i]; ++i)
+        {
+            const char* opt = cellTableOpti[i];
+            int intval;
+
+            if
+            (
+                CCMIOReadOpti
+                (
+                    nullptr,
+                    node,
+                    opt,
+                    &intval
+                )
+             == kCCMIONoErr
+             && intval != 0
+            )
+            {
+                dict.add(opt, intval);
+            }
+        }
+
+        cellTable_.insert(Id, dict);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ccm::reader::printInfo() const
+{
+    Info<< "Mesh Information" << nl
+        << "----------------" << nl
+        << "boundingBox: " << boundBox(points_) << nl
+        << "nPoints: " << nPoints_ << nl
+        << "nCells: " << nCells_ << nl
+        << "nFaces: " << nFaces_ << nl
+        << "nInternalFaces: " << nInternalFaces_ << nl
+        << "nBaffles: " << bafInterfaces_.size() << endl;
+}
+
+
+bool Foam::ccm::reader::readGeometry
+(
+    const scalar scaleFactor
+)
+{
+    detectGeometry();
+
+    if (geometryStatus_ == OKAY)
+    {
+        // Sanity on the scaling factor
+
+        readMeshTopology(scaleFactor <= VSMALL ? 1 : scaleFactor);
+        reorderMesh();
+
+        // assume success if we have points and cells
+        if (nCells_ && points_.size())
+        {
+            geometryStatus_ = READ;
+        }
+        else
+        {
+            geometryStatus_ = BAD;
+        }
+    }
+
+    return (geometryStatus_ == OKAY || geometryStatus_ == READ);
+}
+
+
+bool Foam::ccm::reader::hasGeometry()
+{
+    detectGeometry();
+    return (geometryStatus_ == OKAY || geometryStatus_ == READ);
+}
+
+
+bool Foam::ccm::reader::hasSolution()
+{
+    detectSolution();
+    return (solutionStatus_ == OKAY || solutionStatus_ == READ);
+}
+
+
+void Foam::ccm::reader::writeMesh
+(
+    const polyMesh& mesh,
+    IOstream::streamFormat fmt
+) const
+{
+    mesh.removeFiles();
+
+    Info<< "Writing polyMesh" << endl;
+    mesh.writeObject
+    (
+        fmt,
+        IOstream::currentVersion,
+        IOstream::UNCOMPRESSED
+    );
+    writeAux(mesh);
+}
+
+
+bool Foam::ccm::reader::remapMeshInfo
+(
+    const objectRegistry& registry,
+    const fileName& remappingDictName
+)
+{
+    dictionary remapDict;
+
+    if (remappingDictName.empty())
+    {
+        remapDict = IOdictionary
+        (
+            IOobject
+            (
+                "remapping",
+                "constant",
+                registry,
+                IOobject::READ_IF_PRESENT,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+    }
+    else
+    {
+        // specified (absolute) name: treat like MUST_READ
+        remapDict = dictionary(IFstream(remappingDictName)());
+    }
+
+    bool ok = false;
+
+    if (remapDict.empty())
+    {
+        return false;
+    }
+
+
+    // merge specified cellTable entries together
+    if (remapDict.isDict("cellTable"))
+    {
+        cellTable_.combine(remapDict.subDict("cellTable"), cellTableId_);
+        ok = true;
+    }
+
+    // rename boundaries
+    if (remapDict.isDict("boundaryRegion"))
+    {
+        boundaryRegion_.rename(remapDict.subDict("boundaryRegion"));
+        ok = true;
+    }
+
+    return ok;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+// Construct from reading a file
+Foam::ccm::reader::reader
+(
+    const fileName& file,
+    const reader::options& opts
+)
+:
+    base(),
+    options_(new options(opts)),
+    geometryStatus_(UNKNOWN),
+    solutionStatus_(UNKNOWN),
+    interfaceDefinitions_(),
+    boundaryRegion_(),
+    cellTable_(),
+    nPoints_(0),
+    nInternalFaces_(0),
+    nFaces_(0),
+    nCells_(0),
+    points_(),
+    faces_(),
+    faceOwner_(),
+    faceNeighbour_(),
+    bafInterfaces_(),
+    domInterfaces_(),
+    origFaceId_(),
+    origCellId_(),
+    cellTableId_(),
+    origBndId_(),
+    patchSizes_(),
+    solutionTable_(),
+    fieldTable_(),
+    lagrangianTable_()
+{
+    if (!option().keptSomeRegion())
+    {
+        FatalErrorIn("ccm::reader(const fileName&)")
+            << "must retain at least one region type: fluid | porous | solid"
+            << exit(FatalError);
+    }
+
+    if (!isFile(file, false))
+    {
+        FatalErrorIn("ccm::reader(const fileName&)")
+            << "Cannot read file " << file
+            << exit(FatalError);
+    }
+
+    // Reinitialize error state from the return value
+    globalState_->error = CCMIOOpenFile
+    (
+        nullptr,
+        file.c_str(),
+        kCCMIORead,
+        &(globalState_->root)
+    );
+    assertNoError("Error opening file for reading");
+
+    detectGeometry();
+    detectSolution();
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ccm::reader::~reader()
+{
+    close();
+    deleteDemandDrivenData(options_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+const Foam::ccm::reader::options& Foam::ccm::reader::option() const
+{
+    return *options_;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReader.H b/src/conversion/ccm/reader/ccmReader.H
new file mode 100644
index 0000000000000000000000000000000000000000..aa15978dd35314388bf4de9c407fe4c41c19a710
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReader.H
@@ -0,0 +1,710 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ccm::reader
+
+Description
+    Reads CCM files as written by PROSTAR/STARCCM
+
+    - arbitrary polyhedral meshs
+    - writes interfaces (baffles) to constant/polymesh/interfaces
+    - experimental handling of monitoring (internal) boundaries
+    - does not handle cyclics. Use createPatch to recreate these
+    - does patch names only if they are in the problem description
+    - reads cell and face solution data
+    - reads Lagrangian data
+
+    The Default_Boundary_Region (region 0) is a special region that serves
+    two purposes:
+    -# it contains all wall and baffle boundaries that have not otherwise
+       been assigned.
+    -# it holds the outer bounds of flow domains (fluid/porous/solid)
+
+    The CCM node \c Meshes/FaceBasedTopology/Cells/Interfaces holds the mapping
+    of the corresponding mesh faces, which can be used to merge these internal
+    boundaries.
+
+    If solid cells exist, there are three possible courses of action:
+    -# Remove all solid cells for subsequent flow calculations.
+       This is the default.
+    -# Treat solid cells like fluid cells, but convert the corresponding
+       Default_Boundary_Region to Default_Boundary_Solid for easier
+       identification.
+       This treatment is useful for visualization purposes.
+    -# Move solid cells to a separate mesh region.
+       This would be useful for conjugate heat transfer, but
+       is not implemented.
+
+    \par Files
+
+    The <tt>constant/remapping</tt> file is an \c IOdictionary that is
+    \c READ_IF_PRESENT and can be used to remap certain information. eg,
+
+    \verbatim
+        // rename/combine cellTable entries
+        //   newName ( listOldNames );
+        cellTable
+        {
+            fluid ( inletRegion outletRegion );
+            cat1  ( CAT1 "cat1_(Back|Front|Gamma)" );
+        }
+
+        // rename boundary regions
+        //   newName oldName;
+        boundaryRegion
+        {
+            inlet_4  inlet_1;
+            inlet_5  inlet_2;
+            inlet_6  inlet_3;
+        }
+    \endverbatim
+
+    The <tt>constant/boundaryRegion</tt> file is an \c IOMap<dictionary>
+    that is written. It contains the boundary type and names. eg,
+
+    \verbatim
+        (
+            0
+            {
+                BoundaryType    wall;
+                Label           Default_Boundary_Region;
+            }
+            1
+            {
+                BoundaryType    inlet;
+                Label           inlet_1;
+            }
+            ...
+
+            4
+            {
+                BoundaryType    pressure;
+                Label           outlet;
+            }
+        )
+    \endverbatim
+
+    The <tt>constant/cellTable</tt> file is an \c IOMap<dictionary> that is
+    written. It contains the cellTable information.
+    eg,
+
+    \verbatim
+        (
+            1
+            {
+                Label           inletRegion;
+                MaterialType    fluid;
+                MaterialId      1;
+            }
+            2
+            {
+                Label           cat1;
+                MaterialType    fluid;
+                MaterialId      1;
+                PorosityId      1;
+            }
+            3
+            {
+                Label           outletRegion;
+                MaterialType    fluid;
+                MaterialId      1;
+            }
+        )
+    \endverbatim
+
+Note
+    this class is still under development
+    - any/all of the class names and members may change
+
+SourceFiles
+    ccmReader.C
+    ccmReaderAux.C
+    ccmReaderMesh.C
+    ccmReaderSolution.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ccmReader_H
+#define ccmReader_H
+
+#include "ccmBase.H"
+#include "STARCDCore.H"
+
+#include "labelList.H"
+#include "ListOps.H"
+#include "polyMesh.H"
+#include "boundaryRegion.H"
+#include "cellTable.H"
+#include "ccmInterfaceDefinitions.H"
+#include "ccmSolutionTable.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ccm
+{
+
+// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
+
+class ccmID;
+class ccmNODE;
+class ccmGlobalState;
+class reader;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+/*---------------------------------------------------------------------------*\
+                         Class ccm::reader Declaration
+\*---------------------------------------------------------------------------*/
+
+class reader
+:
+    public base,
+    protected fileFormats::STARCDCore
+{
+public:
+    // Forward Declarations
+    class options;
+
+
+private:
+
+    // Static Data
+
+        //- cellTable integer options
+        static const char* cellTableOpti[];
+
+        //- cellTable string options
+        static const char* cellTableOptstr[];
+
+
+    // Private data
+
+        //- Reader options
+        const options* options_;
+
+
+        //- Enumeration defining the status of a ccmio node
+        enum nodeStatus
+        {
+            UNKNOWN, BAD, OKAY, READ
+        };
+
+
+        //- status of the geometry (topology) information
+        nodeStatus geometryStatus_;
+
+        //- status of the solution (field) information
+        nodeStatus solutionStatus_;
+
+        // Persistent data
+
+        //- ccm node: /InterfaceDefinitions
+        interfaceDefinitions interfaceDefinitions_;
+
+        //- ccm node: ProblemDescriptions/boundaryRegion
+        boundaryRegion boundaryRegion_;
+
+        //- ccm node: ProblemDescriptions/cellType
+        cellTable cellTable_;
+
+        //- Number of points
+        label nPoints_;
+
+        //- Number of internal faces
+        label nInternalFaces_;
+
+        //- Number of faces
+        label nFaces_;
+
+        //- Number of cells
+        label nCells_;
+
+        //- Minimum mesh data
+
+        //- Points
+        pointField points_;
+
+        //- Faces
+        faceList faces_;
+
+        //- Face-owner cells
+        labelList faceOwner_;
+
+        //- Face-neighbour cells
+        labelList faceNeighbour_;
+
+        // List of interface pairs (baffles)
+        List<labelPair> bafInterfaces_;
+
+        //- List of interface pairs between mesh regions (domains)
+        List<labelPair> domInterfaces_;
+
+        //- Face sets for monitoring
+        HashTable<labelList> monitoringSets_;
+
+
+    // Mesh Maps
+
+        //- Map to original face id
+        labelList origFaceId_;
+
+        //- Map to original cell id
+        labelList origCellId_;
+
+        //- Cell table id for each cell
+        labelList cellTableId_;
+
+        //- List of the original ccm boundary region number
+        labelList origBndId_;
+
+        //- Patching and region info
+        labelList patchSizes_;
+
+        //- Solution information
+        solutionTable   solutionTable_;
+
+        //- Field information
+        fieldTable      fieldTable_;
+
+        //- Field information
+        fieldTable      lagrangianTable_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        reader(const reader&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const reader&) = delete;
+
+
+        //- Calculate patch starts from given index with current patch sizes
+        inline labelList patchStartList(label initial) const;
+
+        //- Report mesh sizes to stdout
+        void printSizes() const;
+
+        //- Simulate CCMIOGetEntityIndex for Nodes (not ids)
+        int ccmGetEntityIndex(ccmNODE node);
+
+        //- Read string option from specified ccm node
+        //  return empty string on failure
+        std::string ccmReadNodestr(const char* opt, ccmNODE node);
+
+        //- Read string option from specified ccm node
+        //  return empty string on failure
+        std::string ccmReadOptstr(const char* opt, ccmID node);
+
+        //- Strip invalid characters, prefix leading digit with '_'
+        static word validateWord(const std::string&);
+
+        //- Read map data and check error
+        void readMap(const ccmID& mapId, labelList& data);
+
+        //- Determine if the geometry looks good
+        bool detectGeometry();
+
+        //- Get interfaces, cellTable and boundaryRegion information
+        void readProblemDescription(const ccmID& probNode);
+
+        //- Get /InterfaceDefinitions, used by STARCCM to define in-place interfaces, etc
+        //  only handle in-place (IN_PLACE) ones at the moment
+        void readInterfaceDefinitions();
+
+        //- Get boundaryRegion information
+        void readProblemDescription_boundaryRegion(const ccmID& probNode);
+
+        //- Get cellTable information
+        void readProblemDescription_cellTable(const ccmID& probNode);
+
+        //- Read the geometry without any sorting or renumbering
+        void readMeshTopology(const scalar scaleFactor=1.0);
+
+        //- Read the vertices
+        labelList readVertices
+        (
+            const ccmID& verticesNode,
+            const scalar scaleFactor = 1.0
+        );
+
+        //- Read the cells
+        void readCells(const ccmID& topoNode);
+
+        //- Read the interfaces
+        void readInterfaces(const ccmID& cellsNode);
+
+        //- Read the monitoring
+        void readMonitoring(const ccmID& topoId);
+
+        //- Move solid faces from Default_Boundary_Region -> Default_Boundary_Solid
+        void juggleSolids();
+
+        //- Remove unwanted fluid/porous/solid regions
+        void removeUnwanted();
+
+        //- Remove interfaces with face >= nFace
+        void validateInterface(List<labelPair>&);
+
+        //- Renumber interface faces
+        void renumberInterfaces(const List<label>&);
+
+        //- Remove interfaces between domains (fluid/porosity; fluid/solid, etc)
+        //  reorganize baffle interfaces into [0-N/2; N/2-N] lists at the
+        //  beginning of the corresponding patch
+        void cleanupInterfaces();
+
+        //- Merge the points and faces of in-place conformal interfaces
+        void mergeInplaceInterfaces();
+
+        //- Re-order mesh and ensure upper-triangular order
+        void reorderMesh();
+
+        //- Write interface (baffle) mapping
+        void writeInterfaces(const objectRegistry&) const;
+
+        //- Write List<label> in constant/polyMesh
+        void writeMeshLabelList
+        (
+            const objectRegistry& registry,
+            const word& propertyName,
+            const labelList& list,
+            IOstream::streamFormat fmt = IOstream::ASCII
+        ) const;
+
+        // polyMesh Friend Functions
+        void addPatches(polyMesh&) const;
+
+        //- Add faceZones based on monitoring boundary conditions
+        void addFaceZones(polyMesh&) const;
+
+        //- Get information about all available solutions
+        bool detectSolution();
+
+        //- Get information about available fields
+        //  assume that all fields are available for all solution intervals
+        void determineFieldInfo(const ccmID& fieldSetNode, fieldTable&);
+
+
+    // Static Members
+
+        //- Get map of porous regions
+        static Map<word> selectPorous(const Map<dictionary>&);
+
+
+public:
+
+    // Static Members
+
+        //- Warn about repeated name
+        static void warnDuplicates(const word& context, const wordList&);
+
+
+    // Constructors
+
+        //- Open a file for reading
+        reader(const fileName&, const options& opts);
+
+
+    //- Destructor (closes file)
+    ~reader();
+
+
+    // Member Functions
+
+    // Access
+
+        //- Reference to the reader options
+        const reader::options& option() const;
+
+
+        //- Construct the polyMesh from the read geometry
+        //  provide optional remapping dictionary
+        autoPtr<polyMesh> mesh
+        (
+            const objectRegistry& registry,
+            const fileName& remappingDictName = fileName::null
+        );
+
+
+        // label nPoints() const { return nPoints_; }
+        // label nInternalFaces() const { return nInternalFaces_; }
+        // label nFaces() const { return nFaces_; }
+        // label nCells() const { return nCells_; }
+
+        // const faceList&   faces() const { return faces_; }
+        // const labelList&  faceOwner() const { return faceOwner_; }
+        // const labelList&  faceNeighbour() const { return faceNeighbour_; }
+        // const pointField& points() const { return points_; }
+
+
+    // Check
+
+        //- Return true if file has geometry associated with it
+        bool hasGeometry();
+
+        //- Return true if file has solutions associated with it
+        bool hasSolution();
+
+
+    // Edit
+
+        //- Remap cellTable and boundaryRegion according to dictionary
+        bool remapMeshInfo
+        (
+            const objectRegistry& registry,
+            const fileName& remappingDictName = fileName::null
+        );
+
+
+    // Write
+
+        //- Write the polyMesh
+        void writeMesh
+        (
+            const polyMesh&,
+            IOstream::streamFormat fmt = IOstream::BINARY
+        ) const;
+
+        //- Write cellTable, boundaryRegion and interface information
+        void writeAux(const objectRegistry&) const;
+
+        //- Detect and read geometry if possible
+        bool readGeometry(const scalar scaleFactor = 1.0);
+
+        //- Print general information about the mesh
+        void printInfo() const;
+
+        //- Clear out some information after obtaining a polyMesh
+        void clearGeom();
+
+        //- Map to original cell Id
+        const labelList& origCellId() const
+        {
+            return origCellId_;
+        }
+
+        //- Map to original face Id
+        const labelList& origFaceId() const
+        {
+            return origFaceId_;
+        }
+
+        //- Return interface definitions map
+        const interfaceDefinitions& interfaceDefinitionsInfo() const
+        {
+            return interfaceDefinitions_;
+        }
+
+        //- Return boundaryRegion table
+        const boundaryRegion& boundaryTableInfo() const
+        {
+            return boundaryRegion_;
+        }
+
+        //- Return cell table
+        const cellTable& cellTableInfo() const
+        {
+            return cellTable_;
+        }
+
+        //- Return a list of names corresponding to fluids
+        Map<word> fluids() const
+        {
+            return cellTable_.fluids();
+        }
+
+        //- Return a list of names corresponding to solids
+        Map<word> solids() const
+        {
+            return cellTable_.solids();
+        }
+
+        //- Return table of available solutions
+        const solutionTable& solutions()
+        {
+            detectSolution();
+            return solutionTable_;
+        }
+
+        //- Return table of available fields
+        const fieldTable& fields()
+        {
+            detectSolution();
+            return fieldTable_;
+        }
+
+        //- Return table of available lagrangian fields
+        const fieldTable& lagrangian()
+        {
+            detectSolution();
+            return lagrangianTable_;
+        }
+
+        //- Read solution and field combination
+        tmp<scalarField> readField
+        (
+            const word& solutionName,
+            const word& fieldName,
+            const bool wallData = false
+        );
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                         Class ccm::reader::options Declaration
+\*---------------------------------------------------------------------------*/
+
+class reader::options
+{
+    // Private data
+
+        //- Keep fluid regions (default true)
+        bool keepFluid_;
+
+        //- Keep porous regions (default true)
+        bool keepPorous_;
+
+        //- Keep solid regions (default true)
+        bool keepSolid_;
+
+        //- Merge in-place interfaces (default true)
+        bool mergeInterfaces_;
+
+        //- Rename interface boundaries as InterfaceN_0, InterfaceN_1 (default true)
+        bool renameInterfaces_;
+
+        //- Combine identically named boundaries (default false)
+        bool combineBoundaries_;
+
+        //- Remove baffles by merging their respective faces (default false)
+        bool removeBaffles_;
+
+        //- Use numbered names (eg, patch_0, zone_0) instead of human-readable
+        //  names (default false)
+        bool useNumberedNames_;
+
+        //- merge tolerance for points (default 0.05e-3)
+        scalar mergeTol_;
+
+        //- Value to assign for undefined solutions (default: NaN)
+        scalar undefScalar_;
+
+
+public:
+
+    // Constructors
+
+        //- Construct with the defaults
+        options();
+
+
+    // Member Functions
+
+    // Access
+
+        //- Keep fluid regions (default true)
+        bool keepFluid() const;
+
+        //- Keep porous regions (default true)
+        bool keepPorous() const;
+
+        //- Keep solid regions (default true)
+        bool keepSolid() const;
+
+        //- Some region (fluid, porous, solid) is kept.
+        bool keptSomeRegion() const;
+
+        //- Merge in-place interfaces (default true)
+        bool mergeInterfaces() const;
+
+        //- Rename interface boundaries as InterfaceN_0, InterfaceN_1 (default true)
+        bool renameInterfaces() const;
+
+        //- Combine identically named boundaries (default false)
+        bool combineBoundaries() const;
+
+        //- Remove baffles by merging their respective faces (default false)
+        bool removeBaffles() const;
+
+        //- Use numbered names (eg, patch_0, zone_0) instead of human-readable
+        //  names (default false)
+        bool useNumberedNames() const;
+
+        //- Merge tolerance for points (default 0.05e-3)
+        scalar mergeTol() const;
+
+        //- Value to assign for undefined solutions (default: NaN)
+        scalar undefScalar() const;
+
+
+    // Edit
+
+        //- Keep fluid regions
+        void keepFluid(bool);
+
+        //- Keep porous regions
+        void keepPorous(bool);
+
+        //- Keep solid regions
+        void keepSolid(bool);
+
+        //- Merge in-place interfaces
+        void mergeInterfaces(bool);
+
+        //- Rename interface boundaries as InterfaceN_0, InterfaceN_1
+        void renameInterfaces(bool);
+
+        //- Combine identically named boundaries
+        void combineBoundaries(bool);
+
+        //- Remove baffles by merging their respective faces
+        void removeBaffles(bool);
+
+        //- Use numbered names (eg, patch_0, zone_0) instead of human-readable
+        void useNumberedNames(bool);
+
+        //- Merge tolerance for points (default 0.05e-3)
+        void mergeTol(const scalar&);
+
+        //- Value to assign for undefined solutions (default: NaN)
+        void undefScalar(const scalar&);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReaderAux.C b/src/conversion/ccm/reader/ccmReaderAux.C
new file mode 100644
index 0000000000000000000000000000000000000000..f820dcb7f531871860e9232691cb518d8e121550
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReaderAux.C
@@ -0,0 +1,214 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Description
+    read/write auxiliary files for aiding STARCD/OPENFOAM interoperability
+
+    - cellTable information
+    - boundaryRegion information
+    - interface information
+
+\*----------------------------------------------------------------------------*/
+
+#include "OFstream.H"
+#include "ccmReader.H"
+#include "ccmInternal.H"  // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * * * Static Functions  * * * * * * * * * * * * * //
+
+Foam::Map<Foam::word> Foam::ccm::reader::selectPorous
+(
+    const Map<dictionary>& table
+)
+{
+    Map<word> lookup;
+
+    forAllConstIter(Map<dictionary>, table, iter)
+    {
+        if (iter().lookupOrDefault<label>("PorosityId", 0) != 0)
+        {
+            lookup.insert
+            (
+                iter.key(),
+                iter().lookupOrDefault<word>
+                (
+                    "Label",
+                    "cellTable_" + Foam::name(iter.key())
+                )
+            );
+        }
+    }
+
+    return lookup;
+}
+
+
+void Foam::ccm::reader::warnDuplicates
+(
+    const word& context,
+    const wordList& lst
+)
+{
+    HashTable<label> hashed(lst.size());
+    bool duplicates = false;
+
+    forAll(lst, elemI)
+    {
+        // Check duplicate name
+        HashTable<label>::iterator iter = hashed.find(lst[elemI]);
+        if (iter != hashed.end())
+        {
+            (*iter)++;
+            duplicates = true;
+        }
+        else
+        {
+            hashed.insert(lst[elemI], 1);
+        }
+    }
+
+    // Warn about duplicate names
+    if (duplicates)
+    {
+        Info << nl << "WARNING: " << context << " with identical names:";
+        forAllConstIter(HashTable<label>, hashed, iter)
+        {
+            if (*iter > 1)
+            {
+                Info << "  " << iter.key();
+            }
+        }
+        Info << nl << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::ccm::reader::writeInterfaces
+(
+    const objectRegistry& registry
+) const
+{
+    // Write constant/polyMesh/interface
+    IOList<labelList> ioObj
+    (
+        IOobject
+        (
+            "interfaces",
+            "constant",
+            polyMesh::meshSubDir,
+            registry,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE,
+            false
+        )
+    );
+
+    ioObj.note() = "as yet unsupported interfaces (baffles)";
+
+    Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
+
+    OFstream os(ioObj.objectPath());
+    ioObj.writeHeader(os);
+
+    os  << bafInterfaces_;
+}
+
+
+// Write List<label> in constant/polyMesh
+// - this is crucial for later conversion back to ccm/starcd
+void Foam::ccm::reader::writeMeshLabelList
+(
+    const objectRegistry& registry,
+    const word& propertyName,
+    const labelList& list,
+    IOstream::streamFormat fmt
+) const
+{
+    // Write constant/polyMesh/propertyName
+    IOList<label> ioObj
+    (
+        IOobject
+        (
+            propertyName,
+            "constant",
+            polyMesh::meshSubDir,
+            registry,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE,
+            false
+        ),
+        list
+    );
+
+    ioObj.note() = "persistent data for STARCD <-> OPENFOAM translation";
+    Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
+
+    // NOTE:
+    // The cellTableId is an integer and almost always < 1000, thus ASCII
+    // will be compacter than binary and makes external scripting easier
+    //
+    ioObj.writeObject
+    (
+        fmt,
+        IOstream::currentVersion,
+        IOstream::UNCOMPRESSED
+    );
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ccm::reader::writeAux
+(
+    const objectRegistry& registry
+) const
+{
+    cellTable_.writeDict(registry);
+    boundaryRegion_.writeDict(registry);
+    writeInterfaces(registry);
+
+    // Write origCellId as List<label>
+    writeMeshLabelList
+    (
+        registry,
+        "origCellId",
+        origCellId_,
+        IOstream::BINARY
+    );
+
+    // Write cellTableId as List<label>
+    // - this is crucial for later conversion back to ccm/starcd
+    writeMeshLabelList
+    (
+        registry,
+        "cellTableId",
+        cellTableId_,
+        IOstream::ASCII
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReaderMesh.C b/src/conversion/ccm/reader/ccmReaderMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..aa5058c3cefbdea6b79d7df8ace12d7e734e6b25
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReaderMesh.C
@@ -0,0 +1,2696 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmReader.H"
+
+#include "emptyPolyPatch.H"
+#include "symmetryPolyPatch.H"
+#include "wallPolyPatch.H"
+#include "SortableList.H"
+#include "IFstream.H"
+#include "OFstream.H"
+#include "IOdictionary.H"
+
+#include "ccmBoundaryInfo.H"
+#include "PackedList.H"
+#include "uindirectPrimitivePatch.H"
+#include "SortableList.H"
+#include "mergePoints1.H"
+#include "ListOps1.H"
+
+#include "ccmInternal.H" // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::labelList Foam::ccm::reader::patchStartList
+(
+    label initial
+) const
+{
+    labelList startLst(patchSizes_.size(), Zero);
+
+    label patchFaceI = initial;
+    forAll(patchSizes_, patchI)
+    {
+        startLst[patchI] = patchFaceI;
+        patchFaceI += patchSizes_[patchI];
+    }
+
+    return startLst;
+}
+
+
+void Foam::ccm::reader::printSizes() const
+{
+    Info<<"nPoints:" << nPoints_
+        << "  nCells:" << nCells_
+        << "  nFaces:" << nFaces_
+        << "  nInternalFaces:" << nInternalFaces_
+        << endl;
+}
+
+
+// Determine if the geometry looks good.
+// We'll insist that everything be on the first ("default") state,
+// and is on the same file, and has a problem description
+//
+// The detection reads the problem description as well
+//
+bool Foam::ccm::reader::detectGeometry()
+{
+    // Call once
+    if (geometryStatus_ != UNKNOWN)
+    {
+        return (geometryStatus_ == OKAY || geometryStatus_ == READ);
+    }
+
+    // Explicitly restricted to 'default' state node
+    ccmID stateNode;
+
+    // Get associated problem description
+    ccmID probNode;
+
+    // Only check the first processor
+    ccmID processorNode;
+    int procI = 0;
+
+    // Geometry needs vertices and topology
+    ccmID verticesNode, topoNode;
+
+    if
+    (
+        CCMIOGetState
+        (
+            nullptr,
+            (globalState_->root),
+            "default",
+            &probNode,
+            &stateNode
+        )
+     == kCCMIONoErr
+
+     && CCMIONextEntity
+        (
+            nullptr,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     == kCCMIONoErr
+
+     && CCMIOReadProcessor
+        (
+            nullptr,
+            processorNode,
+            &verticesNode,
+            &topoNode,
+            nullptr,        // Ignore initialField
+            nullptr         // Ignore solutionNode
+        )
+     == kCCMIONoErr
+
+     && CCMIOIsFromSameFile((globalState_->root), verticesNode)
+     && CCMIOIsFromSameFile((globalState_->root), topoNode)
+     && CCMIOIsValidEntity(probNode)
+    )
+    {
+        readProblemDescription(probNode);
+        geometryStatus_ = OKAY;
+    }
+    else
+    {
+        // Missing/incomplete geometry node and/or problem node
+        geometryStatus_ = BAD;
+    }
+
+    return (geometryStatus_ == OKAY || geometryStatus_ == READ);
+}
+
+
+// read the geometry without any sorting
+void Foam::ccm::reader::readMeshTopology
+(
+    const scalar scaleFactor
+)
+{
+    ccmID verticesNode, topoNode;
+
+    // Use first ("default") state node
+    ccmID stateNode;
+    int stateI = 0;
+
+    // Use the first processor to find the mesh nodes
+    ccmID processorNode;
+    int procI = 0;
+
+    if
+    (
+        CCMIONextEntity
+        (
+            nullptr,
+            (globalState_->root),
+            kCCMIOState,
+            &stateI,
+            &stateNode
+        )
+     == kCCMIONoErr
+
+     && CCMIONextEntity
+        (
+            nullptr,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     == kCCMIONoErr
+
+     && CCMIOReadProcessor
+        (
+            nullptr,
+            processorNode,
+            &verticesNode,
+            &topoNode,
+            nullptr,        // Ignore initialField
+            nullptr         // Ignore solutionNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        labelList origPointId = readVertices(verticesNode, scaleFactor);
+        readCells(topoNode);
+        readMonitoring(topoNode);
+
+        // Renumber vertex labels (ccm -> Foam)
+        {
+            label maxId = max(origPointId);
+            labelList mapToFoam(invert(maxId+1, origPointId));
+
+            forAll(faces_, faceI)
+            {
+                inplaceRenumber(mapToFoam, faces_[faceI]);
+            }
+        }
+        origPointId.clear();
+
+        // Renumber owners/neighbours cell labels (ccm -> Foam)
+        {
+            label maxId = max(origCellId_);
+            labelList mapToFoam(invert(maxId+1, origCellId_));
+
+            inplaceRenumber(mapToFoam, faceOwner_);
+            inplaceRenumber(mapToFoam, faceNeighbour_);
+        }
+
+        // Juggle solids into fluid as required
+        juggleSolids();
+
+        // Report sizes
+        printSizes();
+
+        // Remove unwanted fluid/porous/solid types
+        removeUnwanted();
+
+        // Collapse interfaces between domains (eg, fluid|porosity)
+        cleanupInterfaces();
+
+        // Use point merge to join conformal interfaces (STARCCM)
+        mergeInplaceInterfaces();
+    }
+}
+
+
+// readVertices:
+// 1) read the vertex data
+// 2) read the map (which maps the index into the data array with the Id number)
+//
+// returns the original point Id
+Foam::labelList Foam::ccm::reader::readVertices
+(
+    const ccmID& verticesNode,
+    const scalar scaleFactor
+)
+{
+    int dims = 1;
+    float scale = 1.0;
+
+    CCMIOSize size = 0;
+    ccmID mapId;
+
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readVertices()" << endl;
+#endif
+
+    // Determine dimensions and mapId
+    CCMIOEntitySize
+    (
+        &(globalState_->error),
+        verticesNode,
+        &size,
+        nullptr
+    );
+
+    CCMIOReadVerticesd
+    (
+        &(globalState_->error),
+        verticesNode,
+        &dims,
+        &scale,
+        &mapId,
+        nullptr,
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("problem finding 'Vertices' node");
+
+    if (dims != 3)
+    {
+        FatalErrorIn("ccm::reader::readVertices")
+            << "can only handle 3-dimensional vertices"
+            << exit(FatalError);
+    }
+
+    nPoints_ = size;
+    labelList origPointId(nPoints_);
+
+    readMap
+    (
+        mapId,
+        origPointId
+    );
+
+    // Temporary storage for the points - reading piecemeal is much slower
+    List<scalar> vrts(3*nPoints_);
+
+    // The ccm data is double precision too
+    CCMIOReadVerticesd
+    (
+        &(globalState_->error),
+        verticesNode,
+        nullptr,
+        nullptr,
+        nullptr,
+        vrts.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("problem reading 'Vertices' node");
+
+    // Convert to foam Points
+    points_.setSize(nPoints_);
+
+    scalar effectiveScale = scale * scaleFactor;
+    forAll(points_, i)
+    {
+        points_[i].x() = effectiveScale * vrts[i*3];
+        points_[i].y() = effectiveScale * vrts[i*3+1];
+        points_[i].z() = effectiveScale * vrts[i*3+2];
+    }
+
+    vrts.clear();
+
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readVertices: " << nPoints_ << endl;
+#endif
+
+    return origPointId;
+}
+
+
+// readCells:
+// - read faces, faceOwner and faceNeighbour
+// - finally read interfaces
+void Foam::ccm::reader::readCells
+(
+    const ccmID& topoNode
+)
+{
+    CCMIOSize size = 0;
+    ccmID cellsNode, mapId;
+    ccmID nodeId;
+
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readCells()" << endl;
+#endif
+
+    // Determine dimensions and mapId information for 'Cells'
+    CCMIOGetEntity
+    (
+        &(globalState_->error),
+        topoNode,
+        kCCMIOCells,
+        0,
+        &cellsNode
+    );
+
+    CCMIOEntitySize
+    (
+        &(globalState_->error),
+        cellsNode,
+        &size,
+        nullptr
+    );
+    assertNoError("cannot get 'Cells' node");
+
+    nCells_ = size;
+
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readCells: " << nCells_ << endl;
+#endif
+
+    // Store cell ids so that we know which cells are which
+    origCellId_.setSize(nCells_);
+    cellTableId_.setSize(nCells_);
+
+    CCMIOReadCells
+    (
+        &(globalState_->error),
+        cellsNode,
+        &mapId,
+        cellTableId_.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("Error reading 'Cells' node");
+
+    readMap
+    (
+        mapId,
+        origCellId_
+    );
+
+    // Determine dimensions and mapId information for 'InternalFaces'
+    CCMIOGetEntity
+    (
+        &(globalState_->error),
+        topoNode,
+        kCCMIOInternalFaces,
+        0,
+        &nodeId
+    );
+    CCMIOEntitySize
+    (
+        &(globalState_->error),
+        nodeId,
+        &size,
+        nullptr
+    );
+    nInternalFaces_ = size;
+
+    nFaces_ = nInternalFaces_;
+
+    // First pass:
+    //
+    // Determine patch sizes before reading internal faces
+    // also determine the original boundary regions
+
+    label nPatches = 0;
+    DynamicList<ccmBoundaryInfo> bndInfo;
+
+    // Number of children in the parent node is more than number of patches,
+    // but is a good start for allocation
+    if
+    (
+        CCMIOGetNumberOfChildren
+        (
+            nullptr,
+            topoNode.node,
+            &nPatches
+        ) == kCCMIONoErr
+    )
+    {
+        bndInfo.setCapacity(nPatches);
+    }
+
+    for
+    (
+        int index = 0;
+        CCMIONextEntity
+        (
+            nullptr,
+            topoNode,
+            kCCMIOBoundaryFaces,
+            &index,
+            &nodeId
+        ) == kCCMIONoErr
+     && CCMIOEntitySize
+        (
+            &(globalState_->error),
+            nodeId,
+            &size,
+            nullptr
+        ) == kCCMIONoErr;
+        /* nop */
+    )
+    {
+        ccmBoundaryInfo info;
+        info.size = size;
+        nFaces_   += size;
+
+        CCMIOGetEntityIndex
+        (
+            &(globalState_->error),
+            nodeId,
+            &(info.ccmIndex)
+        );
+
+        // Name directly from the node (eg, STARCCM)
+        info.setPatchName(ccmReadOptstr("Label", nodeId));
+
+        // Lookup the name, type from boundary region info:
+        Map<dictionary>::iterator dictIter = boundaryRegion_.find(info.ccmIndex);
+        if (dictIter != boundaryRegion_.end())
+        {
+            word patchName(dictIter()["Label"]);
+            word patchType(dictIter()["BoundaryType"]);
+
+            if (!patchName.empty())
+            {
+                info.patchName = patchName;
+            }
+
+            if (!patchType.empty())
+            {
+                info.patchType = patchType;
+            }
+
+            // Optional, but potentially useful information:
+            dictIter().add("BoundaryIndex", info.ccmIndex);
+            dictIter().add("size", info.size);
+        }
+
+        bndInfo.append(info);
+    }
+
+    // Redimension lists according to the overall sizes
+    faces_.setSize(nFaces_);
+    faceOwner_.setSize(nFaces_);
+    faceNeighbour_.setSize(nFaces_);
+    origFaceId_.setSize(nFaces_);
+
+
+    // May be too large, but is a good place start size
+    patchSizes_.setSize(bndInfo.size());
+    origBndId_.setSize(bndInfo.size());
+    patchSizes_ = 0;
+    origBndId_  = -1;
+    nPatches = 0;
+
+    HashTable<label, std::string> hashedNames;
+    if (option().combineBoundaries())
+    {
+        // Ensure all the interfaces are orderd up-front:
+        forAll(interfaceDefinitions_, interI)
+        {
+            const interfaceEntry& ifentry = interfaceDefinitions_[interI];
+
+            label info0Index = -1;
+            label info1Index = -1;
+
+            forAll(bndInfo, infoI)
+            {
+                if (bndInfo[infoI].ccmIndex == ifentry.bnd0)
+                {
+                    info0Index = infoI;
+                }
+                else if (bndInfo[infoI].ccmIndex == ifentry.bnd1)
+                {
+                    info1Index = infoI;
+                }
+            }
+
+            if (info0Index == info1Index || info0Index < 0 || info1Index < 0)
+            {
+                // this should never be able to happen
+                continue;
+            }
+
+            ccmBoundaryInfo& info0 = bndInfo[info0Index];
+            ccmBoundaryInfo& info1 = bndInfo[info1Index];
+
+            // Preserve interface order
+            info0.patchId = nPatches++;
+            info1.patchId = nPatches++;
+
+            // full safety:
+            info0.patchName = ifentry.canonicalName0();
+            info1.patchName = ifentry.canonicalName1();
+
+            hashedNames.insert(info0.patchName, info0Index);
+            hashedNames.insert(info1.patchName, info1Index);
+        }
+    }
+
+    forAll(bndInfo, infoI)
+    {
+        ccmBoundaryInfo& info = bndInfo[infoI];
+
+        if (info.patchId != -1)
+        {
+            // Already inserted - eg, as interface
+            origBndId_[info.patchId] = info.ccmIndex;
+        }
+        else
+        {
+            if (option().combineBoundaries())
+            {
+                // Check if patch name was already seen
+                HashTable<label, std::string>::const_iterator citer = hashedNames.find(info.patchName);
+                if (citer != hashedNames.end())
+                {
+                    info.patchId = bndInfo[citer()].patchId;
+                }
+                else
+                {
+                    hashedNames.insert(info.patchName, infoI);
+
+                    info.patchId = nPatches++;
+                    origBndId_[info.patchId] = info.ccmIndex;
+                }
+            }
+            else
+            {
+                info.patchId = nPatches++;
+                origBndId_[info.patchId] = info.ccmIndex;
+            }
+        }
+
+        patchSizes_[info.patchId] += info.size;
+    }
+
+    // Shrink to sizes actually used
+    patchSizes_.setSize(nPatches);
+    origBndId_.setSize(nPatches);
+
+    // Boundary info indices flattened and sorted by patchId
+
+    IndirectList<ccmBoundaryInfo> ccmLookupOrder(bndInfo, labelList());
+    {
+        DynamicList<label> addr(bndInfo.size());
+        for (int patchI = 0; patchI < nPatches; ++patchI)
+        {
+            forAll(bndInfo, infoI)
+            {
+                if (bndInfo[infoI].patchId == patchI)
+                {
+                    addr.append(infoI);
+                }
+            }
+        }
+
+        ccmLookupOrder.resetAddressing(addr.xfer());
+    }
+
+    if (option().combineBoundaries())
+    {
+        Info<<"patches combined by name: ";
+        if (nPatches == bndInfo.size())
+        {
+            Info<<"none" << endl;
+        }
+        else
+        {
+            Info<< bndInfo.size() << " into " << nPatches << endl;
+        }
+        // Info<< ccmLookupOrder << endl;
+    }
+
+
+    //
+    // Now we are ready to do the reading
+    //
+    CCMIOGetEntity
+    (
+        &(globalState_->error),
+        topoNode,
+        kCCMIOInternalFaces,
+        0,
+        &nodeId
+    );
+
+    // get allocation sizes
+    CCMIOReadFaces
+    (
+        &(globalState_->error),
+        nodeId,
+        kCCMIOInternalFaces,
+        &mapId,
+        &size,
+        nullptr,
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+
+    List<label> mapData(nInternalFaces_);
+    List<label> faceCells(2*nInternalFaces_);
+    List<label> ccmFaces(size);
+
+    CCMIOReadFaces
+    (
+        &(globalState_->error),
+        nodeId,
+        kCCMIOInternalFaces,
+        nullptr,
+        nullptr,
+        ccmFaces.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+
+    CCMIOReadFaceCells
+    (
+        &(globalState_->error),
+        nodeId,
+        kCCMIOInternalFaces,
+        faceCells.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("Error reading internal faces");
+
+    readMap
+    (
+        mapId,
+        mapData
+    );
+
+    // Copy into Foam list
+    // ccmFaces are organized as [nVert vrt1 .. vrtN]
+    unsigned int pos = 0;
+    for (label faceI = 0; faceI < nInternalFaces_; ++faceI)
+    {
+        origFaceId_[faceI]    = mapData[faceI];
+        faceOwner_[faceI]     = faceCells[2*faceI];
+        faceNeighbour_[faceI] = faceCells[2*faceI+1];
+        face& f = faces_[faceI];
+
+        f.setSize(ccmFaces[pos++]);
+        forAll(f, fp)
+        {
+            f[fp] = ccmFaces[pos++];
+        }
+    }
+
+    // Read the boundary faces
+    // ~~~~~~~~~~~~~~~~~~~~~~~
+    label patchFaceI = nInternalFaces_;
+
+    forAll(ccmLookupOrder, lookupI)
+    {
+        const ccmBoundaryInfo& info = ccmLookupOrder[lookupI];
+        const unsigned int patchSize = info.size;
+
+        if
+        (
+            CCMIOGetEntity
+            (
+                &(globalState_->error),
+                topoNode,
+                kCCMIOBoundaryFaces,
+                info.ccmIndex,
+                &nodeId
+            ) == kCCMIONoErr
+        )
+        {
+            CCMIOReadFaces
+            (
+                &(globalState_->error),
+                nodeId,
+                kCCMIOBoundaryFaces,
+                &mapId,
+                &size,    // size needed for the faces
+                nullptr,
+                kCCMIOStart,
+                kCCMIOEnd
+            );
+
+            mapData.setSize(patchSize);
+            faceCells.setSize(patchSize);
+            ccmFaces.setSize(size);
+
+            readMap
+            (
+                mapId,
+                mapData
+            );
+
+            CCMIOReadFaces
+            (
+                &(globalState_->error),
+                nodeId,
+                kCCMIOBoundaryFaces,
+                nullptr,
+                nullptr,
+                ccmFaces.begin(),
+                kCCMIOStart,
+                kCCMIOEnd
+            );
+            CCMIOReadFaceCells
+            (
+                &(globalState_->error),
+                nodeId,
+                kCCMIOBoundaryFaces,
+                faceCells.begin(),
+                kCCMIOStart,
+                kCCMIOEnd
+            );
+            assertNoError("Error reading boundary face cells - index " + ::Foam::name(info.ccmIndex));
+
+            // Copy into Foam list
+            // ccmFaces are organized as [nVert vrt1 .. vrtN]
+            unsigned int pos = 0;
+            for (unsigned int i = 0; i < patchSize; ++i, ++patchFaceI)
+            {
+                origFaceId_[patchFaceI]    = mapData[i];
+                faceOwner_[patchFaceI]     = faceCells[i];
+                faceNeighbour_[patchFaceI] = -1;
+
+                face& f = faces_[patchFaceI];
+
+                f.setSize(ccmFaces[pos++]);
+                forAll(f, fp)
+                {
+                    f[fp] = ccmFaces[pos++];
+                }
+            }
+        }
+        else
+        {
+            assertNoError("Error reading boundary faces - index " + ::Foam::name(info.ccmIndex));
+        }
+    }
+
+    readInterfaces(cellsNode);
+}
+
+
+// Read any interfaces
+//   1) interfaces between domains (fluid/solid, fluid/porosity)
+//   2) PROSTAR baffles
+//
+void Foam::ccm::reader::readInterfaces
+(
+    const ccmID& cellsNode
+)
+{
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readInterfaces()" << endl;
+#endif
+
+    label nBaffleInterface = 0, nInterfaceTotal = 0;
+    CCMIOIndex size = 0, dims = 0;
+
+    bafInterfaces_.clear();
+    domInterfaces_.clear();
+
+    ccmID interfaceNode;
+
+    if
+    (
+        CCMIOGetEntity
+        (
+            nullptr,
+            cellsNode,
+            kCCMIOInterfaces,
+            0,
+            &interfaceNode
+        )
+     == kCCMIONoErr
+
+     && CCMIOGetOptInfo
+        (
+            nullptr,
+            interfaceNode,
+            "FaceIds",
+            nullptr,
+            &size,
+            &dims,
+            nullptr
+        )
+     == kCCMIONoErr
+
+     && size > 0 && dims == 2
+    )
+    {
+        nInterfaceTotal = size;
+    }
+    else
+    {
+        return;
+    }
+
+    // Get ProstarBaffles
+    // formatted as [ prostarId faceId1 faceId2 celltableId ]
+    if
+    (
+        CCMIOGetOptInfo
+        (
+            nullptr,
+            interfaceNode,
+            "ProstarBaffles",
+            nullptr,
+            &size,
+            nullptr,
+            nullptr
+        )
+     == kCCMIONoErr
+
+     && size > 0
+    )
+    {
+        // Be paranoid - force an integral value of 4
+        nBaffleInterface = (size - size % 4) / 4;
+    }
+
+    // Determine sizes
+    label nDomainInterface = nInterfaceTotal - nBaffleInterface;
+
+    // Maximum dimension
+    List<int> mapData(max(2 * nInterfaceTotal, 4 * nBaffleInterface), -1);
+
+    bafInterfaces_.setSize(nBaffleInterface);
+    domInterfaces_.setSize(nDomainInterface);
+
+    // Face number mapping
+    label maxId = max(origFaceId_);
+    labelList toFoamFaces(invert(maxId+1, origFaceId_));
+
+    if (nBaffleInterface > 0)
+    {
+        mapData = -1;
+
+        CCMIOReadOpt1i
+        (
+            &(globalState_->error),
+            interfaceNode,
+            "ProstarBaffles",
+            mapData.begin(),
+            kCCMIOStart,
+            kCCMIOEnd
+        );
+        assertNoError("problem reading interface 'ProstarBaffles'");
+
+
+        // Copy/compress the desired entries (cannot use a SubList)
+        // Transform
+        //   from [ prostarId faceId1 faceId2 celltableId ]
+        //     to [ faceId1 faceId2 ]
+        for (label i=0; i < nBaffleInterface; ++i)
+        {
+            mapData[i*2]   = mapData[i*4+1];
+            mapData[i*2+1] = mapData[i*4+2];
+        }
+
+        for (label i=2*nBaffleInterface; i < 4*nBaffleInterface; ++i)
+        {
+            mapData[i] = -1;
+        }
+
+        // Translate ccm faceId -> foam faceId
+        inplaceRenumber(toFoamFaces, mapData);
+
+        forAll(bafInterfaces_, i)
+        {
+            bafInterfaces_[i][0] = mapData[i*2];
+            bafInterfaces_[i][1] = mapData[i*2+1];
+        }
+    }
+
+    // Baffles are not domInterfaces, use hash to skip them
+    SubList<label> subMap(mapData, 2*nBaffleInterface);
+    labelHashSet hashedFace(subMap);
+
+    mapData = -1;
+
+    CCMIOReadOpt2i
+    (
+        &(globalState_->error),
+        interfaceNode,
+        "FaceIds",
+        mapData.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("problem reading interface 'FaceIds'");
+
+    // Translate ccm faceId -> foam faceId
+    // newer version handles negatives indices
+    inplaceRenumber(toFoamFaces, mapData);
+
+    nDomainInterface = 0;
+    for (label i=0; i < nInterfaceTotal; ++i)
+    {
+        label face0 = mapData[i*2];
+        label face1 = mapData[i*2+1];
+
+        if
+        (
+            !hashedFace.found(face0)
+         && !hashedFace.found(face1)
+        )
+        {
+            domInterfaces_[nDomainInterface][0] = face0;
+            domInterfaces_[nDomainInterface][1] = face1;
+            ++nDomainInterface;
+            if (nDomainInterface >= domInterfaces_.size())
+            {
+                break;
+            }
+        }
+    }
+
+    // Truncate for extra safety
+    domInterfaces_.setSize(nDomainInterface);
+}
+
+
+// Read monitoring faces
+//
+void Foam::ccm::reader::readMonitoring
+(
+    const ccmID& topoId
+)
+{
+#ifdef DEBUG_CCMIOREAD
+    Info<< "readMonitoring()" << endl;
+#endif
+
+#ifdef WITH_MONITORING
+    CCMIONode topoNode, monitorParent;
+    CCMIONode monitorNode;
+
+    // CCMIOID -> CCMIONODE
+    if
+    (
+        CCMIOGetEntityNode
+        (
+            nullptr,
+            topoId,
+            &topoNode
+        )
+     == kCCMIONoErr
+
+     // Get "/Meshes/FaceBasedTopology/MonitorBoundaryRegions"
+     && CCMIOGetNode
+        (
+            nullptr,
+            topoNode,
+            "MonitorBoundaryRegions",
+            &monitorParent
+        )
+     == kCCMIONoErr
+    )
+    {
+        labelList toFoamFaces(invert(nFaces_+1, origFaceId_));
+
+        // Simulate CCMIONextEntity
+        for
+        (
+            int index = 0;
+            CCMIOGetNextChildWithLabel
+            (
+                nullptr,
+                monitorParent,
+                "boundaryFaces",
+                &index,
+                &monitorNode
+            ) == kCCMIONoErr;
+         /* nop */
+        )
+        {
+#ifdef DEBUG_MONITORING
+            Info<< "index = " << index << endl;
+#endif
+
+            int nMonFaces = 0;
+            // Simulate EntitySize ?
+            CCMIOReadNodei
+            (
+                nullptr,
+                monitorNode,
+                "NumFaces",
+                &nMonFaces
+            );
+
+            int ccmRegionId = ccmGetEntityIndex(monitorNode);
+
+            ccmID mapId;
+
+            int idVal;
+            CCMIOReadNodei
+            (
+                nullptr,
+                monitorNode,
+                "MapId",
+                &idVal
+            );
+
+#ifdef DEBUG_MONITORING
+            Info<< "monitoring mapId " << idVal
+                << " with nFaces = " << nMonFaces
+                << endl;
+#endif
+            // Is it risky changing parents here?
+            CCMIOGetEntity
+            (
+                nullptr,
+                (globalState_->root),
+                kCCMIOMap,
+                idVal,
+                &mapId
+            );
+
+            List<label> mapData(nMonFaces);
+            // mapData.setSize(nMonFaces);
+            // faceCells.setSize(nMonFaces);
+
+            readMap
+            (
+                mapId,
+                mapData
+            );
+
+#ifdef DEBUG_MONITORING
+            Info<< "map: " << mapData << nl
+                << "toFoam: " << toFoamFaces
+                << endl;
+#endif
+
+            // Translate ccm faceId -> foam faceId
+            // newer version handles negatives indices
+            inplaceRenumber(toFoamFaces, mapData);
+
+#ifdef DEBUG_MONITORING
+            Info<< "map: " << mapData << nl
+                << "ccmRegionId: " << ccmRegionId << endl;
+#endif
+
+            Map<dictionary>::const_iterator
+                iter = boundaryRegion_.find(ccmRegionId);
+
+            word zoneName;
+            if (iter != boundaryRegion_.end())
+            {
+                iter().lookup("Label") >> zoneName;
+            }
+            else
+            {
+                zoneName = "monitoring_" + Foam::name(ccmRegionId);
+            }
+
+            monitoringSets_.insert(zoneName, mapData);
+
+            // CCMIONode subNode;
+            //
+            //- simulate ReadFaceCells with kCCMIOBoundaryFaces
+            // CCMIOGetNode(nullptr, childNode, "Cells", &subNode);
+            // CCMIORead1i(nullptr, subNode, faceCells.begin(), kCCMIOStart, kCCMIOEnd);
+            //
+            // Info << "cells: " << faceCells << endl;
+        }
+    }
+#endif
+}
+
+
+// Move solid faces from Default_Boundary_Region -> Default_Boundary_Solid
+void Foam::ccm::reader::juggleSolids()
+{
+    if (!option().keepSolid())
+    {
+        return;
+    }
+
+    // Find "Default_Boundary_Region"
+    label defaultBoundaryRegion = boundaryRegion_.findIndex
+    (
+        defaultBoundaryName
+    );
+
+    // Find "Default_Boundary_Solid"
+    label defaultBoundarySolid = boundaryRegion_.findIndex
+    (
+        defaultSolidBoundaryName
+    );
+
+    // Cannot do anything if Default_Boundary_Region does not exist
+    // or if Default_Boundary_Solid already exists
+    if
+    (
+        defaultBoundaryRegion < 0
+     || defaultBoundarySolid >= 0
+    )
+    {
+        return;
+    }
+
+    // Identify solid cells
+    // ~~~~~~~~~~~~~~~~~~~~
+    label nSolids = 0;
+    boolList solidCells(cellTableId_.size(), false);
+    {
+        Map<word> solidMap = cellTable_.solids();
+
+        forAll(cellTableId_, cellI)
+        {
+            if (solidMap.found(cellTableId_[cellI]))
+            {
+                solidCells[cellI] = true;
+                ++nSolids;
+            }
+        }
+    }
+
+    if (!nSolids)
+    {
+        return;
+    }
+
+
+    // The corresponding Foam patch
+    const label patchIndex  = findIndex(origBndId_, defaultBoundaryRegion);
+    const label nPatchFaces = patchSizes_[patchIndex];
+
+    labelList patchStarts(patchStartList(nInternalFaces_));
+    label adjustPatch = 0;
+    for (label i = 0; i < nPatchFaces; ++i)
+    {
+        label faceI = patchStarts[patchIndex] + i;
+        label cellI = faceOwner_[faceI];
+
+        if (solidCells[cellI])
+        {
+            ++adjustPatch;
+        }
+    }
+
+    // No solid cells on the Default_Boundary_Region
+    if (!adjustPatch)
+    {
+        return;
+    }
+
+
+    // Insert Default_Boundary_Solid immediately after Default_Boundary_Region
+    // then we only need to adjust a single patch and can easily re-merge
+    // later
+    label nPatches = patchSizes_.size();
+    patchStarts.setSize(nPatches+1, 0);
+    patchSizes_.setSize(nPatches+1, 0);
+    origBndId_.setSize(nPatches+1, 0);
+
+    // make room for new entry
+    for (label i = nPatches; i > patchIndex; --i)
+    {
+        patchStarts[i]   = patchStarts[i-1];
+        patchSizes_[i]   = patchSizes_[i-1];
+        origBndId_[i] = origBndId_[i-1];
+    }
+
+    // Adjust start and sizes
+    patchSizes_[patchIndex] -= adjustPatch;
+    patchSizes_[patchIndex+1] = adjustPatch;
+    patchStarts[patchIndex+1] = patchStarts[patchIndex] + patchSizes_[patchIndex];
+
+    origBndId_[patchIndex+1] = boundaryRegion_.append
+    (
+        dictionary
+        (
+            IStringStream
+            (
+                "BoundaryType wall;"
+                "Label " + word(defaultSolidBoundaryName) + ";"
+            )()
+        )
+    );
+
+    label fluidFace = patchStarts[patchIndex];
+    label solidFace = patchStarts[patchIndex+1];
+
+    labelList oldToNew(identity(nFaces_));
+    for (label i = 0; i < nPatchFaces; ++i)
+    {
+        label faceI = patchStarts[patchIndex] + i;
+        label cellI = faceOwner_[faceI];
+
+        if (solidCells[cellI])
+        {
+            oldToNew[faceI] = solidFace++;
+        }
+        else
+        {
+            oldToNew[faceI] = fluidFace++;
+        }
+    }
+
+    // Re-order faces, owners/neighbours
+    inplaceReorder(oldToNew, faces_);
+    inplaceReorder(oldToNew, faceOwner_);
+    inplaceReorder(oldToNew, faceNeighbour_);
+    inplaceReorder(oldToNew, origFaceId_);
+
+    renumberInterfaces(oldToNew);
+}
+
+
+// In CCM, separate mesh domains are used for fluid/porous/solid
+// Thus the fluid/porous/solid cells correspond uniquely to a face owner
+void Foam::ccm::reader::removeUnwanted()
+{
+    // Identify fluid/porous/solid cells for removal
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    label nRemove = 0;
+    boolList removeCells(cellTableId_.size(), false);
+
+    {
+        Map<word> fluidMap  = cellTable_.fluids();
+        Map<word> porousMap = selectPorous(cellTable_);
+        Map<word> solidMap  = cellTable_.solids();
+        Map<word> removeMap;
+
+        forAll(cellTableId_, cellI)
+        {
+            label tableId = cellTableId_[cellI];
+
+            if
+            (
+                porousMap.found(tableId)
+              ? !option().keepPorous()
+              : fluidMap.found(tableId)
+              ? !option().keepFluid()
+              : solidMap.found(tableId)
+              ? !option().keepSolid()
+              : false
+            )
+            {
+                removeCells[cellI] = true;
+                ++nRemove;
+                removeMap.set(tableId, cellTable_.name(tableId));
+            }
+        }
+
+        if (nRemove)
+        {
+            Map<word> keepMap;
+
+            forAllConstIter(Map<dictionary>, cellTable_, iter)
+            {
+                const label tableId = iter.key();
+                if (!removeMap.found(tableId))
+                {
+                    keepMap.set(tableId, cellTable_.name(tableId));
+                }
+            }
+
+            Info<<"remove "<< nRemove << " cells in "
+                << removeMap.size() << " unwanted cellZone(s)" << nl;
+
+            forAllConstIter(Map<word>, removeMap, iter)
+            {
+                Info<< "    zone " << iter.key() << " : "<< iter() << nl;
+            }
+
+            Info<<"retain "<< (nCells_ - nRemove) << " cells in "
+                << keepMap.size() << " cellZone(s)" << nl;
+
+            forAllConstIter(Map<word>, keepMap, iter)
+            {
+                Info<< "    zone " << iter.key() << " : "<< iter() << nl;
+            }
+        }
+    }
+
+    if (!nRemove)
+    {
+        return;
+    }
+
+    // Remove all faces where the owner corresponds to a removed cell
+    // Adjust the nInternalFaces and patch sizes accordingly
+    label adjustInternal = 0;
+    labelList adjustPatchSize(patchSizes_.size(), 0);
+
+    label newFaceI = 0;
+    label oldFaceI = nFaces_ - 1;
+    labelList oldToNew(nFaces_, -1);
+    for (label faceI = 0; faceI < nFaces_; ++faceI)
+    {
+        label cellI = faceOwner_[faceI];
+        if (removeCells[cellI])
+        {
+            if (faceI < nInternalFaces_)
+            {
+                ++adjustInternal;
+            }
+            else
+            {
+                // need to adjust the patch sizes
+                label beg = nInternalFaces_;
+                forAll(patchSizes_, patchI)
+                {
+                    label end = beg + patchSizes_[patchI];
+
+                    if (faceI >= beg && faceI < end)
+                    {
+                        ++adjustPatchSize[patchI];
+                        break;
+                    }
+
+                    beg = end;
+                }
+            }
+
+            // Put discarded faces at the end of the list
+            oldToNew[faceI] = oldFaceI--;
+        }
+        else
+        {
+            if (newFaceI != faceI)
+            {
+                faces_[newFaceI] = faces_[faceI];
+                faceOwner_[newFaceI] = faceOwner_[faceI];
+                faceNeighbour_[newFaceI] = faceNeighbour_[faceI];
+                origFaceId_[newFaceI] = origFaceId_[faceI];
+            }
+
+            // New position for the face
+            oldToNew[faceI] = newFaceI++;
+        }
+    }
+
+    nFaces_ = newFaceI;
+
+    // Redimension
+    faces_.setSize(nFaces_);
+    faceOwner_.setSize(nFaces_);
+    faceNeighbour_.setSize(nFaces_);
+    origFaceId_.setSize(nFaces_);
+
+    // Adjust internal faces and patch sizes
+
+    nInternalFaces_ -= adjustInternal;
+    forAll(patchSizes_, patchI)
+    {
+        patchSizes_[patchI] -= adjustPatchSize[patchI];
+    }
+
+    renumberInterfaces(oldToNew);
+
+    // Renumber cells
+    label nCell = 0;
+    oldToNew.setSize(nCells_, -1);
+    for (label cellI = 0; cellI < nCells_; ++cellI)
+    {
+        if (!removeCells[cellI])
+        {
+            if (nCell != cellI)
+            {
+                origCellId_[nCell] = origCellId_[cellI];
+                cellTableId_[nCell] = cellTableId_[cellI];
+            }
+            oldToNew[cellI] = nCell;
+            ++nCell;
+        }
+    }
+
+    inplaceRenumber(oldToNew, faceOwner_);
+    inplaceRenumber(oldToNew, faceNeighbour_);
+
+    // Redimension
+    nCells_ = nCell;
+    origCellId_.setSize(nCells_);
+    cellTableId_.setSize(nCells_);
+
+
+    // Remove unused points - adjust points, faces accordingly
+    oldToNew.setSize(nPoints_);
+    oldToNew = -1;
+
+    // Mark up all the used points
+    forAll(faces_, faceI)
+    {
+        const labelList& facePoints = faces_[faceI];
+
+        forAll(facePoints, ptI)
+        {
+            ++oldToNew[facePoints[ptI]];
+        }
+    }
+
+    label nPointUsed = 0;
+    forAll(oldToNew, ptI)
+    {
+        if (oldToNew[ptI] >= 0)
+        {
+            oldToNew[ptI] = nPointUsed;
+            if (ptI != nPointUsed)
+            {
+                points_[nPointUsed] = points_[ptI];
+            }
+            ++nPointUsed;
+        }
+    }
+
+    nPoints_ = nPointUsed;
+    points_.setSize(nPoints_);
+
+    forAll(faces_, faceI)
+    {
+        inplaceRenumber(oldToNew, faces_[faceI]);
+    }
+
+    // Report sizes
+    printSizes();
+}
+
+
+void Foam::ccm::reader::validateInterface
+(
+    List<labelPair>& lst
+)
+{
+    label nElem = 0;
+    forAll(lst, elemI)
+    {
+        label face0 = lst[elemI][0];
+        label face1 = lst[elemI][1];
+
+        if (face0 < nFaces_ && face1 < nFaces_)
+        {
+            if (nElem != elemI)
+            {
+                lst[nElem][0] = face0;
+                lst[nElem][1] = face1;
+            }
+            ++nElem;
+        }
+    }
+    lst.setSize(nElem);
+}
+
+
+void Foam::ccm::reader::renumberInterfaces
+(
+    const labelList& oldToNew
+)
+{
+    forAll(domInterfaces_, elemI)
+    {
+        domInterfaces_[elemI][0] = oldToNew[domInterfaces_[elemI][0]];
+        domInterfaces_[elemI][1] = oldToNew[domInterfaces_[elemI][1]];
+    }
+
+    forAll(bafInterfaces_, elemI)
+    {
+        bafInterfaces_[elemI][0] = oldToNew[bafInterfaces_[elemI][0]];
+        bafInterfaces_[elemI][1] = oldToNew[bafInterfaces_[elemI][1]];
+    }
+
+    validateInterface(domInterfaces_);
+    validateInterface(bafInterfaces_);
+}
+
+
+//
+// 1) remove interfaces between domains (fluid/porosity; fluid/solid, etc)
+// 2) reorganize baffle interfaces into [0-N/2; N/2-N] lists at the beginning
+//    of the corresponding patch
+//
+void Foam::ccm::reader::cleanupInterfaces()
+{
+    validateInterface(bafInterfaces_);
+    validateInterface(domInterfaces_);
+
+    if (bafInterfaces_.size() <= 0 && domInterfaces_.size() <= 0)
+    {
+        Info<<"0 baffle interface pairs" << endl;
+        Info<<"0 domain interface pairs" << endl;
+        return;
+    }
+
+#ifdef DEBUG_BAFFLES
+    Info<< "baffle Interfaces " << bafInterfaces_ << nl
+        << "domain Interfaces " << domInterfaces_ << nl
+        << "nCells:" << nCells_ << nl
+        << "nFaces:" << nFaces_ << nl
+        << "patchSizes:"  << patchSizes_ << nl
+        << "nInternalFaces:" << nInternalFaces_ << endl;
+
+    forAll(domInterfaces_, elemI)
+    {
+        label face0 = domInterfaces_[elemI][0];
+        label face1 = domInterfaces_[elemI][1];
+
+        Info<< "interface [" << elemI << "] = "
+            << face0 << " - " << face1 << " own/neigh = "
+            << faceOwner_[face0] << "/" << faceNeighbour_[face0] << "  "
+            << faceOwner_[face1] << "/" << faceNeighbour_[face1] << endl;
+    }
+#endif
+
+    // Only reorder faces that need it
+    labelList oldToNew(nFaces_, -1);
+
+    // - move side0 face from domInterfaces to join the internal faces
+    // - move the redundant side1 to the end of the list for later deletion
+    label begOfList = nInternalFaces_;
+    label endOfList = nFaces_ - 1;
+
+    // The patch sizes (and the start) will definitely change
+    const labelList origPatchStarts(patchStartList(nInternalFaces_));
+    labelList adjustPatchSize(patchSizes_.size(), 0);
+    labelList bafflePatchCount(patchSizes_.size(), 0);
+
+    // The new dimensions after merging the domain interfaces:
+    nInternalFaces_ += domInterfaces_.size();
+    nFaces_         -= domInterfaces_.size();
+
+    Info<< domInterfaces_.size() << " domain interface pairs";
+    if (domInterfaces_.size())
+    {
+        Info<<" to merge" << endl;
+        printSizes();
+    }
+    else
+    {
+        Info<< endl;
+    }
+
+    forAll(domInterfaces_, elemI)
+    {
+        label face0 = domInterfaces_[elemI][0];
+        label face1 = domInterfaces_[elemI][1];
+
+        oldToNew[face0] = begOfList++;
+        oldToNew[face1] = endOfList--;     // End of list for truncationx
+
+        // face0 gets a new neighbour, face1 loses its owner
+        faceNeighbour_[face0] = faceOwner_[face1];
+        faceOwner_[face1] = -1;
+
+        // Need to adjust the patch sizes
+        forAll(patchSizes_, patchI)
+        {
+            label beg = origPatchStarts[patchI];
+            label end = beg + patchSizes_[patchI];
+
+            if (face0 >= beg && face0 < end)
+            {
+                ++adjustPatchSize[patchI];
+            }
+            if (face1 >= beg && face1 < end)
+            {
+                ++adjustPatchSize[patchI];
+            }
+        }
+    }
+
+    // Count the number of baffles per patch
+    forAll(bafInterfaces_, elemI)
+    {
+        label face0 = bafInterfaces_[elemI][0];
+        label face1 = bafInterfaces_[elemI][1];
+
+        forAll(patchSizes_, patchI)
+        {
+            label beg = origPatchStarts[patchI];
+            label end = beg + patchSizes_[patchI];
+
+            if (face0 >= beg && face0 < end)
+            {
+                ++bafflePatchCount[patchI];
+            }
+            if (face1 >= beg && face1 < end)
+            {
+                ++bafflePatchCount[patchI];
+            }
+        }
+    }
+
+
+    if (option().removeBaffles())
+    {
+        // The new dimensions after merging the baffles:
+        nInternalFaces_ += bafInterfaces_.size();
+        nFaces_         -= bafInterfaces_.size();
+    }
+
+    Info<< bafInterfaces_.size() << " baffle interface pairs";
+    if (bafInterfaces_.size())
+    {
+        if (option().removeBaffles())
+        {
+            Info<< " to merge" << endl;
+            printSizes();
+        }
+        else
+        {
+            Info<< " to be sorted" << endl;
+        }
+    }
+    else
+    {
+        Info<< endl;
+    }
+
+    if (option().removeBaffles())
+    {
+        forAll(bafInterfaces_, elemI)
+        {
+            label face0 = bafInterfaces_[elemI][0];
+            label face1 = bafInterfaces_[elemI][1];
+
+            oldToNew[face0] = begOfList++;
+            oldToNew[face1] = endOfList--;     // End of list for truncation
+
+            // face0 gets a new neighbour, face1 loses its owner
+            faceNeighbour_[face0] = faceOwner_[face1];
+            faceOwner_[face1] = -1;
+        }
+
+
+        // Boundary faces continue from the new nInternalFaces
+        label pos = nInternalFaces_;
+        forAll(patchSizes_, patchI)
+        {
+            label beg = origPatchStarts[patchI];
+            label end = beg + patchSizes_[patchI];
+
+            // Fill in values for the remainder of the boundary patch
+            for (label faceI = beg; faceI < end; ++faceI)
+            {
+                if (oldToNew[faceI] < 0)
+                {
+                    oldToNew[faceI] = pos;
+                    ++pos;
+                }
+            }
+        }
+
+        // Baffles have been resolved - remove last traces
+        bafInterfaces_.clear();
+    }
+    else
+    {
+        // This check is probably unnecessary
+        forAll(bafflePatchCount, patchI)
+        {
+            if (bafflePatchCount[patchI] % 2)
+            {
+                Info<< "WARNING: patch " << patchI
+                    << " has an uneven number of baffles ("
+                    << bafflePatchCount[patchI] << ") expect strange results"
+                    << endl;
+            }
+        }
+
+
+        // Reordered faces continue from the new nInternalFaces
+        label pos = nInternalFaces_;
+        forAll(patchSizes_, patchI)
+        {
+            const label beg = origPatchStarts[patchI];
+            const label end = beg + patchSizes_[patchI];
+
+            const label nsize = bafflePatchCount[patchI];
+            if (nsize > 0)
+            {
+                // Reorganize baffle interfaces into [0-N/2; N/2-N] lists
+                // at the beginning of the corresponding patch
+                const label nsizeby2 = (nsize - nsize % 2) / 2;
+                label nsorted = 0;
+
+                // Renumber the normal (baffle) interfaces
+                forAll(bafInterfaces_, elemI)
+                {
+                    const label face0 = bafInterfaces_[elemI][0];
+                    const label face1 = bafInterfaces_[elemI][1];
+
+                    if
+                    (
+                        (face0 >= beg && face0 < end)
+                     || (face1 >= beg && face1 < end)
+                    )
+                    {
+                        oldToNew[face0] = pos + nsorted;
+                        oldToNew[face1] = pos + nsorted + nsizeby2;
+
+                        // Mark destination of the faces, but cannot renumber yet
+                        // use negative to potential overlap with other patch regions
+                        bafInterfaces_[elemI][0] = -oldToNew[face0];
+                        bafInterfaces_[elemI][1] = -oldToNew[face1];
+
+                        ++nsorted;
+                    }
+                }
+                pos += 2*nsorted;
+            }
+
+            // Fill in values for the remainder of the boundary patch
+            for (label faceI = beg; faceI < end; ++faceI)
+            {
+                if (oldToNew[faceI] < 0)
+                {
+                    oldToNew[faceI] = pos;
+                    ++pos;
+                }
+            }
+        }
+
+        // Finalize new numbers for the normal (baffle) interfaces
+        forAll(bafInterfaces_, elemI)
+        {
+            bafInterfaces_[elemI][0] = abs(bafInterfaces_[elemI][0]);
+            bafInterfaces_[elemI][1] = abs(bafInterfaces_[elemI][1]);
+        }
+    }
+
+#ifdef DEBUG_BAFFLES
+    Info<< "remap with " << oldToNew << nl
+        << "owners:" << faceOwner_ << nl
+        << "neighbours:" << faceNeighbour_ << nl
+        << endl;
+#endif
+
+    // Re-order faces, owners/neighbours
+    inplaceReorder(oldToNew, faces_);
+    inplaceReorder(oldToNew, faceOwner_);
+    inplaceReorder(oldToNew, faceNeighbour_);
+    inplaceReorder(oldToNew, origFaceId_);
+
+    if (monitoringSets_.size())
+    {
+#ifdef WITH_MONITORING
+        // Modify oldToNew mapping to account for monitoring faces that
+        // coincided with a domain interface
+        //
+        // TODO - should modify flip map as well
+        forAll(domInterfaces_, elemI)
+        {
+            label face0 = domInterfaces_[elemI][0];
+            label face1 = domInterfaces_[elemI][1];
+            oldToNew[face1] = oldToNew[face0];
+        }
+
+//         Info<< "nInternalFaces " << nInternalFaces_ << nl
+//             << "oldToNew (internal) "
+//             << SubList<label>(oldToNew, nInternalFaces_)
+//             << nl
+//             << "oldToNew (extern) "
+//             << SubList<label>(oldToNew, nFaces_ - nInternalFaces_, nInternalFaces_)
+//             << endl;
+
+        forAllIter(HashTable<labelList>, monitoringSets_, iter)
+        {
+            inplaceRenumber(oldToNew, iter());
+        }
+#endif
+    }
+
+    // We can finally drop this information now
+    domInterfaces_.clear();
+
+    // Truncate lists
+    faces_.setSize(nFaces_);
+    faceOwner_.setSize(nFaces_);
+    faceNeighbour_.setSize(nFaces_);
+    origFaceId_.setSize(nFaces_);
+
+    // Remove empty patches:
+
+    // Fix patch sizes:
+    oldToNew.setSize(patchSizes_.size());
+    oldToNew = -1;
+
+    label nPatches = 0;
+    forAll(patchSizes_, patchI)
+    {
+        patchSizes_[patchI] -= adjustPatchSize[patchI];
+        if (option().removeBaffles())
+        {
+            patchSizes_[patchI] -= bafflePatchCount[patchI];
+        }
+
+        if (patchSizes_[patchI])
+        {
+            oldToNew[patchI] = nPatches++;
+        }
+    }
+
+    inplaceReorder(oldToNew, patchSizes_);
+    inplaceReorder(oldToNew, origBndId_);
+
+    patchSizes_.setSize(nPatches);
+    origBndId_.setSize(nPatches);
+
+#ifdef DEBUG_BAFFLES
+    Info<< "nCells:" << nCells_ << nl
+        << "nFaces:" << nFaces_ << nl
+        << "PatchSizes:"  << patchSizes_ << nl
+        << "nInternalFaces:" << nInternalFaces_ << nl
+        << endl;
+#endif
+}
+
+
+//
+// Merge STARCCM in-place interfaces
+//
+void Foam::ccm::reader::mergeInplaceInterfaces()
+{
+    if (interfaceDefinitions_.empty())
+    {
+        return;
+    }
+    if (!option().mergeInterfaces())
+    {
+        Info<< interfaceDefinitions_.size() << " interface definitions"
+            << " - leaving unmerged" << endl;
+        return;
+    }
+
+    // List of patch pairs that are interfaces
+    DynamicList<labelPair> interfacePatches(interfaceDefinitions_.size());
+
+    forAll(interfaceDefinitions_, interI)
+    {
+        const interfaceEntry& ifentry = interfaceDefinitions_[interI];
+
+        labelPair patchPair
+        (
+            findIndex(origBndId_, ifentry.bnd0),
+            findIndex(origBndId_, ifentry.bnd1)
+        );
+
+        if (patchPair[0] == patchPair[1] || patchPair[0] < 0 || patchPair[1] < 0)
+        {
+            // This should not happen
+            Info<<"Warning : bad interface " << interI << " " << ifentry
+                <<" on patches " << patchPair << endl;
+        }
+        else if
+        (
+            patchSizes_[patchPair[0]] != patchSizes_[patchPair[1]]
+         || patchSizes_[patchPair[0]] == 0
+         || patchSizes_[patchPair[1]] == 0
+        )
+        {
+            Info<<"Warning : skip interface " << interI << " " << ifentry
+                <<" on patches " << patchPair << nl
+                <<"   has zero or different number of faces: ("
+                << patchSizes_[patchPair[0]]  << " " << patchSizes_[patchPair[0]] << ")"
+                << endl;
+        }
+        else
+        {
+            interfacePatches.append(patchPair);
+        }
+    }
+
+    if (interfacePatches.empty())
+    {
+        return;
+    }
+
+
+    // Local point mapping
+    labelList mergedPointMap;
+
+    // Global remapping
+    labelList oldToNew(identity(points_.size()));
+
+    const labelList origPatchStarts(patchStartList(nInternalFaces_));
+
+    label nMergedTotal = 0;
+
+    // Markup points to merge
+    PackedBoolList whichPoints(points_.size());
+
+    Info<< "interface merge points (tol=" << option().mergeTol() << "):" << endl;
+
+    DynamicList<label> interfacesToMerge(interfacePatches.size());
+    forAll(interfacePatches, interI)
+    {
+        const label patch0 = interfacePatches[interI][0];
+        const label patch1 = interfacePatches[interI][1];
+        const label nPatch0Faces = patchSizes_[patch0];
+        const label nPatch1Faces = patchSizes_[patch1];
+
+        // Markup points to merge
+        whichPoints.reset();
+        for (label local0FaceI = 0; local0FaceI < nPatch0Faces; ++local0FaceI)
+        {
+            const face& f = faces_[origPatchStarts[patch0] + local0FaceI];
+
+            forAll(f, fp)
+            {
+                // Simultaneously account for previous point merges
+                whichPoints.set(oldToNew[f[fp]]);
+            }
+        }
+        for (label local1FaceI = 0; local1FaceI < nPatch1Faces; ++local1FaceI)
+        {
+            const face& f = faces_[origPatchStarts[patch1] + local1FaceI];
+
+            forAll(f, fp)
+            {
+                // Simultaneously account for previous point merges
+                whichPoints.set(oldToNew[f[fp]]);
+            }
+        }
+
+        // The global addresses
+        labelList addr(whichPoints.used());
+
+        const UIndirectList<point> pointsToMerge(points_, addr);
+
+        label nMerged = mergePoints
+        (
+            true,
+            pointsToMerge,
+            option().mergeTol(),
+            false,
+            mergedPointMap
+        );
+
+        Info<< "    patch "  << patch0 << ", " << patch1 << ": "
+            << nMerged << " from " << pointsToMerge.size() << " points"
+            << endl;
+
+        if (nMerged)
+        {
+            // Transcribe local to global addressing
+            forAll(mergedPointMap, lookupI)
+            {
+                oldToNew[addr[lookupI]] = addr[mergedPointMap[lookupI]];
+            }
+
+            interfacesToMerge.append(interI);
+            nMergedTotal += nMerged;
+        }
+    }
+
+
+    //
+    // Nothing to do
+    //
+    if (!nMergedTotal)
+    {
+        return;
+    }
+
+    // Update point references to account for point merge:
+    forAll(faces_, faceI)
+    {
+        inplaceRenumber(oldToNew, faces_[faceI]);
+    }
+
+    // Determine which points are actually in use:
+    oldToNew.setSize(nPoints_);
+    oldToNew = -1;
+
+    // Mark up all the used points
+    forAll(faces_, faceI)
+    {
+        const labelList& facePoints = faces_[faceI];
+
+        forAll(facePoints, ptI)
+        {
+            ++oldToNew[facePoints[ptI]];
+        }
+    }
+
+    label nPointUsed = 0;
+    forAll(oldToNew, ptI)
+    {
+        if (oldToNew[ptI] >= 0)
+        {
+            oldToNew[ptI] = nPointUsed;
+            if (ptI != nPointUsed)
+            {
+                points_[nPointUsed] = points_[ptI];
+            }
+            ++nPointUsed;
+        }
+    }
+
+    // Info<< "merge " << nMergedTotal << " points from "
+    //     << nPoints_ << " to " << nPointUsed << endl;
+
+    nPoints_ = nPointUsed;
+    points_.setSize(nPoints_);
+
+    forAll(faces_, faceI)
+    {
+        inplaceRenumber(oldToNew, faces_[faceI]);
+    }
+
+
+    //
+    // Merge the faces as well
+    //
+    Info<< "interface merge faces:" << endl;
+
+    nMergedTotal = 0;
+    labelList adjustPatchSize(patchSizes_.size(), 0);
+    forAll(interfacesToMerge, mergeI)
+    {
+        const label patch0 = interfacePatches[interfacesToMerge[mergeI]][0];
+        const label patch1 = interfacePatches[interfacesToMerge[mergeI]][1];
+
+        labelList faceAddr0(patchSizes_[patch0]);
+        labelList faceAddr1(patchSizes_[patch1]);
+
+        forAll(faceAddr0, localFaceI)
+        {
+            faceAddr0[localFaceI] = origPatchStarts[patch0] + localFaceI;
+        }
+        forAll(faceAddr1, localFaceI)
+        {
+            faceAddr1[localFaceI] = origPatchStarts[patch1] + localFaceI;
+        }
+
+        if (faceAddr0.size() != faceAddr1.size())
+        {
+            // This should not occur, we avoided the same thing above
+            continue;
+        }
+
+        // Improve comparision speed by sorting by distance
+        SortableList<scalar> pts0MagSqr
+        (
+            magSqr
+            (
+                uindirectPrimitivePatch
+                (
+                    UIndirectList<face>
+                    (
+                        faces_,
+                        faceAddr0
+                    ),
+                    points_
+                ).faceCentres()
+            )
+        );
+        SortableList<scalar> pts1MagSqr
+        (
+            magSqr
+            (
+                uindirectPrimitivePatch
+                (
+                    UIndirectList<face>
+                    (
+                        faces_,
+                        faceAddr1
+                    ),
+                    points_
+                ).faceCentres()
+            )
+        );
+
+        label nMerged = 0;
+
+        // Record which faces failed to merge - use slower ad hoc merging
+        labelHashSet failed0, failed1;
+        forAll(pts0MagSqr, sortI)
+        {
+            const label face0I = faceAddr0[pts0MagSqr.indices()[sortI]];
+            const label face1I = faceAddr1[pts1MagSqr.indices()[sortI]];
+
+            // This is what we expect
+            if (face::compare(faces_[face0I], faces_[face1I]))
+            {
+                ++nMerged;
+
+                // Moved from boundary patch to internal patch
+                ++adjustPatchSize[patch0];
+                ++adjustPatchSize[patch1];
+
+                if (faceOwner_[face0I] < faceOwner_[face1I])
+                {
+                    // keep 0, discard 1
+                    faceNeighbour_[face0I] = faceOwner_[face1I];
+                    faceNeighbour_[face1I] = faceOwner_[face1I] = -1;
+                }
+                else
+                {
+                    // keep 1, discard 0
+                    faceNeighbour_[face1I] = faceOwner_[face0I];
+                    faceNeighbour_[face0I] = faceOwner_[face0I] = -1;
+                }
+            }
+            else
+            {
+                failed0.set(face0I);
+                failed1.set(face1I);
+            }
+        }
+
+        // Perhaps some sorting issues, recheck
+        if (failed0.size())
+        {
+            // Note which one were successful
+            labelHashSet done(failed0.size());
+
+            forAllConstIter(labelHashSet, failed0, iter0)
+            {
+                const label face0I = iter0.key();
+
+                forAllConstIter(labelHashSet, failed1, iter1)
+                {
+                    const label face1I = iter1.key();
+
+                    // This is what we expect
+                    if (face::compare(faces_[face0I], faces_[face1I]))
+                    {
+                        ++nMerged;
+
+                        // Moved from boundary patch to internal patch
+                        ++adjustPatchSize[patch0];
+                        ++adjustPatchSize[patch1];
+
+                        if (faceOwner_[face0I] < faceOwner_[face1I])
+                        {
+                            // keep 0, discard 1
+                            faceNeighbour_[face0I] = faceOwner_[face1I];
+                            faceNeighbour_[face1I] = faceOwner_[face1I] = -1;
+                        }
+                        else
+                        {
+                            // keep 1, discard 0
+                            faceNeighbour_[face1I] = faceOwner_[face0I];
+                            faceNeighbour_[face0I] = faceOwner_[face0I] = -1;
+                        }
+
+                        failed1.erase(face1I);   // Never check again
+                        done.set(face0I);        // Mark as done
+                        break;                   // Stop looking
+                    }
+                }
+            }
+
+            // Transfer to note how many were successful
+            failed0 = done;
+        }
+
+        Info<< "    patch "  << patch0 << ", " << patch1 << ": "
+            << nMerged << " from " << faceAddr0.size() << " faces";
+
+        if (failed0.size())
+        {
+            Info<< " (" << failed0.size() << " merged ad hoc)";
+        }
+        Info<< endl;
+
+
+        nMergedTotal += nMerged;
+    }
+
+
+    // Nothing to do
+    if (!nMergedTotal)
+    {
+        return;
+    }
+
+    // Info<< "merge " << nMergedTotal << " faces from "
+    //     << nFaces_ << " to " << (nFaces_ - nMergedTotal) << endl;
+
+    oldToNew.setSize(nFaces_);
+    oldToNew = -1;
+
+    // Remaining external faces will be shifted here:
+    label extFaceI = nInternalFaces_ + nMergedTotal;
+
+    // Start over
+    nInternalFaces_ = 0;
+    label nFaceUsed = 0;
+    for (label faceI = 0; faceI < nFaces_; ++faceI)
+    {
+        if (faceOwner_[faceI] != -1)
+        {
+            if (faceNeighbour_[faceI] != -1)
+            {
+                // Internal face
+                oldToNew[faceI] = nInternalFaces_;
+                ++nInternalFaces_;
+                ++nFaceUsed;
+            }
+            else
+            {
+                // External face
+                oldToNew[faceI] = extFaceI;
+                ++extFaceI;
+                ++nFaceUsed;
+            }
+        }
+    }
+
+    if (nFaceUsed != extFaceI)
+    {
+        FatalErrorIn("ccm::reader::mergeInplaceInterfaces")
+            << "coding error: used " << nFaceUsed
+            << " faces, but expected to use " << extFaceI << " faces"
+            << exit(FatalError);
+    }
+
+    // Re-order faces, owners/neighbours
+    inplaceReorder(oldToNew, faces_, true);
+    inplaceReorder(oldToNew, faceOwner_, true);
+    inplaceReorder(oldToNew, faceNeighbour_, true);
+    inplaceReorder(oldToNew, origFaceId_, true);
+
+    nFaces_ = nFaceUsed;
+
+    faces_.setSize(nFaces_);
+    faceOwner_.setSize(nFaces_);
+    faceNeighbour_.setSize(nFaces_);
+    origFaceId_.setSize(nFaces_);
+
+    // Fix patch sizes:
+    oldToNew.setSize(patchSizes_.size());
+    oldToNew = -1;
+
+    label nPatches = 0;
+    forAll(patchSizes_, patchI)
+    {
+        patchSizes_[patchI] -= adjustPatchSize[patchI];
+        if (patchSizes_[patchI])
+        {
+            oldToNew[patchI] = nPatches++;
+        }
+    }
+
+    inplaceReorder(oldToNew, patchSizes_);
+    inplaceReorder(oldToNew, origBndId_);
+
+    patchSizes_.setSize(nPatches);
+    origBndId_.setSize(nPatches);
+
+    // Report we are done
+    Info<< ".." << endl;
+}
+
+
+//
+// Re-order mesh into Foam convention
+// - owner < neighbour
+// - face vertices such that normal points away from owner
+// - order faces: upper-triangular for internal faces;
+//    boundary faces after internal faces
+//
+void Foam::ccm::reader::reorderMesh()
+{
+    // Set owner/neighbour so owner < neighbour
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    forAll(faceOwner_, faceI)
+    {
+        label nbr = faceNeighbour_[faceI];
+        label own = faceOwner_[faceI];
+
+        if (nbr >= cellTableId_.size() || own >= cellTableId_.size())
+        {
+            FatalErrorIn("ccm::reader::reorderMesh")
+                << "face:" << faceI
+                << " nbr:" << nbr
+                << " own:" << own
+                << " nCells:" << cellTableId_.size()
+                << exit(FatalError);
+        }
+
+        if (nbr >= 0 && nbr < own)
+        {
+            faceOwner_[faceI] = faceNeighbour_[faceI];
+            faceNeighbour_[faceI] = own;
+            faces_[faceI] = faces_[faceI].reverseFace();
+        }
+
+        // And check the face
+        const face& f = faces_[faceI];
+
+        forAll(f, fp)
+        {
+            if (f[fp] < 0 || f[fp] >= points_.size())
+            {
+                FatalErrorIn("ccm::reader::reorderMesh")
+                    << "face:" << faceI << " f:" << f
+                    << abort(FatalError);
+            }
+        }
+    }
+
+    // Do upper-triangular ordering
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    labelList oldToNew(faceOwner_.size(), -1);
+
+    // Create cells (inverse of face-to-cell addressing)
+    cellList cellFaceAddr;
+    primitiveMesh::calcCells
+    (
+        cellFaceAddr,
+        faceOwner_,
+        faceNeighbour_,
+        nCells_
+    );
+
+    label newFaceI = 0;
+    forAll(cellFaceAddr, cellI)
+    {
+        const labelList& cFaces = cellFaceAddr[cellI];
+        SortableList<label> nbr(cFaces.size(), -1);
+
+        forAll(cFaces, i)
+        {
+            label faceI = cFaces[i];
+            label nbrCellI = faceNeighbour_[faceI];
+
+            if (nbrCellI >= 0)
+            {
+                // Internal face. Get cell on other side
+                if (nbrCellI == cellI)
+                {
+                    nbrCellI = faceOwner_[faceI];
+                }
+
+                // cellI is master
+                if (cellI < nbrCellI)
+                {
+                    nbr[i] = nbrCellI;
+                }
+            }
+        }
+
+        nbr.sort();
+
+        forAll(nbr, i)
+        {
+            if (nbr[i] >= 0)
+            {
+                oldToNew[cFaces[nbr.indices()[i]]] = newFaceI++;
+            }
+        }
+    }
+
+    // Reorder faces accordingly
+    inplaceReorder(oldToNew, faces_);
+    inplaceReorder(oldToNew, faceOwner_);
+    inplaceReorder(oldToNew, faceNeighbour_);
+    inplaceReorder(oldToNew, origFaceId_);
+
+    forAllIter(HashTable<labelList>, monitoringSets_, iter)
+    {
+        inplaceRenumber(oldToNew, iter());
+        labelList &lst = iter();
+
+        // disallow monitoring on boundaries
+        label nElem = 0;
+        forAll(lst, i)
+        {
+            if (lst[i] >= 0 && lst[i] < nInternalFaces_)
+            {
+                if (nElem != i)
+                {
+                    lst[nElem] = lst[i];
+                }
+                nElem++;
+            }
+        }
+
+        if (nElem)
+        {
+            lst.setSize(nElem);
+        }
+        else
+        {
+            Info << "remove monitor " << iter.key() << endl;
+            monitoringSets_.erase(iter);
+        }
+    }
+}
+
+
+// Attach patches
+//
+// - patchSizes_   : obvious
+// - origBndId_ : lookup for patch name/type
+//
+void Foam::ccm::reader::addPatches
+(
+    polyMesh& mesh
+) const
+{
+    // Create patches
+    // use patch types to determine what Foam types to generate
+    List<polyPatch*> newPatches(origBndId_.size());
+
+    label meshFaceI = nInternalFaces_;
+    wordHashSet hashedNames(origBndId_.size());
+
+    // lookup patch names/types from the problem description
+    // provide some fallback vlues
+    forAll(newPatches, patchI)
+    {
+        word fallbackName("patch" + Foam::name(patchI));
+        word patchName;
+        word patchType;
+
+        Map<dictionary>::const_iterator
+            citer = boundaryRegion_.find(origBndId_[patchI]);
+
+        if (citer != boundaryRegion_.end())
+        {
+            citer().lookup("Label") >> patchName;
+            citer().lookup("BoundaryType") >> patchType;
+        }
+        else
+        {
+            patchName = fallbackName;
+            patchType = "patch";
+        }
+
+        // Avoid duplicate names
+        // - don't bother checking if the modified name is also a duplicate
+        if (hashedNames.found(patchName))
+        {
+            Info<< "renamed patch " << patchName << " to ";
+            patchName = fallbackName + "_" + patchName;
+            Info<< patchName << endl;
+        }
+        hashedNames.insert(patchName);
+
+        Info<< "patch " << patchI
+            << " (start: " << meshFaceI << " size: " << patchSizes_[patchI]
+            << ") name: " << patchName
+            << endl;
+
+        if (patchType == "wall")
+        {
+            newPatches[patchI] =
+                new wallPolyPatch
+                (
+                    patchName,
+                    patchSizes_[patchI],
+                    meshFaceI,
+                    patchI,
+                    mesh.boundaryMesh(),
+                    patchType
+                );
+        }
+        else if (patchType == "symmetry")
+        {
+            newPatches[patchI] =
+                new symmetryPolyPatch
+                (
+                    patchName,
+                    patchSizes_[patchI],
+                    meshFaceI,
+                    patchI,
+                    mesh.boundaryMesh(),
+                    patchType
+                );
+        }
+        else if (patchType == "empty")
+        {
+            // Note: not ccm name, may have been introduced by us
+            newPatches[patchI] =
+                new emptyPolyPatch
+                (
+                    patchName,
+                    patchSizes_[patchI],
+                    meshFaceI,
+                    patchI,
+                    mesh.boundaryMesh(),
+                    patchType
+                );
+        }
+        else
+        {
+            // All other ccm types become straight polyPatch:
+            // 'inlet', 'outlet', 'pressure'.
+            newPatches[patchI] =
+                new polyPatch
+                (
+                    patchName,
+                    patchSizes_[patchI],
+                    meshFaceI,
+                    patchI,
+                    mesh.boundaryMesh(),
+                    patchType
+                );
+        }
+
+        meshFaceI += patchSizes_[patchI];
+    }
+
+    if (meshFaceI != mesh.nFaces())
+    {
+        FatalErrorIn("ccm::reader::addPatches(polyMesh& mesh)")
+            << "meshFaceI:" << meshFaceI << " nFaces:" << mesh.nFaces()
+            << abort(FatalError);
+    }
+
+    mesh.addPatches(newPatches);
+}
+
+
+
+// Attach faceZones based on the monitoring boundary conditions
+void Foam::ccm::reader::addFaceZones
+(
+    polyMesh& mesh
+) const
+{
+    label nZone = monitoringSets_.size();
+    mesh.faceZones().setSize(nZone);
+
+    if (!nZone)
+    {
+        return;
+    }
+
+    nZone = 0;
+    forAllConstIter(HashTable<labelList>, monitoringSets_, iter)
+    {
+        Info<< "faceZone " << nZone
+            << " (size: " << iter().size() << ") name: "
+            << iter.key() << endl;
+
+        mesh.faceZones().set
+        (
+            nZone,
+            new faceZone
+            (
+                iter.key(),
+                iter(),
+                boolList(iter().size(), false),
+                nZone,
+                mesh.faceZones()
+            )
+        );
+
+        nZone++;
+    }
+
+    mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
+    warnDuplicates("faceZones", mesh.faceZones().names());
+}
+
+
+// Remove most of the ccm-specific information with the exception of information
+// auxiliary to the normal polyMesh:
+//   (cellTableId_, origCellId_, origFaceId_, interfaces_, ...)
+void Foam::ccm::reader::clearGeom()
+{
+    // allow re-reading the file
+    if (geometryStatus_ == OKAY || geometryStatus_ == READ)
+    {
+        geometryStatus_ = UNKNOWN;
+    }
+
+    points_.clear();
+    faces_.clear();
+    faceOwner_.clear();
+    faceNeighbour_.clear();
+
+    origBndId_.clear();
+    patchSizes_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::polyMesh> Foam::ccm::reader::mesh
+(
+    const objectRegistry& registry,
+    const fileName& remappingDictName
+)
+{
+    if (!readGeometry())
+    {
+        return autoPtr<polyMesh>();
+    }
+
+    // merge cellTable and rename boundaryRegion
+    remapMeshInfo(registry, remappingDictName);
+
+    // Construct polyMesh
+    // ~~~~~~~~~~~~~~~~~~
+    autoPtr<polyMesh> mesh
+    (
+        new polyMesh
+        (
+            IOobject
+            (
+                polyMesh::defaultRegion,
+                "constant",
+                registry
+            ),
+            xferMove(points_),
+            xferMove(faces_),
+            xferMove(faceOwner_),
+            xferMove(faceNeighbour_)
+        )
+    );
+
+    addPatches(mesh());
+
+    // Attach cellZones based on the cellTable Id
+    // any other values can be extracted later from the cellTable dictionary
+    cellTable_.addCellZones(mesh(), cellTableId_);
+    warnDuplicates("cellZones", mesh().cellZones().names());
+
+    addFaceZones(mesh());
+
+    warnDuplicates("boundaries", mesh().boundaryMesh().names());
+    clearGeom();
+
+    return mesh;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReaderOptions.C b/src/conversion/ccm/reader/ccmReaderOptions.C
new file mode 100644
index 0000000000000000000000000000000000000000..c6bfe87d7dc6413818aeb0a5d3f50f7883073a66
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReaderOptions.C
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmReader.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ccm::reader::options::options()
+:
+    keepFluid_(true),
+    keepPorous_(true),
+    keepSolid_(true),
+    mergeInterfaces_(false),
+    renameInterfaces_(true),
+    combineBoundaries_(false),
+    removeBaffles_(false),
+    useNumberedNames_(false),
+    mergeTol_(0.05e-3),
+    undefScalar_(NAN)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::ccm::reader::options::keepFluid() const
+{
+    return keepFluid_;
+}
+
+
+bool Foam::ccm::reader::options::keepPorous() const
+{
+    return keepPorous_;
+}
+
+
+bool Foam::ccm::reader::options::keepSolid() const
+{
+    return keepSolid_;
+}
+
+
+bool Foam::ccm::reader::options::keptSomeRegion() const
+{
+    return keepFluid_ || keepPorous_ || !keepSolid_;
+}
+
+
+bool Foam::ccm::reader::options::mergeInterfaces() const
+{
+    return mergeInterfaces_;
+}
+
+
+bool Foam::ccm::reader::options::renameInterfaces() const
+{
+    return renameInterfaces_;
+}
+
+
+bool Foam::ccm::reader::options::combineBoundaries() const
+{
+    return combineBoundaries_;
+}
+
+
+bool Foam::ccm::reader::options::removeBaffles() const
+{
+    return removeBaffles_;
+}
+
+
+bool Foam::ccm::reader::options::useNumberedNames() const
+{
+    return useNumberedNames_;
+}
+
+
+Foam::scalar Foam::ccm::reader::options::mergeTol() const
+{
+    return mergeTol_;
+}
+
+
+Foam::scalar Foam::ccm::reader::options::undefScalar() const
+{
+    return undefScalar_;
+}
+
+
+
+void Foam::ccm::reader::options::keepFluid(bool b)
+{
+    keepFluid_ = b;
+}
+
+
+void Foam::ccm::reader::options::keepPorous(bool b)
+{
+    keepPorous_ = b;
+}
+
+
+void Foam::ccm::reader::options::keepSolid(bool b)
+{
+    keepSolid_ = b;
+}
+
+
+void Foam::ccm::reader::options::mergeInterfaces(bool b)
+{
+    mergeInterfaces_ = b;
+}
+
+
+void Foam::ccm::reader::options::renameInterfaces(bool b)
+{
+    renameInterfaces_ = b;
+}
+
+
+void Foam::ccm::reader::options::combineBoundaries(bool b)
+{
+    combineBoundaries_ = b;
+}
+
+
+void Foam::ccm::reader::options::removeBaffles(bool b)
+{
+    removeBaffles_ = b;
+}
+
+
+void Foam::ccm::reader::options::useNumberedNames(bool b)
+{
+    useNumberedNames_ = b;
+}
+
+
+void Foam::ccm::reader::options::mergeTol(const scalar& val)
+{
+    mergeTol_ = val;
+}
+
+
+void Foam::ccm::reader::options::undefScalar(const scalar& val)
+{
+    undefScalar_ = val;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmReaderSolution.C b/src/conversion/ccm/reader/ccmReaderSolution.C
new file mode 100644
index 0000000000000000000000000000000000000000..04881011f355398f79489875fd0245249512daaa
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmReaderSolution.C
@@ -0,0 +1,643 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmReader.H"
+#include "ccmInternal.H" // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// Get information about available fields.
+// - assume that all fields are available for all solution intervals
+// eg,
+//   /FieldSets/FieldSet-1/Phase-1/Fields/Velocity
+//   /FieldSets/FieldSet-1/Phase-1/Fields/Pressure
+//   ...
+void Foam::ccm::reader::determineFieldInfo
+(
+    const ccmID& fieldSetNode,
+    fieldTable& table
+)
+{
+    char fullName[kCCMIOMaxStringLength + 1];
+    char shortName[kCCMIOProstarShortNameLength+1];
+
+    // Loop through all phases
+    ccmID phaseNode;
+    int phaseI = 0;
+
+    while
+    (
+        CCMIONextEntity
+        (
+            NULL,
+            fieldSetNode,
+            kCCMIOFieldPhase,
+            &phaseI,
+            &phaseNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        CCMIODimensionality dims;
+
+        // Examine each field in this fieldSet
+        ccmID fieldNode;
+        int fieldI = 0;
+
+        // Get full/short names and dimension (scalar/vector/tensor).
+        // Use short name as unique identifier.
+
+        while
+        (
+            CCMIONextEntity
+            (
+                NULL,
+                phaseNode,
+                kCCMIOField,
+                &fieldI,
+                &fieldNode
+            )
+         == kCCMIONoErr
+
+         && CCMIOReadField
+            (
+                NULL,
+                fieldNode,
+                fullName,
+                shortName,
+                &dims,
+                NULL
+            )
+         == kCCMIONoErr
+        )
+        {
+            // The shortName *should* be a word, but some fields seem
+            // to have blanks!
+            {
+                char *ptr = shortName;
+                while (*ptr)
+                {
+                    if (!word::valid(*ptr))
+                    {
+                        *ptr = '_';
+                    }
+                    ptr++;
+                }
+            }
+
+            word fieldName(shortName);
+
+            if (dims == kCCMIOScalar)
+            {
+                // Add to table as required
+                if (!table.found(fieldName))
+                {
+                    fieldEntry entry(fieldName, fullName);
+
+                    entry.units
+                    (
+                        ccmReadOptstr("Units", fieldNode)
+                    );
+
+                    table.append(entry);
+                }
+
+                fieldEntry& entry = table.find(fieldName)();
+
+                // Obtain sizes of data field
+                // - only process cell/face data
+                ccmID dataNode;
+                int dataI = 0;
+
+                CCMIODataLocation dataLocation;
+                CCMIOIndex maxId;
+
+                while
+                (
+                    CCMIONextEntity
+                    (
+                        NULL,
+                        fieldNode,
+                        kCCMIOFieldData,
+                        &dataI,
+                        &dataNode
+                    )
+                 == kCCMIONoErr
+
+                 && CCMIOEntitySize
+                    (
+                        NULL,
+                        dataNode,
+                        NULL,
+                        &maxId
+                    )
+                 == kCCMIONoErr
+
+                 && CCMIOReadFieldDatad
+                    (
+                        NULL,
+                        dataNode,
+                        NULL,
+                        &dataLocation,
+                        NULL,
+                        kCCMIOStart,
+                        kCCMIOEnd
+                    )
+                 == kCCMIONoErr
+                )
+                {
+                    if (dataLocation == kCCMIOCell)
+                    {
+                        entry.maxCellId(maxId);
+                    }
+                    else if (dataLocation == kCCMIOFace)
+                    {
+                        entry.maxFaceId(maxId);
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+// Get information about all available solutions.
+// - it is sufficient to examine the first processor
+//
+// The "States":
+//      Restart_1/Processor-1
+//  -OR-
+//      Transient_1/Processor-1
+//      ...
+//      Transient_N/Processor-1
+//
+// point to the "FieldSets":
+//      FieldSet-1/RestartInfo
+//
+bool Foam::ccm::reader::detectSolution()
+{
+    // call once
+    if (solutionStatus_ != UNKNOWN)
+    {
+        return (solutionStatus_ == OKAY || solutionStatus_ == READ);
+    }
+
+    // loop through all States
+    ccmID stateNode;
+    int stateI = 0;
+    while
+    (
+        CCMIONextEntity
+        (
+            NULL,
+            (globalState_->root),
+            kCCMIOState,
+            &stateI,
+            &stateNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        // Loop through all processors/solutions
+        ccmID processorNode;
+        ccmID solutionNode;
+        int procI = 0;
+
+        while
+        (
+            CCMIONextEntity
+            (
+                NULL,
+                stateNode,
+                kCCMIOProcessor,
+                &procI,
+                &processorNode
+            )
+         == kCCMIONoErr
+
+         && CCMIOReadProcessor
+            (
+                NULL,
+                processorNode,
+                NULL,           // Ignore verticesNode
+                NULL,           // Ignore topologyNode
+                NULL,           // Ignore initialField
+                &solutionNode
+            )
+         == kCCMIONoErr
+        )
+        {
+            // Restrict to solutions with RestartInfo on the first cpu
+            // (there is normally only one set of restart data)
+            ccmID restartNode;
+            int restartI = 0;
+
+            char  solutionName[kCCMIOMaxStringLength + 1];
+            int   iteration = 0;
+            float timeValue = 0;
+
+            if
+            (
+                CCMIONextEntity
+                (
+                    NULL,
+                    solutionNode,
+                    kCCMIORestart,
+                    &restartI,
+                    &restartNode
+                )
+             == kCCMIONoErr
+
+             && CCMIOEntityName
+                (
+                    NULL,
+                    stateNode,
+                    solutionName
+                )
+             == kCCMIONoErr
+
+             && CCMIOReadRestartInfo
+                (
+                    NULL,
+                    restartNode,
+                    NULL,          // Ignore solverName
+                    &iteration,
+                    &timeValue,
+                    NULL,          // Ignore timeUnits
+                    NULL           // Ignore startAngle
+                )
+             == kCCMIONoErr
+            )
+            {
+                solutionTable_.append
+                (
+                    solutionEntry(solutionName, iteration, timeValue)
+                );
+            }
+
+            // Determine field information
+            determineFieldInfo(solutionNode, fieldTable_);
+
+            // check Lagrangian data
+            ccmID lagrangianNode;
+            ccmID lagrangianSolutions;
+            int lagrangianI = 0;
+
+            if
+            (
+                CCMIONextEntity
+                (
+                    NULL,
+                    processorNode,
+                    kCCMIOLagrangianData,
+                    &lagrangianI,
+                    &lagrangianNode
+                )
+             == kCCMIONoErr
+
+             && CCMIOReadLagrangianData
+                (
+                    NULL,
+                    lagrangianNode,
+                    NULL,
+                    &lagrangianSolutions
+                )
+             == kCCMIONoErr
+            )
+            {
+                determineFieldInfo(lagrangianSolutions, lagrangianTable_);
+            }
+        }
+    }
+
+    if (solutionTable_.size() && fieldTable_.size())
+    {
+        solutionStatus_ = OKAY;
+    }
+    else
+    {
+        solutionStatus_ = BAD;
+    }
+
+    return (solutionStatus_ == OKAY || solutionStatus_ == READ);
+}
+
+#define SOLID_STRESS_HACK
+
+//
+// Read solution and field combination
+//
+Foam::tmp<Foam::scalarField>
+Foam::ccm::reader::readField
+(
+    const word& solutionName,
+    const word& fieldName,
+    const bool wallData
+)
+{
+    // get State by name
+    ccmID stateNode;
+    ccmID solutionNode;
+
+    if
+    (
+        CCMIOGetState
+        (
+            NULL,
+            (globalState_->root),
+            solutionName.c_str(),
+            NULL,
+            &stateNode
+        )
+     != kCCMIONoErr
+
+     || !fieldTable_.found(fieldName)
+    )
+    {
+        return tmp<scalarField>(new Field<scalar>());
+    }
+
+    CCMIODataLocation requestedLocation = kCCMIOCell;
+
+    fieldEntry& entry = fieldTable_.find(fieldName)();
+
+    label maxId = entry.maxCellId();
+
+    if (wallData)
+    {
+        maxId = entry.maxFaceId();
+        requestedLocation = kCCMIOFace;
+    }
+
+    // we can skip empty fields immediately
+    if (!maxId)
+    {
+        return tmp<scalarField>(new Field<scalar>());
+    }
+
+    char shortName[kCCMIOProstarShortNameLength+1];
+
+    List<label>  mapData;
+    List<scalar> rawData;
+
+    tmp<scalarField> tscalarData
+    (
+        new scalarField(maxId + 1, option().undefScalar())
+    );
+    scalarField& scalarData = tscalarData.ref();
+
+
+    CCMIODimensionality dims;
+
+    // Loop across all processors
+    ccmID processorNode;
+    int procI = 0;
+
+    while
+    (
+        CCMIONextEntity
+        (
+            NULL,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     == kCCMIONoErr
+
+    && CCMIOReadProcessor
+        (
+            NULL,
+            processorNode,
+            NULL,           // Ignore verticesNode
+            NULL,           // Ignore topologyNode
+            NULL,           // Ignore initialField
+            &solutionNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        // loop through all phases
+        int phaseI = 0;
+        ccmID phaseNode;
+
+        while
+        (
+            CCMIONextEntity
+            (
+                NULL,
+                solutionNode,
+                kCCMIOFieldPhase,
+                &phaseI,
+                &phaseNode
+            )
+         == kCCMIONoErr
+        )
+        {
+            // Get Field that matches the name
+            ccmID fieldNode;
+            int fieldI = 0;
+
+            while
+            (
+                CCMIONextEntity
+                (
+                    NULL,
+                    phaseNode,
+                    kCCMIOField,
+                    &fieldI,
+                    &fieldNode
+                )
+                == kCCMIONoErr
+            )
+            {
+                // Get full/short names and dimension (scalar/vector/tensor)
+                // use short name as unique identifier
+                CCMIOReadField
+                (
+                    &(globalState_->error),
+                    fieldNode,
+                    NULL,
+                    shortName,
+                    &dims,
+                    NULL
+                );
+                assertNoError
+                (
+                    "reading post data field: "
+                  + string(shortName)
+                );
+
+                if (fieldName == shortName && dims == kCCMIOScalar)
+                {
+                    // Obtain sizes of data field
+                    ccmID dataNode;
+                    ccmID mapId;
+                    int dataI = 0;
+                    while
+                    (
+                        CCMIONextEntity
+                        (
+                            NULL,
+                            fieldNode,
+                            kCCMIOFieldData,
+                            &dataI,
+                            &dataNode
+                        )
+                     == kCCMIONoErr
+                    )
+                    {
+                        CCMIODataLocation dataLocation;
+                        CCMIOSize  n;
+
+                        // Only process cell/face data
+                        if
+                        (
+                            CCMIOEntitySize
+                            (
+                                NULL,
+                                dataNode,
+                                &n,
+                                NULL
+                            )
+                         == kCCMIONoErr
+
+                         && CCMIOReadFieldDatad
+                            (
+                                NULL,
+                                dataNode,
+                                &mapId,
+                                &dataLocation,
+                                NULL,
+                                kCCMIOStart,
+                                kCCMIOEnd
+                            )
+                         == kCCMIONoErr
+
+                         && dataLocation == requestedLocation
+                        )
+                        {
+
+#ifdef SOLID_STRESS_HACK
+                            bool okayCombination = true;
+
+                            CCMIOSize len;
+                            if
+                            (
+                                CCMIOEntityDescription
+                                (
+                                    NULL,
+                                    dataNode,
+                                    &len,
+                                    NULL
+                                )
+                             == kCCMIONoErr
+                            )
+                            {
+                                char* dataLabel = new char[len + 1];
+
+                                if
+                                (
+                                    CCMIOEntityDescription
+                                    (
+                                        NULL,
+                                        dataNode,
+                                        &len,
+                                        dataLabel
+                                    )
+                                 == kCCMIONoErr
+                                )
+                                {
+                                    if
+                                    (
+                                        (
+                                            strstr(fieldName.c_str(), "SIG")
+                                         || strstr(fieldName.c_str(), "EPS")
+                                        )
+                                     && strstr(dataLabel,  "So") == NULL
+                                    )
+                                    {
+                                        okayCombination = false;
+                                        // skip non-solid
+                                    }
+                                }
+
+                                delete[] dataLabel;
+                            }
+
+                            if (!okayCombination)
+                            {
+                                continue;
+                            }
+#endif
+
+                            mapData.setSize(n);
+                            rawData.setSize(n);
+
+                            readMap
+                            (
+                                mapId,
+                                mapData
+                            );
+
+                            CCMIOReadFieldDatad
+                            (
+                                &(globalState_->error),
+                                dataNode,
+                                NULL,
+                                NULL,
+                                rawData.begin(),
+                                kCCMIOStart,
+                                kCCMIOEnd
+                            );
+                            assertNoError
+                            (
+                                "reading post data field: "
+                              + string(shortName)
+                            );
+
+                            // transcribe to output list
+                            forAll(mapData, i)
+                            {
+                                label cellId = mapData[i];
+                                scalarData[cellId] = rawData[i];
+                            }
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Overwrite possible junk in cell 0 (often used as /dev/null)
+    scalarData[0] = option().undefScalar();
+
+    return tscalarData;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/reader/ccmSolutionTable.H b/src/conversion/ccm/reader/ccmSolutionTable.H
new file mode 100644
index 0000000000000000000000000000000000000000..e223d1c7480cca60c7b476de073ce0b7e9ad0010
--- /dev/null
+++ b/src/conversion/ccm/reader/ccmSolutionTable.H
@@ -0,0 +1,452 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+Description
+    Containers for holding ccm solution and field listings.
+
+\*---------------------------------------------------------------------------*/
+#ifndef ccmSolutionTable_H
+#define ccmSolutionTable_H
+
+#include "SLList.H"
+#include "stringListOps.H"
+#include "Ostream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ccm
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class ccm::namesList Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A linked-list that is searchable by the 'name()' of the items
+template<class T>
+class namesList
+:
+    public SLList<T>
+{
+public:
+    typedef typename SLList<T>::const_iterator const_iterator;
+    typedef typename SLList<T>::iterator iterator;
+
+    // Constructors
+
+        //- Null construct
+        namesList()
+        {}
+
+
+    // Access
+
+        //- Return true if a list element has a name that matches key
+        bool found(const word& key) const
+        {
+            for
+            (
+                const_iterator iter = SLList<T>::begin();
+                iter != SLList<T>::end();
+                ++iter
+            )
+            {
+                if (iter().name() == key)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+
+        //- Find a list element has a name matching key
+        iterator find(const word& key)
+        {
+            for
+            (
+                iterator iter = SLList<T>::begin();
+                iter != SLList<T>::end();
+                ++iter
+            )
+            {
+                if (iter().name() == key)
+                {
+                    return iter;
+                }
+            }
+
+            return SLList<T>::end();
+        }
+
+
+        //- Return a list of names matching whiteList and not matching blackList
+        List<word> findNames
+        (
+            const UList<wordRe>& whiteLst,
+            const UList<wordRe>& blackLst = UList<wordRe>()
+        ) const
+        {
+            List<word> matched(SLList<T>::size());
+
+            label matchI = 0;
+            for
+            (
+                const_iterator iter = SLList<T>::begin();
+                iter != SLList<T>::end();
+                ++iter
+            )
+            {
+                const word& name = iter().name();
+
+                if
+                (
+                    findStrings(whiteLst, name)
+                 && !findStrings(blackLst, name)
+                )
+                {
+                    matched[matchI++] = name;
+                }
+            }
+            matched.setSize(matchI);
+
+            return matched;
+        }
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                      Class ccm::fieldEntry Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A ccm field entry with short name, name, maxId and type
+//  shortName => ( fullName, maxId, type );
+class fieldEntry
+{
+    // Private Data
+
+        //- The field name (PROSTAR short name)
+        word name_;
+
+        //- The full field name
+        string fullName_;
+
+        //- The field units
+        string units_;
+
+        //- The max cell id for the field
+        label maxCellId_;
+
+        //- The max face id for the field
+        label maxFaceId_;
+
+public:
+
+    // Constructors
+
+        //- Construct from components with optional units
+        fieldEntry
+        (
+            const word& shortName,
+            const string& fullName,
+            const char* units = nullptr
+        )
+        :
+            name_(shortName),
+            fullName_(fullName),
+            units_(),
+            maxCellId_(0),
+            maxFaceId_(0)
+        {
+            if (units && *units)
+            {
+                units_ = units;
+            }
+        }
+
+
+    // Access
+
+        //- The field name (PROSTAR short name)
+        const word& name() const
+        {
+            return name_;
+        }
+
+        //- The full field name
+        const string& fullName() const
+        {
+            return fullName_;
+        }
+
+        //- The field units
+        const string& units() const
+        {
+            return units_;
+        }
+
+        //- The max cell id for the field
+        label maxCellId() const
+        {
+            return maxCellId_;
+        }
+
+        //- The max face id for the field
+        label maxFaceId() const
+        {
+            return maxFaceId_;
+        }
+
+
+    // Edit
+
+        //- Set the field units
+        void units(const char* units)
+        {
+            if (units && *units)
+            {
+                units_ = units;
+            }
+        }
+
+        //- Set the field units
+        void units(const std::string& units)
+        {
+            if (!units.empty())
+            {
+                units_ = units;
+            }
+        }
+
+        //- Set the max cell Id for the field
+        void maxCellId(const int newMax)
+        {
+            if (maxCellId_ < newMax)
+            {
+                maxCellId_ = newMax;
+            }
+        }
+
+
+        //- Set the max face Id for the field
+        void maxFaceId(const int newMax)
+        {
+            if (maxFaceId_ < newMax)
+            {
+                maxFaceId_ = newMax;
+            }
+        }
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const fieldEntry& entry
+        )
+        {
+            os  << entry.name_ << " => " << entry.fullName_
+                << " [" << entry.units_.c_str()
+                << "] maxCell: " << entry.maxCellId_
+                << " maxFace: " << entry.maxFaceId_;
+
+            return os;
+        }
+
+};
+
+/*---------------------------------------------------------------------------*\
+                    Class ccm::solutionEntry Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A ccm solution entry with name, iteration and time
+//  stateName => ( iteration, time );
+class solutionEntry
+{
+    // Private Data
+
+        //- The solution name
+        word name_;
+
+        //- The solution iteration/timestep
+        label iter_;
+
+        //- The solution time (sec)
+        scalar time_;
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        solutionEntry
+        (
+            const word& name,
+            const label& iteration,
+            const scalar& timeValue = 0
+        )
+        :
+            name_(name),
+            iter_(iteration),
+            time_(timeValue)
+        {}
+
+    // Access
+
+        //- The solution name
+        const word& name() const
+        {
+            return name_;
+        }
+
+        //- The solution iteration/timestep
+        label iteration() const
+        {
+            return iter_;
+        }
+
+        //- The solution time (sec)
+        scalar timeValue() const
+        {
+            return time_;
+        }
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const solutionEntry& entry
+        )
+        {
+            os  << entry.name_ << " =>"
+                << " iter: " << entry.iter_
+                << " time: " << entry.time_;
+
+            return os;
+        }
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                    Class ccm::solutionTable Declaration
+\*---------------------------------------------------------------------------*/
+
+// Typedef: ccm::solutionTable
+// A list of all the available solutions
+typedef namesList<solutionEntry> solutionTable;
+
+
+/*---------------------------------------------------------------------------*\
+                      Class ccm::fieldTable Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A list of the available fields
+class fieldTable
+:
+    public namesList<fieldEntry>
+{
+public:
+
+    // Constructor
+
+        //- Null construct
+        fieldTable()
+        :
+            namesList<fieldEntry>()
+        {}
+
+    // Access
+
+        //- The maximum cell Id referenced in the list
+        label maxCellId() const
+        {
+            label maxId = 0;
+            forAllConstIter(namesList<fieldEntry>, *this, iter)
+            {
+                label currMax = (iter()).maxCellId();
+
+                if (maxId < currMax)
+                {
+                    maxId = currMax;
+                }
+            }
+
+            return maxId;
+        }
+
+
+        //- The maximum face Id referenced in the list
+        label maxFaceId() const
+        {
+            label maxId = 0;
+
+            forAllConstIter(namesList<fieldEntry>, *this, iter)
+            {
+                label currMax = (iter()).maxFaceId();
+
+                if (maxId < currMax)
+                {
+                    maxId = currMax;
+                }
+            }
+
+            return maxId;
+        }
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const fieldTable& tbl
+        )
+        {
+            os  << static_cast<const namesList<fieldEntry>& >(tbl)
+                << nl
+                << "maxCell: "  << tbl.maxCellId()
+                << " maxFace: " << tbl.maxFaceId();
+
+            return os;
+        }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/remapping b/src/conversion/ccm/remapping
new file mode 100644
index 0000000000000000000000000000000000000000..d2013ecfcb0691a8d0486724389fbbdbd33f398f
--- /dev/null
+++ b/src/conversion/ccm/remapping
@@ -0,0 +1,96 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v1612+                                |
+|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    note        "remapping for STARCD <-> OPENFOAM translation";
+    object      remapping;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//
+// rename/combine cellTable entries
+//    target  ( source names )
+//
+cellTable
+{
+    fluid ( FLUID "cat[0-9]_?(In|Out)_?Layer" );
+    cat1  ( CAT1 "cat1_?(Front|Back|Gamma)" );
+    cat2  ( CAT2 "cat2_?(Front|Back|Gamma)" );
+    cat3  ( CAT3 "cat3_?(Front|Back|Gamma)" );
+    cat4  ( CAT4 "cat4_?(Front|Back|Gamma)" );
+}
+
+
+//
+// rename boundary regions
+//     newName <- oldName
+//
+boundaryRegion
+{
+    walls       Default_Boundary_Region;
+    inlet1      inlet_1;
+    inlet2      inlet_2;
+    inlet3      inlet_3;
+    inlet4      inlet_4;
+    inlet5      inlet_5;
+    inlet6      inlet_6;
+    outlet1     outlet_1;
+    outlet2     outlet_2;
+    outlet3     outlet_3;
+    outlet4     outlet_4;
+    outlet5     outlet_5;
+    outlet6     outlet_6;
+}
+
+
+boundary
+{
+    empty       symmetryPlane;
+}
+
+
+//
+// map OPENFOAM field names to CCM fields
+//
+fields
+{
+    tracer0
+    {
+        name    CONC_001;
+        Label   "tracer0";
+    }
+
+    tracer1
+    {
+        name    CONC_002;
+        Label   "tracer1";
+    }
+
+    tracer2
+    {
+        name    CONC_003;
+        Label   "tracer2";
+    }
+
+    divPhi
+    {
+        name    CONC_004;
+        Label   "divPhi";
+    }
+
+    Ma
+    {
+        name    CONC_100;
+        Label   "Mach";
+    }
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/conversion/ccm/writer/ccmWriter.C b/src/conversion/ccm/writer/ccmWriter.C
new file mode 100644
index 0000000000000000000000000000000000000000..c78a2fa068626d15cf77f154581529ff6546d631
--- /dev/null
+++ b/src/conversion/ccm/writer/ccmWriter.C
@@ -0,0 +1,389 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmWriter.H"
+#include "cellModeller.H"
+#include "demandDrivenData.H"
+#include "ccmInternal.H" // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// name for the topology file reference
+Foam::string Foam::ccm::writer::defaultMeshName = "meshExport";
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// Create a filled linear map with 'size' from 'start + 1'
+void Foam::ccm::writer::addLinearMap
+(
+    const string& mapName,
+    ccmID& mapId,
+    label size,
+    label start
+) const
+{
+    if (globalState_->hasError() || size <= 0)
+    {
+        return;
+    }
+
+    CCMIONewEntity
+    (
+        &(globalState_->error),
+        (globalState_->root),
+        kCCMIOMap,
+        mapName.c_str(),
+        &mapId
+    );
+    assertNoError("creating linearMap '" + mapName + "' node");
+
+    List<int> data(size);
+    forAll(data, i)
+    {
+        data[i] = start + 1 + i;
+    }
+
+    CCMIOWriteMap
+    (
+        &(globalState_->error),
+        mapId,
+        size,
+        (start + size),
+        data.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("writing linearMap '" + mapName + "' data");
+}
+
+
+Foam::label Foam::ccm::writer::findDefaultBoundary() const
+{
+    return mesh_.boundaryMesh().findPatchID(defaultBoundaryName);
+}
+
+
+void Foam::ccm::writer::writeBoundaryRegion
+(
+    const ccmID& probNode
+) const
+{
+    // Create dictionary lookup for constant/boundaryRegion
+    dictionary typeDict;
+
+    forAllConstIter(Map<dictionary>, boundaryRegion_, iter)
+    {
+        const dictionary& dict = iter();
+        if
+        (
+            dict.found("Label")
+         && dict.found("BoundaryType")
+        )
+        {
+            word nameEntry, typeEntry;
+
+            dict.lookup("Label") >> nameEntry;
+            dict.lookup("BoundaryType") >> typeEntry;
+
+            if (!typeDict.found(nameEntry))
+            {
+                typeDict.add(nameEntry, typeEntry);
+            }
+        }
+    }
+
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    label defaultId = findDefaultBoundary();
+
+    // Force write Default_Boundary_Region as BoundaryRegion-0
+    {
+        ccmID nodeId;
+        CCMIONewIndexedEntity
+        (
+            &(globalState_->error),
+            probNode,
+            kCCMIOBoundaryRegion,
+            0,
+            nullptr,
+            &nodeId
+        );
+        CCMIOWriteOptstr
+        (
+            nullptr,
+            nodeId,
+            "Label",
+            defaultBoundaryName
+        );
+        CCMIOWriteOptstr
+        (
+            nullptr,
+            nodeId,
+            "BoundaryType",
+            "wall"
+        );
+    }
+
+    forAll(patches, patchI)
+    {
+        word patchName = patches[patchI].name();
+        word patchType = patches[patchI].type();
+
+        label regionId = patchI;
+        if (regionId == defaultId)
+        {
+            continue;  // Skip - already written
+        }
+        else if (defaultId == -1 || regionId < defaultId)
+        {
+            regionId++;
+        }
+
+        // Use BoundaryType from constant/boundaryRegion
+        typeDict.readIfPresent(patchName, patchType);
+
+        ccmID nodeId;
+        CCMIONewIndexedEntity
+        (
+            &(globalState_->error),
+            probNode,
+            kCCMIOBoundaryRegion,
+            regionId,
+            nullptr,
+            &nodeId
+        );
+        CCMIOWriteOptstr
+        (
+            nullptr,
+            nodeId,
+            "Label",
+            patchName.c_str()
+        );
+        CCMIOWriteOptstr
+        (
+            nullptr,
+            nodeId,
+            "BoundaryType",
+            patchType.c_str()
+        );
+    }
+}
+
+
+void Foam::ccm::writer::writeCellTable
+(
+    const ccmID& probNode
+) const
+{
+    if (!cellTable_.size())
+    {
+        Info<< "No cellTable" << endl;
+        return;
+    }
+
+    ccmID nodeId;
+
+    forAllConstIter(Map<dictionary>, cellTable_, iter)
+    {
+        label intVal = iter.key();
+        const dictionary& dict = iter();
+
+        CCMIONewIndexedEntity
+        (
+            &(globalState_->error),
+            probNode,
+            kCCMIOCellType,
+            intVal,
+            nullptr,
+            &nodeId
+        );
+
+        wordList toc = dict.toc();
+        forAll(toc, i)
+        {
+            word keyword = toc[i];
+            int pos = keyword.find("Id");
+
+            // Tags containing 'Id' are integers
+            if (pos > 0)
+            {
+                dict.lookup(keyword) >> intVal;
+                CCMIOWriteOpti
+                (
+                    nullptr,
+                    nodeId,
+                    keyword.c_str(),
+                    intVal
+                );
+            }
+            else if (pos < 0)
+            {
+                word strVal;
+                dict.lookup(keyword) >> strVal;
+
+                CCMIOWriteOptstr
+                (
+                    nullptr,
+                    nodeId,
+                    keyword.c_str(),
+                    strVal.c_str()
+                );
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+// Write out problem description
+void Foam::ccm::writer::writeProblem
+(
+    const ccmID& stateNode
+) const
+{
+    ccmID probNode;
+    CCMIONewEntity
+    (
+        &(globalState_->error),
+        (globalState_->root),
+        kCCMIOProblemDescription,
+        nullptr,
+        &probNode
+    );
+
+    writeCellTable(probNode);
+    writeBoundaryRegion(probNode);
+
+    // let the state know about our problem
+    CCMIOWriteState
+    (
+        &(globalState_->error),
+        stateNode,
+        probNode,
+        nullptr
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+// Construct for writing geometry
+Foam::ccm::writer::writer
+(
+    const fileName& file,
+    const polyMesh& mesh,
+    const bool backup
+)
+:
+    base(),
+    maps_(new ccmMaps),
+    mesh_(mesh),
+    // Mapping between OpenFOAM and PROSTAR primitives
+    prostarShapeLookup_
+    ({
+        { cellModeller::lookup("hex")->index(),   STARCDCore::starcdHex },
+        { cellModeller::lookup("prism")->index(), STARCDCore::starcdPrism },
+        { cellModeller::lookup("tet")->index(),   STARCDCore::starcdTet },
+        { cellModeller::lookup("pyr")->index(),   STARCDCore::starcdPyr }
+    }),
+    boundaryRegion_(mesh),
+    cellTable_(mesh)
+{
+    // Writing/re-writing existing files is too annoying - start anew
+    if (backup)
+    {
+        if (Foam::mvBak(file))
+        {
+            Info<< "moved existing file -> " << fileName(file + ".bak*") << nl;
+        }
+    }
+    else if (exists(file, false))
+    {
+        Foam::rm(file);
+        Info<< "removed existing file: " << file << nl;
+    }
+
+    // Reinitialize error state from the return value
+    globalState_->error = CCMIOOpenFile
+    (
+        nullptr,
+        file.c_str(),
+        kCCMIOWrite,
+        &(globalState_->root)
+    );
+    assertNoError("Error opening file for writing");
+
+    // We always need the cell map
+    addLinearMap
+    (
+        "cell Map",
+        maps_->cells,
+        mesh_.nCells()
+    );
+
+    // We often need the internalFaces map
+    addLinearMap
+    (
+        "internalFaces Map",
+        maps_->internalFaces,
+        mesh_.nInternalFaces()
+    );
+
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+    maps_->boundary.setSize(patches.size());
+
+    // We always need maps for the boundary regions
+    forAll(patches, patchI)
+    {
+        if (patches[patchI].size() > 0)
+        {
+            string mapName = "boundaryMap-" + Foam::name(patchI);
+
+            addLinearMap
+            (
+                mapName,
+                maps_->boundary[patchI],
+                patches[patchI].size(),
+                patches[patchI].start()
+            );
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ccm::writer::~writer()
+{
+    close();
+
+    deleteDemandDrivenData(maps_);
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/writer/ccmWriter.H b/src/conversion/ccm/writer/ccmWriter.H
new file mode 100644
index 0000000000000000000000000000000000000000..a2d57148c9bb8633630cc79f4fbdd60ce08a2cb1
--- /dev/null
+++ b/src/conversion/ccm/writer/ccmWriter.H
@@ -0,0 +1,256 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ccm::writer
+
+Description
+    Write OpenFOAM meshes and/or results to CCM format
+
+    - partial support for interfaces
+    - no monitoring (internal) boundaries
+    - does not handle Lagrangian data
+
+    \par Files
+
+    The <tt>constant/boundaryRegion</tt> and <tt>constant/cellTable</tt> files,
+    which are described in ccmReader, are used to construct the CCM
+    \c ProblemDescription node.
+
+    The <tt>constant/remapping</tt> file is an \c IOdictionary that is
+    \c READ_IF_PRESENT and can be used to remap certain information.
+    eg,
+
+    \verbatim
+        // map OpenFOAM scalar fields to CCM output fields
+        fields
+        {
+            tracer0
+            {
+                name    CONC_001;
+                Label   "tracer0";
+            }
+            tracer1
+            {
+                name    CONC_002;
+                Label   "tracer1";
+            }
+            tracer2
+            {
+                name    CONC_003;
+                Label   "tracer2";
+            }
+            divPhi
+            {
+                name    CONC_004;
+                Label   "divPhi";
+            }
+            // an example with units:
+            p
+            {
+                name    P;
+                Label   "Pressure";
+                units   "Pa";
+            }
+        }
+    \endverbatim
+
+Note
+    This class is in development
+    - any/all of the class names and members may change
+
+SourceFiles
+    ccmWriter.C
+    ccmWriterMesh.C
+    ccmWriterSolution.C
+
+\*---------------------------------------------------------------------------*/
+#ifndef ccmWriter_H
+#define ccmWriter_H
+
+#include "ccmBase.H"
+#include "STARCDCore.H"
+
+#include "fvMesh.H"
+#include "boundaryRegion.H"
+#include "cellTable.H"
+#include "IOobjectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ccm
+{
+
+// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
+
+class ccmID;
+class ccmMaps;
+class ccmDimension;
+class ccmGlobalState;
+
+/*---------------------------------------------------------------------------*\
+                         Class ccm::writer Declaration
+\*---------------------------------------------------------------------------*/
+
+class writer
+:
+    public base,
+    protected fileFormats::STARCDCore
+{
+    // Private Data
+
+    // Static Data
+
+        //- The OpenFOAM -> CCM field mappings
+        static dictionary defaultNameMapping;
+
+
+    // Member Data
+
+        //- MapIds for various components (cell, internalFaces, boundaries)
+        ccmMaps* maps_;
+
+        //- mesh reference
+        const polyMesh& mesh_;
+
+        //- Lookup between cellModel shape and PROSTAR shape
+        const Map<label> prostarShapeLookup_;
+
+        //- ccm node: ProblemDescriptions/boundaryRegion
+        boundaryRegion boundaryRegion_;
+
+        // ccm node: ProblemDescriptions/cellType
+        cellTable cellTable_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        writer(const writer&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const writer&) = delete;
+
+
+        //- create a filled linear map with 'size' from 'start + 1'
+        void addLinearMap
+        (
+            const string& mapName,
+            ccmID& mapId,
+            label size,
+            label start = 0
+        ) const;
+
+        void writeBoundaryRegion(const ccmID& probNode) const;
+
+        void writeCellTable(const ccmID& probNode) const;
+
+        //- write out problem description
+        void writeProblem(const ccmID& stateNode) const;
+
+        //- Return the PROSTAR face id for the given cell/face
+        label prostarCellFaceId(const label& cellId, const label& faceI) const;
+
+        // write the faces, the number of vertices appears before each entry
+        void writeFaces
+        (
+            const ccmID& nodeId,
+            const ccmID& mapId,
+            bool  isBoundary,    // boundary or internal faces
+            label size,
+            label start = 0
+        ) const;
+
+        void writeVertices(const ccmID& verticesNode) const;
+
+        // - write internal faces with owner/neighbour
+        void writeInternalFaces(const ccmID& topoNode) const;
+
+        // - write boundary faces with owner
+        void writeBoundaryFaces(const ccmID& topoNode) const;
+
+        void writeCells(const ccmID& topoNode);
+
+        void writeInterfaces(const ccmID& cellsNode) const;
+
+        bool newFieldNode
+        (
+            const ccmID& phaseNode,
+            const word& fieldName,
+            const dictionary& nameMapping,
+            const ccmDimension& ccmDim,
+            ccmID& fieldNode
+        ) const;
+
+
+        //- Return patch named 'Default_Boundary_Region' or -1 on error
+        label findDefaultBoundary() const;
+
+public:
+
+    // Static data members
+
+        //- The name for the topology file reference
+        static string defaultMeshName;
+
+
+    // Constructors
+
+        //- Open a file for writing, with backup/overwrite existing file
+        writer(const fileName&, const polyMesh&, const bool backup=true);
+
+
+    //- Destructor (closes file)
+    ~writer();
+
+
+    // Member Functions
+
+        // Write
+
+        //- Write the mesh
+        void writeGeometry();
+
+        //- Write the solutions
+        //  provide optional remapping dictionary
+        void writeSolution
+        (
+            const IOobjectList&,
+            const fileName& remappingDictName = fileName::null
+        );
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ccm
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/writer/ccmWriterMesh.C b/src/conversion/ccm/writer/ccmWriterMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..506e9fc1c9c419e4ce8527eb1de1675ddc388fce
--- /dev/null
+++ b/src/conversion/ccm/writer/ccmWriterMesh.C
@@ -0,0 +1,831 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmWriter.H"
+#include "ccmInternal.H"  // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::label Foam::ccm::writer::prostarCellFaceId
+(
+    const label& cellId,
+    const label& faceI
+) const
+{
+    const faceList&   faces = mesh_.faces();
+    const cellShape&  shape = mesh_.cellShapes()[cellId];
+    const labelList& cFaces = mesh_.cells()[cellId];
+
+    label cellFaceId = findIndex(cFaces, faceI);
+    label mapIndex = shape.model().index();
+
+    if (ccm::debug > 1)
+    {
+        Info<< " face[" << faceI << "]: " << faces[faceI] << nl
+            << " owner: " << cellId
+            << " cellFace: " << cellFaceId
+            << " cellFaces: " << cFaces
+            << " shape [index " << mapIndex << "] "  << shape
+            << endl;
+
+        Info << "cellFaces" << nl;
+        forAll(cFaces, cFaceI)
+        {
+            Info<< "  face [" << cFaces[cFaceI] << "] = "
+                << faces[cFaces[cFaceI]] << nl;
+        }
+
+        Info << "shapeFaces" << nl;
+        {
+            const faceList sFaces = shape.faces();
+            forAll(sFaces, sFaceI)
+            {
+                Info<< "  sFace[" << sFaceI << "] = "
+                    << sFaces[sFaceI] << nl;
+            }
+        }
+    }
+
+    // The face order returned by primitiveMesh::cells() is not
+    // necessarily the same as defined by
+    // primitiveMesh::cellShapes().
+    // Thus do the lookup for registered primitive types.
+    // Finally, remap the cellModel face number to the ProstarFaceId
+    if (prostarShapeLookup_.found(mapIndex))
+    {
+        const faceList sFaces = shape.faces();
+        forAll(sFaces, sFaceI)
+        {
+            if (faces[faceI] == sFaces[sFaceI])
+            {
+                cellFaceId = sFaceI;
+
+                if (ccm::debug > 1)
+                {
+                    Info << " FoamCellFace: " << sFaceI;
+                }
+
+                break;
+            }
+        }
+
+        mapIndex = prostarShapeLookup_[mapIndex];
+        cellFaceId = STARCDCore::foamToStarFaceAddr[mapIndex][cellFaceId];
+
+        if (ccm::debug > 1)
+        {
+            Info<< " ProstarShape: " << mapIndex
+                << " ProstarFaceId: " << cellFaceId + 1
+                << endl;
+        }
+    }
+
+    // PROSTAR used 1-based indices
+    return cellFaceId + 1;
+}
+
+
+// write the faces, the number of vertices appears before each entry
+void Foam::ccm::writer::writeFaces
+(
+    const ccmID& nodeId,
+    const ccmID& mapId,
+    bool  isBoundary,
+    label size,
+    label start
+) const
+{
+    if (globalState_->hasError() || size <= 0)
+    {
+        return;
+    }
+
+    CCMIOEntity nodeType;
+    if (isBoundary)
+    {
+        nodeType = kCCMIOBoundaryFaces;
+    }
+    else
+    {
+        nodeType = kCCMIOInternalFaces;
+    }
+
+    const faceList&  faces = mesh_.faces();
+    const labelList& owner = mesh_.faceOwner();
+    const labelList& neigh = mesh_.faceNeighbour();
+
+    // 1. write vertices to define faces
+
+    // Determine allocation size
+    label streamSize = size;
+    for (label faceI = 0; faceI < size; ++faceI)
+    {
+        streamSize += faces[faceI + start].size();
+    }
+
+    // Build a vertex stream
+    List<int> ccmStream(streamSize);
+    streamSize = 0;
+    for (label faceI = 0; faceI < size; ++faceI)
+    {
+        const labelList& vrtList = faces[faceI + start];
+
+        ccmStream[streamSize++] = vrtList.size();
+        forAll(vrtList, i)
+        {
+            ccmStream[streamSize++] = vrtList[i] + 1;
+        }
+    }
+
+    if (ccm::debug)
+    {
+        Info<<"CCMIOWriteFaces()  size:" << size << " streamSize:" << streamSize << endl;
+    }
+
+    CCMIOWriteFaces
+    (
+        &(globalState_->error),
+        nodeId,
+        nodeType,
+        mapId,
+        streamSize,
+        ccmStream.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+
+    if (globalState_->hasError())
+    {
+        return;
+    }
+
+    // 2. write face owner/neighbours
+    if (isBoundary)
+    {
+        streamSize = size;
+        if (ccmStream.size() < streamSize)
+        {
+            ccmStream.setSize(streamSize);
+        }
+
+        for (int faceI = 0; faceI < size; ++faceI)
+        {
+            ccmStream[faceI] = owner[faceI + start] + 1;
+        }
+    }
+    else
+    {
+        // kCCMIOInternalFaces
+        streamSize = 2 * size;
+        if (ccmStream.size() < streamSize)
+        {
+            ccmStream.setSize(streamSize);
+        }
+
+        for (int faceI = 0; faceI < size; ++faceI)
+        {
+            ccmStream[faceI*2]   = owner[faceI + start] + 1;
+            ccmStream[faceI*2+1] = neigh[faceI + start] + 1;
+        }
+    }
+
+    if (ccm::debug)
+    {
+        Info<<"CCMIOWriteFaceCells()  size:" << size;
+        if (isBoundary)
+        {
+            Info<< " boundary";
+        }
+        else
+        {
+            Info<<" internal";
+        }
+        Info<<"Faces"<<endl;
+    }
+
+    CCMIOWriteFaceCells
+    (
+        &(globalState_->error),
+        nodeId,
+        nodeType,
+        mapId,
+        ccmStream.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+
+    // determine corresponding ProstarFaceId
+    if (isBoundary)
+    {
+        streamSize = size;
+        if (ccmStream.size() < streamSize)
+        {
+            ccmStream.setSize(streamSize);
+        }
+
+        for (int faceIdx = 0; faceIdx < size; ++faceIdx)
+        {
+            label faceI = faceIdx + start;
+            // boundary face - owner only
+            ccmStream[faceIdx] = prostarCellFaceId(owner[faceI], faceI);
+        }
+
+        CCMIOWriteOpt1i
+        (
+            &(globalState_->error),
+            nodeId,
+            "ProstarFaceId",
+            size,
+            ccmStream.begin(),
+            kCCMIOStart,
+            kCCMIOEnd
+        );
+    }
+    else
+    {
+        // kCCMIOInternalFaces
+        streamSize = 2 * size;
+        if (ccmStream.size() < streamSize)
+        {
+            ccmStream.setSize(streamSize);
+        }
+
+        for (int faceIdx = 0; faceIdx < size; ++faceIdx)
+        {
+            label faceI = faceIdx + start;
+            ccmStream[faceIdx*2]   = prostarCellFaceId(owner[faceI], faceI);
+            ccmStream[faceIdx*2+1] = prostarCellFaceId(neigh[faceI], faceI);
+        }
+
+        CCMIOWriteOpt2i
+        (
+            &(globalState_->error),
+            nodeId,
+            "ProstarFaceId",
+            size,
+            2,
+            ccmStream.begin(),
+            kCCMIOStart,
+            kCCMIOEnd
+        );
+    }
+}
+
+
+// writeVertices
+// 1) write the vertex map (starting with 1)
+// 2) write the vertex data
+//
+void Foam::ccm::writer::writeVertices
+(
+    const ccmID& verticesNode
+) const
+{
+    const pointField& pts = mesh_.points();
+
+    Info<< "writing points: " << pts.size() << endl;
+
+    // 1. mapping data array index to the vertex Id (starting with 1)
+    ccmID vertexMap;
+    addLinearMap
+    (
+        "vertex Map",
+        vertexMap,
+        pts.size()
+    );
+
+    // 2. write vertices - scale [m] -> [mm] for consistency with PROSTAR
+    //    but is probably immaterial
+    const float scaling(0.001);   // to recover meters
+    List<float> vrts(3*pts.size());
+    forAll(pts, i)
+    {
+        vrts[3*i]    = 1000.0 * pts[i].x();
+        vrts[3*i+1]  = 1000.0 * pts[i].y();
+        vrts[3*i+2]  = 1000.0 * pts[i].z();
+    }
+
+    CCMIOWriteVerticesf
+    (
+        &(globalState_->error),
+        verticesNode,
+        3, scaling,
+        vertexMap,
+        vrts.begin(),
+        kCCMIOStart,
+        kCCMIOEnd
+    );
+    assertNoError("writing 'Vertices' node");
+}
+
+
+// writeInternalFaces
+// 1) write the face map (starting with 1)
+// 2) write owner/neighbour
+//
+void Foam::ccm::writer::writeInternalFaces
+(
+    const ccmID& topoNode
+) const
+{
+    label nFaces = mesh_.nInternalFaces();
+
+    Info<< "writing internalFaces: " << nFaces << endl;
+    if (nFaces > 0)
+    {
+        ccmID nodeId;
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            topoNode,
+            kCCMIOInternalFaces,
+            nullptr,
+            &nodeId
+        );
+        assertNoError("creating internalFaces node");
+
+        writeFaces
+        (
+            nodeId,
+            maps_->internalFaces,
+            false,
+            nFaces
+        );
+        assertNoError("writing internalFaces");
+    }
+}
+
+
+// writeBoundaryFaces:
+// - write faces with owner
+void Foam::ccm::writer::writeBoundaryFaces
+(
+    const ccmID& topoNode
+) const
+{
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    // 4. write boundary faces
+    Info<< "writing boundaryFaces:" << flush;
+
+    label defaultId = findDefaultBoundary();
+
+    // write Default_Boundary_Region as BoundaryFaces-0
+    if (defaultId >= 0)
+    {
+        Info<< " " << patches[defaultId].size() << flush;
+
+        ccmID nodeId;
+        CCMIONewIndexedEntity
+        (
+            &(globalState_->error),
+            topoNode,
+            kCCMIOBoundaryFaces,
+            0,
+            nullptr,
+            &nodeId
+        );
+        assertNoError
+        (
+            "creating boundaryFaces node patch: " + patches[defaultId].name()
+        );
+
+        writeFaces
+        (
+            nodeId,
+            maps_->boundary[defaultId],
+            true,
+            patches[defaultId].size(),
+            patches[defaultId].start()
+        );
+        assertNoError
+        (
+            "writing boundaryFaces patch: " + patches[defaultId].name()
+        );
+    }
+
+    //
+    // write boundary faces - skip Default_Boundary_Region
+    //
+    forAll(patches, patchI)
+    {
+        label regionId = patchI;
+        if (regionId == defaultId)
+        {
+            continue;  // skip - already written
+        }
+        else if (defaultId == -1 || regionId < defaultId)
+        {
+            regionId++;
+        }
+
+        Info<< " " << patches[patchI].size() << flush;
+
+        if (patches[patchI].size() > 0)
+        {
+            ccmID nodeId;
+            CCMIONewIndexedEntity
+            (
+                &(globalState_->error),
+                topoNode,
+                kCCMIOBoundaryFaces,
+                regionId,
+                nullptr,
+                &nodeId
+            );
+            assertNoError
+            (
+                "creating boundaryFaces node patch: " + patches[patchI].name()
+            );
+
+            writeFaces
+            (
+                nodeId,
+                maps_->boundary[patchI],
+                true,
+                patches[patchI].size(),
+                patches[patchI].start()
+            );
+            assertNoError
+            (
+                "writing boundaryFaces patch: " + patches[patchI].name()
+            );
+        }
+    }
+
+    Info<< endl;
+}
+
+
+// writeCells:
+// - write faces with owner/neighbour
+// - write interfaces
+void Foam::ccm::writer::writeCells
+(
+    const ccmID& topoNode
+)
+{
+    Info<< "writing cells: " << mesh_.nCells() << endl;
+
+    // 1. cellTableId
+    //    - if possible, read from constant/polyMesh/cellTableId
+    //    - otherwise use cellZone information
+    List<int> mapData(mesh_.nCells(), -1);
+    bool useCellZones = false;
+
+    IOList<label> ioList
+    (
+        IOobject
+        (
+            "cellTableId",
+            "constant",
+            polyMesh::meshSubDir,
+            mesh_,
+            IOobject::READ_IF_PRESENT,
+            IOobject::NO_WRITE,
+            false
+        )
+    );
+
+
+    if (ioList.headerOk())
+    {
+        if (ioList.size() == mesh_.nCells())
+        {
+            mapData.transfer(ioList);
+        }
+        else
+        {
+            WarningIn("ccm::writer::writeCells(polyMesh&)")
+                << ioList.objectPath() << endl
+                << "    Has incorrect number of cells: "
+                << ioList.size() << " instead of " << mesh_.nCells()
+                << " -    use cellZone information instead"
+                << endl;
+
+            ioList.clear();
+            useCellZones = true;
+        }
+    }
+    else
+    {
+        useCellZones = true;
+    }
+
+
+    if (useCellZones)
+    {
+        if (!cellTable_.size())
+        {
+            Info<< "created cellTable from cellZones" << endl;
+            cellTable_ = mesh_;
+        }
+
+        // track if there are unzoned cells
+        label nUnzoned = mesh_.nCells();
+
+        // get the cellZone <-> cellTable correspondence
+        Info<< "matching cellZones to cellTable" << endl;
+
+        forAll(mesh_.cellZones(), zoneI)
+        {
+            const cellZone& cZone = mesh_.cellZones()[zoneI];
+            if (cZone.size())
+            {
+                nUnzoned -= cZone.size();
+
+                label tableId = cellTable_.findIndex(cZone.name());
+                if (tableId < 0)
+                {
+                    dictionary dict;
+
+                    dict.add("Label", cZone.name());
+                    dict.add("MaterialType", "fluid");
+                    tableId = cellTable_.append(dict);
+                }
+
+                forAll(cZone, i)
+                {
+                    mapData[cZone[i]] = tableId;
+                }
+            }
+        }
+
+        if (nUnzoned)
+        {
+            dictionary dict;
+
+            dict.add("Label", "__unzonedCells__");
+            dict.add("MaterialType", "fluid");
+            label tableId = cellTable_.append(dict);
+
+            forAll(mapData, i)
+            {
+                if (mapData[i] < 0)
+                {
+                    mapData[i] = tableId;
+                }
+            }
+        }
+    }
+
+    // 2. mapping data array index to the cell Id (starting with 1)
+    ccmID cellsNode;
+    CCMIONewEntity
+    (
+        &(globalState_->error),
+        topoNode,
+        kCCMIOCells,
+        nullptr,
+        &cellsNode
+    );
+    assertNoError("creating 'Cells' node");
+
+    CCMIOWriteCells
+    (
+        &(globalState_->error),
+        cellsNode,
+        maps_->cells,
+        mapData.begin(),
+        kCCMIOStart, kCCMIOEnd
+    );
+    assertNoError("writing 'Cells' node");
+
+    // 3. add cell topology information, if possible
+    const cellShapeList& shapes = mesh_.cellShapes();
+    forAll(shapes, cellI)
+    {
+        label mapIndex = shapes[cellI].model().index();
+
+        // A registered primitive type
+        if (prostarShapeLookup_.found(mapIndex))
+        {
+            mapData[cellI] = prostarShapeLookup_[mapIndex];
+        }
+        else
+        {
+            mapData[cellI] = STARCDCore::starcdPoly;  // Treat as polyhedral
+        }
+    }
+
+    CCMIOWriteOpt1i
+    (
+        &(globalState_->error),
+        cellsNode,
+        "CellTopologyType",
+        mesh_.nCells(),
+        mapData.begin(),
+        kCCMIOStart, kCCMIOEnd
+    );
+
+    // 4. write interfaces
+    writeInterfaces(cellsNode);
+}
+
+
+// write interfaces
+//   1) PROSTAR baffles
+//
+void Foam::ccm::writer::writeInterfaces
+(
+    const ccmID& cellsNode
+) const
+{
+    IOList<labelList> interfaces
+    (
+        IOobject
+        (
+            "interfaces",
+            "constant",
+            "polyMesh",
+            mesh_,
+            IOobject::READ_IF_PRESENT,
+            IOobject::NO_WRITE,
+            false
+        )
+    );
+
+    if (interfaces.headerOk() && interfaces.size() > 0)
+    {
+        List<int> mapData(2 * interfaces.size());
+
+        forAll(interfaces, i)
+        {
+            mapData[i*2]   = interfaces[i][0];
+            mapData[i*2+1] = interfaces[i][1];
+        }
+
+        ccmID nodeId;
+        if
+        (
+            CCMIONewEntity
+            (
+                &(globalState_->error),
+                cellsNode,
+                kCCMIOInterfaces,
+                0,
+                &nodeId
+            )
+         != kCCMIONoErr
+
+         || CCMIOWriteOpt2i
+            (
+                &(globalState_->error),
+                nodeId,
+                "FaceIds",
+                interfaces.size(),
+                2,
+                mapData.begin(), kCCMIOStart, kCCMIOEnd
+            )
+         != kCCMIONoErr
+        )
+        {
+            assertNoError("writing interfaces 'FaceIds'");
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ccm::writer::writeGeometry()
+{
+    // use first ("default") state node
+    ccmID stateNode;
+    // int stateI = 0;
+
+    // create "default" State
+    CCMIONewState
+    (
+        &(globalState_->error),
+        (globalState_->root),
+        "default",
+        nullptr,
+        nullptr,
+        &stateNode
+    );
+    assertNoError("could not create default state");
+
+    // use first processor - create a new one
+    ccmID processorNode;
+    int procI = 0;
+
+    if
+    (
+        CCMIONextEntity
+        (
+            nullptr,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     != kCCMIONoErr
+    )
+    {
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            stateNode,
+            kCCMIOProcessor,
+            nullptr,
+            &processorNode
+        );
+        assertNoError("could not create processor node");
+    }
+
+    // remove old data (if it exists)
+    CCMIOClearProcessor
+    (
+        nullptr, stateNode, processorNode,
+        true,   // Clear vertices
+        true,   // Clear topology
+        true,   // Clear initial field
+        true,   // Clear solution
+        true    // Clear lagrangian
+    );
+
+#if 0
+    CCMIOWriteOptstr
+    (
+        nullptr,
+        processorNode,
+        "CreatingProgram",
+        "ccm::writer"
+    );
+#endif
+
+    //
+    // create vertices and topology nodes
+    //
+    ccmID verticesNode, topoNode;
+    if
+    (
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            (globalState_->root),
+            kCCMIOVertices,
+            nullptr,
+            &verticesNode
+        )
+     == kCCMIONoErr
+
+     && CCMIONewEntity
+        (
+            &(globalState_->error),
+            (globalState_->root),
+            kCCMIOTopology,
+            nullptr,
+            &topoNode
+        )
+     == kCCMIONoErr
+    )
+    {
+        writeVertices(verticesNode);
+        writeInternalFaces(topoNode);
+        writeBoundaryFaces(topoNode);
+        writeCells(topoNode);
+        writeProblem(stateNode);
+    }
+
+    // Now we have the mesh (vertices and topology),
+    // we can write out the processor information.
+    CCMIOWriteProcessor
+    (
+        &(globalState_->error),
+        processorNode,
+        nullptr, &verticesNode, // no verticesFile, write verticesNode
+        nullptr, &topoNode,     // no topologyFile, write topoNode
+        nullptr, nullptr,       // initialField unchanged
+        nullptr, nullptr        // no solutionFile, solution unchanged
+    );
+    assertNoError("Error after writing geometry processor");
+
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ccm/writer/ccmWriterSolution.C b/src/conversion/ccm/writer/ccmWriterSolution.C
new file mode 100644
index 0000000000000000000000000000000000000000..c351ef76c86650be2bd3218bfb0d13e409ec4279
--- /dev/null
+++ b/src/conversion/ccm/writer/ccmWriterSolution.C
@@ -0,0 +1,814 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ccmWriter.H"
+#include "dictionary.H"
+#include "IFstream.H"
+#include "IStringStream.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "ccmInternal.H"  // include last to avoid any strange interactions
+
+
+// * * * * * * * * * * * * * * * Static Data Member  * * * * * * * * * * * * //
+
+// names for known field types
+Foam::dictionary Foam::ccm::writer::defaultNameMapping
+(
+    IStringStream
+    (
+        // volScalarField
+        "p   { name P; Label \"Pressure\"; units \"Pa\"; }"
+     // "?? { name PTER; Label \"Thermo. Pressure\"; units \"Pa\"; }"
+     // "yPlus { name YPLU; Label \"YPLUS\"; }"
+     // "?? { name DIST; Label \"Normal Distance\"; units \"m\"; }"
+     // "?? { name H; Label \"Enthalpy\"; units \"J/kg\"; }"
+        "rho { name DENS; Label \"Density\"; units \"kg/m3\"; }"
+        "T   { name T; Label \"Temperature\"; units \"K\"; }"
+        "k   { name TE; Label \"Turb Kinetic Energy\"; units \"m2/s2\"; }"
+        "epsilon { name ED; Label \"Dissipation Rate\"; units \"m2/s3\"; }"
+        "mu  { name LAMV; Label \"Molecular Viscosity\"; units \"Pa s\"; }"
+        "mut { name VIS;  Label \"Turbulent Viscosity\"; units \"Pa s\"; }"
+        // volVectorField
+        "U   { name ALL; Label \"Velocity\"; units \"m/s\"; }"
+        // U-components:
+        "_0U { name SU; Label \"Velocity Component U\"; units \"m/s\"; }"
+        "_1U { name SV; Label \"Velocity Component V\"; units \"m/s\"; }"
+        "_2U { name SW; Label \"Velocity Component W\"; units \"m/s\"; }"
+        // surfaceScalarField
+        "phi { name MassFlux; Label \"Mass Flux\"; units \"kg/s\"; }"
+    )()
+);
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+bool Foam::ccm::writer::newFieldNode
+(
+    const ccmID& phaseNode,
+    const word& fieldName,
+    const dictionary& nameMapping,
+    const ccmDimension& dims,
+    ccmID& fieldNode
+) const
+{
+    if (!nameMapping.found(fieldName) || !nameMapping.isDict(fieldName))
+    {
+        return false;
+    }
+
+    const dictionary& dict = nameMapping.subDict(fieldName);
+
+    word shortName;
+    if (!dict.readIfPresent("name", shortName))
+    {
+        return false;
+    }
+
+    string ccmLabel(fieldName);
+    dict.readIfPresent("Label", ccmLabel);
+
+    CCMIONewField
+    (
+        &(globalState_->error),
+        phaseNode,
+        ccmLabel.c_str(),
+        shortName.c_str(),
+        dims(),
+        &fieldNode
+    );
+
+
+    string units;
+    if (dims() == kCCMIOScalar && dict.readIfPresent("units", units))
+    {
+        CCMIOWriteOptstr
+        (
+            &(globalState_->error),
+            fieldNode,
+            "Units",
+            units.c_str()
+        );
+    }
+
+    return true;
+
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ccm::writer::writeSolution
+(
+    const IOobjectList& objects,
+    const fileName& remappingDictName
+)
+{
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    if (!isA<fvMesh>(mesh_))
+    {
+        WarningIn("ccm::writer::writeSolution(const IOobjectList&, const fileName&)")
+            << "cannot write solutions with a polyMesh instead of a fvMesh"
+            << endl;
+        return;
+    }
+
+    dictionary remapDict;
+
+    if (remappingDictName.empty())
+    {
+        remapDict = IOdictionary
+        (
+            IOobject
+            (
+                "remapping",
+                mesh_.time().constant(),
+                mesh_,
+                IOobject::READ_IF_PRESENT,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+    }
+    else
+    {
+        // Specified (absolute/relative) name: treat like MUST_READ
+        remapDict = dictionary(IFstream(remappingDictName)());
+    }
+
+
+    dictionary nameMapping(defaultNameMapping);
+
+    // Merge without overwrite
+    if (remapDict.isDict("fields"))
+    {
+        nameMapping |= remapDict.subDict("fields");
+    }
+
+
+    ccmID stateNode, processorNode, nodeId;
+    int procI = 0;
+
+    // Create first ("default") state node
+    CCMIONewState
+    (
+        &(globalState_->error),
+        (globalState_->root),
+        "default",
+        nullptr,
+        nullptr,
+        &stateNode
+    );
+    assertNoError("could not create default state");
+
+    // Use first processor or create a new one
+    procI = 0;
+    if
+    (
+        CCMIONextEntity
+        (
+            nullptr,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     != kCCMIONoErr
+    )
+    {
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            stateNode,
+            kCCMIOProcessor,
+            nullptr,
+            &processorNode
+        );
+        assertNoError("could not create processor node");
+    }
+
+    // Remove old data (if it exists)
+    CCMIOClearProcessor
+    (
+        nullptr, stateNode, processorNode,
+        true,   // Clear vertices
+        true,   // Clear topology
+        true,   // Clear initial field
+        true,   // Clear solution
+        true    // Clear lagrangian
+    );
+
+    //
+    // Create vertices and topology nodes
+    // and references to vertices and topology files
+    //
+    {
+        ccmID verticesNode, topoNode;
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            (globalState_->root),
+            kCCMIOVertices,
+            nullptr,
+            &verticesNode
+        );
+
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            (globalState_->root),
+            kCCMIOTopology,
+            nullptr,
+            &topoNode
+        );
+
+        string topoFileName = defaultMeshName + ".ccmg";
+
+        CCMIOWriteProcessor
+        (
+            &(globalState_->error),
+            processorNode,
+            topoFileName.c_str(), &verticesNode,// verticesFile, verticesNode
+            topoFileName.c_str(), &topoNode,    // topologyFile, topologyNode
+            nullptr, nullptr,                   // initialField unchanged
+            nullptr, nullptr                    // no solutionFile, solution unchanged
+        );
+    }
+    assertNoError("Error after writing geometry processor");
+
+    CCMIONewState
+    (
+        &(globalState_->error),
+        (globalState_->root),
+        "Restart_1",
+        nullptr,
+        nullptr,
+        &stateNode
+    );
+    assertNoError("could not create Restart_1 state");
+
+    // Use first processor or create a new one
+    procI = 0;
+    if
+    (
+        CCMIONextEntity
+        (
+            nullptr,
+            stateNode,
+            kCCMIOProcessor,
+            &procI,
+            &processorNode
+        )
+     != kCCMIONoErr
+    )
+    {
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            stateNode,
+            kCCMIOProcessor,
+            nullptr,
+            &processorNode
+        );
+        assertNoError("could not create 'Processor' node");
+    }
+
+    // Remove old data (if it exists)
+    CCMIOClearProcessor
+    (
+        nullptr, stateNode, processorNode,
+        true,   // Clear vertices
+        true,   // Clear topology
+        true,   // Clear initial field
+        true,   // Clear solution
+        true    // Clear lagrangian
+    );
+
+    // Write out some simple solution data
+    ccmID phaseNode, fieldSetNode;
+
+    // Use first FieldSet
+    int fieldSetI = 0;
+    if
+    (
+        CCMIONextEntity
+        (
+            nullptr,
+            (globalState_->root),
+            kCCMIOFieldSet,
+            &fieldSetI,
+            &fieldSetNode
+        )
+     != kCCMIONoErr
+    )
+    {
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            (globalState_->root),
+            kCCMIOFieldSet,
+            nullptr,
+            &fieldSetNode
+        );
+        assertNoError("could not create FieldSet node");
+    }
+
+    // RestartInfo
+    {
+        ccmID restartInfoNode, restartDataNode;
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            fieldSetNode,
+            kCCMIORestart,
+            nullptr,
+            &restartInfoNode
+        );
+        assertNoError("could not create restartInfoNode node");
+
+        // Get time information
+        const Time& runTime = mesh_.time();
+        label timeIndex = 0;
+        // scalar timeValue = runTime.timeName();
+        if
+        (
+            runTime.timeName() != runTime.constant()
+         && runTime.timeName() != "0"
+        )
+        {
+            IOobject io
+            (
+                "time",
+                runTime.timeName(),
+                "uniform",
+                runTime,
+                IOobject::READ_IF_PRESENT,
+                IOobject::NO_WRITE,
+                false
+            );
+
+            if (io.typeHeaderOk<IOdictionary>(true))
+            {
+                IOdictionary timeObject
+                (
+                    IOobject
+                    (
+                        "time",
+                        runTime.timeName(),
+                        "uniform",
+                        runTime,
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE,
+                        false
+                    )
+                );
+
+                timeObject.lookup("index") >> timeIndex;
+            }
+        }
+
+        CCMIOWriteRestartInfo
+        (
+            &(globalState_->error),
+            restartInfoNode,
+            "ccm::writer",      // solverName
+            timeIndex,          // iteration
+            0.0,                // time
+            nullptr,            // timeUnits: default  (s)
+            0.0                 // startAngle: non-rotating mesh
+        );
+
+        // RestartData
+        CCMIONewEntity
+        (
+            &(globalState_->error),
+            restartInfoNode,
+            kCCMIORestartData,
+            nullptr,
+            &restartDataNode
+        );
+        assertNoError("could not create restartDataNode node");
+
+        // Minimal information required by PROSTAR
+
+        CCMIOWriteOptf
+        (
+            nullptr,
+            restartDataNode,
+            "SCALE",
+            0.001        // [m] -> [mm]: PROSTAR is still a bit buggy here
+        );
+
+
+        // Add Phase data
+        CCMIONewIndexedEntity
+        (
+            &(globalState_->error),
+            restartDataNode,
+            kCCMIOFieldPhase,
+            1,
+            nullptr,
+            &nodeId
+        );
+
+        // HACK:  for calculating Mach number
+        // FIXME: use thermodynamicProperties /or/ thermophysicalProperties
+        CCMIOWriteOptf
+        (
+            nullptr,
+            nodeId,
+            "Material Specific Heat",
+            1007
+        );
+
+        CCMIOWriteOptf
+        (
+            nullptr,
+            nodeId,
+            "Material Molecular Weight",
+            28.96
+        );
+    }
+
+    CCMIONewIndexedEntity
+    (
+        &(globalState_->error),
+        fieldSetNode,
+        kCCMIOFieldPhase,
+        1,
+        "Phase_0001",
+        &phaseNode
+    );
+
+
+
+    forAllConstIter(IOobjectList, objects, iter)
+    {
+        word fieldName = (*iter()).name();
+        bool variableGood =
+        (
+            nameMapping.found(fieldName)
+         && (*iter()).typeHeaderOk<volScalarField>(false)
+        );
+
+        if (!variableGood)
+        {
+            // Only retain registered fields that are also readable
+            continue;
+        }
+
+        word fieldType = (*iter()).headerClassName();
+
+        if (fieldType == volScalarField::typeName)
+        {
+            Info<< " " << fieldName << flush;
+
+            volScalarField field
+            (
+                IOobject
+                (
+                    fieldName,
+                    mesh_.time().timeName(),
+                    mesh_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                refCast<const fvMesh>(mesh_)
+            );
+
+            ccmID fieldNode;
+
+            // Info<< " call newFieldNode " << fieldName << flush;
+
+            if
+            (
+                !newFieldNode
+                (
+                    phaseNode,
+                    fieldName,
+                    nameMapping,
+                    kCCMIOScalar,
+                    fieldNode
+                )
+            )
+            {
+                continue;
+            }
+
+            // Write cellData first
+            CCMIONewEntity
+            (
+                &(globalState_->error),
+                fieldNode,
+                kCCMIOFieldData,
+                nullptr,
+                &nodeId
+            );
+
+            CCMIOWriteFieldDatad
+            (
+                &(globalState_->error),
+                nodeId,
+                maps_->cells,
+                kCCMIOCell,
+                const_cast<scalar*>
+                (
+                    field.primitiveField().begin()
+                ),
+                kCCMIOStart,
+                kCCMIOEnd
+            );
+            assertNoError("writing internalField " + fieldName);
+
+            // Write boundaryData
+            forAll(patches, patchI)
+            {
+                CCMIONewEntity
+                (
+                    &(globalState_->error),
+                    fieldNode,
+                    kCCMIOFieldData,
+                    nullptr,
+                    &nodeId
+                );
+
+                CCMIOWriteFieldDatad
+                (
+                    &(globalState_->error),
+                    nodeId,
+                    maps_->boundary[patchI],
+                    kCCMIOFace,
+                    const_cast<scalar*>
+                    (
+                        field.boundaryField()[patchI].begin()
+                    ),
+                    kCCMIOStart,
+                    kCCMIOEnd
+                );
+            }
+
+            assertNoError("writing boundaryField " + fieldName);
+        }
+        else if (fieldType == volVectorField::typeName && fieldName == "U")
+        {
+            Info<< " " << fieldName << flush;
+
+            volVectorField vfield
+            (
+                IOobject
+                (
+                    fieldName,
+                    mesh_.time().timeName(),
+                    mesh_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                refCast<const fvMesh>(mesh_)
+            );
+
+
+            ccmID vectorNode;
+            newFieldNode
+            (
+                phaseNode,
+                fieldName,
+                nameMapping,
+                kCCMIOVector,
+                vectorNode
+            );
+
+            for (direction cmpt=0; cmpt < pTraits<vector>::nComponents; ++cmpt)
+            {
+                word componentName("_" + Foam::name(cmpt) + fieldName);
+                volScalarField field(vfield.component(cmpt));
+
+                CCMIOComponent ccmComponent = kCCMIOVectorX;
+                switch(cmpt) {
+                    case 0:
+                        ccmComponent = kCCMIOVectorX;
+                        break;
+                    case 1:
+                        ccmComponent = kCCMIOVectorY;
+                        break;
+                    case 2:
+                        ccmComponent = kCCMIOVectorZ;
+                        break;
+                }
+
+                ccmID componentNode;
+                if
+                (
+                    !newFieldNode
+                    (
+                        phaseNode,
+                        componentName,
+                        nameMapping,
+                        kCCMIOScalar,
+                        componentNode
+                    )
+                )
+                {
+                    continue;
+                }
+
+                // Re-register with vector field
+                CCMIOWriteMultiDimensionalFieldData
+                (
+                    &(globalState_->error),
+                    vectorNode,
+                    ccmComponent,
+                    componentNode
+                );
+
+                // Write cellData first
+                CCMIONewEntity
+                (
+                    &(globalState_->error),
+                    componentNode,
+                    kCCMIOFieldData,
+                    nullptr,
+                    &nodeId
+                );
+
+                CCMIOWriteFieldDatad
+                (
+                    &(globalState_->error),
+                    nodeId,
+                    maps_->cells,
+                    kCCMIOCell,
+                    const_cast<scalar*>
+                    (
+                        field.primitiveField().begin()
+                    ),
+                    kCCMIOStart, kCCMIOEnd
+                );
+                assertNoError
+                (
+                    "writing internalField " + fieldName + " " + componentName
+                );
+
+
+                // Write boundaryData
+                forAll(patches, patchI)
+                {
+                    CCMIONewEntity
+                    (
+                        &(globalState_->error),
+                        componentNode,
+                        kCCMIOFieldData,
+                        nullptr,
+                        &nodeId
+                    );
+
+                    CCMIOWriteFieldDatad
+                    (
+                        &(globalState_->error),
+                        nodeId,
+                        maps_->boundary[patchI],
+                        kCCMIOFace,
+                        const_cast<scalar*>
+                        (
+                            field.boundaryField()[patchI].begin()
+                        ),
+                        kCCMIOStart, kCCMIOEnd
+                    );
+                }
+
+                assertNoError
+                (
+                    "writing boundaryField " + fieldName + " " + componentName
+                );
+            }
+        }
+        else if (fieldType == surfaceScalarField::typeName)
+        {
+#if 0
+            // Still have problems reading surface fields in PROSTAR
+            Info<< " " << fieldName << flush;
+
+            surfaceScalarField field
+            (
+                IOobject
+                (
+                    fieldName,
+                    mesh_.time().timeName(),
+                    mesh_,
+                    IOobject::READ_IF_PRESENT,
+                    IOobject::NO_WRITE
+                ),
+                refCast<const fvMesh>(mesh_)
+            );
+
+            ccmID fieldNode;
+
+            // Info<< " call newFieldNode " << fieldName << flush;
+
+            if
+            (
+                !newFieldNode
+                (
+                    phaseNode,
+                    fieldName,
+                    nameMapping,
+                    kCCMIOScalar,
+                    fieldNode
+                )
+            )
+            {
+                continue;
+            }
+
+            // Write cell faceData first
+            CCMIONewEntity
+            (
+                &(globalState_->error),
+                fieldNode,
+                kCCMIOFieldData,
+                nullptr,
+                &nodeId
+            );
+
+            CCMIOWriteFieldDatad
+            (
+                &(globalState_->error),
+                nodeId,
+                maps_->internalFaces,
+                kCCMIOFace,
+                const_cast<scalar*>
+                (
+                    field.primitiveField().begin()
+                ),
+                kCCMIOStart,
+                kCCMIOEnd
+            );
+            assertNoError("writing internalField " + fieldName);
+
+            // Write boundaryData
+            forAll(patches, patchI)
+            {
+                CCMIONewEntity
+                (
+                    &(globalState_->error),
+                    fieldNode,
+                    kCCMIOFieldData,
+                    nullptr,
+                    &nodeId
+                );
+
+                CCMIOWriteFieldDatad
+                (
+                    &(globalState_->error),
+                    nodeId,
+                    maps_->boundary[patchI],
+                    kCCMIOFace,
+                    field.boundaryField()[patchI].begin(),
+                    kCCMIOStart,
+                    kCCMIOEnd
+                );
+            }
+
+            assertNoError("writing boundaryField " + fieldName);
+#endif
+        }
+    }
+    Info<< endl;
+
+    assertNoError("Error before writing processor");
+
+    CCMIOWriteProcessor
+    (
+        &(globalState_->error),
+        processorNode,
+        nullptr, nullptr,     // vertices
+        nullptr, nullptr,     // topology
+        nullptr, nullptr,     // initial field
+        nullptr, &fieldSetNode
+    );
+    assertNoError("Error after writing processor");
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/common/reader/createPolyBoundary.C b/src/conversion/common/reader/createPolyBoundary.C
index 7279b73c4135b8e98aabbd9c0ff706fd882ed027..645c90f6b5a7abed22eef3509d3ccc19b8395dec 100644
--- a/src/conversion/common/reader/createPolyBoundary.C
+++ b/src/conversion/common/reader/createPolyBoundary.C
@@ -439,14 +439,26 @@ Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
         }
         dictionary& patchDict = patchDicts[patchi];
 
-        // add but not overwrite type
-        patchDict.add("type", patchTypes_[patchi], false);
-        if (patchPhysicalTypes_.size() && patchPhysicalTypes_[patchi].size())
+        // Add but not override 'type'
+        if (!patchDict.found("type"))
         {
-            patchDict.add("startFace", patchPhysicalTypes_[patchi], false);
+            patchDict.add("type", patchTypes_[patchi], false);
         }
 
-        // overwrite sizes and start
+        // Add but not override 'physicalType' but only if it differs
+        // from 'type'
+        if
+        (
+            patchi < patchPhysicalTypes_.size()
+         && patchPhysicalTypes_[patchi].size()
+         && patchPhysicalTypes_[patchi] != patchTypes_[patchi]
+         && !patchDict.found("physicalType")
+        )
+        {
+            patchDict.add("physicalType", patchPhysicalTypes_[patchi], false);
+        }
+
+        // Overwrite sizes and start
         patchDict.add("nFaces", patchSizes_[patchi], true);
         patchDict.add("startFace", patchStarts_[patchi], true);
     }
diff --git a/src/conversion/common/reader/meshReader.C b/src/conversion/common/reader/meshReader.C
index c7e2d67980f6a0419c5a8168a04d274b445aeebd..4a6356910cb76d13e11e8d34a6c0d8273068af13 100644
--- a/src/conversion/common/reader/meshReader.C
+++ b/src/conversion/common/reader/meshReader.C
@@ -213,7 +213,13 @@ Foam::meshReader::meshReader
     baffleFaces_(0),
     cellTableId_(0),
     cellTable_()
-{}
+{
+    // Sanity
+    if (scaleFactor_ <= VSMALL)
+    {
+        scaleFactor_ = 1;
+    }
+}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
diff --git a/src/conversion/common/reader/meshReader.H b/src/conversion/common/reader/meshReader.H
index 54d5876e96448902374c72fb9fe7b06076da3756..b53d0c1e4dfbcdd93da2f09f35b3e47f1b177a7c 100644
--- a/src/conversion/common/reader/meshReader.H
+++ b/src/conversion/common/reader/meshReader.H
@@ -275,7 +275,7 @@ public:
     // Constructors
 
         //- Construct from fileName
-        meshReader(const fileName&, const scalar scaleFactor = 1.0);
+        meshReader(const fileName&, const scalar scaling = 1.0);
 
 
     //- Destructor
diff --git a/src/conversion/common/writer/meshWriter.C b/src/conversion/common/writer/meshWriter.C
index 36d6426757254d8ab97ecf9da6d3bbfaeadcbb2c..760cccea7a23697c655ef3fed30b4a42bf9568d2 100644
--- a/src/conversion/common/writer/meshWriter.C
+++ b/src/conversion/common/writer/meshWriter.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,15 +68,24 @@ lookup
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::meshWriter::meshWriter(const polyMesh& mesh, const scalar scaleFactor)
+Foam::meshWriter::meshWriter
+(
+    const polyMesh& mesh,
+    const scalar scaling
+)
 :
     mesh_(mesh),
-    scaleFactor_(scaleFactor),
-    writeBoundary_(true),
+    scaleFactor_(scaling),
     boundaryRegion_(),
     cellTable_(),
     cellTableId_()
-{}
+{
+    // Sanity
+    if (scaleFactor_ <= VSMALL)
+    {
+        scaleFactor_ = 1;
+    }
+}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
diff --git a/src/conversion/common/writer/meshWriter.H b/src/conversion/common/writer/meshWriter.H
index 51f4c4014a911bd39d48b9da74d6796f5aa958a3..d17322fde0754480c3eb7a2a6864fba89b318d6f 100644
--- a/src/conversion/common/writer/meshWriter.H
+++ b/src/conversion/common/writer/meshWriter.H
@@ -98,9 +98,6 @@ protected:
         //- Scaling factor for points (eg, [m] -> [mm])
         scalar scaleFactor_;
 
-        //- Write bnd file
-        bool writeBoundary_;
-
         //- boundaryRegion persistent data saved as a dictionary
         boundaryRegion boundaryRegion_;
 
@@ -125,13 +122,14 @@ public:
         //- Specify a default mesh name
         static string defaultMeshName;
 
+
     // Constructors
 
-        //- Create a writer object
+        //- Create a writer object with given output scaling
         meshWriter
         (
             const polyMesh&,
-            const scalar scaleFactor = 1.0
+            const scalar scaling = 1.0
         );
 
 
@@ -141,28 +139,13 @@ public:
 
     // Member Functions
 
-        // Edit
-
-            //- Set points scaling
-            void scaleFactor(const scalar scaling)
-            {
-                scaleFactor_ = scaling;
-            }
+    // Write
 
-            //- Suppress writing boundary (bnd) file
-            void noBoundary()
-            {
-                writeBoundary_ = false;
-            }
-
-
-        // Write
-
-            //- Write volume mesh. Subclass must supply this method
-            virtual bool write
-            (
-                const fileName& timeName = fileName::null
-            ) const = 0;
+        //- Write volume mesh. Subclass must supply this method
+        virtual bool write
+        (
+            const fileName& timeName = fileName::null
+        ) const = 0;
 
 };
 
diff --git a/src/conversion/ensight/mesh/ensightMesh.C b/src/conversion/ensight/mesh/ensightMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..c10721d51e8799a33aa47b672eac769ad09a010a
--- /dev/null
+++ b/src/conversion/ensight/mesh/ensightMesh.C
@@ -0,0 +1,434 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "ensightMesh.H"
+#include "fvMesh.H"
+#include "globalMeshData.H"
+#include "PstreamCombineReduceOps.H"
+#include "processorPolyPatch.H"
+#include "mapDistribute.H"
+#include "stringListOps.H"
+
+#include "ensightFile.H"
+#include "ensightGeoFile.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::ensightMesh::clear()
+{
+    meshCells_.clear();
+    boundaryPatchFaces_.clear();
+    faceZoneFaces_.clear();
+    patchLookup_.clear();
+    globalPointsPtr_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightMesh::ensightMesh
+(
+    const fvMesh& mesh,
+    const ensightMesh::options& opts
+)
+:
+    options_(new options(opts)),
+    mesh_(mesh),
+    needsUpdate_(true)
+{
+    if (!option().lazy())
+    {
+        correct();
+    }
+}
+
+
+Foam::ensightMesh::ensightMesh
+(
+    const fvMesh& mesh,
+    const IOstream::streamFormat format
+)
+:
+    options_(new options(format)),
+    mesh_(mesh),
+    needsUpdate_(true)
+{
+    if (!option().lazy())
+    {
+        correct();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ensightMesh::~ensightMesh()
+{
+    deleteDemandDrivenData(options_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::ensightMesh::needsUpdate() const
+{
+    return needsUpdate_;
+}
+
+
+bool Foam::ensightMesh::expire()
+{
+    clear();
+
+    // already marked as expired
+    if (needsUpdate_)
+    {
+        return false;
+    }
+
+    needsUpdate_ = true;
+    return true;
+}
+
+
+void Foam::ensightMesh::correct()
+{
+    clear();
+
+    // First see if patches are allowed/disallowed
+    // and if only particular patches should be selected
+
+    label nParts = 1;  // provisionally (for internalMesh)
+
+    if (option().usePatches())
+    {
+        // Patches are output. Check that they are synced.
+        mesh_.boundaryMesh().checkParallelSync(true);
+
+        wordList patchNames = mesh_.boundaryMesh().names();
+        if (Pstream::parRun())
+        {
+            patchNames.setSize
+            (
+                mesh_.boundary().size()
+              - mesh_.globalData().processorPatches().size()
+            );
+        }
+
+        labelList matched;
+
+        bool useAll = true;
+        const wordReList& matcher = option().patchSelection();
+        if (notNull(matcher))
+        {
+            nParts = 0; // no internalMesh
+
+            if (!matcher.empty())
+            {
+                useAll = false;
+                matched = findMatchingStrings
+                (
+                    wordReListMatcher(matcher),
+                    patchNames
+                );
+            }
+        }
+
+        if (useAll)
+        {
+            matched = identity(patchNames.size());
+        }
+
+        forAll(matched, matchi)
+        {
+            const label patchId   = matched[matchi];
+            const word& patchName = patchNames[patchId];
+
+            // use fvPatch (not polyPatch) to automatically remove empty patches
+            const fvPatch& p = mesh_.boundary()[patchId];
+
+            // yes we most likely want this patch.
+            // - can use insert or set, since hash was cleared before
+            boundaryPatchFaces_.set(patchName, ensightFaces());
+            ensightFaces& ensFaces = boundaryPatchFaces_[patchName];
+
+            if (p.size())
+            {
+                // use local face addressing (offset = 0),
+                // since this is what we'll need later when writing fields
+                ensFaces.classify(p.patch());
+            }
+            else
+            {
+                // patch is empty (on this processor)
+                // or the patch is 'empty' (as fvPatch type)
+                ensFaces.clear();
+            }
+
+            // finalize
+            ensFaces.reduce();
+
+            if (ensFaces.total())
+            {
+                patchLookup_.set(patchId, patchName);
+                ensFaces.index() = nParts++;
+            }
+            else
+            {
+                boundaryPatchFaces_.erase(patchName);
+            }
+        }
+
+        // At this point,
+        // * patchLookup_        is a map of (patchId, name)
+        // * boundaryPatchFaces_ is a lookup by name for the faces elements
+    }
+
+    if (useInternalMesh())
+    {
+        meshCells_.index() = 0;
+        meshCells_.classify(mesh_);
+
+        // Determine parallel shared points
+        globalPointsPtr_ = mesh_.globalData().mergePoints
+        (
+            pointToGlobal_,
+            uniquePointMap_
+        );
+    }
+
+    meshCells_.reduce();
+
+    // faceZones
+    if (option().useFaceZones())
+    {
+        // Mark boundary faces to be excluded from export
+        PackedBoolList excludeFace(mesh_.nFaces()); // all false
+
+        forAll(mesh_.boundaryMesh(), patchi)
+        {
+            const polyPatch& pp = mesh_.boundaryMesh()[patchi];
+            if
+            (
+                isA<processorPolyPatch>(pp)
+             && !refCast<const processorPolyPatch>(pp).owner()
+            )
+            {
+                label bFaceI = pp.start();
+                forAll(pp, i)
+                {
+                    excludeFace.set(bFaceI++);
+                }
+            }
+        }
+
+        const wordReList& matcher = option().faceZoneSelection();
+
+        wordList selectZones = mesh_.faceZones().names();
+        inplaceSubsetMatchingStrings
+        (
+            wordReListMatcher(matcher),
+            selectZones
+        );
+
+        // have same order as later with sortedToc()
+        Foam::sort(selectZones);
+
+        // Count face types in each selected faceZone
+        forAll(selectZones, zoneI)
+        {
+            const word& zoneName = selectZones[zoneI];
+            const label zoneID = mesh_.faceZones().findZoneID(zoneName);
+            const faceZone& fz = mesh_.faceZones()[zoneID];
+
+            // yes we most likely want this zone
+            // - can use insert or set, since hash was cleared before
+            faceZoneFaces_.set(zoneName, ensightFaces());
+            ensightFaces& ensFaces = faceZoneFaces_[zoneName];
+
+            if (fz.size())
+            {
+                ensFaces.classify
+                (
+                    mesh_.faces(),
+                    fz,
+                    fz.flipMap(),
+                    excludeFace
+                );
+            }
+
+            // finalize
+            ensFaces.reduce();
+
+            if (ensFaces.total())
+            {
+                ensFaces.index() = nParts++;
+            }
+            else
+            {
+                faceZoneFaces_.erase(zoneName);
+            }
+        }
+    }
+
+    needsUpdate_ = false;
+}
+
+
+void Foam::ensightMesh::write(ensightGeoFile& os) const
+{
+    if (useInternalMesh())
+    {
+        label nPoints = globalPoints().size();
+
+        const pointField uniquePoints(mesh_.points(), uniquePointMap_);
+
+        // writePartHeader(os, 0, "internalMesh");
+        // beginCoordinates(os, nPoints);
+        writeAllPoints
+        (
+            meshCells_.index(),
+            "internalMesh",
+            nPoints,
+            uniquePoints,
+            os
+        );
+
+        writeCellConnectivity(meshCells_, pointToGlobal_, os);
+    }
+
+
+    //
+    // write patches
+    // use sortedToc for extra safety
+    //
+    const labelList patchIds = patchLookup_.sortedToc();
+    forAll(patchIds, listi)
+    {
+        const label patchId   = patchIds[listi];
+        const word& patchName = patchLookup_[patchId];
+        const ensightFaces& ensFaces = boundaryPatchFaces_[patchName];
+
+        const polyPatch& pp = mesh_.boundaryMesh()[patchId];
+
+        // Renumber the patch points/faces into unique points
+        labelList pointToGlobal;
+        labelList uniqueMeshPointLabels;
+        autoPtr<globalIndex> globalPointsPtr =
+            mesh_.globalData().mergePoints
+            (
+                pp.meshPoints(),
+                pp.meshPointMap(),
+                pointToGlobal,
+                uniqueMeshPointLabels
+            );
+
+        pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
+        // Renumber the patch faces
+        faceList patchFaces(pp.localFaces());
+        forAll(patchFaces, i)
+        {
+            inplaceRenumber(pointToGlobal, patchFaces[i]);
+        }
+
+        writeAllPoints
+        (
+            ensFaces.index(),
+            patchName,
+            globalPointsPtr().size(),
+            uniquePoints,
+            os
+        );
+
+        writeFaceConnectivity(ensFaces, patchFaces, os);
+    }
+
+
+    //
+    // write faceZones, if requested
+    //
+    const wordList zoneNames = faceZoneFaces_.sortedToc();
+    forAll(zoneNames, zonei)
+    {
+        const word& zoneName = zoneNames[zonei];
+        const ensightFaces& ensFaces = faceZoneFaces_[zoneName];
+
+        label zoneId = mesh_.faceZones().findZoneID(zoneName);
+        const faceZone& fz = mesh_.faceZones()[zoneId];
+
+        // Renumber the faceZone points/faces into unique points
+        labelList pointToGlobal;
+        labelList uniqueMeshPointLabels;
+        autoPtr<globalIndex> globalPointsPtr =
+            mesh_.globalData().mergePoints
+            (
+                fz().meshPoints(),
+                fz().meshPointMap(),
+                pointToGlobal,
+                uniqueMeshPointLabels
+            );
+
+        pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
+
+        primitiveFacePatch facePatch
+        (
+            faceList(mesh_.faces(), ensFaces.faceIds()),
+            mesh_.points()
+        );
+
+        const boolList& flip = ensFaces.flipMap();
+        forAll(facePatch[faceI], faceI)
+        {
+            if (flip[faceI])
+            {
+                facePatch[faceI].flip();
+            }
+        }
+
+        // Faces belonging to the faceZone, in local numbering
+        faceList localFaces(facePatch.localFaces());
+
+        // Renumber the faceZone master faces
+        forAll(localFaces, i)
+        {
+            inplaceRenumber(pointToGlobal, localFaces[i]);
+        }
+
+        writeAllPoints
+        (
+            ensFaces.index(),
+            zoneName,
+            globalPointsPtr().size(),
+            uniquePoints,
+            os
+        );
+
+        writeFaceConnectivity(ensFaces, localFaces, os, true);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/mesh/ensightMesh.H b/src/conversion/ensight/mesh/ensightMesh.H
new file mode 100644
index 0000000000000000000000000000000000000000..41ebb07aa7786c428d46fdc0645b0309d6de2767
--- /dev/null
+++ b/src/conversion/ensight/mesh/ensightMesh.H
@@ -0,0 +1,453 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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/>.
+
+Class
+    Foam::ensightMesh
+
+Description
+    Encapsulation of volume meshes for writing in ensight format.
+
+SourceFiles
+    ensightMesh.C
+    ensightMeshIO.C
+    ensightMeshOptions.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightMesh_H
+#define ensightMesh_H
+
+#include "ensightCells.H"
+#include "ensightFaces.H"
+#include "ensightGeoFile.H"
+#include "cellList.H"
+#include "faceList.H"
+#include "cellShapeList.H"
+#include "HashTable.H"
+#include "Map.H"
+#include "scalarField.H"
+#include "wordReList.H"
+#include "globalIndex.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class fvMesh;
+class ensightMesh;
+
+/*---------------------------------------------------------------------------*\
+                         Class ensightMesh Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightMesh
+{
+public:
+    // Forward declarations
+    class options;
+
+
+private:
+
+    // Private data
+
+        //- Writer options
+        const options* options_;
+
+        //- Reference to the OpenFOAM mesh
+        const fvMesh& mesh_;
+
+        //- The volume cells (internalMesh)
+        ensightCells meshCells_;
+
+        //- Face elements per patch
+        HashTable<ensightFaces> boundaryPatchFaces_;
+
+        //- Face elements per faceZone
+        HashTable<ensightFaces> faceZoneFaces_;
+
+        //- The list of patches to be output
+        Map<word> patchLookup_;
+
+        //- Track if it needs an update
+        mutable bool needsUpdate_;
+
+
+        // Parallel merged points
+
+            //- Global numbering for merged points
+            autoPtr<globalIndex> globalPointsPtr_;
+
+            //- From mesh point to global merged point
+            labelList pointToGlobal_;
+
+            //- Local points that are unique
+            labelList uniquePointMap_;
+
+
+    // Private Member Functions
+
+        //- Clear some storage
+        void clear();
+
+
+        //- Inplace renumber of cell-shapes
+        static cellShapeList& renumberShapes
+        (
+            cellShapeList&,
+            const labelUList& pointToGlobal
+        );
+
+        static cellShapeList map
+        (
+            const cellShapeList&,
+            const labelUList& prims,
+            const labelUList& pointToGlobal
+        );
+
+        //- Write list of faces
+        static void writeFaceList
+        (
+            const faceList&,
+            ensightGeoFile&
+        );
+
+        //- Write list of faces
+        static void writeFaceList
+        (
+            const UIndirectList<face>&,
+            ensightGeoFile&
+        );
+
+        //- Write sizes of faces in the list
+        static void writeFaceSizes
+        (
+            const faceList&,
+            ensightGeoFile&
+        );
+
+        //- Write sizes of faces in the list
+        static void writeFaceSizes
+        (
+            const UIndirectList<face>&,
+            ensightGeoFile&
+        );
+
+        //- Write cell connectivity via shell shapes
+        static void writeCellShapes
+        (
+            const cellShapeList&,
+            ensightGeoFile&
+        );
+
+        void writePolysNFaces
+        (
+            const labelList& polys,
+            const cellList& cellFaces,
+            ensightGeoFile&
+        ) const;
+
+        void writePolysNPointsPerFace
+        (
+            const labelList& polys,
+            const cellList& cellFaces,
+            const faceList& faces,
+            ensightGeoFile&
+        ) const;
+
+        void writePolysPoints
+        (
+            const labelList& polys,
+            const cellList& cellFaces,
+            const faceList& faces,
+            const labelList& faceOwner,
+            ensightGeoFile&
+        ) const;
+
+        void writePolysConnectivity
+        (
+            const labelList& addr,
+            const labelList& pointToGlobal,
+            ensightGeoFile&
+        ) const;
+
+        void writeCellConnectivity
+        (
+            const ensightCells&,
+            const labelList& pointToGlobal,
+            ensightGeoFile&
+        ) const;
+
+        void writeCellConnectivity
+        (
+            ensightCells::elemType elemType,
+            const ensightCells&,
+            const labelList& pointToGlobal,
+            ensightGeoFile&
+        ) const;
+
+        void writeFaceConnectivity
+        (
+            ensightFaces::elemType elemType,
+            const label nTotal,
+            const faceList& faceLst,
+            const labelList& addr,
+            ensightGeoFile&
+        ) const;
+
+
+        void writeFaceConnectivity
+        (
+            ensightFaces::elemType elemType,
+            const label nTotal,
+            const faceList& faceLst,
+            ensightGeoFile&
+        ) const;
+
+
+        void writeFaceConnectivity
+        (
+            const ensightFaces&,
+            const faceList& faceLst,
+            ensightGeoFile&,
+            const bool raw = false
+        ) const;
+
+
+        void writeAllPoints
+        (
+            const label partId,
+            const word& ensightPartName,
+            const label nTotal,
+            const pointField& uniquePoints,
+            ensightGeoFile&
+        ) const;
+
+
+        //- Disallow default bitwise copy construct
+        ensightMesh(const ensightMesh&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightMesh&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        ensightMesh
+        (
+            const fvMesh& mesh,
+            const options& opts
+        );
+
+        //- Construct from fvMesh with all default options
+        ensightMesh
+        (
+            const fvMesh& mesh,
+            const IOstream::streamFormat format = IOstream::BINARY
+        );
+
+
+    //- Destructor
+    ~ensightMesh();
+
+
+    // Member Functions
+
+    // Access
+
+        //- Reference to the underlying fvMesh
+        inline const fvMesh& mesh() const;
+
+        //- Reference to the writer/mesh options
+        inline const ensightMesh::options& option() const;
+
+        //- Ascii/Binary file output
+        inline IOstream::streamFormat format() const;
+
+        //- Using internalMesh?
+        inline bool useInternalMesh() const;
+
+        //- Using deprecated order? (hex prism pyr tet poly)
+        inline bool deprecatedOrder() const;
+
+        //- The volume cells (internalMesh)
+        inline const ensightCells& meshCells() const;
+
+        //- The list of patches to be output
+        inline const Map<word>& patches() const;
+
+        //- Face elements per selected patch
+        inline const HashTable<ensightFaces>& boundaryPatchFaces() const;
+
+        //- Face elements per selected faceZone.
+        //  To be output in sorted order.
+        inline const HashTable<ensightFaces>& faceZoneFaces() const;
+
+
+    // Parallel point merging
+
+        //- Global numbering for merged points
+        const globalIndex& globalPoints() const
+        {
+            return globalPointsPtr_();
+        }
+
+        //- From mesh point to global merged point
+        const labelList& pointToGlobal() const
+        {
+            return pointToGlobal_;
+        }
+
+        //- Local points that are unique
+        const labelList& uniquePointMap() const
+        {
+            return uniquePointMap_;
+        }
+
+
+    // Other
+
+        //- Does the content need an update?
+        bool needsUpdate() const;
+
+        //- Mark as needing an update.
+        //  May also free up unneeded data.
+        //  Return false if already marked as expired.
+        bool expire();
+
+
+        //- Update for new mesh
+        void correct();
+
+
+    // I-O
+
+        //- Write to file
+        inline void write(autoPtr<ensightGeoFile>& os) const;
+
+        //- Write to file
+        void write(ensightGeoFile& os) const;
+
+};
+
+
+//- Configuration options for the ensightMesh
+class ensightMesh::options
+{
+    //- Ascii/Binary file output
+    IOstream::streamFormat format_;
+
+    //- Create in 'expired' mode
+    bool lazy_;
+
+    //- Suppress patches
+    bool noPatches_;
+
+    //- Using deprecated order (hex prism pyr tet poly)
+    bool deprecatedOrder_;
+
+    //- Output selected patches only
+    autoPtr<wordReList> patchPatterns_;
+
+    //- Output selected faceZones
+    autoPtr<wordReList> faceZonePatterns_;
+
+public:
+
+    // Constructors
+
+        //- Construct with the specified format (default is binary)
+        options(IOstream::streamFormat format = IOstream::BINARY);
+
+
+    // Member Functions
+
+    // Access
+
+        //- Ascii/Binary file output
+        IOstream::streamFormat format() const;
+
+        //- Lazy creation? (ie, ensightMesh starts as needsUpdate)
+        bool lazy() const;
+
+        //- Using internalMesh?
+        bool useInternalMesh() const;
+
+        //- Using deprecated order? (hex prism pyr tet poly)
+        bool deprecatedOrder() const;
+
+        //- Using patches?
+        bool usePatches() const;
+
+        //- Using faceZones?
+        bool useFaceZones() const;
+
+        //- Selection of patches in effect?
+        bool usePatchSelection() const;
+
+        //- Selection of patches - null reference if not available
+        const wordReList& patchSelection() const;
+
+        //- Selection of faceZones - null reference if not available
+        const wordReList& faceZoneSelection() const;
+
+
+    // Edit
+
+        //- Reset to defaults
+        void reset();
+
+        //- Lazy creation - ensightMesh starts as needsUpdate.
+        void lazy(const bool);
+
+        //- Alter deprecated order.
+        void deprecatedOrder(const bool);
+
+        //- Alter the patches/no-patches state
+        void noPatches(const bool);
+
+        //- Define patch selection matcher
+        void patchSelection(const wordReList&);
+
+        //- Define faceZone selection matcher
+        void faceZoneSelection(const wordReList&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightMeshI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMPoints.H b/src/conversion/ensight/mesh/ensightMeshI.H
similarity index 53%
rename from applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMPoints.H
rename to src/conversion/ensight/mesh/ensightMeshI.H
index 9f51c757e4df032b80972cc24c3f2a6bd1959bbb..1f0bc4a14662b0eb75eb381e7d231e6ee763e1dd 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMPoints.H
+++ b/src/conversion/ensight/mesh/ensightMeshI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,59 +21,70 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-InClass
-    vtkPV3Foam
-
 \*---------------------------------------------------------------------------*/
 
-#ifndef vtkOpenFOAMPoints_H
-#define vtkOpenFOAMPoints_H
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// VTK includes
-#include "vtkPoints.h"
+inline const Foam::fvMesh& Foam::ensightMesh::mesh() const
+{
+    return mesh_;
+}
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-inline void vtkInsertNextOpenFOAMPoint
-(
-    vtkPoints *points,
-    const Foam::point& p
-)
+inline const Foam::ensightMesh::options& Foam::ensightMesh::option() const
 {
-    points->InsertNextPoint(p.x(), p.y(), p.z());
+    return *options_;
 }
 
-#if 0
-// this should be faster, but didn't get it working ...
-inline void vtkSetOpenFOAMPoint
-(
-    vtkPoints *points,
-    const Foam::label id,
-    const Foam::point& p
-)
+
+inline Foam::IOstream::streamFormat Foam::ensightMesh::format() const
 {
-    points->SetPoint(id, p.x(), p.y(), p.z());
+    return options_->format();
 }
 
 
-// Convert OpenFOAM mesh vertices to VTK
-inline vtkPoints* vtkSetOpenFOAMPoints(const Foam::pointField& points)
+inline bool Foam::ensightMesh::useInternalMesh() const
 {
-    vtkPoints *vtkpoints = vtkPoints::New();
-    vtkpoints->SetNumberOfPoints(points.size());
-    forAll(points, i)
-    {
-        const Foam::point& p = points[i];
-        vtkpoints->SetPoint(i, p.x(), p.y(), p.z());
-    }
-
-    return vtkpoints;
+    return options_->useInternalMesh();
 }
 
-#endif
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+inline bool Foam::ensightMesh::deprecatedOrder() const
+{
+    return options_->deprecatedOrder();
+}
+
+
+inline const Foam::ensightCells& Foam::ensightMesh::meshCells() const
+{
+    return meshCells_;
+}
+
+
+inline const Foam::Map<Foam::word>& Foam::ensightMesh::patches() const
+{
+    return patchLookup_;
+}
+
+
+inline const Foam::HashTable<Foam::ensightFaces>&
+Foam::ensightMesh::boundaryPatchFaces() const
+{
+    return boundaryPatchFaces_;
+}
+
+
+inline const Foam::HashTable<Foam::ensightFaces>&
+Foam::ensightMesh::faceZoneFaces() const
+{
+    return faceZoneFaces_;
+}
+
+
+inline void Foam::ensightMesh::write(autoPtr<ensightGeoFile>& os) const
+{
+    write(os.rawRef());
+}
 
-#endif
 
 // ************************************************************************* //
diff --git a/src/conversion/ensight/mesh/ensightMeshIO.C b/src/conversion/ensight/mesh/ensightMeshIO.C
new file mode 100644
index 0000000000000000000000000000000000000000..406697d94296f5ea076f3edd14115c08d2891742
--- /dev/null
+++ b/src/conversion/ensight/mesh/ensightMeshIO.C
@@ -0,0 +1,698 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "ensightMesh.H"
+#include "fvMesh.H"
+#include "globalMeshData.H"
+#include "PstreamCombineReduceOps.H"
+#include "processorPolyPatch.H"
+#include "mapDistribute.H"
+#include "stringListOps.H"
+
+#include "ensightFile.H"
+#include "ensightGeoFile.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::cellShapeList& Foam::ensightMesh::renumberShapes
+(
+    cellShapeList& shapes,
+    const labelUList& pointToGlobal
+)
+{
+    forAll(shapes, i)
+    {
+        inplaceRenumber(pointToGlobal, shapes[i]);
+    }
+
+    return shapes;
+}
+
+
+Foam::cellShapeList Foam::ensightMesh::map
+(
+    const cellShapeList& shapes,
+    const labelUList& addr,
+    const labelUList& pointToGlobal
+)
+{
+    cellShapeList lst(addr.size());
+
+    forAll(addr, i)
+    {
+        lst[i] = shapes[addr[i]];
+        inplaceRenumber(pointToGlobal, lst[i]);
+    }
+
+    return lst;
+}
+
+
+void Foam::ensightMesh::writeFaceList
+(
+    const faceList& faceLst,
+    ensightGeoFile& os
+)
+{
+    forAll(faceLst, i)
+    {
+        const face& f = faceLst[i];
+
+        forAll(f, fp)
+        {
+            os.write(f[fp] + 1);
+        }
+
+        os.newline();
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceList
+(
+    const UIndirectList<face>& faceLst,
+    ensightGeoFile& os
+)
+{
+    forAll(faceLst, i)
+    {
+        const face& f = faceLst[i];
+
+        forAll(f, fp)
+        {
+            os.write(f[fp] + 1);
+        }
+
+        os.newline();
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceSizes
+(
+    const faceList& faceLst,
+    ensightGeoFile& os
+)
+{
+    forAll(faceLst, i)
+    {
+        const face& f = faceLst[i];
+
+        os.write(f.size());
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceSizes
+(
+    const UIndirectList<face>& faceLst,
+    ensightGeoFile& os
+)
+{
+    forAll(faceLst, i)
+    {
+        const face& f = faceLst[i];
+
+        os.write(f.size());
+    }
+}
+
+
+void Foam::ensightMesh::writeCellShapes
+(
+    const cellShapeList& shapes,
+    ensightGeoFile& os
+)
+{
+    forAll(shapes, i)
+    {
+        const cellShape& cellPoints = shapes[i];
+
+        // convert global -> local index
+        // (note: Ensight indices start with 1)
+
+        // In ASCII, write one cell per line
+        forAll(cellPoints, pointI)
+        {
+            os.write(cellPoints[pointI] + 1);
+        }
+
+        os.newline();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ensightMesh::writePolysNFaces
+(
+    const labelList& addr,
+    const cellList&  cellFaces,
+    ensightGeoFile& os
+) const
+{
+    forAll(addr, i)
+    {
+        const labelList& cf = cellFaces[addr[i]];
+        os.write(cf.size());
+    }
+}
+
+
+void Foam::ensightMesh::writePolysNPointsPerFace
+(
+    const labelList& addr,
+    const cellList& cellFaces,
+    const faceList& faces,
+    ensightGeoFile& os
+) const
+{
+    forAll(addr, i)
+    {
+        const labelList& cf = cellFaces[addr[i]];
+
+        forAll(cf, faceI)
+        {
+            os.write(faces[cf[faceI]].size());
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writePolysPoints
+(
+    const labelList& addr,
+    const cellList& cellFaces,
+    const faceList& faces,
+    const labelList& faceOwner,
+    ensightGeoFile& os
+) const
+{
+    forAll(addr, i)
+    {
+        const label cellId = addr[i];
+        const labelList& cf = cellFaces[cellId];
+
+        forAll(cf, faceI)
+        {
+            const label faceId = cf[faceI];
+            const face& f = faces[faceId];  // face points (in global points)
+
+            if (faceId < faceOwner.size() && faceOwner[faceId] != cellId)
+            {
+                // internal face, neighbour
+                //
+                // as per face::reverseFace(), but without copying
+
+                os.write(f[0] + 1);
+                for (label ptI = f.size()-1; ptI > 0; --ptI)
+                {
+                    os.write(f[ptI] + 1);
+                }
+            }
+            else
+            {
+                forAll(f, ptI)
+                {
+                    os.write(f[ptI] + 1);
+                }
+            }
+
+            os.newline();
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writePolysConnectivity
+(
+    const labelList& addr,
+    const labelList& pointToGlobal,
+    ensightGeoFile& os
+) const
+{
+    const cellList&  cellFaces = mesh_.cells();
+    const faceList&  meshFaces = mesh_.faces();
+    const labelList& faceOwner = mesh_.faceOwner();
+
+    if (Pstream::master())
+    {
+        // Number of faces for each poly cell
+
+        // Master
+        writePolysNFaces(addr, cellFaces, os);
+
+        // Slaves
+        for (int slave=1; slave<Pstream::nProcs(); ++slave)
+        {
+            IPstream fromSlave(Pstream::scheduled, slave);
+            labelList addr(fromSlave);
+            cellList  cellFaces(fromSlave);
+
+            writePolysNFaces(addr, cellFaces, os);
+        }
+    }
+    else
+    {
+        OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+        toMaster
+            << addr
+            << cellFaces;
+    }
+
+    // Number of points for each face of the above list
+    if (Pstream::master())
+    {
+        // Master
+        writePolysNPointsPerFace
+        (
+            addr,
+            cellFaces,
+            meshFaces,
+            os
+        );
+        // Slaves
+        for (int slave=1; slave<Pstream::nProcs(); ++slave)
+        {
+            IPstream fromSlave(Pstream::scheduled, slave);
+            labelList addr(fromSlave);
+            cellList  cellFaces(fromSlave);
+            faceList  meshFaces(fromSlave);
+
+            writePolysNPointsPerFace
+            (
+                addr,
+                cellFaces,
+                meshFaces,
+                os
+            );
+        }
+    }
+    else
+    {
+        OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+        toMaster
+            << addr
+            << cellFaces
+            << meshFaces;
+    }
+
+
+    // Renumber faces to use global point numbers
+    faceList faces(mesh_.faces());
+    forAll(faces, i)
+    {
+        inplaceRenumber(pointToGlobal, faces[i]);
+    }
+
+    // List of points id for each face of the above list
+    if (Pstream::master())
+    {
+        // Master
+        writePolysPoints
+        (
+            addr,
+            cellFaces,
+            faces,
+            faceOwner,
+            os
+        );
+        // Slaves
+        for (int slave=1; slave<Pstream::nProcs(); ++slave)
+        {
+            IPstream fromSlave(Pstream::scheduled, slave);
+            labelList addr(fromSlave);
+            cellList  cellFaces(fromSlave);
+            faceList  faces(fromSlave);
+            labelList faceOwner(fromSlave);
+
+            writePolysPoints
+            (
+                addr,
+                cellFaces,
+                faces,
+                faceOwner,
+                os
+            );
+        }
+    }
+    else
+    {
+        OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+        toMaster
+            << addr
+            << cellFaces
+            << faces
+            << faceOwner;
+    }
+}
+
+
+void Foam::ensightMesh::writeCellConnectivity
+(
+    const ensightCells::elemType elemType,
+    const ensightCells& ensCells,
+    const labelList& pointToGlobal,
+    ensightGeoFile& os
+) const
+{
+    const label nTotal = ensCells.total(elemType);
+
+    if (nTotal)
+    {
+        const labelUList& addr = ensCells.cellIds(elemType);
+
+        if (Pstream::master())
+        {
+            os.writeKeyword(ensightCells::key(elemType));
+            os.write(nTotal);
+            os.newline();
+        }
+
+        if (elemType == ensightCells::NFACED)
+        {
+            writePolysConnectivity
+            (
+                addr,
+                pointToGlobal,
+                os
+            );
+        }
+        else
+        {
+            const cellShapeList shapes = map
+            (
+                mesh_.cellShapes(),
+                addr,
+                pointToGlobal
+            );
+
+
+            if (Pstream::master())
+            {
+                writeCellShapes(shapes, os);
+
+                for (int slave=1; slave<Pstream::nProcs(); ++slave)
+                {
+                    IPstream fromSlave(Pstream::scheduled, slave);
+                    cellShapeList received(fromSlave);
+
+                    writeCellShapes(received, os);
+                }
+            }
+            else
+            {
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+                toMaster
+                    << shapes;
+            }
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writeCellConnectivity
+(
+    const ensightCells& ensCells,
+    const labelList& pointToGlobal,
+    ensightGeoFile& os
+) const
+{
+    if (deprecatedOrder())
+    {
+        // element ordering used in older versions
+        ensightCells::elemType oldOrder[5] =
+        {
+            ensightCells::HEXA8,
+            ensightCells::PENTA6,
+            ensightCells::PYRAMID5,
+            ensightCells::TETRA4,
+            ensightCells::NFACED
+        };
+
+        for (int i=0; i < 5; ++i)
+        {
+            const ensightCells::elemType& what = oldOrder[i];
+
+            writeCellConnectivity(what, ensCells, pointToGlobal, os);
+        }
+    }
+    else
+    {
+        const List<ensightCells::elemType> enums =
+            ensightCells::elemEnum.enums();
+
+        forAllConstIter(List<ensightCells::elemType>, enums, iter)
+        {
+            const ensightCells::elemType what = *iter;
+
+            writeCellConnectivity(what, ensCells, pointToGlobal, os);
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceConnectivity
+(
+    ensightFaces::elemType elemType,
+    const label nTotal,
+    const faceList& faces,
+    ensightGeoFile& os
+) const
+{
+    if (nTotal)
+    {
+        if (Pstream::master())
+        {
+            os.writeKeyword(ensightFaces::key(elemType));
+            os.write(nTotal);
+            os.newline();
+        }
+
+        if (elemType == ensightFaces::NSIDED)
+        {
+            // Number of points per face
+
+            if (Pstream::master())
+            {
+                writeFaceSizes(faces, os);
+
+                for (int slave=1; slave<Pstream::nProcs(); ++slave)
+                {
+                    IPstream fromSlave(Pstream::scheduled, slave);
+                    faceList received(fromSlave);
+
+                    writeFaceSizes(received, os);
+                }
+            }
+            else
+            {
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+                toMaster
+                    << faces;
+            }
+        }
+
+
+        // List of points id for each face
+        if (Pstream::master())
+        {
+            writeFaceList(faces, os);
+
+            for (int slave=1; slave<Pstream::nProcs(); ++slave)
+            {
+                IPstream fromSlave(Pstream::scheduled, slave);
+                faceList received(fromSlave);
+
+                writeFaceList(received, os);
+            }
+        }
+        else
+        {
+            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+            toMaster
+                << faces;
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceConnectivity
+(
+    ensightFaces::elemType elemType,
+    const label nTotal,
+    const faceList& faceLst,
+    const labelList& addr,
+    ensightGeoFile& os
+) const
+{
+    if (nTotal)
+    {
+        if (Pstream::master())
+        {
+            os.writeKeyword(ensightFaces::key(elemType));
+            os.write(nTotal);
+            os.newline();
+        }
+
+        const UIndirectList<face> faces(faceLst, addr);
+
+        if (elemType == ensightFaces::NSIDED)
+        {
+            // Number of points per face
+
+            if (Pstream::master())
+            {
+                writeFaceSizes(faces, os);
+
+                for (int slave=1; slave<Pstream::nProcs(); ++slave)
+                {
+                    IPstream fromSlave(Pstream::scheduled, slave);
+                    faceList received(fromSlave);
+
+                    writeFaceSizes(received, os);
+                }
+            }
+            else
+            {
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+                toMaster
+                    << faces;
+            }
+        }
+
+        // List of points id per face
+        if (Pstream::master())
+        {
+            writeFaceList(faces, os);
+
+            for (int slave=1; slave<Pstream::nProcs(); ++slave)
+            {
+                IPstream fromSlave(Pstream::scheduled, slave);
+                faceList received(fromSlave);
+
+                writeFaceList(received, os);
+            }
+        }
+        else
+        {
+            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+            toMaster
+                << faces;
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writeFaceConnectivity
+(
+    const ensightFaces& ensFaces,
+    const faceList& faceLst,
+    ensightGeoFile& os,
+    const bool raw
+) const
+{
+    const List<ensightFaces::elemType> enums = ensightFaces::elemEnum.enums();
+
+    if (raw)
+    {
+        forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+        {
+            const ensightFaces::elemType what = *iter;
+
+            writeFaceConnectivity
+            (
+                what,
+                ensFaces.total(what),
+                SubList<face>
+                (
+                    faceLst,
+                    ensFaces.faceIds(what).size(),
+                    ensFaces.offset(what)
+                ),
+                os
+            );
+        }
+    }
+    else
+    {
+        forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+        {
+            const ensightFaces::elemType what = *iter;
+
+            writeFaceConnectivity
+            (
+                what,
+                ensFaces.total(what),
+                faceLst,
+                ensFaces.faceIds(what),
+                os
+            );
+        }
+    }
+}
+
+
+void Foam::ensightMesh::writeAllPoints
+(
+    const label partId,
+    const word& ensightPartName,
+    const label nPoints,
+    const pointField& uniquePoints,
+    ensightGeoFile& os
+) const
+{
+    if (Pstream::master())
+    {
+        os.beginPart(partId, ensightPartName);
+
+        // write points
+        os.beginCoordinates(nPoints);
+
+        for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
+        {
+            os.writeList(uniquePoints.component(cmpt));
+
+            for (int slave=1; slave<Pstream::nProcs(); ++slave)
+            {
+                IPstream fromSlave(Pstream::scheduled, slave);
+                scalarField received(fromSlave);
+                os.writeList(received);
+            }
+        }
+    }
+    else
+    {
+        for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
+        {
+            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+            toMaster
+                << uniquePoints.component(cmpt);
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/mesh/ensightMeshOptions.C b/src/conversion/ensight/mesh/ensightMeshOptions.C
new file mode 100644
index 0000000000000000000000000000000000000000..ea89d43993999898820409389742f57eace694c6
--- /dev/null
+++ b/src/conversion/ensight/mesh/ensightMeshOptions.C
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightMesh.H"
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightMesh::options::options(IOstream::streamFormat format)
+:
+    format_(format),
+    lazy_(false),
+    noPatches_(false),
+    deprecatedOrder_(false),
+    patchPatterns_(),
+    faceZonePatterns_()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::IOstream::streamFormat Foam::ensightMesh::options::format() const
+{
+    return format_;
+}
+
+
+bool Foam::ensightMesh::options::lazy() const
+{
+    return lazy_;
+}
+
+
+bool Foam::ensightMesh::options::useInternalMesh() const
+{
+    return noPatches_ ? true : !patchPatterns_.valid();
+}
+
+
+bool Foam::ensightMesh::options::deprecatedOrder() const
+{
+    return deprecatedOrder_;
+}
+
+
+bool Foam::ensightMesh::options::usePatches() const
+{
+    return !noPatches_;
+}
+
+
+bool Foam::ensightMesh::options::useFaceZones() const
+{
+    return faceZonePatterns_.valid();
+}
+
+
+bool Foam::ensightMesh::options::usePatchSelection() const
+{
+    return noPatches_ ? false : patchPatterns_.valid();
+}
+
+
+void Foam::ensightMesh::options::reset()
+{
+    noPatches_ = false;
+    patchPatterns_.clear();
+    faceZonePatterns_.clear();
+}
+
+
+void Foam::ensightMesh::options::lazy(const bool b)
+{
+    lazy_ = b;
+}
+
+
+void Foam::ensightMesh::options::deprecatedOrder(const bool b)
+{
+    deprecatedOrder_ = b;
+}
+
+
+void Foam::ensightMesh::options::noPatches(const bool b)
+{
+    noPatches_ = b;
+
+    if (noPatches_ && patchPatterns_.valid())
+    {
+        WarningInFunction
+            << " existing patch selection disabled"
+            << endl;
+
+        patchPatterns_.clear();
+    }
+}
+
+
+void Foam::ensightMesh::options::patchSelection
+(
+    const wordReList& patterns
+)
+{
+    if (noPatches_)
+    {
+        WarningInFunction
+            << " patch selection specified, but noPatches was already active"
+            << endl;
+    }
+    else
+    {
+        patchPatterns_.reset(new wordReList(patterns));
+    }
+}
+
+
+void Foam::ensightMesh::options::faceZoneSelection
+(
+    const wordReList& patterns
+)
+{
+    faceZonePatterns_.reset(new wordReList(patterns));
+}
+
+
+const Foam::wordReList& Foam::ensightMesh::options::patchSelection() const
+{
+    if (usePatchSelection())
+    {
+        return patchPatterns_();
+    }
+    else
+    {
+        return wordReList::null();
+    }
+}
+
+
+const Foam::wordReList& Foam::ensightMesh::options::faceZoneSelection() const
+{
+    if (faceZonePatterns_.valid())
+    {
+        return faceZonePatterns_();
+    }
+    else
+    {
+        return wordReList::null();
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightOutput.H b/src/conversion/ensight/output/ensightOutput.H
new file mode 100644
index 0000000000000000000000000000000000000000..5fec26bbf8c35c1c804070522fe3dc14b296bb45
--- /dev/null
+++ b/src/conversion/ensight/output/ensightOutput.H
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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/>.
+
+Class
+    Foam::ensightOutput
+
+Description
+    A collection of functions for writing ensight file content in parallel.
+
+SourceFiles
+    ensightOutput.C
+    ensightOutputTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightOutput_H
+#define ensightOutput_H
+
+#include "ensightFile.H"
+#include "ensightMesh.H"
+#include "autoPtr.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class ensightOutput Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightOutput
+{
+    // Private Methods
+
+    template<class Type>
+    static void writeField
+    (
+        const char* key,
+        const Field<Type>& fld,
+        ensightFile& os
+    );
+
+    template<class Type>
+    static bool writePatchField
+    (
+        const Field<Type>& pf,
+        const ensightFaces& ensFaces,
+        ensightFile& os
+    );
+
+    template<class Type>
+    static bool writeVolField
+    (
+        const Field<Type>& vf,
+        const ensightCells& ensCells,
+        ensightFile& os,
+        const bool deprecatedOrder = false
+    );
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>& vf,
+        const ensightMesh& ensMesh,
+        ensightFile& os
+    );
+
+    //- Write point field component-wise
+    template<class Type>
+    static bool ensightPointField
+    (
+        const GeometricField<Type, pointPatchField, pointMesh>& pf,
+        const ensightMesh& ensMesh,
+        ensightFile& os
+    );
+
+
+    //- Disallow null constructor
+    ensightOutput() = delete;
+
+public:
+
+    // Public Methods
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>&,
+        const ensightMesh& ensMesh,
+        ensightFile& os,
+        const bool nodeValues
+    );
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static inline bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>& vf,
+        const ensightMesh& ensMesh,
+        autoPtr<ensightFile>& output,
+        const bool nodeValues = false
+    )
+    {
+        return writeField(vf, ensMesh, output.rawRef(), nodeValues);
+    }
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ensightOutputTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightOutputTemplates.C b/src/conversion/ensight/output/ensightOutputTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..a68058faf76a904ca823a167a091752c49f9e05d
--- /dev/null
+++ b/src/conversion/ensight/output/ensightOutputTemplates.C
@@ -0,0 +1,461 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "ensightFile.H"
+#include "ensightOutput.H"
+#include "ensightPTraits.H"
+
+#include "fvMesh.H"
+#include "volFields.H"
+#include "IOField.H"
+#include "OFstream.H"
+#include "IOmanip.H"
+#include "Time.H"
+#include "volPointInterpolation.H"
+#include "globalIndex.H"
+#include "uindirectPrimitivePatch.H"
+#include "interpolation.H"
+#include "linear.H"
+
+// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
+
+template<class Type>
+void Foam::ensightOutput::writeField
+(
+    const char* key,
+    const Field<Type>& fld,
+    ensightFile& os
+)
+{
+    if (returnReduce(fld.size(), sumOp<label>()) > 0)
+    {
+        if (Pstream::master())
+        {
+            os.writeKeyword(key);
+
+            for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+            {
+                const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+                os.writeList(fld.component(cmpt));
+
+                for (int slave=1; slave<Pstream::nProcs(); ++slave)
+                {
+                    IPstream fromSlave(Pstream::scheduled, slave);
+                    scalarField received(fromSlave);
+                    os.writeList(received);
+                }
+            }
+        }
+        else
+        {
+            for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+            {
+                const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
+                toMaster
+                    << fld.component(cmpt);
+            }
+        }
+    }
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::writePatchField
+(
+    const Field<Type>& pf,
+    const ensightFaces& ensFaces,
+    Foam::ensightFile& os
+)
+{
+    if (ensFaces.total())
+    {
+        if (Pstream::master())
+        {
+            os.beginPart(ensFaces.index());
+        }
+
+        const List<ensightFaces::elemType> enums =
+            ensightFaces::elemEnum.enums();
+
+        forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+        {
+            const ensightFaces::elemType& what = *iter;
+
+            writeField
+            (
+                ensightFaces::key(what),
+                Field<Type>(pf, ensFaces.faceIds(what)),
+                os
+            );
+        }
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::writeVolField
+(
+    const Field<Type>& vf,
+    const ensightCells& ensCells,
+    ensightFile& os,
+    const bool deprecatedOrder
+)
+{
+    if (ensCells.total())
+    {
+        if (Pstream::master())
+        {
+            os.beginPart(ensCells.index());
+        }
+
+        if (deprecatedOrder)
+        {
+            // element ordering used in older versions
+            ensightCells::elemType oldOrder[5] =
+            {
+                ensightCells::HEXA8,
+                ensightCells::PENTA6,
+                ensightCells::PYRAMID5,
+                ensightCells::TETRA4,
+                ensightCells::NFACED
+            };
+
+            for (int i=0; i < 5; ++i)
+            {
+                const ensightCells::elemType& what = oldOrder[i];
+
+                writeField
+                (
+                    ensightCells::key(what),
+                    Field<Type>(vf, ensCells.cellIds(what)),
+                    os
+                );
+            }
+        }
+        else
+        {
+            const List<ensightCells::elemType> enums =
+                ensightCells::elemEnum.enums();
+
+            forAllConstIter(List<ensightCells::elemType>, enums, iter)
+            {
+                const ensightCells::elemType& what = *iter;
+
+                writeField
+                (
+                    ensightCells::key(what),
+                    Field<Type>(vf, ensCells.cellIds(what)),
+                    os
+                );
+            }
+        }
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::writeField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightMesh& ensMesh,
+    ensightFile& os
+)
+{
+    const fvMesh& mesh = ensMesh.mesh();
+    const ensightCells& meshCells = ensMesh.meshCells();
+    const Map<word>&  patchLookup = ensMesh.patches();
+    const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
+    const HashTable<ensightFaces>&  zoneFaces = ensMesh.faceZoneFaces();
+
+    //
+    // write internalMesh, unless patch-selection was requested
+    //
+    if (ensMesh.useInternalMesh())
+    {
+        writeVolField(vf, meshCells, os, ensMesh.deprecatedOrder());
+    }
+
+    //
+    // write patches
+    // use sortedToc for extra safety
+    //
+    const labelList patchIds = patchLookup.sortedToc();
+    forAll(patchIds, listi)
+    {
+        const label patchId   = patchIds[listi];
+        const word& patchName = patchLookup[listi];
+        const ensightFaces& ensFaces = patchFaces[patchName];
+
+        writePatchField
+        (
+            vf.boundaryField()[patchId],
+            ensFaces,
+            os
+        );
+    }
+
+
+    //
+    // write faceZones, if requested
+    // use sortedToc for extra safety
+    //
+    const wordList zoneNames = zoneFaces.sortedToc();
+    if (!zoneNames.empty())
+    {
+        // Interpolates cell values to faces - needed only when exporting
+        // faceZones...
+        GeometricField<Type, fvsPatchField, surfaceMesh> sf
+        (
+            Foam::linearInterpolate(vf)
+        );
+
+        // flat boundary field
+        // as per volPointInterpolation::flatBoundaryField()
+
+        Field<Type> flat(mesh.nFaces() - mesh.nInternalFaces());
+
+        const fvBoundaryMesh& bm = mesh.boundary();
+        forAll(vf.boundaryField(), patchI)
+        {
+            const polyPatch& pp = bm[patchI].patch();
+            const label bFaceI = pp.start() - mesh.nInternalFaces();
+
+            if
+            (
+                isA<emptyFvPatch>(bm[patchI])
+             || vf.boundaryField()[patchI].coupled()
+            )
+            {
+                SubList<Type>
+                (
+                    flat,
+                    pp.size(),
+                    bFaceI
+                ) = Zero;
+            }
+            else
+            {
+                SubList<Type>
+                (
+                    flat,
+                    vf.boundaryField()[patchI].size(),
+                    bFaceI
+                ) = vf.boundaryField()[patchI];
+            }
+        }
+
+        forAll(zoneNames, zonei)
+        {
+            const word& zoneName = zoneNames[zonei];
+            const ensightFaces& ensFaces = zoneFaces[zoneName];
+
+            // field (local size)
+            Field<Type> values(ensFaces.size());
+
+            // Loop over face ids to store the needed field values
+            // - internal faces use linear interpolation
+            // - boundary faces use the corresponding patch value
+            forAll(ensFaces, i)
+            {
+                label faceId = ensFaces[i];
+                values[i] =
+                (
+                    mesh.isInternalFace(faceId)
+                  ? sf[faceId]
+                  : flat[faceId - mesh.nInternalFaces()]
+                );
+            }
+
+            writePatchField(values, ensFaces, os);
+        }
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::ensightPointField
+(
+    const GeometricField<Type, pointPatchField, pointMesh>& pf,
+    const ensightMesh& ensMesh,
+    ensightFile& os
+)
+{
+    const fvMesh& mesh = ensMesh.mesh();
+    const Map<word>& patchLookup  = ensMesh.patches();
+
+    const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
+    const HashTable<ensightFaces>&  zoneFaces = ensMesh.faceZoneFaces();
+
+    //
+    // write internalMesh, unless patch-selection was requested
+    //
+    if (ensMesh.useInternalMesh())
+    {
+        if (Pstream::master())
+        {
+            os.beginPart(0); // 0 = internalMesh
+        }
+
+        writeField
+        (
+            "coordinates",
+            Field<Type>(pf.internalField(), ensMesh.uniquePointMap()),
+            os
+        );
+    }
+
+    //
+    // write patches
+    // use sortedToc for extra safety
+    //
+    const labelList patchIds = patchLookup.sortedToc();
+    forAll(patchIds, listi)
+    {
+        const label patchId   = patchIds[listi];
+        const word& patchName = patchLookup[patchId];
+        const ensightFaces& ensFaces = patchFaces[patchName];
+
+        const fvPatch& p = mesh.boundary()[patchId];
+
+        // Renumber the patch points/faces into unique points
+        labelList pointToGlobal;
+        labelList uniqueMeshPointLabels;
+        autoPtr<globalIndex> globalPointsPtr =
+            mesh.globalData().mergePoints
+            (
+                p.patch().meshPoints(),
+                p.patch().meshPointMap(),
+                pointToGlobal,
+                uniqueMeshPointLabels
+            );
+
+        if (Pstream::master())
+        {
+            os.beginPart(ensFaces.index());
+        }
+
+        writeField
+        (
+            "coordinates",
+            Field<Type>(pf.internalField(), uniqueMeshPointLabels),
+            os
+        );
+    }
+
+    //
+    // write faceZones, if requested
+    //
+    const wordList zoneNames = zoneFaces.sortedToc();
+    forAll(zoneNames, zonei)
+    {
+        const word& zoneName = zoneNames[zonei];
+        const ensightFaces& ensFaces = zoneFaces[zoneName];
+
+        uindirectPrimitivePatch p
+        (
+            UIndirectList<face>
+            (
+                mesh.faces(),
+                ensFaces.faceIds()
+            ),
+            mesh.points()
+        );
+
+        // Renumber the patch points/faces into unique points
+        labelList pointToGlobal;
+        labelList uniqueMeshPointLabels;
+        autoPtr<globalIndex> globalPointsPtr =
+            mesh.globalData().mergePoints
+            (
+                p.meshPoints(),
+                p.meshPointMap(),
+                pointToGlobal,
+                uniqueMeshPointLabels
+            );
+
+        if (Pstream::master())
+        {
+            os.beginPart(ensFaces.index());
+        }
+
+        writeField
+        (
+            "coordinates",
+            Field<Type>(pf.internalField(), uniqueMeshPointLabels),
+            os
+        );
+    }
+
+    return true;
+}
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::ensightOutput::writeField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightMesh& ensMesh,
+    ensightFile& os,
+    const bool nodeValues
+)
+{
+    if (nodeValues)
+    {
+        tmp<GeometricField<Type, pointPatchField, pointMesh>> pfld
+        (
+            volPointInterpolation::New(vf.mesh()).interpolate(vf)
+        );
+        pfld.ref().checkOut();
+        pfld.ref().rename(vf.name());
+
+        return ensightPointField<Type>(pfld, ensMesh, os);
+    }
+    else
+    {
+        return writeField<Type>(vf, ensMesh, os);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightSerialOutput.H b/src/conversion/ensight/output/ensightSerialOutput.H
new file mode 100644
index 0000000000000000000000000000000000000000..8fcbc3025fe6fd0370e03a9762121ad7744e39e8
--- /dev/null
+++ b/src/conversion/ensight/output/ensightSerialOutput.H
@@ -0,0 +1,146 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ensightSerialOutput
+
+Description
+    A collection of functions for writing ensight file content in serial.
+    Can be considered transitional and may eventually merge with ensightOutput.
+
+SourceFiles
+    ensightSerialOutputTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightSerialOutput_H
+#define ensightSerialOutput_H
+
+#include "ensightPart.H"
+#include "ensightPartFaces.H"
+#include "ensightPartCells.H"
+#include "ensightParts.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                     Class ensightSerialOutput Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightSerialOutput
+{
+    // Private Methods
+
+    //- Write field component-wise
+    template<class Type>
+    static void writeField
+    (
+        const word& key,
+        const Field<Type>& field,
+        ensightFile& os
+    );
+
+
+    //- Disallow null constructor
+    ensightSerialOutput() = delete;
+
+public:
+
+    // Public Methods
+
+    //- Write field component-wise
+    template<class Type>
+    static bool writeField
+    (
+        const Field<Type>&,
+        const ensightPartFaces& part,
+        ensightFile& os,
+        const bool nodeValues
+    );
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>&,
+        const ensightPartCells& part,
+        ensightFile& os
+    );
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>&,
+        const ensightParts& list,
+        ensightFile& os
+    );
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static inline bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>& vf,
+        const ensightPartCells& part,
+        autoPtr<ensightFile>& output
+    )
+    {
+        return writeField(vf, part, output.rawRef());
+    }
+
+
+    //- Write volume field component-wise
+    template<class Type>
+    static inline bool writeField
+    (
+        const GeometricField<Type, fvPatchField, volMesh>& vf,
+        const ensightParts& list,
+        autoPtr<ensightFile>& output
+    )
+    {
+        return writeField(vf, list, output.rawRef());
+    }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ensightSerialOutputTemplates.C"
+#endif
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightSerialOutputTemplates.C b/src/conversion/ensight/output/ensightSerialOutputTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..31f4ad9370d9669bbd9a2ba4a8d1a576912671dc
--- /dev/null
+++ b/src/conversion/ensight/output/ensightSerialOutputTemplates.C
@@ -0,0 +1,178 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightPart.H"
+#include "ensightParts.H"
+#include "ensightPTraits.H"
+#include "direction.H"
+#include "typeInfo.H"
+
+// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
+
+template<class Type>
+void Foam::ensightSerialOutput::writeField
+(
+    const word& key,
+    const Field<Type>& fld,
+    ensightFile& os
+)
+{
+    if (fld.size())
+    {
+        os.writeKeyword(key);
+
+        for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+        {
+            const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+            os.writeList(fld.component(cmpt));
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::ensightSerialOutput::writeField
+(
+    const Field<Type>& fld,
+    const ensightPartFaces& part,
+    ensightFile& os,
+    const bool nodeValues
+)
+{
+    if (part.size() && fld.size())
+    {
+        if (nodeValues)
+        {
+            os.beginPart(part.index());
+
+            os.writeKeyword("coordinates");
+            for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+            {
+                const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+                os.writeList(fld.component(cmpt));
+            }
+        }
+        else
+        {
+            os.beginPart(part.index());
+
+            const List<ensightFaces::elemType> enums =
+                ensightFaces::elemEnum.enums();
+
+            forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+            {
+                const ensightFaces::elemType what = *iter;
+
+                writeField
+                (
+                    ensightFaces::key(what),
+                    Field<Type>(fld, part.faceIds(what)),
+                    os
+                );
+            }
+        }
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightSerialOutput::writeField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& fld,
+    const ensightPartCells& part,
+    ensightFile& os
+)
+{
+    if (part.size() && fld.size())
+    {
+        os.beginPart(part.index());
+
+        const List<ensightCells::elemType> enums =
+            ensightCells::elemEnum.enums();
+
+        forAllConstIter(List<ensightCells::elemType>, enums, iter)
+        {
+            const ensightCells::elemType what = *iter;
+
+            writeField
+            (
+                ensightCells::key(what),
+                Field<Type>(fld, part.cellIds(what)),
+                os
+            );
+        }
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightSerialOutput::writeField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightParts& list,
+    ensightFile& os
+)
+{
+    forAllConstIter(ensightParts::StorageType, list, iter)
+    {
+        if (isA<ensightPartFaces>(*iter))
+        {
+            const ensightPartFaces& part =
+                dynamicCast<const ensightPartFaces&>(*iter);
+
+            const label patchi = part.patchIndex();
+            if (patchi >= 0 && patchi < vf.boundaryField().size())
+            {
+                writeField
+                (
+                    vf.boundaryField()[patchi],
+                    part,
+                    os,
+                    false
+                );
+            }
+        }
+        else
+        {
+            const ensightPartCells& part =
+                dynamicCast<const ensightPartCells&>(*iter);
+
+            writeField(vf, part, os);
+        }
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/part/ensightPart.C b/src/conversion/ensight/part/ensightPart.C
index d06c64e55964eb192ccdeabee6651f721830aef1..2e7fc02c233ebc38e215fe03a246fb56a8c8f139 100644
--- a/src/conversion/ensight/part/ensightPart.C
+++ b/src/conversion/ensight/part/ensightPart.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,164 +24,63 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ensightPart.H"
-#include "dictionary.H"
-#include "ListOps.H"
-#include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
 namespace Foam
 {
     defineTypeNameAndDebug(ensightPart, 0);
-    defineTemplateTypeNameAndDebug(IOPtrList<ensightPart>, 0);
-    defineRunTimeSelectionTable(ensightPart, istream);
 }
 
-const Foam::List<Foam::word> Foam::ensightPart::elemTypes_(0);
-
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
-bool Foam::ensightPart::isFieldDefined(const List<scalar>& field) const
+// TODO - move elsewhere
+#if 0
+bool Foam::ensightPart::isFieldDefined
+(
+    const List<scalar>& field
+    // const labelUList& addr = cellIds() or faceIds()
+) const
 {
-    forAll(elemLists_, elemI)
+    forAll(addr, elemI)
     {
-        const labelUList& idList = elemLists_[elemI];
+        const label id = addr[i];
 
-        forAll(idList, i)
+        if (id >= field.size() || std::isnan(field[id]))
         {
-            const label id = idList[i];
-
-            if (id >= field.size() || std::isnan(field[id]))
-            {
-                return false;
-            }
+            return false;
         }
     }
     return true;
 }
+#endif
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::ensightPart::ensightPart
-()
+Foam::ensightPart::ensightPart(const string& description)
 :
-    number_(0),
-    name_(""),
-    elemLists_(0),
-    offset_(0),
-    size_(0),
-    isCellData_(true),
-    matId_(0),
-    points_(pointField::null())
+    name_(description)
 {}
 
 
-Foam::ensightPart::ensightPart
-(
-    label partNumber,
-    const string& partDescription
-)
-:
-    number_(partNumber),
-    name_(partDescription),
-    elemLists_(0),
-    offset_(0),
-    size_(0),
-    isCellData_(true),
-    matId_(0),
-    points_(pointField::null())
-{}
-
-
-Foam::ensightPart::ensightPart
-(
-    label partNumber,
-    const string& partDescription,
-    const pointField& points
-)
-:
-    number_(partNumber),
-    name_(partDescription),
-    elemLists_(0),
-    offset_(0),
-    size_(0),
-    isCellData_(true),
-    matId_(0),
-    points_(points)
-{}
-
-
-Foam::ensightPart::ensightPart(const ensightPart& part)
-:
-    number_(part.number_),
-    name_(part.name_),
-    elemLists_(part.elemLists_),
-    offset_(part.offset_),
-    size_(part.size_),
-    isCellData_(part.isCellData_),
-    matId_(part.matId_),
-    points_(part.points_)
-{}
-
-
-// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
-
-Foam::autoPtr<Foam::ensightPart> Foam::ensightPart::New(Istream& is)
-{
-    const word partType(is);
-
-    istreamConstructorTable::iterator cstrIter =
-        istreamConstructorTablePtr_->find(partType);
-
-    if (cstrIter == istreamConstructorTablePtr_->end())
-    {
-        FatalIOErrorInFunction
-        (
-            is
-        )   << "unknown ensightPart type "
-            << partType << nl << nl
-            << "Valid ensightPart types are :" << endl
-            << istreamConstructorTablePtr_->sortedToc()
-            << exit(FatalIOError);
-    }
-
-    return autoPtr<ensightPart>(cstrIter()(is));
-}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightPart::~ensightPart()
 {}
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
-void Foam::ensightPart::renumber(const labelUList& origId)
+Foam::ensightGeoFile& Foam::operator<<
+(
+    ensightGeoFile& os,
+    const ensightPart& part
+)
 {
-    // transform to global values first
-    if (offset_)
-    {
-        forAll(elemLists_, elemI)
-        {
-            labelList& idList = elemLists_[elemI];
-            forAll(idList, i)
-            {
-                idList[i] += offset_;
-            }
-        }
-
-        offset_ = 0;
-    }
-
-    if (origId.size())
-    {
-        forAll(elemLists_, elemI)
-        {
-            inplaceRenumber(origId, elemLists_[elemI]);
-        }
-    }
+    part.write(os);
+    return os;
 }
 
 
diff --git a/src/conversion/ensight/part/ensightPart.H b/src/conversion/ensight/part/ensightPart.H
index 170b0e763d2c9fc22c06d71fa1c71ed92f89932f..0a7f8d2679936ec11990deacfcb50d3fe771ebda 100644
--- a/src/conversion/ensight/part/ensightPart.H
+++ b/src/conversion/ensight/part/ensightPart.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,21 +29,17 @@ Description
 
 SourceFiles
     ensightPart.C
-    ensightPartIO.C
-    ensightPartTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
 #ifndef ensightPart_H
 #define ensightPart_H
 
-#include "ensightFile.H"
 #include "ensightGeoFile.H"
 #include "typeInfo.H"
 #include "labelList.H"
 #include "polyMesh.H"
 #include "Field.H"
-#include "IOPtrList.H"
 #include "IOstream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -54,8 +50,6 @@ namespace Foam
 // Forward declaration of friend functions and operators
 
 class ensightPart;
-
-Ostream& operator<<(Ostream&, const ensightPart&);
 ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
 
 
@@ -65,40 +59,22 @@ ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
 
 class ensightPart
 {
-    // Private data
-
-        // Static data members
-        static const List<word> elemTypes_;
-
-
-protected:
-
-    // Protected data
-
-        //- Part number
-        label number_;
+    // Private Data
 
         //- Part name (or description)
         string name_;
 
-        //- Simple labelList with a name
-        labelListList elemLists_;
 
-        //- Start offset for elemLists_
-        label offset_;
+    // Private Member Functions
 
-        //- Number of elements in this part
-        label size_;
+        //- Disallow default bitwise copy construct
+        ensightPart(const ensightPart&) = delete;
 
-        //- Cell or face data
-        bool isCellData_;
-
-        //- Material id (numeric)
-        label matId_;
+        //- Disallow default bitwise assignment
+        void operator=(const ensightPart&) = delete;
 
-        //- pointField referenced
-        const pointField& points_;
 
+protected:
 
     // Protected Classes
 
@@ -127,46 +103,6 @@ protected:
             {}
         };
 
-
-    // Protected Member Functions
-
-        //- Reconstruct part characteristics (eg, element types) from Istream
-        //  A part reconstructed in this manner can be used when writing fields,
-        //  but cannot be used to write a new geometry
-        void reconstruct(Istream&);
-
-        //- Check for fully defined fields
-        bool isFieldDefined(const List<scalar>&) const;
-
-        //- Write the part header
-        void writeHeader(ensightFile&, bool withDescription=false) const;
-
-        //- Write a scalar field for idList
-        //  A null reference for idList writes the perNode values
-        void writeFieldList
-        (
-            ensightFile& os,
-            const List<scalar>& field,
-            const labelUList& idList
-        ) const;
-
-        //- Track points used
-        virtual localPoints calcLocalPoints() const
-        {
-            return localPoints();
-        }
-
-        //- Write connectivities
-        virtual void writeConnectivity
-        (
-            ensightGeoFile&,
-            const word& key,
-            const labelUList& idList,
-            const labelUList& pointMap
-        ) const
-        {}
-
-
 public:
 
     //- Runtime type information
@@ -175,85 +111,23 @@ public:
 
     // Constructors
 
-        //- Construct null
-        ensightPart();
-
-        //- Construct empty part with number and description
-        ensightPart(label partNumber, const string& partDescription);
-
-        //- Construct part with number, description and points reference
-        ensightPart
-        (
-            label partNumber,
-            const string& partDescription,
-            const pointField& points
-        );
-
-        //- Construct as copy
-        ensightPart(const ensightPart&);
-
-
-    // Selectors
-
-        // Declare run-time constructor selection table
-        declareRunTimeSelectionTable
-        (
-            autoPtr,
-            ensightPart,
-            istream,
-            (
-                Istream& is
-            ),
-            (is)
-        );
-
-        //- Construct and return clone
-        autoPtr<ensightPart> clone() const
-        {
-            return autoPtr<ensightPart>(new ensightPart(*this));
-        };
-
-        //- Reconstruct part characteristics on freestore from Istream
-        //  \sa reconstruct
-        static autoPtr<ensightPart> New(Istream&);
+        //- Construct with description
+        ensightPart(const string& description);
 
 
     //- Destructor
     virtual ~ensightPart();
 
 
-    // Static members
-
-        virtual const List<word>& elementTypes() const
-        {
-            return elemTypes_;
-        }
-
-
     // Access
 
-        //- Number of elements in this part
-        label size() const
-        {
-            return size_;
-        }
-
-        //- Represents cell data
-        bool isCellData() const
-        {
-            return isCellData_;
-        }
-
-        //- Represents face data
-        bool isFaceData() const
-        {
-            return !isCellData_;
-        }
+        //- Part index (0-based)
+        virtual label index() const = 0;
 
-        //- Part number
-        label number() const
+        //- Number of elements in this part
+        virtual label size() const
         {
-            return number_;
+            return 0;
         }
 
         //- Part name or description
@@ -262,80 +136,35 @@ public:
             return name_;
         }
 
-        //- Material id
-        label materialId() const
-        {
-            return matId_;
-        }
-
         //- non-const access to part name or description
         void name(const string& value)
         {
             name_ = value;
         }
 
-        //- non-const access to material id
-        void materialId(const label value)
-        {
-            matId_ = value;
-        }
 
-        //- Simple labelList with a name
-        const labelListList& elemLists() const
-        {
-            return elemLists_;
-        }
-
-        //- Offset for element ids
-        label offset() const
-        {
-            return offset_;
-        }
-
-
-    // Edit
-
-        //- Renumber elements
-        void renumber(const labelUList&);
-
-        //- Write summary information about the object
-        bool writeSummary(Ostream&) const;
-
-        //- Write reconstruction information for the object
-        bool writeData(Ostream&) const;
+    // Output
 
         //- Write geometry
-        virtual void writeGeometry(ensightGeoFile&) const
-        {}
+        virtual void write(ensightGeoFile&) const = 0;
 
-        //- Helper: write geometry given the pointField
-        void writeGeometry(ensightGeoFile&, const pointField&) const;
-
-        //- Write generalized field components
-        //  optionally write data per node
-        template<class Type>
-        void writeField
+        //- Helper: write geometry with given pointField
+        virtual void write
         (
-            ensightFile&,
-            const Field<Type>&,
-            const bool perNode = false
-        ) const;
+            ensightGeoFile&,
+            const pointField&
+        ) const = 0;
 
 
-    // Member Operators
+        //- Write summary information about the object
+        virtual void writeSummary(Ostream&) const = 0;
 
-        //- Disallow default bitwise assignment
-        void operator=(const ensightPart&)
-        {
-            NotImplemented;
-        }
+        //- Print various types of debugging information
+        virtual void dumpInfo(Ostream&) const = 0;
 
 
     // IOstream Operators
 
-        //- Write data (reconstruction information)
-        friend Ostream& operator<<(Ostream&, const ensightPart&);
-
         //- Write geometry
         friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
 
@@ -348,12 +177,6 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#ifdef NoRepository
-    #include "ensightPartTemplates.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/conversion/ensight/part/ensightPartCells.C b/src/conversion/ensight/part/ensightPartCells.C
index 82ef148e036d746dccbbfe3ecad76ce6c43b7fd0..cfd5c9482fc84ccde70aced8fcc826e7b63995de 100644
--- a/src/conversion/ensight/part/ensightPartCells.C
+++ b/src/conversion/ensight/part/ensightPartCells.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,152 +24,57 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ensightPartCells.H"
-#include "IOstream.H"
-#include "IStringStream.H"
-#include "dictionary.H"
-#include "cellModeller.H"
-#include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
     defineTypeNameAndDebug(ensightPartCells, 0);
-    addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream);
 }
 
-const Foam::List<Foam::word> Foam::ensightPartCells::elemTypes_
-(
-    IStringStream
-    (
-        "(tetra4 pyramid5 penta6 hexa8 nfaced)"
-    )()
-);
-
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::ensightPartCells::classify
-(
-    const polyMesh& mesh,
-    const labelUList& idList
-)
+Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
 {
-    // References to cell shape models
-    const cellModel& tet   = *(cellModeller::lookup("tet"));
-    const cellModel& pyr   = *(cellModeller::lookup("pyr"));
-    const cellModel& prism = *(cellModeller::lookup("prism"));
-    const cellModel& hex   = *(cellModeller::lookup("hex"));
-
-    const cellShapeList& cellShapes = mesh.cellShapes();
+    localPoints ptList(mesh_.points());
+    labelList& usedPoints = ptList.list;
+    label nPoints = 0;
 
-    offset_ = 0;
-    size_ = mesh.nCells();
+    // add all points from cells
+    const labelUList& idList = this->cellIds();
 
-    bool limited = false;
-    if (notNull(idList))
+    forAll(idList, i)
     {
-        limited = true;
-        size_ = idList.size();
-    }
-
-    // count the shapes
-    label nTet   = 0;
-    label nPyr   = 0;
-    label nPrism = 0;
-    label nHex   = 0;
-    label nPoly  = 0;
+        const label id = idList[i];
+        const labelUList& cFaces = mesh_.cells()[id];
 
-    for (label listI = 0; listI < size_; ++listI)
-    {
-        label cellId = listI;
-        if (limited)
+        forAll(cFaces, cFacei)
         {
-            cellId = idList[listI];
-        }
+            const face& f = mesh_.faces()[cFaces[cFacei]];
 
-        const cellShape& cellShape = cellShapes[cellId];
-        const cellModel& cellModel = cellShape.model();
-
-        if (cellModel == tet)
-        {
-            nTet++;
-        }
-        else if (cellModel == pyr)
-        {
-            nPyr++;
-        }
-        else if (cellModel == prism)
-        {
-            nPrism++;
-        }
-        else if (cellModel == hex)
-        {
-            nHex++;
-        }
-        else
-        {
-            nPoly++;
+            forAll(f, fp)
+            {
+                if (usedPoints[f[fp]] == -1)
+                {
+                    usedPoints[f[fp]] = nPoints++;
+                }
+            }
         }
     }
 
-
-    // we can avoid double looping, but at the cost of allocation
-    labelList tetCells(nTet);
-    labelList pyramidCells(nPyr);
-    labelList prismCells(nPrism);
-    labelList hexCells(nHex);
-    labelList polyCells(nPoly);
-
-    nTet   = 0,
-    nPyr   = 0;
-    nPrism = 0;
-    nHex   = 0;
-    nPoly  = 0;
-
-    // classify the shapes
-    for (label listI = 0; listI < size_; ++listI)
+    // this is not absolutely necessary, but renumber anyhow
+    nPoints = 0;
+    forAll(usedPoints, ptI)
     {
-        label cellId = listI;
-        if (limited)
-        {
-            cellId = idList[listI];
-        }
-
-        const cellShape& cellShape = cellShapes[cellId];
-        const cellModel& cellModel = cellShape.model();
-
-        if (cellModel == tet)
-        {
-            tetCells[nTet++] = cellId;
-        }
-        else if (cellModel == pyr)
-        {
-            pyramidCells[nPyr++] = cellId;
-        }
-        else if (cellModel == prism)
-        {
-            prismCells[nPrism++] = cellId;
-        }
-        else if (cellModel == hex)
-        {
-            hexCells[nHex++] = cellId;
-        }
-        else
+        if (usedPoints[ptI] > -1)
         {
-            polyCells[nPoly++] = cellId;
+            usedPoints[ptI] = nPoints++;
         }
     }
 
-
-    // MUST match with elementTypes
-    elemLists_.setSize(elementTypes().size());
-
-    elemLists_[tetra4Elements].transfer(tetCells);
-    elemLists_[pyramid5Elements].transfer(pyramidCells);
-    elemLists_[penta6Elements].transfer(prismCells);
-    elemLists_[hexa8Elements].transfer(hexCells);
-    elemLists_[nfacedElements].transfer(polyCells);
+    ptList.nPoints = nPoints;
+    return ptList;
 }
 
 
@@ -177,22 +82,12 @@ void Foam::ensightPartCells::classify
 
 Foam::ensightPartCells::ensightPartCells
 (
-    label partNumber,
-    const string& partDescription
-)
-:
-    ensightPart(partNumber, partDescription),
-    mesh_(*reinterpret_cast<polyMesh*>(0))
-{}
-
-
-Foam::ensightPartCells::ensightPartCells
-(
-    label partNumber,
+    label partIndex,
     const polyMesh& mesh
 )
 :
-    ensightPart(partNumber, "cells", mesh.points()),
+    ensightCells(partIndex),
+    ensightPart("cells"),
     mesh_(mesh)
 {
     classify(mesh);
@@ -201,12 +96,13 @@ Foam::ensightPartCells::ensightPartCells
 
 Foam::ensightPartCells::ensightPartCells
 (
-    label partNumber,
+    label partIndex,
     const polyMesh& mesh,
     const labelUList& idList
 )
 :
-    ensightPart(partNumber, "cells", mesh.points()),
+    ensightCells(partIndex),
+    ensightPart("cells"),
     mesh_(mesh)
 {
     classify(mesh, idList);
@@ -215,34 +111,19 @@ Foam::ensightPartCells::ensightPartCells
 
 Foam::ensightPartCells::ensightPartCells
 (
-    label partNumber,
+    label partIndex,
     const polyMesh& mesh,
     const cellZone& cZone
 )
 :
-    ensightPart(partNumber, cZone.name(), mesh.points()),
+    ensightCells(partIndex),
+    ensightPart(cZone.name()),
     mesh_(mesh)
 {
     classify(mesh, cZone);
 }
 
 
-Foam::ensightPartCells::ensightPartCells(const ensightPartCells& part)
-:
-    ensightPart(part),
-    mesh_(part.mesh_)
-{}
-
-
-Foam::ensightPartCells::ensightPartCells(Istream& is)
-:
-    ensightPart(),
-    mesh_(*reinterpret_cast<polyMesh*>(0))
-{
-    reconstruct(is);
-}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightPartCells::~ensightPartCells()
@@ -251,52 +132,6 @@ Foam::ensightPartCells::~ensightPartCells()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
-{
-    localPoints ptList(points_);
-    labelList& usedPoints = ptList.list;
-    label nPoints = 0;
-
-    forAll(elemLists_, typeI)
-    {
-        const labelUList& idList = elemLists_[typeI];
-
-        // add all points from cells
-        forAll(idList, i)
-        {
-            const label id = idList[i] + offset_;
-            const labelUList& cFaces = mesh_.cells()[id];
-
-            forAll(cFaces, cFacei)
-            {
-                const face& f = mesh_.faces()[cFaces[cFacei]];
-
-                forAll(f, fp)
-                {
-                    if (usedPoints[f[fp]] == -1)
-                    {
-                        usedPoints[f[fp]] = nPoints++;
-                    }
-                }
-            }
-        }
-    }
-
-    // this is not absolutely necessary, but renumber anyhow
-    nPoints = 0;
-    forAll(usedPoints, ptI)
-    {
-        if (usedPoints[ptI] > -1)
-        {
-            usedPoints[ptI] = nPoints++;
-        }
-    }
-
-    ptList.nPoints = nPoints;
-    return ptList;
-}
-
-
 void Foam::ensightPartCells::writeConnectivity
 (
     ensightGeoFile& os,
@@ -305,6 +140,8 @@ void Foam::ensightPartCells::writeConnectivity
     const labelUList& pointMap
 ) const
 {
+    if (idList.empty()) return;
+
     os.writeKeyword(key);
     os.write(idList.size());
     os.newline();
@@ -318,7 +155,7 @@ void Foam::ensightPartCells::writeConnectivity
         // write the number of faces per element
         forAll(idList, i)
         {
-            const label id = idList[i] + offset_;
+            const label id = idList[i];
             const labelUList& cFace = mesh_.cells()[id];
 
             os.write(cFace.size());
@@ -328,7 +165,7 @@ void Foam::ensightPartCells::writeConnectivity
         // write the number of points per element face
         forAll(idList, i)
         {
-            const label id = idList[i] + offset_;
+            const label id = idList[i];
             const labelUList& cFace = mesh_.cells()[id];
 
             forAll(cFace, facei)
@@ -343,7 +180,7 @@ void Foam::ensightPartCells::writeConnectivity
         // write the points describing each element face
         forAll(idList, i)
         {
-            const label id = idList[i] + offset_;
+            const label id = idList[i];
             const labelUList& cFace = mesh_.cells()[id];
 
             forAll(cFace, cFacei)
@@ -380,12 +217,12 @@ void Foam::ensightPartCells::writeConnectivity
     else
     {
         // write primitive
-        const cellShapeList& cellShapes = mesh_.cellShapes();
+        const cellShapeList& shapes = mesh_.cellShapes();
 
         forAll(idList, i)
         {
-            const label id = idList[i] + offset_;
-            const cellShape& cellPoints = cellShapes[id];
+            const label id = idList[i];
+            const cellShape& cellPoints = shapes[id];
 
             // convert global -> local index
             // (note: Ensight indices start with 1)
@@ -399,9 +236,97 @@ void Foam::ensightPartCells::writeConnectivity
 }
 
 
-void Foam::ensightPartCells::writeGeometry(ensightGeoFile& os) const
+void Foam::ensightPartCells::write
+(
+    ensightGeoFile& os,
+    const pointField& points
+) const
+{
+    if (size())
+    {
+        const localPoints ptList = calcLocalPoints();
+        const labelUList& pointMap = ptList.list;
+
+        os.beginPart(index(), name());
+        os.beginCoordinates(ptList.nPoints);
+
+        for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
+        {
+            forAll(pointMap, ptI)
+            {
+                if (pointMap[ptI] > -1)
+                {
+                    os.write(points[ptI].component(cmpt));
+                    os.newline();
+                }
+            }
+        }
+
+        // write each element type
+        const List<ensightCells::elemType> enums =
+            ensightCells::elemEnum.enums();
+
+        forAllConstIter(List<ensightCells::elemType>, enums, iter)
+        {
+            const ensightCells::elemType what = *iter;
+
+            writeConnectivity
+            (
+                os,
+                ensightCells::key(what),
+                cellIds(what),
+                pointMap
+            );
+        }
+    }
+}
+
+
+void Foam::ensightPartCells::write(ensightGeoFile& os) const
+{
+    this->write(os, mesh_.points());
+}
+
+
+void Foam::ensightPartCells::writeSummary(Ostream& os) const
+{
+    os.beginBlock(type());
+
+    os.writeEntry("id",     index()+1); // Ensight starts with 1
+    os.writeEntry("name",   name());
+    os.writeEntry("size",   size());
+
+    os.endBlock() << flush;
+}
+
+
+void Foam::ensightPartCells::dumpInfo(Ostream& os) const
 {
-    ensightPart::writeGeometry(os, points_);
+    os.beginBlock(type());
+
+    os.writeEntry("id",     index()+1); // Ensight starts with 1
+    os.writeEntry("name",   name());
+    os.writeEntry("size",   size());
+
+    const List<ensightCells::elemType> enums = ensightCells::elemEnum.enums();
+    forAllConstIter(List<ensightCells::elemType>, enums, iter)
+    {
+        const ensightCells::elemType what = *iter;
+        const labelUList& addr = this->cellIds(what);
+
+        os.writeKeyword(ensightCells::key(what));
+
+        // DIY flat output
+        os << addr.size() << '(';
+        forAll(addr, i)
+        {
+            if (i) os << ' ';
+            os << addr[i];
+        }
+        os << ')' << endEntry;
+    }
+
+    os.endBlock() << flush;
 }
 
 
diff --git a/src/conversion/ensight/part/ensightPartCells.H b/src/conversion/ensight/part/ensightPartCells.H
index d1b3bcb72dbaf6bd307b5e5bd5b462910d29db8c..f256a4800f0d55f011160c2747b68fbf80c720ca 100644
--- a/src/conversion/ensight/part/ensightPartCells.H
+++ b/src/conversion/ensight/part/ensightPartCells.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,6 +36,7 @@ SourceFiles
 #define ensightPartCells_H
 
 #include "ensightPart.H"
+#include "ensightCells.H"
 #include "typeInfo.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -49,28 +50,22 @@ namespace Foam
 
 class ensightPartCells
 :
+    public ensightCells,
     public ensightPart
 {
-    // Private Member Functions
+    // Private data
 
-        //- Disallow default bitwise assignment
-        void operator=(const ensightPartCells&);
+        //- Mesh referenced
+        const polyMesh& mesh_;
 
-        //- Classify the cell types, set elemLists.
-        void classify
-        (
-            const polyMesh&,
-            const labelUList& idLabels = labelUList::null()
-        );
 
-        //- Track points used
-        virtual localPoints calcLocalPoints() const;
+    // Private Member Functions
 
-        //- Track the points used
-        // virtual void makeLocalPointMap();
+        //- Track points used
+        localPoints calcLocalPoints() const;
 
         //- Element connectivity
-        virtual void writeConnectivity
+        void writeConnectivity
         (
             ensightGeoFile&,
             const word& key,
@@ -79,28 +74,11 @@ class ensightPartCells
         ) const;
 
 
-protected:
+        //- Disallow default bitwise copy construct
+        ensightPartCells(const ensightPartCells&) = delete;
 
-        //- Addressable ensight element types
-        enum elemType
-        {
-            tetra4Elements,
-            pyramid5Elements,
-            penta6Elements,
-            hexa8Elements,
-            nfacedElements
-        };
-
-
-    // Static data members
-
-        static const List<word> elemTypes_;
-
-
-    // Protected data
-
-        //- Mesh referenced
-        const polyMesh& mesh_;
+        //- Disallow default bitwise assignment
+        void operator=(const ensightPartCells&) = delete;
 
 
 public:
@@ -110,16 +88,17 @@ public:
 
     // Constructors
 
-        //- Construct empty part with number and description
-        ensightPartCells(label partNumber, const string& partDescription);
-
         //- Construct from polyMesh without zones
-        ensightPartCells(label partNumber, const polyMesh&);
+        ensightPartCells
+        (
+            label partIndex,
+            const polyMesh&
+        );
 
         //- Construct from polyMesh and list of (non-zoned) cells
         ensightPartCells
         (
-            label partNumber,
+            label partIndex,
             const polyMesh&,
             const labelUList&
         );
@@ -127,26 +106,11 @@ public:
         //- Construct from polyMesh and cellZone
         ensightPartCells
         (
-            label partNumber,
+            label partIndex,
             const polyMesh&,
             const cellZone&
         );
 
-        //- Construct as copy
-        ensightPartCells(const ensightPartCells&);
-
-        //- Reconstruct part characteristics (eg, element types) from Istream
-        //  A part reconstructed in this manner can be used when writing fields,
-        //  but cannot be used to write a new geometry
-        //  \sa Foam::ensightPart::reconstruct
-        ensightPartCells(Istream&);
-
-        //- Reconstruct part characteristics on freestore from Istream
-        static autoPtr<ensightPartCells> New(Istream& is)
-        {
-            return autoPtr<ensightPartCells>(new ensightPartCells(is));
-        }
-
 
     //- Destructor
     virtual ~ensightPartCells();
@@ -154,14 +118,36 @@ public:
 
     // Member Functions
 
-        //- Write geometry
-        virtual void writeGeometry(ensightGeoFile&) const;
+    // Access
 
-        //- Static listing of the element types
-        virtual const List<word>& elementTypes() const
+        //- Part index (0-based)
+        virtual label index() const
         {
-            return elemTypes_;
+            return ensightCells::index();
         }
+
+        //- Number of elements in this part
+        virtual label size() const
+        {
+            return ensightCells::size();
+        }
+
+
+    // Output
+
+        //- Write geometry
+        virtual void write(ensightGeoFile&) const;
+
+        //- Helper: write geometry given the pointField
+        virtual void write(ensightGeoFile&, const pointField&) const;
+
+
+        //- Write summary information about the object
+        virtual void writeSummary(Ostream&) const;
+
+        //- Print various types of debugging information
+        virtual void dumpInfo(Ostream&) const;
+
 };
 
 
diff --git a/src/conversion/ensight/part/ensightPartFaces.C b/src/conversion/ensight/part/ensightPartFaces.C
index ba28b3a13cdb32b0991bf40c6ef5d7e73d3701cd..4875b19cfbfcce79779f6666f37bf012f5ba8cf2 100644
--- a/src/conversion/ensight/part/ensightPartFaces.C
+++ b/src/conversion/ensight/part/ensightPartFaces.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,94 +24,61 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ensightPartFaces.H"
-#include "IOstreams.H"
-#include "IStringStream.H"
-#include "dictionary.H"
-#include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
     defineTypeNameAndDebug(ensightPartFaces, 0);
-    addToRunTimeSelectionTable(ensightPart, ensightPartFaces, istream);
 }
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-const Foam::List<Foam::word> Foam::ensightPartFaces::elemTypes_
-(
-    IStringStream
-    (
-        "(tria3 quad4 nsided)"
-    )()
-);
-
+Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
+{
+    if (contiguousPoints_)
+    {
+        localPoints ptList;
+        ptList.list = identity(points_.size());
+        ptList.nPoints = points_.size();
+        return ptList;
+    }
 
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+    localPoints ptList(points_);
+    labelList& usedPoints = ptList.list;
+    label nPoints = 0;
 
-void Foam::ensightPartFaces::classify(const faceList& faces)
-{
-    // count the shapes
-    label nTri  = 0;
-    label nQuad = 0;
-    label nPoly = 0;
+    // add all points from faces
+    const labelUList& idList = this->faceIds();
 
-    forAll(faces, facei)
+    // add all points from faces
+    forAll(idList, i)
     {
-        const face& f = faces[facei];
+        const label id = idList[i] + start_;
+        const face& f = faces_[id];
 
-        if (f.size() == 3)
-        {
-            nTri++;
-        }
-        else if (f.size() == 4)
-        {
-            nQuad++;
-        }
-        else
+        forAll(f, fp)
         {
-            nPoly++;
+            if (usedPoints[f[fp]] == -1)
+            {
+                usedPoints[f[fp]] = nPoints++;
+            }
         }
     }
 
-    // we can avoid double looping, but at the cost of allocation
-
-    labelList triCells(nTri);
-    labelList quadCells(nQuad);
-    labelList polygonCells(nPoly);
 
-    nTri  = 0;
-    nQuad = 0;
-    nPoly = 0;
-
-    // classify the shapes
-    forAll(faces, facei)
+    // this is not absolutely necessary, but renumber anyhow
+    nPoints = 0;
+    forAll(usedPoints, ptI)
     {
-        const face& f = faces[facei];
-
-        if (f.size() == 3)
-        {
-            triCells[nTri++] = facei;
-        }
-        else if (f.size() == 4)
-        {
-            quadCells[nQuad++] = facei;
-        }
-        else
+        if (usedPoints[ptI] > -1)
         {
-            polygonCells[nPoly++] = facei;
+            usedPoints[ptI] = nPoints++;
         }
     }
 
-
-    // MUST match with elementTypes
-    elemLists_.setSize(elementTypes().size());
-
-    elemLists_[tria3Elements].transfer(triCells);
-    elemLists_[quad4Elements].transfer(quadCells);
-    elemLists_[nsidedElements].transfer(polygonCells);
-
-    size_ = faces.size();
+    ptList.nPoints = nPoints;
+    return ptList;
 }
 
 
@@ -119,37 +86,21 @@ void Foam::ensightPartFaces::classify(const faceList& faces)
 
 Foam::ensightPartFaces::ensightPartFaces
 (
-    label partNumber,
-    const string& partDescription
-)
-:
-    ensightPart(partNumber, partDescription),
-    faces_(faceList::null()),
-    contiguousPoints_(false)
-{
-    isCellData_ = false;
-    offset_ = 0;
-    size_ = 0;
-}
-
-
-Foam::ensightPartFaces::ensightPartFaces
-(
-    label partNumber,
-    const string& partDescription,
+    label partIndex,
+    const string& description,
     const pointField& points,
     const faceList& faces,
     const bool contiguousPoints
 )
 :
-    ensightPart(partNumber, partDescription, points),
+    ensightFaces(partIndex),
+    ensightPart(description),
+    start_(0),
+    patchIndex_(-1),
     faces_(faces),
+    points_(points),
     contiguousPoints_(contiguousPoints)
 {
-    isCellData_ = false;
-    offset_ = 0;
-    size_ = 0;
-
     // classify the face shapes
     classify(faces);
 }
@@ -157,42 +108,24 @@ Foam::ensightPartFaces::ensightPartFaces
 
 Foam::ensightPartFaces::ensightPartFaces
 (
-    label partNumber,
+    label partIndex,
     const polyMesh& mesh,
     const polyPatch& patch
 )
 :
-    ensightPart(partNumber, patch.name(), mesh.points()),
+    ensightFaces(partIndex),
+    ensightPart(patch.name()),
+    start_(patch.start()),
+    patchIndex_(patch.index()),
     faces_(mesh.faces()),
+    points_(mesh.points()),
     contiguousPoints_(false)
 {
-    isCellData_ = false;
-    offset_ = patch.start();
-
     // classify the face shapes
     classify(patch);
 }
 
 
-Foam::ensightPartFaces::ensightPartFaces(const ensightPartFaces& part)
-:
-    ensightPart(part),
-    faces_(part.faces_),
-    contiguousPoints_(part.contiguousPoints_)
-{}
-
-
-Foam::ensightPartFaces::ensightPartFaces(Istream& is)
-:
-    ensightPart(),
-    faces_(faceList::null()),
-    contiguousPoints_(false)
-{
-    isCellData_ = false;
-    reconstruct(is);
-}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightPartFaces::~ensightPartFaces()
@@ -201,55 +134,6 @@ Foam::ensightPartFaces::~ensightPartFaces()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
-{
-    if (contiguousPoints_)
-    {
-        localPoints ptList;
-        ptList.list = identity(points_.size());
-        ptList.nPoints = points_.size();
-        return ptList;
-    }
-
-    localPoints ptList(points_);
-    labelList& usedPoints = ptList.list;
-    label nPoints = 0;
-
-    forAll(elemLists_, typeI)
-    {
-        const labelUList& idList = elemLists_[typeI];
-
-        // add all points from faces
-        forAll(idList, i)
-        {
-            const label id = idList[i] + offset_;
-            const face& f = faces_[id];
-
-            forAll(f, fp)
-            {
-                if (usedPoints[f[fp]] == -1)
-                {
-                    usedPoints[f[fp]] = nPoints++;
-                }
-            }
-        }
-    }
-
-    // this is not absolutely necessary, but renumber anyhow
-    nPoints = 0;
-    forAll(usedPoints, ptI)
-    {
-        if (usedPoints[ptI] > -1)
-        {
-            usedPoints[ptI] = nPoints++;
-        }
-    }
-
-    ptList.nPoints = nPoints;
-    return ptList;
-}
-
-
 void Foam::ensightPartFaces::writeConnectivity
 (
     ensightGeoFile& os,
@@ -259,6 +143,8 @@ void Foam::ensightPartFaces::writeConnectivity
     const labelUList& pointMap
 ) const
 {
+    if (idList.empty()) return;
+
     os.writeKeyword(key);
     os.write(idList.size());
     os.newline();
@@ -269,7 +155,7 @@ void Foam::ensightPartFaces::writeConnectivity
         // write the number of points per face
         forAll(idList, i)
         {
-            const label id = idList[i] + offset_;
+            const label id = idList[i] + start_;
             const face& f = faces[id];
 
             os.write(f.size());
@@ -280,7 +166,7 @@ void Foam::ensightPartFaces::writeConnectivity
     // write the points describing the face
     forAll(idList, i)
     {
-        const label id = idList[i] + offset_;
+        const label id = idList[i] + start_;
         const face& f = faces[id];
 
         // convert global -> local index
@@ -313,9 +199,99 @@ void Foam::ensightPartFaces::writeConnectivity
 }
 
 
-void Foam::ensightPartFaces::writeGeometry(ensightGeoFile& os) const
+void Foam::ensightPartFaces::write
+(
+    ensightGeoFile& os,
+    const pointField& points
+) const
+{
+    if (ensightPart::size())
+    {
+        const localPoints ptList = calcLocalPoints();
+        const labelUList& pointMap = ptList.list;
+
+        os.beginPart(index(), name());
+        os.beginCoordinates(ptList.nPoints);
+
+        for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
+        {
+            forAll(pointMap, ptI)
+            {
+                if (pointMap[ptI] > -1)
+                {
+                    os.write(points[ptI].component(cmpt));
+                    os.newline();
+                }
+            }
+        }
+
+        // write part
+        const List<ensightFaces::elemType> enums =
+            ensightFaces::elemEnum.enums();
+
+        forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+        {
+            const ensightFaces::elemType what = *iter;
+
+            writeConnectivity
+            (
+                os,
+                ensightFaces::key(what),
+                faceIds(what),
+                pointMap
+            );
+        }
+    }
+}
+
+
+void Foam::ensightPartFaces::write(ensightGeoFile& os) const
+{
+    this->write(os, points_);
+}
+
+
+void Foam::ensightPartFaces::writeSummary(Ostream& os) const
+{
+    os.beginBlock(type());
+
+    os.writeEntry("id",     index()+1); // Ensight starts with 1
+    os.writeEntry("name",   name());
+    os.writeEntry("start",  start_);
+    os.writeEntry("size",   size());
+
+    os.endBlock() << flush;
+}
+
+
+void Foam::ensightPartFaces::dumpInfo(Ostream& os) const
 {
-    ensightPart::writeGeometry(os, points_);
+    os.beginBlock(type());
+
+    os.writeEntry("id",     index()+1); // Ensight starts with 1
+    os.writeEntry("name",   name());
+    os.writeEntry("start",  start_);
+    os.writeEntry("size",   size());
+
+    const List<ensightFaces::elemType> enums = ensightFaces::elemEnum.enums();
+    forAllConstIter(List<ensightFaces::elemType>, enums, iter)
+    {
+        const ensightFaces::elemType what = *iter;
+        const labelUList& addr = this->faceIds(what);
+
+        os.writeKeyword(ensightFaces::key(what));
+
+        // DIY flat output
+        os << addr.size() << '(';
+        forAll(addr, i)
+        {
+            if (i) os << ' ';
+            os << addr[i];
+        }
+        os << ')' << endEntry;
+    }
+
+    os.endBlock() << flush;
 }
 
 
diff --git a/src/conversion/ensight/part/ensightPartFaces.H b/src/conversion/ensight/part/ensightPartFaces.H
index ea27d0cf51e832a17b543cb50839070ac1b970a6..974ca68a055783cb702077a64320b59becbe9ff2 100644
--- a/src/conversion/ensight/part/ensightPartFaces.H
+++ b/src/conversion/ensight/part/ensightPartFaces.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,7 +25,7 @@ Class
     Foam::ensightPartFaces
 
 Description
-    An implementation of ensightPart to hold volume mesh faces.
+    An implementation of ensightPart to hold mesh faces.
 
 SourceFiles
     ensightPartFaces.C
@@ -36,6 +36,8 @@ SourceFiles
 #define ensightPartFaces_H
 
 #include "ensightPart.H"
+#include "ensightFaces.H"
+#include "typeInfo.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -43,23 +45,39 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                     Class ensightPartFaces Declaration
+                      Class ensightPartFaces Declaration
 \*---------------------------------------------------------------------------*/
 
 class ensightPartFaces
 :
+    public ensightFaces,
     public ensightPart
 {
-    // Private Member Functions
+    // Private data
 
-        //- Disallow default bitwise assignment
-        void operator=(const ensightPartFaces&);
+        //- Start offset for patch
+        const label start_;
+
+        //- Patch index
+        const label patchIndex_;
+
+        //- Faces referenced
+        const faceList& faces_;
+
+        //- pointField referenced
+        const pointField& points_;
+
+        //- Can skip local point renumbering when points are contiguous
+        const bool contiguousPoints_;
+
+
+    // Private Member Functions
 
         //- Track points used
-        virtual localPoints calcLocalPoints() const;
+        localPoints calcLocalPoints() const;
 
         //- Element connectivity
-        virtual void writeConnectivity
+        void writeConnectivity
         (
             ensightGeoFile&,
             const word& key,
@@ -68,36 +86,6 @@ class ensightPartFaces
         ) const;
 
 
-protected:
-
-        //- Addressable ensight element types
-        enum elemType
-        {
-            tria3Elements,
-            quad4Elements,
-            nsidedElements
-        };
-
-
-    // Static data members
-
-        static const List<word> elemTypes_;
-
-
-    // Protected data
-
-        //- Faces referenced
-        const faceList& faces_;
-
-        //- Can skip local point renumbering when points are contiguous
-        const bool contiguousPoints_;
-
-
-    // Protected Member Functions
-
-        //- Classify the face shapes, set elemLists.
-        void classify(const faceList&);
-
         //- Helper: write connectivity
         void writeConnectivity
         (
@@ -109,22 +97,27 @@ protected:
         ) const;
 
 
+        //- Disallow default bitwise copy construct
+        ensightPartFaces(const ensightPartFaces&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightPartFaces&) = delete;
+
+
 public:
 
     //- Runtime type information
     TypeName("ensightFaces");
 
-    // Constructors
 
-        //- Construct empty part with number and description
-        ensightPartFaces(label partNumber, const string& partDescription);
+    // Constructors
 
-        //- Construct part with number, description, points and faces
+        //- Construct part with 0-based index, description, points and faces
         //  Can skip local point renumbering when points are contiguous
         ensightPartFaces
         (
-            label partNumber,
-            const string& partDescription,
+            label partIndex,
+            const string& description,
             const pointField&,
             const faceList&,
             const bool contiguousPoints = false
@@ -133,41 +126,56 @@ public:
         //- Construct from polyMesh and polyPatch
         ensightPartFaces
         (
-            label partNumber,
+            label partIndex,
             const polyMesh&,
             const polyPatch&
         );
 
-        //- Construct as copy
-        ensightPartFaces(const ensightPartFaces&);
 
-        //- Reconstruct part characteristics (eg, element types) from Istream
-        //  A part reconstructed in this manner can be used when writing fields,
-        //  but cannot be used to write a new geometry
-        //  \sa Foam::ensightPart::reconstruct
-        ensightPartFaces(Istream&);
+    //- Destructor
+    virtual ~ensightPartFaces();
 
-        //- Reconstruct part characteristics on freestore from Istream
-        static autoPtr<ensightPartFaces> New(Istream& is)
+
+    // Member Functions
+
+    // Access
+
+        //- Part index (0-based)
+        virtual label index() const
         {
-            return autoPtr<ensightPartFaces>(new ensightPartFaces(is));
+            return ensightFaces::index();
         }
 
 
-    //- Destructor
-    virtual ~ensightPartFaces();
+        //- Number of elements in this part
+        virtual label size() const
+        {
+            return ensightFaces::size();
+        }
 
 
-    // Member Functions
+        //- Return the patch index, -1 when not in use.
+        inline label patchIndex() const
+        {
+            return patchIndex_;
+        }
+
+
+    // Output
+
+        //- Write summary information about the object
+        virtual void writeSummary(Ostream&) const;
 
         //- Write geometry
-        virtual void writeGeometry(ensightGeoFile&) const;
+        virtual void write(ensightGeoFile&) const;
+
+        //- Helper: write geometry given the pointField
+        virtual void write(ensightGeoFile&, const pointField&) const;
+
+
+        //- Print various types of debugging information
+        virtual void dumpInfo(Ostream&) const;
 
-        //- Static listing of the element types
-        virtual const List<word>& elementTypes() const
-        {
-            return elemTypes_;
-        }
 };
 
 
diff --git a/src/conversion/ensight/part/ensightPartIO.C b/src/conversion/ensight/part/ensightPartIO.C
deleted file mode 100644
index 4e21d6dd62b8bfbea7d8caeadab33267f3455632..0000000000000000000000000000000000000000
--- a/src/conversion/ensight/part/ensightPartIO.C
+++ /dev/null
@@ -1,240 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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/>.
-
-Description
-    Output for ensightPart
-
-\*---------------------------------------------------------------------------*/
-
-#include "ensightPart.H"
-#include "dictionary.H"
-#include "IOstreams.H"
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::ensightPart::writeHeader
-(
-    ensightFile& os,
-    bool withDescription
-) const
-{
-    os.write("part");
-    os.newline();
-
-    os.write(number() + 1);   // Ensight starts with 1
-    os.newline();
-
-    if (withDescription)
-    {
-        os.write(name());
-        os.newline();
-    }
-}
-
-
-void Foam::ensightPart::writeFieldList
-(
-    ensightFile& os,
-    const List<scalar>& field,
-    const labelUList& idList
-) const
-{
-    if (notNull(idList))
-    {
-        forAll(idList, i)
-        {
-            if (idList[i] >= field.size() || std::isnan(field[idList[i]]))
-            {
-                os.writeUndef();
-            }
-            else
-            {
-                os.write(field[idList[i]]);
-            }
-
-            os.newline();
-        }
-    }
-    else
-    {
-        // no idList => perNode
-        forAll(field, i)
-        {
-            if (std::isnan(field[i]))
-            {
-                os.writeUndef();
-            }
-            else
-            {
-                os.write(field[i]);
-            }
-
-            os.newline();
-        }
-    }
-}
-
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::ensightPart::reconstruct(Istream& is)
-{
-    dictionary dict(is);
-    dict.lookup("id") >> number_;
-    dict.lookup("name") >> name_;
-
-    offset_ = 0;
-    dict.readIfPresent("offset", offset_);
-
-    // populate elemLists_
-    elemLists_.setSize(elementTypes().size());
-
-    forAll(elementTypes(), elemI)
-    {
-        word key(elementTypes()[elemI]);
-
-        elemLists_[elemI].clear();
-        dict.readIfPresent(key, elemLists_[elemI]);
-
-        size_ += elemLists_[elemI].size();
-    }
-
-    is.check("ensightPart::reconstruct(Istream&)");
-}
-
-
-bool Foam::ensightPart::writeSummary(Ostream& os) const
-{
-    os  << indent << type() << nl
-        << indent << token::BEGIN_BLOCK << incrIndent << nl;
-
-    // Ensight starts with 1
-    os.writeKeyword("id") << (number() + 1) << token::END_STATEMENT << nl;
-    os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
-    os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
-    os.writeKeyword("size") << size() << token::END_STATEMENT << nl;
-
-    os  << decrIndent << indent << token::END_BLOCK << nl << endl;
-
-    return true;
-}
-
-
-bool Foam::ensightPart::writeData(Ostream& os) const
-{
-    os  << indent << type() << nl
-        << indent << token::BEGIN_BLOCK << incrIndent << nl;
-
-    os.writeKeyword("id") << number() << token::END_STATEMENT << nl;
-    os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
-    os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
-
-    forAll(elementTypes(), typeI)
-    {
-        word key(elementTypes()[typeI]);
-        if (elemLists_[typeI].size())
-        {
-            elemLists_[typeI].writeEntry(key, os);
-        }
-    }
-
-    os  << decrIndent << indent << token::END_BLOCK << nl << endl;
-
-    return true;
-}
-
-
-void Foam::ensightPart::writeGeometry
-(
-    ensightGeoFile& os,
-    const pointField& points
-) const
-{
-    if (size())
-    {
-        const localPoints ptList = calcLocalPoints();
-        const labelUList& pointMap = ptList.list;
-
-        writeHeader(os, true);
-
-        // write points
-        os.writeKeyword("coordinates");
-        os.write(ptList.nPoints);
-        os.newline();
-
-        for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
-        {
-            forAll(pointMap, ptI)
-            {
-                if (pointMap[ptI] > -1)
-                {
-                    os.write(points[ptI].component(cmpt));
-                    os.newline();
-                }
-            }
-        }
-
-        // write parts
-        forAll(elementTypes(), elemI)
-        {
-            if (elemLists_[elemI].size())
-            {
-                writeConnectivity
-                (
-                    os,
-                    elementTypes()[elemI],
-                    elemLists_[elemI],
-                    pointMap
-                );
-            }
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
-
-Foam::Ostream& Foam::operator<<
-(
-    Ostream& os,
-    const ensightPart& part
-)
-{
-    part.writeData(os);
-    return os;
-}
-
-
-Foam::ensightGeoFile& Foam::operator<<
-(
-    ensightGeoFile& os,
-    const ensightPart& part
-)
-{
-    part.writeGeometry(os);
-    return os;
-}
-
-
-// ************************************************************************* //
diff --git a/src/conversion/ensight/part/ensightParts.C b/src/conversion/ensight/part/ensightParts.C
index c6f81160686a91cf503e16dfafbb5b4e3e5e7bff..2bcf5b96854c7ffaa8c2ed3fbf3edded80a56c03 100644
--- a/src/conversion/ensight/part/ensightParts.C
+++ b/src/conversion/ensight/part/ensightParts.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,21 +29,12 @@ License
 
 Foam::ensightParts::ensightParts(const polyMesh& mesh)
 :
-    partsList_()
+    StorageType()
 {
     recalculate(mesh);
 }
 
 
-Foam::ensightParts::ensightParts(const IOobject& ioObj)
-:
-    partsList_()
-{
-    IOPtrList<ensightPart> ioList(ioObj);
-    partsList_.transfer(ioList);
-}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightParts::~ensightParts()
@@ -54,19 +45,9 @@ Foam::ensightParts::~ensightParts()
 
 void Foam::ensightParts::recalculate(const polyMesh& mesh)
 {
-    partsList_.clear();
-
-    // extra space for unzoned cells
-    label nPart =
-    (
-        mesh.cellZones().size()
-      + mesh.boundaryMesh().size()
-      + 1
-    );
-
-    partsList_.setSize(nPart);
-    nPart = 0;
+    StorageType::clear();
 
+    label nPart = 0;
     label nZoneCells = 0;
 
     // do cell zones
@@ -77,13 +58,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
 
         if (cZone.size())
         {
-            partsList_.set
-            (
-                nPart,
-                new ensightPartCells(nPart, mesh, cZone)
-            );
-
-            nPart++;
+            this->append(new ensightPartCells(nPart++, mesh, cZone));
         }
     }
 
@@ -92,13 +67,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
     // special case: no zones at all - do entire mesh
     if (nZoneCells == 0)
     {
-        partsList_.set
-        (
-            nPart,
-            new ensightPartCells(nPart, mesh)
-        );
-
-        nPart++;
+        this->append(new ensightPartCells(nPart++, mesh));
     }
     else if (mesh.nCells() > nZoneCells)
     {
@@ -128,13 +97,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
 
         if (unzoned.size())
         {
-            partsList_.set
-            (
-                nPart,
-                new ensightPartCells(nPart, mesh, unzoned)
-            );
-
-            nPart++;
+            this->append(new ensightPartCells(nPart++, mesh, unzoned));
         }
     }
 
@@ -145,96 +108,41 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
         const polyPatch& patch = mesh.boundaryMesh()[patchi];
         if (patch.size() && !isA<processorPolyPatch>(patch))
         {
-            partsList_.set
-            (
-                nPart,
-                new ensightPartFaces(nPart, mesh, patch)
-            );
-
-            nPart++;
+            this->append(new ensightPartFaces(nPart++, mesh, patch));
         }
     }
-
-    // truncate to correct size
-    partsList_.setSize(nPart);
 }
 
 
-void Foam::ensightParts::renumber
-(
-    const labelUList& origCellId,
-    const labelUList& origFaceId
-)
+void Foam::ensightParts::write(ensightGeoFile& os) const
 {
-    forAll(partsList_, partI)
-    {
-        if (partsList_[partI].isCellData())
-        {
-            partsList_[partI].renumber(origCellId);
-        }
-        else
-        {
-            partsList_[partI].renumber(origFaceId);
-        }
-    }
-}
-
+    // Some feedback
+    Info<< "Write geometry part (" << flush;
 
-void Foam::ensightParts::writeGeometry(ensightGeoFile& os) const
-{
-    // with some feedback
-    Info<< "write geometry part (" << flush;
-
-    forAll(partsList_, partI)
+    forAllConstIter(StorageType, *this, iter)
     {
-        Info<< " " << partI << flush;
-        partsList_[partI].writeGeometry(os);
+        Info<< ' ' << (*iter).index() << flush;
+        (*iter).write(os);
     }
     Info<< " )" << endl;
 }
 
 
-bool Foam::ensightParts::writeSummary(Ostream& os) const
+void Foam::ensightParts::writeSummary(Ostream& os) const
 {
-    forAll(partsList_, partI)
+    forAllConstIter(StorageType, *this, iter)
     {
-        partsList_[partI].writeSummary(os);
+        (*iter).writeSummary(os);
     }
-
-    return true;
 }
 
 
-void Foam::ensightParts::writeData(Ostream& os) const
+void Foam::ensightParts::dumpInfo(Ostream& os) const
 {
-    // Begin write list
-    os  << nl << partsList_.size()
-        << nl << token::BEGIN_LIST;
-
-    // Write list contents
-    forAll(partsList_, i)
+    forAllConstIter(StorageType, *this, iter)
     {
-        os  << nl << partsList_[i];
+        (*iter).dumpInfo(os);
     }
-
-    // End write list
-    os  << nl << token::END_LIST << nl;
-
-    // Check state of IOstream
-    os.check("ensightParts::writeData(Ostream&)");
-}
-
-
-// * * * * * * * * * * * * * * * *  IOStream operators * * * * * * * * * * * //
-
-Foam::ensightGeoFile& Foam::operator<<
-(
-    ensightGeoFile& os,
-    const ensightParts& parts
-)
-{
-    parts.writeGeometry(os);
-    return os;
 }
 
 
diff --git a/src/conversion/ensight/part/ensightParts.H b/src/conversion/ensight/part/ensightParts.H
index 84fc47fae99862dcad1bdc6531a20d821e379ddd..e51e53135783c8a1f92df68ba11aac1862440c96 100644
--- a/src/conversion/ensight/part/ensightParts.H
+++ b/src/conversion/ensight/part/ensightParts.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,13 +29,13 @@ Description
 
 SourceFiles
     ensightParts.C
-    ensightPartsTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
 #ifndef ensightParts_H
 #define ensightParts_H
 
+#include "SLPtrList.H"
 #include "ensightPart.H"
 #include "ensightPartFaces.H"
 #include "ensightPartCells.H"
@@ -46,43 +46,34 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of friend functions and operators
-
-class ensightParts;
-
-ensightGeoFile& operator<<(ensightGeoFile&, const ensightParts&);
-
-
 /*---------------------------------------------------------------------------*\
-                       Class ensightParts Declaration
+                        Class ensightParts Declaration
 \*---------------------------------------------------------------------------*/
 
 class ensightParts
+:
+    public SLPtrList<ensightPart>
 {
-    // Private Data
-
-        //- List of parts
-        PtrList<ensightPart> partsList_;
-
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        ensightParts(const ensightParts&);
+        ensightParts(const ensightParts&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const ensightParts&);
+        void operator=(const ensightParts&) = delete;
 
 
 public:
 
+    //- Storage type used
+    typedef SLPtrList<ensightPart> StorageType;
+
+
     // Constructors
 
         //- Construct from polyMesh
         ensightParts(const polyMesh&);
 
-        //- Construct from IOobject
-        ensightParts(const IOobject&);
-
 
     //- Destructor
     ~ensightParts();
@@ -93,41 +84,19 @@ public:
         //- Clear old information and construct anew from polyMesh
         void recalculate(const polyMesh&);
 
-        //- Renumber elements
-        void renumber
-        (
-            const labelUList& origCellId,
-            const labelUList& origFaceId
-        );
-
         //- Number of parts
-        label size() const
-        {
-            return partsList_.size();
-        }
+        using StorageType::size;
+
 
         //- Write the geometry
-        void writeGeometry(ensightGeoFile&) const;
+        void write(ensightGeoFile&) const;
 
         //- Write summary information about the objects
-        bool writeSummary(Ostream&) const;
-
-        //- Write the lists
-        void writeData(Ostream&) const;
+        void writeSummary(Ostream&) const;
 
-        //- Write generalized volume field components
-        template<class Type>
-        void writeField
-        (
-            ensightFile&,
-            const GeometricField<Type, fvPatchField, volMesh>&
-        ) const;
+        //- Print various types of debugging information
+        void dumpInfo(Ostream&) const;
 
-
-    // Friend Operators
-
-        //- Write geometry
-        friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightParts&);
 };
 
 
@@ -137,10 +106,6 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#ifdef NoRepository
-    #include "ensightPartsTemplates.C"
-#endif
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/conversion/fire/FIREMeshReader.C b/src/conversion/fire/FIREMeshReader.C
new file mode 100644
index 0000000000000000000000000000000000000000..ef8576cf5f543665a282d97ecf9250a20cbf607c
--- /dev/null
+++ b/src/conversion/fire/FIREMeshReader.C
@@ -0,0 +1,549 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "FIREMeshReader.H"
+#include "wallPolyPatch.H"
+#include "ListOps.H"
+#include "IFstream.H"
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::word Foam::fileFormats::FIREMeshReader::validateWord
+(
+    const std::string& str
+)
+{
+    std::string::size_type ngood = 0;
+    bool prefix = false;
+    bool first  = true;
+
+    for
+    (
+        std::string::const_iterator iter = str.begin();
+        iter != str.end();
+        ++iter
+    )
+    {
+        if (word::valid(*iter))
+        {
+            ++ngood;
+            if (first)
+            {
+                first = false;
+
+                // start with a digit? need to prefix with '_'
+                if (isdigit(*iter))
+                {
+                    prefix = true;
+                }
+            }
+        }
+    }
+
+    if (prefix)
+    {
+        ++ngood;
+    }
+    else if (ngood == str.size())
+    {
+        return str;
+    }
+
+    Foam::word out;
+    out.resize(ngood);
+    ngood = 0;
+
+    Foam::word::iterator iter2 = out.begin();
+    for
+    (
+        std::string::const_iterator iter1 = str.begin();
+        iter1 != str.end();
+        ++iter1
+    )
+    {
+        register char c = *iter1;
+
+        if (Foam::word::valid(c))
+        {
+            if (prefix)
+            {
+                prefix = false;
+                *(iter2++) = '_';
+                ++ngood;
+            }
+            *(iter2++) = c;
+            ++ngood;
+        }
+    }
+
+    out.resize(ngood);
+
+    return out;
+}
+
+
+void Foam::fileFormats::FIREMeshReader::readPoints
+(
+    ISstream& is,
+    const scalar scaleFactor
+)
+{
+    const label n = FIRECore::readPoints(is, points_);
+    // the above has FatalError if there are no points
+
+    Info<< "Number of points = " << n << endl;
+    if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
+    {
+        points_ *= scaleFactor;
+    }
+}
+
+
+void Foam::fileFormats::FIREMeshReader::readFaces(ISstream& is)
+{
+    const label nFaces = getFireLabel(is);
+    Info<< "Number of faces  = " << nFaces << endl;
+    meshFaces_.setSize(nFaces);
+
+    if (nFaces > 0)
+    {
+        forAll(meshFaces_, faceI)
+        {
+            const label size = getFireLabel(is);
+
+            face& f = meshFaces_[faceI];
+            f.setSize(size);
+            forAll(f, fp)
+            {
+                f[fp] = getFireLabel(is);
+            }
+
+            // flip in-place
+            f.flip();
+        }
+    }
+    else
+    {
+        FatalErrorInFunction
+            << "no faces in file " << is.name()
+            << abort(FatalError);
+    }
+}
+
+
+void Foam::fileFormats::FIREMeshReader::readCells(ISstream& is)
+{
+    const label nCells = getFireLabel(is);
+    Info<< "Number of cells  = " << nCells << endl;
+
+    owner_.setSize(meshFaces_.size());
+    neigh_.setSize(meshFaces_.size());
+
+    owner_ = -1;
+    neigh_ = -1;
+
+    if (nCells > 0)
+    {
+        for (label cellI = 0; cellI < nCells; ++cellI)
+        {
+            const label nface = getFireLabel(is);
+
+            for (label i = 0; i < nface; ++i)
+            {
+                const label faceI = getFireLabel(is);
+
+                if (owner_[faceI] == -1)
+                {
+                    owner_[faceI] = cellI;
+                }
+                else if (neigh_[faceI] == -1)
+                {
+                    neigh_[faceI] = cellI;
+                }
+                else
+                {
+                    Warning
+                        << "bad cell connectivity for face " << faceI
+                        << " on cell " << cellI
+                        << endl;
+                }
+            }
+        }
+    }
+    else
+    {
+        FatalErrorInFunction
+            << "no cells in file " << is.name()
+            << abort(FatalError);
+    }
+
+    cellTableId_.setSize(nCells);
+    cellTableId_ = -1;
+}
+
+
+void Foam::fileFormats::FIREMeshReader::readSelections(ISstream& is)
+{
+    const label nSelect = getFireLabel(is);
+    Info<< "Number of select = " << nSelect << endl;
+
+    label nCellSelections = 0;
+    label nFaceSelections = 0;
+
+    faceZoneId_.setSize(meshFaces_.size());
+    faceZoneId_ = -1;
+
+    DynamicList<word> faceNames(32);
+
+    for (label selI = 0; selI < nSelect; ++selI)
+    {
+        std::string name    = getFireString(is);
+        const label selType = getFireLabel(is);
+        const label count   = getFireLabel(is);
+
+        if (selType == FIRECore::cellSelection)
+        {
+            // index starting at 1
+            const label selId = ++nCellSelections;
+
+            cellTable_.setName(selId, validateWord(name));
+            cellTable_.setMaterial(selId, "fluid");
+
+            for (label i = 0; i < count; ++i)
+            {
+                const label cellId = getFireLabel(is);
+
+                cellTableId_[cellId] = selId;
+            }
+        }
+        else if (selType == FIRECore::faceSelection)
+        {
+            // index starting at 0
+            const label selId = nFaceSelections++;
+
+            faceNames.append(validateWord(name));
+
+            for (label i = 0; i < count; ++i)
+            {
+                const label faceId = getFireLabel(is);
+
+                faceZoneId_[faceId] = selId;
+            }
+        }
+        else
+        {
+            // discard other selection types (eg, nodes)
+            for (label i = 0; i < count; ++i)
+            {
+                getFireLabel(is);
+            }
+        }
+    }
+
+    Info<< nFaceSelections << " face selections" << endl;
+    Info<< nCellSelections << " cell selections" << endl;
+
+    // add extra for missed boundary faces
+    faceNames.append("__MISSED_FACES__");
+    faceNames_.transfer(faceNames);
+}
+
+
+void Foam::fileFormats::FIREMeshReader::reorganize()
+{
+    nInternalFaces_ = 0;
+
+    // pass 1:
+    // count internal faces and also swap owner <-> neigh as required
+    forAll(meshFaces_, faceI)
+    {
+        if (neigh_[faceI] != -1)
+        {
+            ++nInternalFaces_;
+
+            if (owner_[faceI] > neigh_[faceI])
+            {
+                Swap(owner_[faceI], neigh_[faceI]);
+            }
+        }
+    }
+
+    label posInternal = 0;
+    label posExternal = nInternalFaces_;
+
+    labelList oldToNew(meshFaces_.size(), -1);
+
+    // pass 2:
+    // mapping to ensure proper division of internal / external
+    forAll(meshFaces_, faceI)
+    {
+        if (neigh_[faceI] == -1)
+        {
+            oldToNew[faceI] = posExternal++;
+        }
+        else
+        {
+            oldToNew[faceI] = posInternal++;
+        }
+    }
+
+    inplaceReorder(oldToNew, meshFaces_);
+    inplaceReorder(oldToNew, owner_);
+    inplaceReorder(oldToNew, neigh_);
+    inplaceReorder(oldToNew, faceZoneId_);
+
+    // determine the patch sizes - faceNames_ already has extra place for missed faces
+    const label zoneMissed = faceNames_.size() - 1;
+    patchSizes_.setSize(faceNames_.size());
+    patchSizes_ = 0;
+
+    patchStarts_.setSize(patchSizes_.size());
+    patchStarts_ = 0;
+
+    for (label faceI = nInternalFaces_; faceI < meshFaces_.size(); ++faceI)
+    {
+        label zoneI = faceZoneId_[faceI];
+        if (zoneI == -1)
+        {
+            ++patchSizes_[zoneMissed];
+        }
+        else
+        {
+            ++patchSizes_[zoneI];
+        }
+    }
+
+    if (patchSizes_[zoneMissed])
+    {
+        Info<<"collecting " << patchSizes_[zoneMissed]
+            << " missed boundary faces to final patch" << endl;
+    }
+
+    oldToNew = -1;
+
+    // calculate the patch starts
+    {
+        label pos = nInternalFaces_;
+
+        forAll(patchStarts_, patchI)
+        {
+            patchStarts_[patchI] = pos;
+            pos += patchSizes_[patchI];
+        }
+
+        forAll(patchSizes_, patchI)
+        {
+            patchSizes_[patchI] = 0;
+        }
+    }
+
+    // reordering
+    for (label faceI = nInternalFaces_; faceI < meshFaces_.size(); ++faceI)
+    {
+        label patchI = faceZoneId_[faceI];
+        if (patchI == -1)
+        {
+            oldToNew[faceI] = patchStarts_[zoneMissed] + patchSizes_[zoneMissed];
+            ++patchSizes_[zoneMissed];
+        }
+        else
+        {
+            oldToNew[faceI] = patchStarts_[patchI] + patchSizes_[patchI];
+            ++patchSizes_[patchI];
+        }
+    }
+
+    // discard old information
+    faceZoneId_.clear();
+
+    inplaceReorder(oldToNew, meshFaces_);
+    inplaceReorder(oldToNew, owner_);
+    inplaceReorder(oldToNew, neigh_);
+
+    //--- neigh_.setSize(nInternalFaces_);
+
+    // finally reduce to the number of patches actually used
+    patchNames_.setSize(patchSizes_.size());
+    oldToNew = -1;
+
+    label nPatches = 0;
+    forAll(patchSizes_, patchI)
+    {
+        if (patchSizes_[patchI])
+        {
+            patchNames_[nPatches] = faceNames_[patchI];
+
+            oldToNew[patchI] = nPatches;
+            ++nPatches;
+        }
+    }
+
+    inplaceReorder(oldToNew, patchStarts_);
+    inplaceReorder(oldToNew, patchSizes_);
+
+    patchStarts_.setSize(nPatches);
+    patchSizes_.setSize(nPatches);
+    patchNames_.setSize(nPatches);
+}
+
+
+void Foam::fileFormats::FIREMeshReader::addPatches(polyMesh& mesh) const
+{
+    // create patches
+    List<polyPatch*> newPatches(patchSizes_.size());
+
+    label meshFaceI = nInternalFaces_;
+
+    forAll(patchStarts_, patchI)
+    {
+        Info<< "patch " << patchI
+            << " (start: " << meshFaceI << " size: " << patchSizes_[patchI]
+            << ") name: " << patchNames_[patchI]
+            << endl;
+
+        // don't know anything better - just make it a wall
+        newPatches[patchI] = new polyPatch
+        (
+            patchNames_[patchI],
+            patchSizes_[patchI],
+            meshFaceI,
+            patchI,
+            mesh.boundaryMesh(),
+            word::null
+        );
+
+        meshFaceI += patchSizes_[patchI];
+    }
+
+    mesh.addPatches(newPatches);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+bool Foam::fileFormats::FIREMeshReader::readGeometry(const scalar scaleFactor)
+{
+    IOstream::streamFormat fmt = IOstream::ASCII;
+
+    const word ext = geometryFile_.ext();
+    bool supported = FIRECore::file3dExtensions.found(ext);
+    if (supported)
+    {
+        FIRECore::fileExt3d fireFileType = FIRECore::file3dExtensions[ext];
+        if (fireFileType == FIRECore::POLY_ASCII)
+        {
+            fmt = IOstream::ASCII;
+        }
+        else if (fireFileType == FIRECore::POLY_BINARY)
+        {
+            fmt = IOstream::BINARY;
+        }
+        else
+        {
+            // compressed or something
+            supported = false;
+        }
+    }
+
+    if (!supported)
+    {
+        FatalErrorInFunction
+            << "File-type '" << ext
+            << "' is not supported for reading as a FIRE mesh." << nl
+            << "If it is a compressed file, use gunzip first."
+            << abort(FatalError);
+    }
+
+    IFstream is(geometryFile_, fmt, false);
+
+    readPoints(is, scaleFactor);
+    readFaces(is);
+    readCells(is);
+    readSelections(is);
+
+    return true;
+}
+
+Foam::autoPtr<Foam::polyMesh> Foam::fileFormats::FIREMeshReader::mesh
+(
+    const objectRegistry& registry
+)
+{
+    readGeometry(scaleFactor_);
+    reorganize();
+
+    Info<< "Creating a polyMesh" << endl;
+
+    autoPtr<polyMesh> mesh
+    (
+        new polyMesh
+        (
+            IOobject
+            (
+                polyMesh::defaultRegion,
+                "constant",
+                registry
+            ),
+            xferMove(points_),
+            xferMove(meshFaces_),
+            xferMove(owner_),
+            xferMove(neigh_)
+        )
+    );
+
+    // adding patches also checks the mesh
+    addPatches(mesh());
+
+    cellTable_.addCellZones(mesh(), cellTableId_);
+
+    // addFaceZones(mesh());
+
+    return mesh;
+}
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::FIREMeshReader::FIREMeshReader
+(
+    const fileName& name,
+    const scalar scaleFactor
+)
+:
+    meshReader(name, scaleFactor),
+    owner_(0),
+    neigh_(0),
+    faceZoneId_(0),
+    faceNames_()
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fileFormats::FIREMeshReader::~FIREMeshReader()
+{}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/fire/FIREMeshReader.H b/src/conversion/fire/FIREMeshReader.H
new file mode 100644
index 0000000000000000000000000000000000000000..0c95cb5fa21eb39a0110168d8d4d90e0436478ac
--- /dev/null
+++ b/src/conversion/fire/FIREMeshReader.H
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::fileFormats::FIREMeshReader
+
+Description
+    Read AVL/FIRE fpma, fpmb files.
+
+Note
+    Does not handle compressed versions (fpmaz, fpmbz) of these files.
+
+SourceFiles
+    FIREMeshReader.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FIREMeshReader_H
+#define FIREMeshReader_H
+
+#include "meshReader.H"
+#include "FIRECore.H"
+#include "labelList.H"
+#include "IFstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+// forward declarations
+class polyMesh;
+
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class fileFormats::FIREMeshReader Declaration
+\*---------------------------------------------------------------------------*/
+
+class FIREMeshReader
+:
+    public meshReader,
+    public FIRECore
+{
+
+protected:
+
+    // Protected Data
+
+        labelList  owner_;
+        labelList  neigh_;
+
+        labelList  faceZoneId_;
+        wordList   faceNames_;
+
+
+    // Protected Member Functions
+
+        //- Disallow default bitwise copy construct
+        FIREMeshReader(const FIREMeshReader&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const FIREMeshReader&) = delete;
+
+
+        //- Validate word (eg, avoid leading digits)
+        static word validateWord(const std::string&);
+
+
+        //- Read the mesh from the file(s)
+        virtual bool readGeometry(const scalar scaleFactor = 1.0);
+
+        //- Read points from file
+        void readPoints(ISstream&, const scalar scaleFactor = 1.0);
+
+        //- Read points from file
+        void readFaces(ISstream&);
+
+        //- Read cell connectivities from file
+        void readCells(ISstream&);
+
+        //- Read cell/face selections from file
+        void readSelections(ISstream&);
+
+        //-
+        void reorganize();
+
+        void addPatches(polyMesh&) const;
+
+
+public:
+
+    // Constructors
+
+        //- Construct by reading file, optionally with scaling
+        FIREMeshReader(const fileName&, const scalar scaleFactor = 1.0);
+
+
+    //- Destructor
+    virtual ~FIREMeshReader();
+
+
+    // Member Functions
+
+        //- Create and return polyMesh
+        virtual autoPtr<polyMesh> mesh(const objectRegistry&);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/fire/FIREMeshWriter.C b/src/conversion/fire/FIREMeshWriter.C
new file mode 100644
index 0000000000000000000000000000000000000000..29746005d077f069cf23f14214cfdd7c86d059c0
--- /dev/null
+++ b/src/conversion/fire/FIREMeshWriter.C
@@ -0,0 +1,364 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "FIREMeshWriter.H"
+#include "Time.H"
+#include "HashTable.H"
+#include "OFstream.H"
+#include "processorPolyPatch.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+bool Foam::fileFormats::FIREMeshWriter::binary         = false;
+bool Foam::fileFormats::FIREMeshWriter::compress       = false;
+bool Foam::fileFormats::FIREMeshWriter::prefixBoundary = true;
+
+
+//! \cond fileScope
+//- Output newline in ascii mode, no-op in binary mode
+inline static void newline(Foam::OSstream& os)
+{
+    if (os.format() == Foam::IOstream::ASCII)
+    {
+        os  << Foam::endl;
+    }
+}
+
+//! \endcond
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+
+bool Foam::fileFormats::FIREMeshWriter::writeGeometry(OSstream& os) const
+{
+    const faceList&   faces  = mesh_.faces();
+    const pointField& points = mesh_.points();
+    const cellList&   cells  = mesh_.cells();
+
+    // Points
+    // ~~~~~~
+
+    // Set the precision of the points data to 10
+    os.precision(10);
+
+    Info<< "points: " << points.size() << endl;
+    putFireLabel(os, points.size());
+    newline(os);
+
+    forAll(points, ptI)
+    {
+        // scaling is normally 1 (ie, none)
+        putFirePoint(os, scaleFactor_ * points[ptI]);
+    }
+    newline(os); // readability
+
+
+    // Faces
+    // ~~~~~
+    // OPENFOAM - faces normals are outward-facing.
+    // FIRE     - faces normals are inward-facing.
+
+    Info<< "faces:  " << faces.size() << endl;
+    putFireLabel(os, faces.size());
+    newline(os);
+
+    forAll(faces, faceI)
+    {
+        // flip face
+        putFireLabels(os, faces[faceI].reverseFace());
+    }
+    newline(os); // readability
+
+
+    // Cells
+    // ~~~~~
+
+    Info<< "cells:  " << cells.size() << endl;
+    putFireLabel(os, cells.size());
+    newline(os);
+
+    forAll(cells, cellId)
+    {
+        putFireLabels(os, cells[cellId]);
+    }
+    newline(os); // readability
+
+    return os.good();
+}
+
+
+bool Foam::fileFormats::FIREMeshWriter::writeSelections(OSstream& os) const
+{
+    label nZones = 0;
+    label nPatches = 0;
+
+    // remap name between patches and cell-zones conflicts!
+
+    HashTable<word, label> patchNames;
+    HashTable<word, label> zoneNames;
+
+    wordHashSet usedPatchNames;
+    wordHashSet usedZoneNames;
+
+    // boundaries, skipping empty and processor patches
+    forAll(mesh_.boundaryMesh(), patchI)
+    {
+        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
+        if (patch.size() && !isA<processorPolyPatch>(patch))
+        {
+            ++nPatches;
+
+            const word oldName = patch.name();
+            word newName;
+            if (prefixBoundary)
+            {
+                newName = "BND_" + oldName;
+
+                if (usedPatchNames.found(newName))
+                {
+                    newName = "BND_patch" + ::Foam::name(patchI);
+                }
+            }
+            else
+            {
+                newName = oldName;
+
+                if (usedPatchNames.found(newName))
+                {
+                    newName = "patch" + ::Foam::name(patchI);
+                }
+            }
+
+            usedPatchNames.set(newName);
+            patchNames.set(patchI, newName);
+        }
+    }
+
+
+    // cellzones, skipping empty zones
+    forAll(mesh_.cellZones(), zoneI)
+    {
+        const cellZone& cZone = mesh_.cellZones()[zoneI];
+        if (cZone.size())
+        {
+            ++nZones;
+
+            const word oldName = cZone.name();
+            word newName = oldName;
+
+            if (usedPatchNames.found(newName) || usedZoneNames.found(newName))
+            {
+                newName = "CEL_zone" + ::Foam::name(zoneI);
+            }
+
+            usedZoneNames.set(newName);
+            zoneNames.set(zoneI, newName);
+        }
+    }
+
+
+    //
+    // actually write things
+    //
+
+    putFireLabel(os, (nZones + nPatches));
+    newline(os);
+
+    // do cell zones
+    forAll(mesh_.cellZones(), zoneI)
+    {
+        const cellZone& cZone = mesh_.cellZones()[zoneI];
+
+        if (cZone.size())
+        {
+            Info<< "cellZone " << zoneI
+                << " (size: "  << cZone.size()
+                << ") name: "  << zoneNames[zoneI] << nl;
+
+            putFireString(os, zoneNames[zoneI]);
+            putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
+            newline(os);
+
+            putFireLabels(os, cZone);
+            newline(os); // readability
+        }
+    }
+
+    // do boundaries, skipping empty and processor patches
+    forAll(mesh_.boundaryMesh(), patchI)
+    {
+        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
+        if (patch.size() && !isA<processorPolyPatch>(patch))
+        {
+            Info<< "patch " << patchI
+                << " (start: " << patch.start() << " size: " << patch.size()
+                << ") name: " << patchNames[patchI]
+                << endl;
+
+            putFireString(os, patchNames[patchI]);
+            putFireLabel(os, static_cast<int>(FIRECore::faceSelection));
+            newline(os);
+
+            putFireLabels(os, patch.size(), patch.start());
+            newline(os); // readability
+        }
+
+        newline(os); // readability
+    }
+
+    return os.good();
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::FIREMeshWriter::FIREMeshWriter
+(
+    const polyMesh& mesh,
+    const scalar scaleFactor
+)
+:
+    meshWriter(mesh, scaleFactor)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fileFormats::FIREMeshWriter::~FIREMeshWriter()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::fileFormats::FIREMeshWriter::write(const fileName& meshName) const
+{
+    bool useBinary   = binary;
+    bool useCompress = compress;
+
+    fileName baseName(meshName);
+    if (baseName.empty())
+    {
+        baseName = meshWriter::defaultMeshName;
+
+        const Time& t = mesh_.time();
+
+        if
+        (
+            t.timeName() != "0"
+         && t.timeName() != t.constant()
+        )
+        {
+            baseName += "_" + t.timeName();
+        }
+    }
+    else
+    {
+        const word ext = baseName.ext();
+
+        if (FIRECore::file3dExtensions.found(ext))
+        {
+            FIRECore::fileExt3d fireFileType = FIRECore::file3dExtensions[ext];
+            if (fireFileType == FIRECore::POLY_ASCII)
+            {
+                useBinary   = false;
+                useCompress = false;
+            }
+            else if (fireFileType == FIRECore::POLY_BINARY)
+            {
+                useBinary   = true;
+                useCompress = false;
+            }
+            else if (fireFileType == FIRECore::POLY_ASCII_COMPRESSED)
+            {
+                useBinary   = false;
+                useCompress = true;
+            }
+            else if (fireFileType == FIRECore::POLY_BINARY_COMPRESSED)
+            {
+                useBinary   = true;
+                useCompress = true;
+            }
+        }
+
+        baseName = baseName.lessExt();
+    }
+
+
+    // A slight hack. Cannot generate compressed files with the desired ending
+    // So create and rename later
+    const fileName filename = FIRECore::fireFileName
+    (
+        baseName,
+        useBinary ? FIRECore::POLY_BINARY : FIRECore::POLY_ASCII
+    );
+
+    autoPtr<OFstream> osPtr
+    (
+        new OFstream
+        (
+            filename,
+            (useBinary   ? IOstream::BINARY : IOstream::ASCII),
+            IOstream::currentVersion,
+            (useCompress ? IOstream::COMPRESSED : IOstream::UNCOMPRESSED)
+        )
+    );
+
+    if (osPtr->good())
+    {
+        Info<< "Writing output to ";
+        if (useCompress)
+        {
+            // output .fpmaz instead of .fpma
+            Info<< '"' << osPtr().name().c_str() << "z\"" << endl;
+        }
+        else
+        {
+            Info<< osPtr().name() << endl;
+        }
+
+        writeGeometry(osPtr());
+        writeSelections(osPtr());
+
+        osPtr.clear();    // implicitly close the file
+
+        if (useCompress)
+        {
+            // rename .fpma.gz -> .fpmaz
+            // The '.gz' is automatically added by OFstream in compression mode
+            Foam::mv(filename + ".gz", filename + "z");
+        }
+    }
+    else
+    {
+        Info<<"could not open file for writing " << filename << endl;
+        return false;
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/fire/FIREMeshWriter.H b/src/conversion/fire/FIREMeshWriter.H
new file mode 100644
index 0000000000000000000000000000000000000000..7d61a0461eb9a585787174f1d8cba60a1b308690
--- /dev/null
+++ b/src/conversion/fire/FIREMeshWriter.H
@@ -0,0 +1,130 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::fileFormats::FIREMeshWriter
+
+Description
+    Writes polyMesh in AVL/FIRE polyhedra format (fpma, fpmb)
+
+    It is also possible to write compressed formats (fpmaz, fpmbz)
+
+Note
+   The fpma, fpmb formats are relatively poorly documented, but are manageable
+   to read and write. It is, however, not recommended to import them directly
+   into AVL/FIRE (the GUI) since it is generally not robust enough.
+   Instead use their file-convertor to reconvert them into their native format.
+
+   In the AVL/FIRE polyhedra format, the faces normals point inwards, whereas
+   the OpenFOAM face normals always point outwards.
+
+SourceFiles
+    FIREMeshWriter.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FIREMeshWriter_H
+#define FIREMeshWriter_H
+
+#include "meshWriter.H"
+#include "FIRECore.H"
+#include "IOstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class fileFormats::FIREMeshWriter Declaration
+\*---------------------------------------------------------------------------*/
+
+class FIREMeshWriter
+:
+    public meshWriter,
+    public FIRECore
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        FIREMeshWriter(const FIREMeshWriter&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const FIREMeshWriter&) = delete;
+
+        //- Write points, faces, cells
+        bool writeGeometry(OSstream&) const;
+
+        //- Write selections
+        bool writeSelections(OSstream&) const;
+
+public:
+
+    // Static data members
+
+        //- Write binary (default ascii)
+        static bool binary;
+
+        //- Write with compression (default false)
+        static bool compress;
+
+        //- Prefix patches with 'BND_' before writing (default true)
+        static bool prefixBoundary;
+
+
+    // Constructors
+
+        //- Prepare for writing, optionally with scaling
+        FIREMeshWriter(const polyMesh&, const scalar scaleFactor = 1.0);
+
+
+    //- Destructor
+    virtual ~FIREMeshWriter();
+
+
+    // Member Functions
+
+        // Write
+
+            //- Write volume mesh
+            virtual bool write
+            (
+                const fileName& meshName = fileName::null
+            ) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/fire/checkFireEdges.C b/src/conversion/fire/checkFireEdges.C
new file mode 100644
index 0000000000000000000000000000000000000000..eb7c3bf9da11bc5bf539062a256357bf83b5852b
--- /dev/null
+++ b/src/conversion/fire/checkFireEdges.C
@@ -0,0 +1,299 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "checkFireEdges.H"
+#include "polyMesh.H"
+#include "edge.H"
+#include "HashSet.H"
+#include "ListOps.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    //! \cond fileScope
+    //- Print face information for debugging purposes
+    static inline void printFace
+    (
+        const face& f,
+        label faceI,
+        const edge& currEdge
+    )
+    {
+        Info<< "face " << faceI << ':';
+        forAll(f, fpI)
+        {
+            Info<< ' ';
+            if (f[fpI] == currEdge[0] || f[fpI] == currEdge[1])
+            {
+                Info<< '_';   // highlight the node
+            }
+            Info<< f[fpI];
+        }
+        Info<< endl;
+    }
+    //! \endcond
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+Foam::label Foam::checkFireEdges
+(
+    const faceList& faces,
+    const labelListList& pointFaces,
+    const UList<point>& points
+)
+{
+    label nFailedEdges = 0;
+    const bool fullCheck = true;
+    typedef HashSet<edge, Hash<edge>> edgeHashSet;
+
+    Info<< "Checking edges according to AVL/FIRE on-the-fly methodology..."
+        << endl;
+
+    labelHashSet strayPoints(100);
+    edgeHashSet  failedEdges(100);
+
+    forAll(faces, faceI)
+    {
+        const face& faceA = faces[faceI];
+
+        forAll(faceA, edgeI)
+        {
+            const edge currEdge = faceA.faceEdge(edgeI);
+
+            // all faces attached to the first point
+            const labelList& otherFaceIds = pointFaces[currEdge[0]];
+
+            forAll(otherFaceIds, otherI)
+            {
+                const int otherFaceI = otherFaceIds[otherI];
+                const face& faceB = faces[otherFaceI];
+
+                // only check once
+                if (otherFaceI <= faceI && !fullCheck)
+                {
+                    continue;
+                }
+
+                // get local edges on the second face
+                int other_p0 = -1;
+                int other_p1 = -1;
+                int size_m1  = faceB.size() - 1;
+
+                forAll(faceB, ptI)
+                {
+                    if (faceB[ptI] == currEdge[0])
+                    {
+                        other_p0 = ptI;
+                    }
+
+                    if (faceB[ptI] == currEdge[1])
+                    {
+                        other_p1 = ptI;
+                    }
+                }
+
+                if
+                (
+                    // did not have both points - can skip
+                    other_p0 == -1
+                 || other_p1 == -1
+                    // a normal edge
+                 || abs(other_p0 - other_p1) == 1
+                    // handle wrapping
+                 || (other_p0 == 0 && other_p1 == size_m1)
+                 || (other_p1 == 0 && other_p0 == size_m1)
+                )
+                {
+                    continue;
+                }
+
+                // find the "stray" point
+                int stray = -1;
+                if (abs(other_p0 - other_p1) == 2)
+                {
+                    // a normal case
+                    stray = (other_p0 + other_p1) / 2;
+                }
+                else if
+                (
+                    (other_p0 == 0 && other_p1+1 == size_m1)
+                 || (other_p1 == 0 && other_p0+1 == size_m1)
+                )
+                {
+                    stray = size_m1;
+                }
+
+                if (stray > 0)
+                {
+                    strayPoints.set(faceB[stray]);
+                }
+
+                failedEdges.set(currEdge);
+
+                ++nFailedEdges;
+
+                Info<< nl
+                    << "Broken edge calculated between points  "
+                    << currEdge[0] << "  " << currEdge[1] << endl;
+
+                printFace(faceA, faceI, currEdge);
+                printFace(faceB, otherFaceI, currEdge);
+            }
+        }
+    }
+
+    if (nFailedEdges)
+    {
+        Info<< endl;
+    }
+    Info<< "detected " << nFailedEdges << " edge failures";
+
+    // reduce to the actual number of edges
+    nFailedEdges = failedEdges.size();
+
+    // report the locations
+    if (nFailedEdges)
+    {
+        Info<< " over " << nFailedEdges << " edges" << endl;
+
+        Info<< nl
+            << "edge points" << nl
+            << "~~~~~~~~~~~" << endl;
+
+
+        forAllConstIter(edgeHashSet, failedEdges, citer)
+        {
+            edge thisEdge = citer.key();
+            if (thisEdge.start() > thisEdge.end())
+            {
+                thisEdge.flip();
+            }
+
+            if (&points)
+            {
+                forAll(thisEdge, keyI)
+                {
+                    const label ptI = thisEdge[keyI];
+                    Info<< "point " << ptI << ": " << points[ptI] << endl;
+                }
+            }
+            else
+            {
+                forAll(thisEdge, keyI)
+                {
+                    const label ptI = thisEdge[keyI];
+                    Info<< "point " << ptI << endl;
+                }
+            }
+            Info<< endl;
+        }
+
+        Info<< nl
+            << "stray points" << nl
+            << "~~~~~~~~~~~~" << endl;
+
+        {
+            labelList keys = strayPoints.sortedToc();
+
+            if (&points)
+            {
+                forAll(keys, keyI)
+                {
+                    const label ptI = keys[keyI];
+                    Info<< "stray " << ptI << ": " << points[ptI] << endl;
+                }
+            }
+            else
+            {
+                forAll(keys, keyI)
+                {
+                    const label ptI = keys[keyI];
+                    Info<< "stray " << ptI << endl;
+                }
+            }
+
+        }
+        Info<< endl;
+    }
+    else
+    {
+        Info<< endl;
+    }
+
+    return nFailedEdges;
+}
+
+
+Foam::label Foam::checkFireEdges
+(
+    const faceList& faces,
+    const UList<point>& points
+)
+{
+    label nPoints = -1;
+
+    if (&points)
+    {
+        nPoints = points.size();
+
+    }
+    else
+    {
+        // get the max point addressed
+        forAll(faces, faceI)
+        {
+            const face& f = faces[faceI];
+            forAll(f, fp)
+            {
+                if (nPoints < f[fp])
+                {
+                    nPoints = f[fp];
+                }
+            }
+        }
+
+        ++nPoints;
+    }
+
+    labelListList pointFaces(nPoints);
+    invertManyToMany(nPoints, faces, pointFaces);
+
+    return checkFireEdges(faces, pointFaces, points);
+}
+
+
+Foam::label Foam::checkFireEdges
+(
+    const polyMesh& mesh
+)
+{
+    return checkFireEdges(mesh.faces(), mesh.pointFaces(), mesh.points());
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.H b/src/conversion/fire/checkFireEdges.H
similarity index 62%
rename from src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.H
rename to src/conversion/fire/checkFireEdges.H
index 65e93f274e9a98b3908485369db485f83e35290f..0f0bffe2c884c4632707499e3000e1349abc0e57 100644
--- a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.H
+++ b/src/conversion/fire/checkFireEdges.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,55 +21,55 @@ License
     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::fileFormats::OFSsurfaceFormatCore
-
 Description
-    Internal class used by the OFSsurfaceFormat
+    Checks the mesh for edge connectivity as expected by the AVL/FIRE
+    on-the-fly calculations.
+    Errors flagged here are not necessarily topological errors at all.
 
 SourceFiles
-    OFSsurfaceFormatCore.C
+    checkFireEdges.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef OFSsurfaceFormatCore_H
-#define OFSsurfaceFormatCore_H
+#ifndef checkFireEdges_H
+#define checkFireEdges_H
 
-#include "Ostream.H"
-#include "OFstream.H"
-#include "MeshedSurface.H"
-#include "UnsortedMeshedSurface.H"
+#include "faceList.H"
+#include "labelList.H"
+#include "point.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-namespace fileFormats
-{
 
-/*---------------------------------------------------------------------------*\
-                    Class OFSsurfaceFormatCore Declaration
-\*---------------------------------------------------------------------------*/
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-class OFSsurfaceFormatCore
-{
-protected:
+class polyMesh;
+
+//- check edge connectivity
+label checkFireEdges
+(
+    const faceList&,
+    const labelListList& pointFaces,
+    const UList<point>& = UList<point>::null()
+);
+
+
+//- check edge connectivity with pointFaces mapping calculated automatically
+label checkFireEdges
+(
+    const faceList&,
+    const UList<point>& = UList<point>::null()
+);
 
-    // Protected Member Functions
 
-        //- Write header information and surfZoneList
-        static void writeHeader
-        (
-            Ostream&,
-            const pointField&,
-            const UList<surfZone>&
-        );
-};
+//- check edge connectivity
+label checkFireEdges(const polyMesh&);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace fileFormats
 } // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/conversion/starcd/STARCDMeshReader.C b/src/conversion/starcd/STARCDMeshReader.C
index e5ddc1bcb5827db70197294f53738e9acd18c9c0..0229eaa0d20b854e84bd92c82652e703c7945e62 100644
--- a/src/conversion/starcd/STARCDMeshReader.C
+++ b/src/conversion/starcd/STARCDMeshReader.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,26 +35,9 @@ License
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-const char* const Foam::fileFormats::STARCDMeshReader::defaultBoundaryName =
-    "Default_Boundary_Region";
-
-const char* const Foam::fileFormats::STARCDMeshReader::defaultSolidBoundaryName =
-    "Default_Boundary_Solid";
-
-bool Foam::fileFormats::STARCDMeshReader::keepSolids = false;
-
-const int Foam::fileFormats::STARCDMeshReader::starToFoamFaceAddr[4][6] =
-{
-    { 4, 5, 2, 3, 0, 1 },     // 11 = pro-STAR hex
-    { 0, 1, 4, -1, 2, 3 },    // 12 = pro-STAR prism
-    { 3, -1, 2, -1, 1, 0 },   // 13 = pro-STAR tetra
-    { 0, -1, 4, 2, 1, 3 }     // 14 = pro-STAR pyramid
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-void Foam::fileFormats::STARCDMeshReader::readToNewline(IFstream& is)
+//! \cond fileScope
+//- Read and discard to newline
+static void readToNewline(Foam::IFstream& is)
 {
     char ch = '\n';
     do
@@ -63,34 +46,7 @@ void Foam::fileFormats::STARCDMeshReader::readToNewline(IFstream& is)
     }
     while ((is) && ch != '\n');
 }
-
-
-bool Foam::fileFormats::STARCDMeshReader::readHeader(IFstream& is, word fileSignature)
-{
-    if (!is.good())
-    {
-        FatalErrorInFunction
-            << abort(FatalError);
-    }
-
-    word header;
-    label majorVersion;
-
-    is >> header;
-    is >> majorVersion;
-
-    // skip the rest of the line
-    readToNewline(is);
-
-    // add other checks ...
-    if (header != fileSignature)
-    {
-        Info<< "header mismatch " << fileSignature << "  " << is.name()
-            << endl;
-    }
-
-    return true;
-}
+//! \endcond
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -118,20 +74,19 @@ Body:
   <vertexId>  <x>  <y>  <z> [newline]
 
 \*---------------------------------------------------------------------------*/
-void Foam::fileFormats::STARCDMeshReader::readPoints
+Foam::label Foam::fileFormats::STARCDMeshReader::readPoints
 (
     const fileName& inputName,
     const scalar scaleFactor
 )
 {
-    const word fileSignature = "PROSTAR_VERTEX";
     label nPoints = 0, maxId = 0;
 
     // Pass 1:
     // get # points and maximum vertex label
     {
         IFstream is(inputName);
-        readHeader(is, fileSignature);
+        readHeader(is, STARCDCore::HEADER_VRT);
 
         label lineLabel;
         scalar x, y, z;
@@ -164,7 +119,7 @@ void Foam::fileFormats::STARCDMeshReader::readPoints
     if (nPoints > 0)
     {
         IFstream is(inputName);
-        readHeader(is, fileSignature);
+        readHeader(is, STARCDCore::HEADER_VRT);
 
         label lineLabel;
 
@@ -200,6 +155,8 @@ void Foam::fileFormats::STARCDMeshReader::readPoints
             << "no points in file " << inputName
             << abort(FatalError);
     }
+
+    return maxId;
 }
 
 
@@ -245,7 +202,6 @@ Strictly speaking, we only need the cellModeller for adding boundaries.
 
 void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
 {
-    const word fileSignature = "PROSTAR_CELL";
     label nFluids = 0, nSolids = 0, nBaffles = 0, nShells = 0;
     label maxId = 0;
 
@@ -257,7 +213,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
     // also see if polyhedral cells were used
     {
         IFstream is(inputName);
-        readHeader(is, fileSignature);
+        readHeader(is, STARCDCore::HEADER_CEL);
 
         label lineLabel, shapeId, nLabels, cellTableId, typeId;
 
@@ -279,7 +235,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
                 nLabels -= 8;
             }
 
-            if (typeId == starcdFluidType)
+            if (typeId == STARCDCore::starcdFluidType)
             {
                 nFluids++;
                 maxId = max(maxId, starCellId);
@@ -290,10 +246,10 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
                     cellTable_.setMaterial(cellTableId, "fluid");
                 }
             }
-            else if (typeId == starcdSolidType)
+            else if (typeId == STARCDCore::starcdSolidType)
             {
                 nSolids++;
-                if (keepSolids)
+                if (keepSolids_)
                 {
                     maxId = max(maxId, starCellId);
                 }
@@ -305,13 +261,13 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
                 }
 
             }
-            else if (typeId == starcdBaffleType)
+            else if (typeId == STARCDCore::starcdBaffleType)
             {
                 // baffles have no cellTable entry
                 nBaffles++;
                 maxId = max(maxId, starCellId);
             }
-            else if (typeId == starcdShellType)
+            else if (typeId == STARCDCore::starcdShellType)
             {
                 nShells++;
                 if (!cellTable_.found(cellTableId))
@@ -326,7 +282,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
 
     Info<< "Number of fluids  = " << nFluids << nl
         << "Number of baffles = " << nBaffles << nl;
-    if (keepSolids)
+    if (keepSolids_)
     {
         Info<< "Number of solids  = " << nSolids << nl;
     }
@@ -338,7 +294,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
 
 
     label nCells;
-    if (keepSolids)
+    if (keepSolids_)
     {
         nCells = nFluids + nSolids;
     }
@@ -374,7 +330,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
     else
     {
         IFstream is(inputName);
-        readHeader(is, fileSignature);
+        readHeader(is, STARCDCore::HEADER_CEL);
 
         labelList starLabels(64);
         label lineLabel, shapeId, nLabels, cellTableId, typeId;
@@ -407,7 +363,11 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
             }
 
             // skip solid cells
-            if (typeId == starcdSolidType && !keepSolids)
+            if
+            (
+                typeId == STARCDCore::starcdSolidType
+             && !keepSolids_
+            )
             {
                 continue;
             }
@@ -418,16 +378,16 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
             // fluid/solid cells
             switch (shapeId)
             {
-                case starcdHex:
+                case STARCDCore::starcdHex:
                     curModelPtr = hexModel;
                     break;
-                case starcdPrism:
+                case STARCDCore::starcdPrism:
                     curModelPtr = prismModel;
                     break;
-                case starcdTet:
+                case STARCDCore::starcdTet:
                     curModelPtr = tetModel;
                     break;
-                case starcdPyr:
+                case STARCDCore::starcdPyr:
                     curModelPtr = pyrModel;
                     break;
             }
@@ -471,7 +431,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
                 cellFaces_[celli] = cellShapes_[celli].faces();
                 celli++;
             }
-            else if (shapeId == starcdPoly)
+            else if (shapeId == STARCDCore::starcdPoly)
             {
                 // polyhedral cell
                 label nFaces = starLabels[0] - 1;
@@ -548,7 +508,7 @@ void Foam::fileFormats::STARCDMeshReader::readCells(const fileName& inputName)
                 cellFaces_[celli]   = faces;
                 celli++;
             }
-            else if (typeId == starcdBaffleType)
+            else if (typeId == STARCDCore::starcdBaffleType)
             {
                 // baffles
 
@@ -639,7 +599,6 @@ void Foam::fileFormats::STARCDMeshReader::readBoundary
     const fileName& inputName
 )
 {
-    const word fileSignature = "PROSTAR_BOUNDARY";
     label nPatches = 0, nFaces = 0, nBafflePatches = 0, maxId = 0;
     label lineLabel, starCellId, cellFaceId, starRegion, configNumber;
     word patchType;
@@ -649,15 +608,17 @@ void Foam::fileFormats::STARCDMeshReader::readBoundary
     labelList origRegion(1000, label(0));
     patchTypes_.setSize(1000);
 
-    // this is what we seem to need
-    // these MUST correspond to starToFoamFaceAddr
     //
-    Map<label> faceLookupIndex;
-
-    faceLookupIndex.insert(hexModel->index(), 0);
-    faceLookupIndex.insert(prismModel->index(), 1);
-    faceLookupIndex.insert(tetModel->index(), 2);
-    faceLookupIndex.insert(pyrModel->index(), 3);
+    // Mapping between OpenFOAM and PROSTAR primitives
+    // - needed for face mapping
+    //
+    const Map<label> prostarShapeLookup =
+    {
+        { hexModel->index(),   STARCDCore::starcdHex },
+        { prismModel->index(), STARCDCore::starcdPrism },
+        { tetModel->index(),   STARCDCore::starcdTet },
+        { pyrModel->index(),   STARCDCore::starcdPyr }
+    };
 
     // Pass 1:
     // collect
@@ -675,7 +636,7 @@ void Foam::fileFormats::STARCDMeshReader::readBoundary
 
         if (is.good())
         {
-            readHeader(is, fileSignature);
+            readHeader(is, STARCDCore::HEADER_BND);
 
             while ((is >> lineLabel).good())
             {
@@ -863,7 +824,7 @@ void Foam::fileFormats::STARCDMeshReader::readBoundary
     if (nPatches > 1 && mapToFoamCellId_.size() > 1)
     {
         IFstream is(inputName);
-        readHeader(is, fileSignature);
+        readHeader(is, STARCDCore::HEADER_BND);
 
         while ((is >> lineLabel).good())
         {
@@ -899,11 +860,11 @@ void Foam::fileFormats::STARCDMeshReader::readBoundary
                 // restrict lookup to volume cells (no baffles)
                 if (cellId < cellShapes_.size())
                 {
-                    label index = cellShapes_[cellId].model().index();
-                    if (faceLookupIndex.found(index))
+                    label mapIndex = cellShapes_[cellId].model().index();
+                    if (prostarShapeLookup.found(mapIndex))
                     {
-                        index = faceLookupIndex[index];
-                        cellFaceId = starToFoamFaceAddr[index][cellFaceId];
+                        mapIndex = prostarShapeLookup[mapIndex];
+                        cellFaceId = STARCDCore::starToFoamFaceAddr[mapIndex][cellFaceId];
                     }
                 }
                 else
@@ -1046,10 +1007,20 @@ void Foam::fileFormats::STARCDMeshReader::cullPoints()
 
 bool Foam::fileFormats::STARCDMeshReader::readGeometry(const scalar scaleFactor)
 {
-    readPoints(geometryFile_ + ".vrt", scaleFactor);
-    readCells(geometryFile_ + ".cel");
+    readPoints
+    (
+        starFileName(geometryFile_, STARCDCore::VRT_FILE),
+        scaleFactor
+    );
+    readCells
+    (
+        starFileName(geometryFile_, STARCDCore::CEL_FILE)
+    );
     cullPoints();
-    readBoundary(geometryFile_ + ".bnd");
+    readBoundary
+    (
+        starFileName(geometryFile_, STARCDCore::BND_FILE)
+    );
 
     return true;
 }
@@ -1061,10 +1032,12 @@ Foam::fileFormats::STARCDMeshReader::STARCDMeshReader
 (
     const fileName& prefix,
     const objectRegistry& registry,
-    const scalar scaleFactor
+    const scalar scaleFactor,
+    const bool keepSolids
 )
 :
     meshReader(prefix, scaleFactor),
+    keepSolids_(keepSolids),
     cellShapes_(0),
     mapToFoamPointId_(0),
     mapToFoamCellId_(0)
diff --git a/src/conversion/starcd/STARCDMeshReader.H b/src/conversion/starcd/STARCDMeshReader.H
index 5025a5c11a2437c2e89cbb3d5a856e0b4b586fa6..9288002991546735fd32642f4d50ce03507ba7b7 100644
--- a/src/conversion/starcd/STARCDMeshReader.H
+++ b/src/conversion/starcd/STARCDMeshReader.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,6 +43,7 @@ SourceFiles
 #define STARCDMeshReader_H
 
 #include "meshReader.H"
+#include "STARCDCore.H"
 #include "boundaryRegion.H"
 #include "cellShape.H"
 #include "IFstream.H"
@@ -61,18 +62,27 @@ namespace fileFormats
 
 class STARCDMeshReader
 :
-    public meshReader
+    public meshReader,
+    protected STARCDCore
 {
+    // Private data
 
-protected:
+        //- Retain solid cell types
+        bool keepSolids_;
 
-    // Protected Data
 
-        static const char* const defaultBoundaryName;
-        static const char* const defaultSolidBoundaryName;
+    // Private member functions
+
+        //- Disallow default bitwise copy construct
+        STARCDMeshReader(const STARCDMeshReader&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const STARCDMeshReader&) = delete;
 
-        //- Face addressing from pro-STAR faces -> OpenFOAM faces
-        static const int starToFoamFaceAddr[4][6];
+
+protected:
+
+    // Protected Data
 
         //- Cell shapes
         cellShapeList cellShapes_;
@@ -92,8 +102,8 @@ protected:
         //- Read the mesh from the file(s)
         virtual bool readGeometry(const scalar scaleFactor = 1.0);
 
-        //- Read points from file
-        void readPoints(const fileName&, const scalar scaleFactor);
+        //- Read points from file, return the max prostar id used.
+        label readPoints(const fileName&, const scalar scaleFactor);
 
         //- Read cell connectivities from file
         virtual void readCells(const fileName&);
@@ -107,57 +117,9 @@ protected:
         //- Read auxiliary data from constant/{boundaryRegion,cellTable}
         void readAux(const objectRegistry&);
 
-        //- Read and discard to newline
-        static void readToNewline(IFstream&);
-
-        //- Read header
-        static bool readHeader(IFstream&, word fileSignature);
-
-
-private:
-
-    // Private member functions
-
-        //- Disallow default bitwise copy construct
-        STARCDMeshReader(const STARCDMeshReader&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const STARCDMeshReader&) = delete;
-
-
-protected:
-
-        enum cellType
-        {
-            starcdFluidType   = 1,
-            starcdSolidType   = 2,
-            starcdBaffleType  = 3,
-            starcdShellType   = 4,
-            starcdLineType    = 5,
-            starcdPointType   = 6
-        };
-
-        enum shapeType
-        {
-            starcdPoint = 1,
-            starcdLine  = 2,
-            starcdShell = 3,
-            starcdHex   = 11,
-            starcdPrism = 12,
-            starcdTet   = 13,
-            starcdPyr   = 14,
-            starcdPoly  = 255
-        };
-
 
 public:
 
-    // Static data
-
-        //- Keep solids (default false)
-        static bool keepSolids;
-
-
     // Constructors
 
         //- Construct from case name
@@ -165,12 +127,14 @@ public:
         (
             const fileName& prefix,
             const objectRegistry&,
-            const scalar scaleFactor = 1.0
+            const scalar scaleFactor = 1.0,
+            const bool keepSolids = false
         );
 
 
     //- Destructor
     virtual ~STARCDMeshReader();
+
 };
 
 
diff --git a/src/conversion/starcd/STARCDMeshWriter.C b/src/conversion/starcd/STARCDMeshWriter.C
index 3436fc5a76c33ecf269be571bd3f05b809443339..c4ccf80faa70a339cc053cd3ab6b9a3f67fca1b7 100644
--- a/src/conversion/starcd/STARCDMeshWriter.C
+++ b/src/conversion/starcd/STARCDMeshWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,20 +29,6 @@ License
 #include "SortableList.H"
 #include "OFstream.H"
 
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-const char* Foam::fileFormats::STARCDMeshWriter::defaultBoundaryName =
-    "Default_Boundary_Region";
-
-const Foam::label Foam::fileFormats::STARCDMeshWriter::foamToStarFaceAddr[4][6] =
-{
-    { 4, 5, 2, 3, 0, 1 },     // 11 = pro-STAR hex
-    { 0, 1, 4, 5, 2, -1 },    // 12 = pro-STAR prism
-    { 5, 4, 2, 0, -1, -1 },   // 13 = pro-STAR tetra
-    { 0, 4, 3, 5, 2, -1 }     // 14 = pro-STAR pyramid
-};
-
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 Foam::label Foam::fileFormats::STARCDMeshWriter::findDefaultBoundary() const
@@ -171,66 +157,37 @@ void Foam::fileFormats::STARCDMeshWriter::getCellTable()
 }
 
 
-void Foam::fileFormats::STARCDMeshWriter::writeHeader(Ostream& os, const char* filetype)
-{
-    os  << "PROSTAR_" << filetype << nl
-        << 4000
-        << " " << 0
-        << " " << 0
-        << " " << 0
-        << " " << 0
-        << " " << 0
-        << " " << 0
-        << " " << 0
-        << endl;
-}
-
-
-void Foam::fileFormats::STARCDMeshWriter::writePoints(const fileName& prefix) const
-{
-    OFstream os(prefix + ".vrt");
-    writeHeader(os, "VERTEX");
-
-    // Set the precision of the points data to 10
-    os.precision(10);
-
-    // force decimal point for Fortran input
-    os.setf(std::ios::showpoint);
-
-    const pointField& points = mesh_.points();
-
-    Info<< "Writing " << os.name() << " : "
-        << points.size() << " points" << endl;
-
-    forAll(points, ptI)
-    {
-        // convert [m] -> [mm]
-        os
-            << ptI + 1 << " "
-            << scaleFactor_ * points[ptI].x() << " "
-            << scaleFactor_ * points[ptI].y() << " "
-            << scaleFactor_ * points[ptI].z() << nl;
-    }
-    os.flush();
-
-}
-
-
 void Foam::fileFormats::STARCDMeshWriter::writeCells
 (
     const fileName& prefix
 ) const
 {
-    OFstream os(prefix + ".cel");
-    writeHeader(os, "CELL");
+    OFstream os(starFileName(prefix, STARCDCore::CEL_FILE));
+    writeHeader(os, STARCDCore::HEADER_CEL);
 
     // this is what we seem to need
     // map foam cellModeller index -> star shape
     Map<label> shapeLookupIndex;
-    shapeLookupIndex.insert(hexModel->index(), 11);
-    shapeLookupIndex.insert(prismModel->index(), 12);
-    shapeLookupIndex.insert(tetModel->index(), 13);
-    shapeLookupIndex.insert(pyrModel->index(), 14);
+    shapeLookupIndex.insert
+    (
+        hexModel->index(),
+        STARCDCore::starcdHex
+    );
+    shapeLookupIndex.insert
+    (
+        prismModel->index(),
+        STARCDCore::starcdPrism
+    );
+    shapeLookupIndex.insert
+    (
+        tetModel->index(),
+        STARCDCore::starcdTet
+    );
+    shapeLookupIndex.insert
+    (
+        pyrModel->index(),
+        STARCDCore::starcdPyr
+    );
 
     const cellShapeList& shapes = mesh_.cellShapes();
     const cellList& cells  = mesh_.cells();
@@ -242,30 +199,30 @@ void Foam::fileFormats::STARCDMeshWriter::writeCells
 
     forAll(cells, cellId)
     {
-        label tableId = cellTableId_[cellId];
-        label materialType  = 1;        // 1(fluid)
+        const label tableId = cellTableId_[cellId];
+        label materialType = STARCDCore::starcdFluidType; // 1(fluid)
         if (cellTable_.found(tableId))
         {
             const dictionary& dict = cellTable_[tableId];
-            if (dict.found("MaterialType"))
-            {
-                word matType;
-                dict.lookup("MaterialType") >> matType;
-                if (matType == "solid")
-                {
-                    materialType = 2;
-                }
+            word matType;
 
+            if
+            (
+                dict.readIfPresent("MaterialType", matType)
+             && matType == "solid"
+            )
+            {
+                materialType = STARCDCore::starcdSolidType; // 2(solid)
             }
         }
 
         const cellShape& shape = shapes[cellId];
-        label mapIndex = shape.model().index();
+        const label mapIndex = shape.model().index();
 
         // a registered primitive type
         if (shapeLookupIndex.found(mapIndex))
         {
-            label shapeId = shapeLookupIndex[mapIndex];
+            const label shapeId = shapeLookupIndex[mapIndex];
             const labelList& vrtList = shapes[cellId];
 
             os  << cellId + 1
@@ -288,11 +245,11 @@ void Foam::fileFormats::STARCDMeshWriter::writeCells
                 count++;
             }
             os << endl;
-
         }
         else
         {
-            label shapeId = 255;        // treat as general polyhedral
+            // treat as general polyhedral
+            const label shapeId = STARCDCore::starcdPoly;
             const labelList& cFaces  = cells[cellId];
 
             // create (beg,end) indices
@@ -366,8 +323,8 @@ void Foam::fileFormats::STARCDMeshWriter::writeBoundary
     const fileName& prefix
 ) const
 {
-    OFstream os(prefix + ".bnd");
-    writeHeader(os, "BOUNDARY");
+    OFstream os(starFileName(prefix, STARCDCore::BND_FILE));
+    writeHeader(os, STARCDCore::HEADER_BND);
 
     const cellShapeList& shapes = mesh_.cellShapes();
     const cellList& cells  = mesh_.cells();
@@ -375,20 +332,23 @@ void Foam::fileFormats::STARCDMeshWriter::writeBoundary
     const labelList& owner = mesh_.faceOwner();
     const polyBoundaryMesh& patches = mesh_.boundaryMesh();
 
-    // this is what we seem to need
-    // these MUST correspond to foamToStarFaceAddr
     //
-    Map<label> faceLookupIndex;
-    faceLookupIndex.insert(hexModel->index(), 0);
-    faceLookupIndex.insert(prismModel->index(), 1);
-    faceLookupIndex.insert(tetModel->index(), 2);
-    faceLookupIndex.insert(pyrModel->index(), 3);
+    // Mapping between OpenFOAM and PROSTAR primitives
+    // - needed for face mapping
+    //
+    const Map<label> prostarShapeLookup =
+    {
+        { hexModel->index(),   STARCDCore::starcdHex },
+        { prismModel->index(), STARCDCore::starcdPrism },
+        { tetModel->index(),   STARCDCore::starcdTet },
+        { pyrModel->index(),   STARCDCore::starcdPyr }
+    };
 
     Info<< "Writing " << os.name() << " : "
         << (mesh_.nFaces() - patches[0].start()) << " boundaries" << endl;
 
 
-    label defaultId = findDefaultBoundary();
+    const label defaultId = findDefaultBoundary();
 
     //
     // write boundary faces - skip Default_Boundary_Region entirely
@@ -435,8 +395,8 @@ void Foam::fileFormats::STARCDMeshWriter::writeBoundary
 
             label mapIndex = shape.model().index();
 
-            // a registered primitive type
-            if (faceLookupIndex.found(mapIndex))
+            // A registered primitive type
+            if (prostarShapeLookup.found(mapIndex))
             {
                 const faceList sFaces = shape.faces();
                 forAll(sFaces, sFacei)
@@ -448,8 +408,8 @@ void Foam::fileFormats::STARCDMeshWriter::writeBoundary
                     }
                 }
 
-                mapIndex = faceLookupIndex[mapIndex];
-                cellFaceId = foamToStarFaceAddr[mapIndex][cellFaceId];
+                mapIndex = prostarShapeLookup[mapIndex];
+                cellFaceId = STARCDCore::foamToStarFaceAddr[mapIndex][cellFaceId];
             }
             // Info<< endl;
 
@@ -473,10 +433,12 @@ void Foam::fileFormats::STARCDMeshWriter::writeBoundary
 Foam::fileFormats::STARCDMeshWriter::STARCDMeshWriter
 (
     const polyMesh& mesh,
-    const scalar scaleFactor
+    const scalar scaleFactor,
+    const bool writeBndFile
 )
 :
-    meshWriter(mesh, scaleFactor)
+    meshWriter(mesh, scaleFactor),
+    writeBoundary_(writeBndFile)
 {
     boundaryRegion_.readDict(mesh_);
     cellTable_.readDict(mesh_);
@@ -492,15 +454,6 @@ Foam::fileFormats::STARCDMeshWriter::~STARCDMeshWriter()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::fileFormats::STARCDMeshWriter::rmFiles(const fileName& baseName) const
-{
-    rm(baseName + ".vrt");
-    rm(baseName + ".cel");
-    rm(baseName + ".bnd");
-    rm(baseName + ".inp");
-}
-
-
 bool Foam::fileFormats::STARCDMeshWriter::write(const fileName& meshName) const
 {
     fileName baseName(meshName);
@@ -519,10 +472,25 @@ bool Foam::fileFormats::STARCDMeshWriter::write(const fileName& meshName) const
         }
     }
 
-    rmFiles(baseName);
-    writePoints(baseName);
+    STARCDCore::removeFiles(baseName);
+
+    // points
+    {
+        OFstream os
+        (
+            starFileName(baseName, STARCDCore::VRT_FILE)
+        );
+
+        Info<< "Writing " << os.name() << " : "
+            << mesh_.nPoints() << " points" << endl;
+
+        writePoints(os, mesh_.points(), scaleFactor_);
+    }
+
+    // cells
     writeCells(baseName);
 
+    // boundaries
     if (writeBoundary_)
     {
         writeBoundary(baseName);
diff --git a/src/conversion/starcd/STARCDMeshWriter.H b/src/conversion/starcd/STARCDMeshWriter.H
index 9de8c60490d33ad19897f5a6fe7ced9b1f4cf9a9..2b33eaa20aca6ed4490a708f22de4e4c2aecabed 100644
--- a/src/conversion/starcd/STARCDMeshWriter.H
+++ b/src/conversion/starcd/STARCDMeshWriter.H
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,6 +39,7 @@ SourceFiles
 #define STARCDMeshWriter_H
 
 #include "meshWriter.H"
+#include "STARCDCore.H"
 #include "IOstream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -55,27 +56,17 @@ namespace fileFormats
 
 class STARCDMeshWriter
 :
-    public meshWriter
+    public meshWriter,
+    protected STARCDCore
 {
-    // Private Data
+    // Private data
 
-        static const char* defaultBoundaryName;
+        //- Write boundary (bnd) file - default true
+        bool writeBoundary_;
 
 
     // Private Member Functions
 
-        //- Disallow default bitwise copy construct
-        STARCDMeshWriter(const STARCDMeshWriter&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const STARCDMeshWriter&) = delete;
-
-        //- Pro-STAR 4+ header format
-        static void writeHeader(Ostream&, const char* filetype);
-
-        //- Write points
-        void writePoints(const fileName& baseName) const;
-
         //- Write cells
         void writeCells(const fileName& baseName) const;
 
@@ -87,18 +78,24 @@ class STARCDMeshWriter
         label findDefaultBoundary() const;
 
 
-public:
+        //- Disallow default bitwise copy construct
+        STARCDMeshWriter(const STARCDMeshWriter&) = delete;
 
-    // Static data members
+        //- Disallow default bitwise assignment
+        void operator=(const STARCDMeshWriter&) = delete;
 
-        //- Face addressing from OpenFOAM faces -> pro-STAR faces
-        static const label foamToStarFaceAddr[4][6];
 
+public:
 
     // Constructors
 
         //- Write mesh files in PROSTAR format
-        STARCDMeshWriter(const polyMesh&, const scalar scaleFactor = 1.0);
+        STARCDMeshWriter
+        (
+            const polyMesh&,
+            const scalar scaleFactor = 1.0,
+            const bool writeBndFile = true
+        );
 
 
     //- Destructor
@@ -107,19 +104,13 @@ public:
 
     // Member Functions
 
-        // Edit
-
-            //- Remove STAR-CD files for the baseName
-            void rmFiles(const fileName& baseName) const;
-
-
-        // Write
+    // Write
 
-            //- Write volume mesh
-            virtual bool write
-            (
-                const fileName& meshName = fileName::null
-            ) const;
+        //- Write volume mesh
+        virtual bool write
+        (
+            const fileName& meshName = fileName::null
+        ) const;
 
 };
 
diff --git a/src/conversion/vtk/output/foamVtkOutput.C b/src/conversion/vtk/output/foamVtkOutput.C
new file mode 100644
index 0000000000000000000000000000000000000000..4ece681a85a8c8b8186ce328bfb528983c9c6205
--- /dev/null
+++ b/src/conversion/vtk/output/foamVtkOutput.C
@@ -0,0 +1,126 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkOutput.H"
+#include "foamVtkAsciiFormatter.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::word Foam::foamVtkOutput::legacy::EXT = "vtk";
+
+
+//! \cond fileScope
+static inline std::ostream& legacyDataHeader
+(
+    std::ostream& os,
+    const char* tag,
+    const Foam::label nItems,
+    const Foam::label nFields
+)
+{
+    os  << tag << ' ' << nItems << '\n'
+        << "FIELD attributes " << nFields << '\n';
+
+    return os;
+}
+//! \endcond
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::label Foam::foamVtkOutput::writeVtmFile
+(
+    std::ostream& os,
+    const UList<fileName>& files
+)
+{
+    const word& content = "vtkMultiBlockDataSet";
+
+    foamVtkAsciiFormatter vtmFile(os);
+
+    vtmFile
+        .xmlHeader()
+        .openTag("VTKFile")
+        ( "type",        content )
+        ( "version",     "1.0" )
+        ( "byte_order",  foamVtkFormatter::byteOrder )
+        ( "header_type", foamVtkFormatter::headerType )
+        .closeTag();
+
+    vtmFile.tag(content);
+
+    forAll(files, i)
+    {
+        vtmFile
+            .openTag("DataSet")
+            ( "index", i )
+            ( "file", files[i] )
+            .closeTag(true);
+    }
+
+    vtmFile.endTag(content).endTag("VTKFile");
+
+    return files.size();
+}
+
+
+std::ostream& Foam::foamVtkOutput::legacy::writeHeader
+(
+    std::ostream& os,
+    const std::string& title,
+    const bool binary
+)
+{
+    os  << "# vtk DataFile Version 2.0" << nl
+        << title << nl
+        << (binary ? "BINARY" : "ASCII") << nl;
+
+    return os;
+}
+
+
+std::ostream& Foam::foamVtkOutput::legacy::writeCellDataHeader
+(
+    std::ostream& os,
+    const label nCells,
+    const label nFields
+)
+{
+    return legacyDataHeader(os, "CELL_DATA", nCells, nFields);
+}
+
+
+std::ostream& Foam::foamVtkOutput::legacy::writePointDataHeader
+(
+    std::ostream& os,
+    const label nPoints,
+    const label nFields
+)
+{
+    return legacyDataHeader(os, "POINT_DATA", nPoints, nFields);
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/vtk/output/foamVtkOutput.H b/src/conversion/vtk/output/foamVtkOutput.H
new file mode 100644
index 0000000000000000000000000000000000000000..ad7964bfff7b638f1ff8837088d125feb10506d5
--- /dev/null
+++ b/src/conversion/vtk/output/foamVtkOutput.H
@@ -0,0 +1,216 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkOutput
+
+Description
+    A collection of functions for writing vtk file content.
+
+SourceFiles
+    foamVtkOutput.C
+    foamVtkOutputTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkOutput_H
+#define foamVtkOutput_H
+
+#include "floatScalar.H"
+#include "volFields.H"
+#include "foamVtkFormatter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class foamVtkOutput Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkOutput
+{
+    // Private Member Functions
+
+        //- Disallow construction
+        foamVtkOutput() = delete;
+
+public:
+
+    // Forward declarations
+    class legacy;
+
+
+    // Static Members
+
+        //- Write vtm datasets for specified files
+        static Foam::label writeVtmFile
+        (
+            std::ostream& os,
+            const UList<fileName>& files
+        );
+
+
+        //- Write a value component-wise.
+        template<class Type>
+        inline static void write(foamVtkFormatter&, const Type&);
+
+
+        //- Write a list of values.
+        //  The output does not include the payload size.
+        template<class Type>
+        static void writeList
+        (
+            foamVtkFormatter&,
+            const UList<Type>&
+        );
+
+
+        //- Write a list of values via indirect addressing.
+        //  The output does not include the payload size.
+        template<class Type>
+        static void writeList
+        (
+            foamVtkFormatter&,
+            const UList<Type>&,
+            const UList<label>& addressing
+        );
+
+
+        //- Write volField with cell values (including decomposed cells).
+        //  The output includes the payload size and flush.
+        template<class Type>
+        static void writeField
+        (
+            foamVtkFormatter&,
+            const GeometricField<Type, fvPatchField, volMesh>&,
+            const UList<label>& superCells
+        );
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                    Class foamVtkOutput::legacy Declaration
+\*---------------------------------------------------------------------------*/
+
+//- Basic support for legacy files
+class foamVtkOutput::legacy
+{
+    // Private Member Functions
+
+        //- Disallow construction
+        legacy() = delete;
+
+public:
+
+    // Static data members
+
+        //- file extension for legacy files (vtk)
+        static const Foam::word EXT;
+
+
+    // Static Members
+
+        //- Emit header for legacy file
+        static std::ostream& writeHeader
+        (
+            std::ostream&,
+            const std::string& title,
+            const bool binary = false
+        );
+
+
+        //- Emit header for legacy CELL_DATA
+        static std::ostream& writeCellDataHeader
+        (
+            std::ostream& os,
+            const label nCells,
+            const label nFields
+        );
+
+
+        //- Emit header for legacy POINT_DATA
+        static std::ostream& writePointDataHeader
+        (
+            std::ostream& os,
+            const label nPoints,
+            const label nFields
+        );
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+//- Template specialization for label
+template<>
+inline void Foam::foamVtkOutput::write<label>
+(
+    foamVtkFormatter& fmt,
+    const label& val
+)
+{
+    fmt.write(val);
+}
+
+
+//- Template specialization for float
+template<>
+inline void Foam::foamVtkOutput::write<float>
+(
+    foamVtkFormatter& fmt,
+    const float& val
+)
+{
+    fmt.write(val);
+}
+
+
+//- Template specialization for double
+template<>
+inline void Foam::foamVtkOutput::write<double>
+(
+    foamVtkFormatter& fmt,
+    const double& val
+)
+{
+    fmt.write(val);
+}
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "foamVtkOutputTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H b/src/conversion/vtk/output/foamVtkOutputTemplates.C
similarity index 53%
rename from applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H
rename to src/conversion/vtk/output/foamVtkOutputTemplates.C
index 521ce14f19949d23c77e54d3d5e5713067f26f55..03c2d56bd9d941d97e427b049914698fd179147a 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H
+++ b/src/conversion/vtk/output/foamVtkOutputTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,52 +23,72 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef vtkPV3FoamAddToSelection_H
-#define vtkPV3FoamAddToSelection_H
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// OpenFOAM includes
-#include "IOobjectList.H"
-#include "SortableList.H"
 
-// VTK includes
-#include "vtkDataArraySelection.h"
+template<class Type>
+inline void Foam::foamVtkOutput::write
+(
+    foamVtkFormatter& fmt,
+    const Type& val
+)
+{
+    for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt)
+    {
+        fmt.write(component(val, cmpt));
+    }
+}
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::label Foam::vtkPV3Foam::addToSelection
+void Foam::foamVtkOutput::writeList
 (
-    vtkDataArraySelection *select,
-    const IOobjectList& objectLst,
-    const string& suffix
+    foamVtkFormatter& fmt,
+    const UList<Type>& lst
 )
 {
-    SortableList<word> names(objectLst.names(Type::typeName));
-
-    forAll(names, nameI)
+    forAll(lst, i)
     {
-        if (suffix.size())
-        {
-            select->AddArray
-            (
-                (names[nameI] + suffix).c_str()
-            );
-        }
-        else
-        {
-            select->AddArray
-            (
-                (names[nameI]).c_str()
-            );
-        }
+        write(fmt, lst[i]);
     }
+}
+
 
-    return names.size();
+template<class Type>
+void Foam::foamVtkOutput::writeList
+(
+    foamVtkFormatter& fmt,
+    const UList<Type>& lst,
+    const UList<label>& addressing
+)
+{
+    forAll(addressing, i)
+    {
+        write(fmt, lst[addressing[i]]);
+    }
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+template<class Type>
+void Foam::foamVtkOutput::writeField
+(
+    foamVtkFormatter& fmt,
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const UList<label>& superCells
+)
+{
+    const uint64_t payLoad =
+    (
+        (vf.size() + superCells.size())
+      * pTraits<Type>::nComponents * sizeof(float)
+    );
+
+    fmt.writeSize(payLoad);
+    writeList(fmt, vf.internalField());
+    writeList(fmt, vf, superCells);
+
+    fmt.flush();
+}
 
-#endif
 
 // ************************************************************************* //
diff --git a/src/conversion/vtk/part/foamVtkCells.C b/src/conversion/vtk/part/foamVtkCells.C
new file mode 100644
index 0000000000000000000000000000000000000000..b4c7beacde9d7523af4cd59f61edac03fc6c2590
--- /dev/null
+++ b/src/conversion/vtk/part/foamVtkCells.C
@@ -0,0 +1,649 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 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 "foamVtkCells.H"
+#include "polyMesh.H"
+#include "cellShape.H"
+#include "cellModeller.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::foamVtkCells::correct()
+{
+    // Clear derived data
+    // clearGeom();
+
+    const cellModel& tet      = *(cellModeller::lookup("tet"));
+    const cellModel& pyr      = *(cellModeller::lookup("pyr"));
+    const cellModel& prism    = *(cellModeller::lookup("prism"));
+    const cellModel& wedge    = *(cellModeller::lookup("wedge"));
+    const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
+    const cellModel& hex      = *(cellModeller::lookup("hex"));
+
+    const cellShapeList& cellShapes = mesh_.cellShapes();
+
+    // face owner is needed to determine the face orientation
+    const labelList& owner = mesh_.faceOwner();
+
+    // Unique vertex labels per polyhedral
+    HashSet<label> hashUniqId(2*256);
+
+    // =======================
+    // PASS 1: Determine sizes
+
+    label nVertLabels = 0;
+    label nFaceLabels = 0;
+    label nAddPoints  = 0;
+    label nAddCells   = 0;
+    label nAddVerts   = 0;
+
+    forAll(cellShapes, cellI)
+    {
+        const cellShape& shape = cellShapes[cellI];
+        const cellModel& model = shape.model();
+
+        if
+        (
+            model == tet
+         || model == pyr
+         || model == prism
+         || model == hex
+        )
+        {
+            // normal primitives
+            nVertLabels += shape.size();
+        }
+        else if (model == tetWedge && decompose_.requested())
+        {
+            // Treat as squeezed prism (VTK_WEDGE)
+            nVertLabels += 6;
+        }
+        else if (model == wedge && decompose_.requested())
+        {
+            // Treat as squeezed hex
+            nVertLabels += 8;
+        }
+        else if (decompose_.requested())
+        {
+            // Polyhedral: Decompose into tets + pyramids.
+
+            // Count vertices in first decomposed cell
+            bool first = true;
+
+            const cell& cFaces = mesh_.cells()[cellI];
+            forAll(cFaces, cFaceI)
+            {
+                const face& f = mesh_.faces()[cFaces[cFaceI]];
+
+                // Face decomposed into triangles and quads
+                // Tri -> Tet, Quad -> Pyr
+                label nTria = 0, nQuad = 0;
+                f.nTrianglesQuads(mesh_.points(), nTria, nQuad);
+
+                nAddCells  += nTria + nQuad;
+                nAddVerts  += (nTria * 4) + (nQuad * 5);
+
+                if (first)
+                {
+                    const label nvrt = (nQuad ? 5 : 4);
+                    nAddCells--;
+                    nAddVerts   -= nvrt;
+                    nVertLabels += nvrt;
+
+                    first = false;
+                }
+            }
+
+            ++nAddPoints;
+        }
+        else
+        {
+            // Polyhedral: Not decomposed.
+
+            const labelList& cFaces = mesh_.cells()[cellI];
+
+            // establish unique node ids used (only needed for XML)
+            hashUniqId.clear();
+
+            // determing sizing for face stream
+            // number of faces, size of each face, vertices per face
+            // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...]
+
+            forAll(cFaces, cFaceI)
+            {
+                const face& f = mesh_.faces()[cFaces[cFaceI]];
+                nFaceLabels += f.size();
+
+                forAll(f, fp)
+                {
+                    hashUniqId.insert(f[fp]);
+                }
+            }
+
+            nVertLabels += hashUniqId.size();
+            nFaceLabels += 1 + cFaces.size();
+        }
+    }
+
+
+    //
+    // adjust/reserve sizes
+    //
+
+    // Cell types (including added cells) in vtk numbering
+    cellTypes_.setSize(cellShapes.size() + nAddCells);
+
+    // List of vertex labels in VTK ordering
+    vertLabels_.setSize(nVertLabels + nAddVerts);
+
+    vertOffset_.setSize(cellShapes.size() + nAddCells);
+
+    faceLabels_.clear();
+    faceOffset_.clear();
+    if (nFaceLabels)
+    {
+        faceLabels_.setSize(nFaceLabels);
+
+        // only need nCells (without nAddCells)
+        // set to -1 (primitive)
+        faceOffset_.setSize(cellShapes.size(), -1);
+    }
+
+    if (decompose_.requested())
+    {
+        decompose_.addPointCellLabels_.setSize(nAddPoints);
+        decompose_.superCells_.setSize(nAddCells);
+    }
+
+
+    // ======================
+    // PASS 2: Fill in arrays
+
+    // Need this offset later, but only for decomposed polys
+    const label offsetAddVerts = nVertLabels;
+
+    // Reset counters
+    nVertLabels = 0;
+    nFaceLabels = 0;
+    nAddPoints  = 0;
+    nAddCells   = 0;
+    nAddVerts   = 0;
+
+    forAll(cellShapes, cellI)
+    {
+        const cellShape& shape = cellShapes[cellI];
+        const cellModel& model = shape.model();
+
+        if (model == tet)
+        {
+            cellTypes_[cellI] = foamVtkCore::VTK_TETRA;
+            forAll(shape, i)
+            {
+                vertLabels_[nVertLabels++] = shape[i];
+            }
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (model == pyr)
+        {
+            cellTypes_[cellI] = foamVtkCore::VTK_PYRAMID;
+            forAll(shape, i)
+            {
+                vertLabels_[nVertLabels++] = shape[i];
+            }
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (model == hex)
+        {
+            cellTypes_[cellI] = foamVtkCore::VTK_HEXAHEDRON;
+            forAll(shape, i)
+            {
+                vertLabels_[nVertLabels++] = shape[i];
+            }
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (model == prism)
+        {
+            cellTypes_[cellI] = foamVtkCore::VTK_WEDGE;
+
+            // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5)
+            vertLabels_[nVertLabels++] = shape[0];
+            vertLabels_[nVertLabels++] = shape[2];
+            vertLabels_[nVertLabels++] = shape[1];
+            vertLabels_[nVertLabels++] = shape[3];
+            vertLabels_[nVertLabels++] = shape[5];
+            vertLabels_[nVertLabels++] = shape[4];
+
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (model == tetWedge && decompose_.requested())
+        {
+            // Treat as squeezed prism (VTK_WEDGE)
+            cellTypes_[cellI] = foamVtkCore::VTK_WEDGE;
+
+            vertLabels_[nVertLabels++] = shape[0];
+            vertLabels_[nVertLabels++] = shape[2];
+            vertLabels_[nVertLabels++] = shape[1];
+            vertLabels_[nVertLabels++] = shape[3];
+            vertLabels_[nVertLabels++] = shape[4];
+            vertLabels_[nVertLabels++] = shape[3];
+
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (model == wedge && decompose_.requested())
+        {
+            // Treat as squeezed hex
+            cellTypes_[cellI] = foamVtkCore::VTK_HEXAHEDRON;
+
+            vertLabels_[nVertLabels++] = shape[0];
+            vertLabels_[nVertLabels++] = shape[1];
+            vertLabels_[nVertLabels++] = shape[2];
+            vertLabels_[nVertLabels++] = shape[2];
+            vertLabels_[nVertLabels++] = shape[3];
+            vertLabels_[nVertLabels++] = shape[4];
+            vertLabels_[nVertLabels++] = shape[5];
+            vertLabels_[nVertLabels++] = shape[6];
+
+            vertOffset_[cellI] = nVertLabels;
+        }
+        else if (decompose_.requested())
+        {
+            // Polyhedral cell - decompose into tet/pyr.
+
+            // Ensure we have the correct orientation for the base of the
+            // primitive cell shape.
+            // If the cell is face owner, the orientation needs to be flipped
+            // to avoid defining negative cells.
+            // VTK doesn't seem to care, but we'll do it anyhow for safety.
+
+            // The new vertex from the cell-centre
+            const label newVertexLabel = mesh_.nPoints() + nAddPoints;
+
+            // Mapping from additional point to cell
+            decompose_.addPointCellLabels_[nAddPoints++] = cellI;
+
+            // Whether to insert cell in place of original or not.
+            bool first = true;
+
+            const labelList& cFaces = mesh_.cells()[cellI];
+            forAll(cFaces, cFaceI)
+            {
+                const face& f = mesh_.faces()[cFaces[cFaceI]];
+                const bool isOwner = (owner[cFaces[cFaceI]] == cellI);
+
+                // Count triangles/quads in decomposition
+                label nTria = 0;
+                label nQuad = 0;
+                f.nTrianglesQuads(mesh_.points(), nTria, nQuad);
+
+                // Do actual decomposition
+                faceList faces3(nTria);
+                faceList faces4(nQuad);
+                nTria = 0, nQuad = 0;
+                f.trianglesQuads(mesh_.points(), nTria, nQuad, faces3, faces4);
+
+                forAll(faces4, fci)
+                {
+                    const face& quad = faces4[fci];
+
+                    label celLoc;
+                    label vrtLoc;
+
+                    if (first)
+                    {
+                        celLoc = cellI;
+                        vrtLoc = nVertLabels;
+                        nVertLabels += 5;
+
+                        vertOffset_[celLoc] = nVertLabels;
+                        first = false;
+                    }
+                    else
+                    {
+                        celLoc = mesh_.nCells() + nAddCells;
+                        vrtLoc = offsetAddVerts  + nAddVerts;
+                        nAddVerts += 5;
+
+                        vertOffset_[celLoc] = nAddVerts;
+                        decompose_.superCells_[nAddCells++] = celLoc;
+                    }
+
+                    cellTypes_[celLoc] = foamVtkCore::VTK_PYRAMID;
+
+                    // See note above about the orientation.
+                    if (isOwner)
+                    {
+                        vertLabels_[vrtLoc++] = quad[3];
+                        vertLabels_[vrtLoc++] = quad[2];
+                        vertLabels_[vrtLoc++] = quad[1];
+                        vertLabels_[vrtLoc++] = quad[0];
+                    }
+                    else
+                    {
+                        vertLabels_[vrtLoc++] = quad[0];
+                        vertLabels_[vrtLoc++] = quad[1];
+                        vertLabels_[vrtLoc++] = quad[2];
+                        vertLabels_[vrtLoc++] = quad[3];
+                    }
+
+                    vertLabels_[vrtLoc++] = newVertexLabel;
+                }
+
+                forAll(faces3, fci)
+                {
+                    const face& tria = faces3[fci];
+
+                    label celLoc;
+                    label vrtLoc;
+
+                    if (first)
+                    {
+                        celLoc = cellI;
+                        vrtLoc = nVertLabels;
+                        nVertLabels += 4;
+
+                        vertOffset_[celLoc] = nVertLabels;
+                        first = false;
+                    }
+                    else
+                    {
+                        celLoc = mesh_.nCells() + nAddCells;
+                        vrtLoc = offsetAddVerts + nAddVerts;
+                        nAddVerts += 4;
+
+                        vertOffset_[celLoc] = nAddVerts;
+                        decompose_.superCells_[nAddCells++] = celLoc;
+                    }
+
+                    cellTypes_[celLoc] = foamVtkCore::VTK_TETRA;
+
+                    // See note above about the orientation.
+                    if (isOwner)
+                    {
+                        vertLabels_[vrtLoc++] = tria[2];
+                        vertLabels_[vrtLoc++] = tria[1];
+                        vertLabels_[vrtLoc++] = tria[0];
+                    }
+                    else
+                    {
+                        vertLabels_[vrtLoc++] = tria[0];
+                        vertLabels_[vrtLoc++] = tria[1];
+                        vertLabels_[vrtLoc++] = tria[2];
+                    }
+                    vertLabels_[vrtLoc++] = newVertexLabel;
+                }
+            }
+        }
+        else
+        {
+            // Polyhedral cell - not decomposed
+
+            hashUniqId.clear();  // unique node ids used (only needed for XML)
+
+            // face-stream
+            //   [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...]
+
+            cellTypes_[cellI] = foamVtkCore::VTK_POLYHEDRON;
+            const labelList& cFaces = mesh_.cells()[cellI];
+
+            faceLabels_[nFaceLabels++] = cFaces.size();
+
+            forAll(cFaces, cFaceI)
+            {
+                const face& f = mesh_.faces()[cFaces[cFaceI]];
+                const bool isOwner = (owner[cFaces[cFaceI]] == cellI);
+
+                forAll(f, fp)
+                {
+                    hashUniqId.insert(f[fp]);
+                }
+
+                // number of labels for this face
+                faceLabels_[nFaceLabels++] = f.size();
+
+                if (isOwner)
+                {
+                    forAll(f, fp)
+                    {
+                        faceLabels_[nFaceLabels++] = f[fp];
+                    }
+                }
+                else
+                {
+                    // fairly immaterial if we reverse the list
+                    // or use face::reverseFace()
+                    forAllReverse(f, fp)
+                    {
+                        faceLabels_[nFaceLabels++] = f[fp];
+                    }
+                }
+            }
+
+            faceOffset_[cellI] = nFaceLabels;
+
+            const labelList uniq = hashUniqId.sortedToc();
+            forAll(uniq, i)
+            {
+                vertLabels_[nVertLabels++] = uniq[i];
+            }
+
+            vertOffset_[cellI] = nVertLabels;
+        }
+    }
+
+    // ===========================================
+    // PASS 3: Repair offsets for additional cells
+
+//     Info<<"vertOffset: " << vertOffset_.size() << " VS. " << (mesh_.nCells()) << endl;
+//     Info<<"nAddCells: "  << nAddCells << " VS. " << (mesh_.nCells()) << endl;
+
+    if (nAddCells)
+    {
+        const label beg = mesh_.nCells();
+        const label add = vertOffset_[beg-1];
+
+        for (label i = beg; i < vertOffset_.size(); ++i)
+        {
+            vertOffset_[i] += add;
+        }
+    }
+
+    // Some basic programming/sanity checks
+
+    if ((nVertLabels + nAddVerts) != vertOffset_[mesh_.nCells()-1 + nAddCells])
+    {
+        WarningInFunction
+            << "predicted offsets (" << nVertLabels << " + " << nAddVerts << ") != "
+            << vertOffset_[mesh_.nCells()-1 + nAddCells]
+            << endl;
+    }
+
+    if (offsetAddVerts != vertOffset_[mesh_.nCells()-1])
+    {
+        WarningInFunction
+            << "predicted regular offset " << offsetAddVerts
+            << " != " << vertOffset_[mesh_.nCells()]
+            << endl;
+    }
+
+    // nFaceLabels = 0;
+    // nAddPoints  = 0;
+    // nAddCells   = 0;
+
+    // Pout<<"vertLabels: " << vertLabels_.size() << " vs. " << (nVertLabels + nAddVerts) << endl;
+    // Pout<<"faceLabels: " << faceLabels_.size() << " vs. " << nFaceLabels << endl;
+#if 0
+    if (decompose_.requested())
+    {
+        Pout<< "    Original cells:" << mesh_.nCells()
+            << " points:" << mesh_.nPoints()
+            << " Additional cells:" << decompose_.superCells_.size()
+            << " additional points:" << decompose_.addPointCellLabels_.size()
+            << nl << endl;
+    }
+#endif
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkCells::decomp::decomp(const bool decomposePoly)
+:
+    addPointCellLabels_(),
+    superCells_(),
+    pointMap_(),
+    requested_(decomposePoly)
+{}
+
+
+Foam::foamVtkCells::foamVtkCells
+(
+    const polyMesh& mesh,
+    const bool decomposePoly,
+    const bool lazy
+)
+:
+    mesh_(mesh),
+    cellTypes_(),
+    vertLabels_(),
+    vertOffset_(),
+    faceLabels_(),
+    faceOffset_(),
+    decompose_(decomposePoly),
+    needsUpdate_(true)
+{
+    if (!lazy)
+    {
+        correct();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkCells::decomp::~decomp()
+{}
+
+
+Foam::foamVtkCells::~foamVtkCells()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+void Foam::foamVtkCells::decomp::clear()
+{
+    superCells_.clear();
+    addPointCellLabels_.clear();
+    pointMap_.clear();
+}
+
+
+Foam::label Foam::foamVtkCells::nFieldPoints() const
+{
+    return mesh_.nPoints() + decompose_.addPointCellLabels_.size();
+}
+
+
+Foam::label Foam::foamVtkCells::legacyCellPayLoad() const
+{
+    label payLoad = cellTypes_.size();
+
+    if (faceOffset_.size())
+    {
+        // also has polys with face streams
+
+        label begVert = 0;
+        label begFace = 0;
+
+        forAll(faceOffset_, i)
+        {
+            label endFace = faceOffset_[i];
+            label endVert = vertOffset_[i];
+
+            if (endFace > 0)
+            {
+                // poly with face stream
+                payLoad += endFace - begFace;
+
+                begFace = endFace;
+            }
+            else
+            {
+                // primitive without face stream
+                payLoad += endVert - begVert;
+            }
+            begVert = endVert;
+        }
+    }
+    else if (vertOffset_.size())
+    {
+        // primitives only, trivial
+        payLoad += vertOffset_[vertOffset_.size()-1];
+    }
+
+    return payLoad;
+}
+
+
+bool Foam::foamVtkCells::needsUpdate() const
+{
+    return needsUpdate_;
+}
+
+
+bool Foam::foamVtkCells::expire()
+{
+    // Clear any stored topologies
+
+    // Clear derived data
+    // clearGeom();
+
+    // already marked as expired
+    if (needsUpdate_)
+    {
+        return false;
+    }
+
+    needsUpdate_ = true;
+    return true;
+}
+
+
+bool Foam::foamVtkCells::update()
+{
+    if (!needsUpdate_)
+    {
+        return false;
+    }
+
+    correct();
+
+    needsUpdate_ = false;
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/vtk/part/foamVtkCells.H b/src/conversion/vtk/part/foamVtkCells.H
new file mode 100644
index 0000000000000000000000000000000000000000..692614a4b9b98e272062fb199751cde0c37980be
--- /dev/null
+++ b/src/conversion/vtk/part/foamVtkCells.H
@@ -0,0 +1,350 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 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::foamVtkCells
+
+Description
+    The deep-copy description of an OpenFOAM volume mesh in data structures
+    corresponding to an VTK UnstructuredGrid, including the possiblity of
+    decomposing polyhedral cells into primitive cell types.
+
+    Knowledge of the vtkUnstructuredGrid and the corresponding \c .vtu
+    xml file-format aids in understanding this class.
+    For flexibilty, support for the legacy vtk file-format is also provided.
+
+    Primitive cell types are straighforward, polyhedral cells are represented
+    by a face stream:
+    \verbatim
+        [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...]
+    \endverbatim
+
+    For the legacy format, the face stream is simply passed as vertex labels
+    (connectivity).
+
+    For the xml format, the face stream is saved separately:
+    \verbatim
+        "connectivity"
+        == the unique vertex labels used by the cell (optionally sorted).
+
+        "offsets":
+        == offset + sizeof(connectivity)
+
+        "faces":
+        [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...]
+
+        "faceoffsets":
+        == faceoffsets + sizeof(faces)
+    \endverbatim
+
+    The storage of "connectivity" and "offsets" strongly resembles a
+    CompactListList, but the "offsets" point to the end of the respective
+    sub-lists.
+
+SourceFiles
+    foamVtkCells.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkCells_H
+#define foamVtkCells_H
+
+#include "foamVtkCore.H"
+#include "DynamicList.H"
+#include "SubList.H"
+#include "labelList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+                      Class foamVtkCells Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkCells
+:
+    public fileFormats::foamVtkCore
+{
+public:
+
+    //- Bookkeeping for polyhedral cell decomposition
+    class decomp
+    {
+    private:
+        friend foamVtkCells;
+
+        // Private data
+
+            //- Cell-centre labels for additional points of decomposed cells
+            DynamicList<label> addPointCellLabels_;
+
+            //- Label of original cell for decomposed cells
+            DynamicList<label> superCells_;
+
+            //- Point labels for subsetted meshes
+            DynamicList<label> pointMap_;
+
+            //- Track if decomposition was requested
+            const bool requested_;
+
+
+        // Private Member Functions
+
+            //- Disallow default bitwise copy construct
+            decomp(const decomp&) = delete;
+
+            //- Disallow default bitwise assignment
+            void operator=(const decomp&) = delete;
+
+    public:
+
+        // Constructors
+
+            //- Construct null
+            decomp(const bool decomposePoly = false);
+
+
+        //- Destructor
+        ~decomp();
+
+
+        // Member Functions
+
+        // Access
+
+            //- Polyhedral decomposition requested
+            inline bool requested() const;
+
+            //- Polyhedral decomposition used
+            inline bool used() const;
+
+            //- Label of original cell for decomposed cells
+            inline const labelList& superCells() const;
+
+            //- Cell-centre labels for additional points of decomposed cells
+            inline const labelList& addPointCellLabels() const;
+
+            //- Point labels for subsetted meshes
+            inline const labelList& pointMap() const;
+
+
+        // Edit
+
+            //- Clear
+            void clear();
+    };
+
+
+private:
+
+    // Private data
+
+        //- Reference to underlying mesh or mesh sub-set
+        const polyMesh& mesh_;
+
+        //- Cell types (including added cells) in vtk numbering
+        //  Range is 1-255
+        List<uint8_t> cellTypes_;
+
+        //- Vertices per cell (including added cells) in vtk ordering
+        DynamicList<label> vertLabels_;
+
+        //- Vertices per cell (including added cells) in vtk ordering
+        DynamicList<label> vertOffset_;
+
+        //- Face lists per polyhedral cell
+        DynamicList<label> faceLabels_;
+
+        //- Face label offsets
+        DynamicList<label> faceOffset_;
+
+        //- Bookkeeping for polyhedral cell decomposition
+        decomp decompose_;
+
+        //- Needs update
+        bool needsUpdate_;
+
+
+
+    // Private Member Functions
+
+        //- Create the geometry
+        void correct();
+
+        //- Disallow default bitwise copy construct
+        foamVtkCells(const foamVtkCells&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const foamVtkCells&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components.
+        //  Optionally with polyhedral decomposition and/or lazy evaluation.
+        //  A 'lazy' evaluation avoids fully creation within the constructor.
+        foamVtkCells
+        (
+            const polyMesh&,
+            const bool decomposePoly = false,
+            const bool lazy = false
+        );
+
+
+    //- Destructor
+    ~foamVtkCells();
+
+
+    // Member Functions
+
+        // Access
+
+            //- Query the poly decompose flag.
+            inline bool decomposeRequested() const;
+
+            //- Values for "connectivity" (XML) or basis for "CELLS" (legacy)
+            //  In the legacy format, the size (offset) must be prefixed.
+            inline const labelList& vertLabels() const;
+
+            //- Values for "offsets" (XML)
+            //  or sizes to prefix for for "CELLS" (legacy)
+            inline const labelList& vertOffsets() const;
+
+            //- Values for "types" (XML) and "CELL_TYPES" (legacy)
+            inline const List<uint8_t>& cellTypes() const;
+
+            //- Values for "faces" (XML)
+            inline const labelList& faceLabels() const;
+
+            //- Values for "faceoffsets" (XML)
+            inline const labelList& faceOffsets() const;
+
+            //- Additional point addressing (from added point to original cell)
+            inline const labelList& addPointCellLabels() const;
+
+            //- Additional cells mapping (from added cell to original cell)
+            inline const labelList& superCells() const;
+
+
+            //- Number of field cells
+            inline label nFieldCells() const;
+
+            //- Number of field points
+            label nFieldPoints() const;
+
+            //- The field size for legacy "CELLS".
+            //  In the legacy format, the size (offset) must be prefixed.
+            label legacyCellPayLoad() const;
+
+
+        //- Does the mapping need an update?
+        bool needsUpdate() const;
+
+        //- Mark as needing an update.
+        //  May also free up unneeded data.
+        //  Return false if it was already marked as expired.
+        bool expire();
+
+        //- Update the description (and decomposition) as required.
+        //  Do nothing (and return false) if no update was required
+        bool update();
+
+
+        //- The const_iterator for foamVtkCells
+        class const_iterator
+        {
+            friend class foamVtkCells;
+
+        protected:
+
+            // Protected Data
+
+                //- Reference to parent list
+                const foamVtkCells& parent_;
+
+                //- Element index
+                label index_;
+
+                //- Begin of connectivity sub-list
+                mutable label begVert_;
+
+                //- Begin of faces sub-list
+                mutable label begFace_;
+
+                //- On-demand legacy pointer
+                mutable autoPtr<SubList<label>> legacy_;
+
+
+            // Constructors
+
+                //- Construct begin/end iterator
+                inline const_iterator
+                (
+                    const foamVtkCells&,
+                    bool isEnd = false
+                );
+
+        public:
+
+            // Member operators
+
+                //- On-demand legacy cell labels (primitive or faces)
+                inline const labelUList& legacyCell() const;
+
+                //- Compare position
+                inline bool operator!=(const const_iterator&) const;
+
+                //- Pre-increment iterator
+                inline const_iterator& operator++();
+        };
+
+
+        //- const_iterator set to the beginning
+        inline const_iterator begin() const;
+
+        //- const_iterator set to beyond the end
+        inline const_iterator end() const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "foamVtkCellsI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/vtk/part/foamVtkCellsI.H b/src/conversion/vtk/part/foamVtkCellsI.H
new file mode 100644
index 0000000000000000000000000000000000000000..5973f5113e8de89c3630fa095c201fed966401ca
--- /dev/null
+++ b/src/conversion/vtk/part/foamVtkCellsI.H
@@ -0,0 +1,239 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkCells.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+inline bool Foam::foamVtkCells::decomp::requested() const
+{
+    return requested_;
+}
+
+
+inline bool Foam::foamVtkCells::decomp::used() const
+{
+    return !superCells_.empty();
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::decomp::superCells() const
+{
+    return superCells_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::decomp::addPointCellLabels() const
+{
+    return addPointCellLabels_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::decomp::pointMap() const
+{
+    return pointMap_;
+}
+
+
+inline bool Foam::foamVtkCells::decomposeRequested() const
+{
+    return decompose_.requested();
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::vertLabels() const
+{
+    return vertLabels_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::vertOffsets() const
+{
+    return vertOffset_;
+}
+
+
+inline const Foam::List<uint8_t>&
+Foam::foamVtkCells::cellTypes() const
+{
+    return cellTypes_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::faceLabels() const
+{
+    return faceLabels_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::faceOffsets() const
+{
+    return faceOffset_;
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::addPointCellLabels() const
+{
+    return decompose_.addPointCellLabels();
+}
+
+
+inline const Foam::labelList&
+Foam::foamVtkCells::superCells() const
+{
+    return decompose_.superCells();
+}
+
+
+inline Foam::label
+Foam::foamVtkCells::nFieldCells() const
+{
+    return cellTypes_.size();
+}
+
+
+inline Foam::foamVtkCells::const_iterator
+Foam::foamVtkCells::begin() const
+{
+    return const_iterator(*this);
+}
+
+
+inline Foam::foamVtkCells::const_iterator
+Foam::foamVtkCells::end() const
+{
+    return const_iterator(*this, true);
+}
+
+
+// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
+
+inline Foam::foamVtkCells::const_iterator::const_iterator
+(
+    const foamVtkCells& cells,
+    bool isEnd
+)
+:
+    parent_(cells),
+    index_(0),
+    begVert_(0),
+    begFace_(0),
+    legacy_()
+{
+    if (isEnd)
+    {
+        index_ = parent_.vertOffsets().size();
+    }
+}
+
+
+inline
+Foam::foamVtkCells::const_iterator&
+Foam::foamVtkCells::const_iterator::operator++()
+{
+    ++index_;
+    legacy_.clear();
+
+    return *this;
+}
+
+
+inline
+const Foam::UList<Foam::label>&
+Foam::foamVtkCells::const_iterator::legacyCell() const
+{
+    if
+    (
+        legacy_.valid()
+     || index_ >= parent_.vertOffsets().size()
+    )
+    {
+        return legacy_();
+    }
+
+    const label endVert = parent_.vertOffsets()[index_];
+
+    const label endFace =
+    (
+        parent_.faceOffsets().size()
+      ? parent_.faceOffsets()[index_]
+      : -1
+    );
+
+    if (endFace > 0)
+    {
+        // poly with face stream
+
+        legacy_.reset
+        (
+            new SubList<label>
+            (
+                parent_.faceLabels(),
+                endFace - begFace_,
+                begFace_
+            )
+        );
+
+        begFace_ = endFace;
+    }
+    else
+    {
+        // primitive without face stream
+        legacy_.reset
+        (
+            new SubList<label>
+            (
+                parent_.vertLabels(),
+                endVert - begVert_,
+                begVert_
+            )
+        );
+    }
+
+    begVert_ = endVert;
+
+    return legacy_();
+}
+
+
+inline bool
+Foam::foamVtkCells::const_iterator::operator!=
+(
+    const const_iterator& rhs
+) const
+{
+    return (index_ != rhs.index_);
+}
+
+
+// ************************************************************************* //
diff --git a/src/dynamicMesh/Make/files b/src/dynamicMesh/Make/files
index 215d35048d1e33999822dc8be39d9589a241d232..de8f61296cd77d4c7d1a774f90da81716deffefc 100644
--- a/src/dynamicMesh/Make/files
+++ b/src/dynamicMesh/Make/files
@@ -90,6 +90,7 @@ polyMeshAdder/polyMeshAdder.C
 fvMeshTools/fvMeshTools.C
 
 fvMeshSubset/fvMeshSubset.C
+meshSubsetHelper/meshSubsetHelper.C
 
 motionSmoother/motionSmoother.C
 motionSmoother/motionSmootherAlgo.C
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.C b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.C
similarity index 60%
rename from applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.C
rename to src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.C
index d13a96df3d4753375cdbfc514c4f6571ca82fa2c..0f3760654cb11e43358124b3f66d71f1799f9bbb 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK/vtkMesh.C
+++ b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,56 +23,78 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "vtkMesh.H"
-#include "fvMeshSubset.H"
-#include "Time.H"
+#include "meshSubsetHelper.H"
+
 #include "cellSet.H"
+#include "cellZone.H"
+#include "Time.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::vtkMesh::vtkMesh
+Foam::meshSubsetHelper::meshSubsetHelper
 (
-    fvMesh& baseMesh,
-    const word& setName
+    fvMesh& baseMesh
 )
 :
     baseMesh_(baseMesh),
     subsetter_(baseMesh),
-    setName_(setName)
+    type_(NONE),
+    name_()
 {
-    if (setName.size())
-    {
-        // Read cellSet using whole mesh
-        cellSet currentSet(baseMesh_, setName_);
+    correct();
+}
 
-        // Set current subset
-        subsetter_.setLargeCellSubset(currentSet);
-    }
+
+Foam::meshSubsetHelper::meshSubsetHelper
+(
+    fvMesh& baseMesh,
+    const subsetType type,
+    const word& name
+)
+:
+    baseMesh_(baseMesh),
+    subsetter_(baseMesh),
+    type_(name.empty() ? NONE : type),
+    name_(name)
+{
+    correct();
 }
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::polyMesh::readUpdateState Foam::vtkMesh::readUpdate()
+void Foam::meshSubsetHelper::correct(bool verbose)
 {
-    polyMesh::readUpdateState meshState = baseMesh_.readUpdate();
+    if (type_ == SET)
+    {
+        if (verbose)
+        {
+            Info<< "Subsetting mesh based on cellSet " << name_ << endl;
+        }
 
-    if (meshState != polyMesh::UNCHANGED)
+        cellSet subset(baseMesh_, name_);
+        subsetter_.setLargeCellSubset(subset);
+    }
+    else if (type_ == ZONE)
     {
-        // Note: since fvMeshSubset has no movePoints() functionality,
-        // reconstruct the subset even if only movement.
+        if (verbose)
+        {
+            Info<< "Subsetting mesh based on cellZone " << name_ << endl;
+        }
 
-        topoPtr_.clear();
+        labelHashSet subset(baseMesh_.cellZones()[name_]);
+        subsetter_.setLargeCellSubset(subset, 0);
+    }
+}
 
-        if (setName_.size())
-        {
-            Info<< "Subsetting mesh based on cellSet " << setName_ << endl;
 
-            // Read cellSet using whole mesh
-            cellSet currentSet(baseMesh_, setName_);
+Foam::polyMesh::readUpdateState Foam::meshSubsetHelper::readUpdate()
+{
+    polyMesh::readUpdateState meshState = baseMesh_.readUpdate();
 
-            subsetter_.setLargeCellSubset(currentSet);
-        }
+    if (meshState != polyMesh::UNCHANGED)
+    {
+        correct(true);
     }
 
     return meshState;
diff --git a/src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.H b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.H
new file mode 100644
index 0000000000000000000000000000000000000000..891e6d94a6ed625f6a4416203f7deebb9bdf80dc
--- /dev/null
+++ b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelper.H
@@ -0,0 +1,212 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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/>.
+
+Class
+    Foam::meshSubsetHelper
+
+Description
+    Simple helper to hold a mesh or mesh-subset and provide uniform access.
+
+SourceFiles
+    meshSubsetHelper.C
+    meshSubsetHelperTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef meshSubsetHelper_H
+#define meshSubsetHelper_H
+
+#include "fvMeshSubset.H"
+#include "zeroGradientFvPatchField.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                      Class meshSubsetHelper Declaration
+\*---------------------------------------------------------------------------*/
+
+class meshSubsetHelper
+{
+public:
+
+        //- Internal book-keeping for subset type
+        enum subsetType
+        {
+            NONE,       //<! Not a subset
+            SET,        //<! Using a cellSet for the subset
+            ZONE        //<! Using a cellZone for the subset
+        };
+
+
+    // Private data
+
+        //- Reference to mesh
+        fvMesh& baseMesh_;
+
+        //- Subsetting engine + sub-fvMesh
+        fvMeshSubset subsetter_;
+
+        //- Subset type if any.
+        const subsetType type_;
+
+        //- Name of current cellSet/cellZone (or empty)
+        const word name_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        meshSubsetHelper(const meshSubsetHelper&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const meshSubsetHelper&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        meshSubsetHelper(fvMesh& baseMesh);
+
+        //- Construct from components
+        meshSubsetHelper
+        (
+            fvMesh& baseMesh,
+            const subsetType,
+            const word& name
+        );
+
+
+    // Member Functions
+
+    // Access
+
+        //- The entire base mesh
+        inline const fvMesh& baseMesh() const
+        {
+            return baseMesh_;
+        }
+
+        //- The mesh subsetter
+        inline const fvMeshSubset& subsetter() const
+        {
+            return subsetter_;
+        }
+
+        //- Check if running a sub-mesh is being used
+        inline bool useSubMesh() const
+        {
+            return type_ != NONE;
+        }
+
+        //- Access either mesh or submesh
+        inline const fvMesh& mesh() const
+        {
+            if (useSubMesh())
+            {
+                return subsetter_.subMesh();
+            }
+            else
+            {
+                return baseMesh_;
+            }
+        }
+
+
+    // Edit
+
+        //- Update mesh subset
+        void correct(bool verbose = false);
+
+        //- Read mesh
+        polyMesh::readUpdateState readUpdate();
+
+
+        //- Construct volField (with zeroGradient) from an internal field
+        template<class Type>
+        static tmp<GeometricField<Type, fvPatchField, volMesh>>
+        zeroGradientField
+        (
+            const typename GeometricField
+            <
+                Type,
+                fvPatchField,
+                volMesh
+            >::Internal&
+        );
+
+
+        //- Wrapper for field or the subsetted field.
+        //  Map volume field (does in fact do very little interpolation;
+        //  just copied from fvMeshSubset)
+        template<class Type>
+        tmp<GeometricField<Type, fvPatchField, volMesh>>
+        interpolate
+        (
+            const GeometricField<Type, fvPatchField, volMesh>&
+        ) const;
+
+
+        //- Convert an internal field to a volume field
+        template<class Type>
+        tmp<GeometricField<Type, fvPatchField, volMesh>>
+        interpolate
+        (
+            const typename GeometricField
+            <
+                Type,
+                fvPatchField,
+                volMesh
+            >::Internal&
+        ) const;
+
+
+        //- Map volume field (does in fact do very little interpolation;
+        //  just copied from fvMeshSubset)
+        template<class GeoField>
+        tmp<GeoField> interpolate(const GeoField& fld) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "meshSubsetHelperTemplates.C"
+#endif
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/dynamicMesh/meshSubsetHelper/meshSubsetHelperTemplates.C b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelperTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..25a6d1301b7671324d1b63aacc9f0a5ecf0b98ff
--- /dev/null
+++ b/src/dynamicMesh/meshSubsetHelper/meshSubsetHelperTemplates.C
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "meshSubsetHelper.H"
+#include "fvMesh.H"
+#include "volFields.H"
+#include "globalIndex.H"
+#include "zeroGradientFvPatchField.H"
+
+
+// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
+
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
+Foam::meshSubsetHelper::zeroGradientField
+(
+    const typename GeometricField
+    <
+        Type,
+        fvPatchField,
+        volMesh
+    >::Internal& df
+)
+{
+    IOobject io(df);
+    io.readOpt()  = IOobject::NO_READ;
+    io.writeOpt() = IOobject::NO_WRITE;
+    io.registerObject() = false;
+
+    tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
+    (
+        new GeometricField<Type, fvPatchField, volMesh>
+        (
+            io,
+            df.mesh(),
+            dimensioned<Type>("0", df.dimensions(), Zero),
+            zeroGradientFvPatchField<Type>::typeName
+        )
+    );
+    tvf.ref().primitiveFieldRef() = df;
+    tvf.ref().correctBoundaryConditions();
+
+    return tvf;
+}
+
+
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
+Foam::meshSubsetHelper::interpolate
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf
+) const
+{
+    if (subsetter_.hasSubMesh())
+    {
+        tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
+        (
+            subsetter_.interpolate(vf)
+        );
+        tfld.ref().checkOut();
+        tfld.ref().rename(vf.name());
+        return tfld;
+    }
+    else
+    {
+        return vf;
+    }
+}
+
+
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
+Foam::meshSubsetHelper::interpolate
+(
+    const typename GeometricField
+    <
+        Type,
+        fvPatchField,
+        volMesh
+    >::Internal& df
+) const
+{
+    tmp<GeometricField<Type, fvPatchField, volMesh>> tvf =
+        zeroGradientField<Type>(df);
+
+    if (subsetter_.hasSubMesh())
+    {
+        return interpolate<Type>(tvf());
+    }
+    else
+    {
+        return tvf;
+    }
+}
+
+
+template<class GeoField>
+Foam::tmp<GeoField>
+Foam::meshSubsetHelper::interpolate
+(
+    const GeoField& fld
+) const
+{
+    if (subsetter_.hasSubMesh())
+    {
+        tmp<GeoField> subFld = subsetter_.interpolate(fld);
+        subFld.ref().checkOut();
+        subFld.ref().rename(fld.name());
+        return subFld;
+    }
+    else
+    {
+        return fld;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/edgeMesh/Make/options b/src/edgeMesh/Make/options
index 61439e40e2654c4db581a973662a613ec0624b8f..d488d6522e5113c40833de9767808d3422723db5 100644
--- a/src/edgeMesh/Make/options
+++ b/src/edgeMesh/Make/options
@@ -7,5 +7,4 @@ EXE_INC = \
 LIB_LIBS = \
     -ltriSurface \
     -lmeshTools \
-    -lfileFormats \
     -lsurfMesh
diff --git a/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C b/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
index d58a67c562b0dfb2275384579f8ccc65055e6f26..9a002009a1c84f0bb88d4bf32134570edc983f5a 100644
--- a/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
+++ b/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,7 +37,7 @@ inline void Foam::fileFormats::STARCDedgeFormat::writeLines
     const edgeList& edges
 )
 {
-    writeHeader(os, "CELL");
+    writeHeader(os, STARCDCore::HEADER_CEL);
 
     forAll(edges, edgeI)
     {
@@ -45,10 +45,10 @@ inline void Foam::fileFormats::STARCDedgeFormat::writeLines
         const label cellId = edgeI + 1;
 
         os  << cellId                    // includes 1 offset
-            << ' ' << starcdLineShape_   // 2(line) shape
+            << ' ' << starcdLine         // 2(line) shape
             << ' ' << e.size()
             << ' ' << 401                // arbitrary value
-            << ' ' << starcdLineType_;   // 5(line)
+            << ' ' << starcdLineType;    // 5(line)
 
         os  << nl << "  " << cellId << "  "
             << (e[0]+1) << "  " << (e[1]+1) << nl;
@@ -118,7 +118,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
     // read points from .vrt file
     readPoints
     (
-        IFstream(baseName + ".vrt")(),
+        IFstream(starFileName(baseName, STARCDCore::VRT_FILE))(),
         storedPoints(),
         pointId
     );
@@ -137,7 +137,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
     //
     // read .cel file
     // ~~~~~~~~~~~~~~
-    IFstream is(baseName + ".cel");
+    IFstream is(starFileName(baseName, STARCDCore::CEL_FILE));
     if (!is.good())
     {
         FatalErrorInFunction
@@ -145,7 +145,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
             << exit(FatalError);
     }
 
-    readHeader(is, "PROSTAR_CELL");
+    readHeader(is, STARCDCore::HEADER_CEL);
 
     DynamicList<edge>  dynEdges;
 
@@ -173,7 +173,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
             vertexLabels.append(mapPointId[vrtId]);
         }
 
-        if (typeId == starcdLineType_)
+        if (typeId == starcdLineType)
         {
             if (vertexLabels.size() >= 2)
             {
@@ -239,13 +239,21 @@ void Foam::fileFormats::STARCDedgeFormat::write
 
     fileName baseName = filename.lessExt();
 
-    writePoints(OFstream(baseName + ".vrt")(), pointLst);
-    writeLines(OFstream(baseName + ".cel")(), edgeLst);
+    writePoints
+    (
+        OFstream(starFileName(baseName, STARCDCore::VRT_FILE))(),
+        pointLst
+    );
+    writeLines
+    (
+        OFstream(starFileName(baseName, STARCDCore::CEL_FILE))(),
+        edgeLst
+    );
 
     // write a simple .inp file
     writeCase
     (
-        OFstream(baseName + ".inp")(),
+        OFstream(starFileName(baseName, STARCDCore::INP_FILE))(),
         pointLst,
         edgeLst.size()
     );
diff --git a/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.H b/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.H
index bc5a0ec1bbc96f4aefc533901580a4755443e698..d4c2206ff6c31e0c3dc16144d8ed149168d5edb9 100644
--- a/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.H
+++ b/src/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -62,30 +62,18 @@ namespace fileFormats
 class STARCDedgeFormat
 :
     public edgeMesh,
-    public STARCDCore
+    protected STARCDCore
 {
-    // Private Data
-
-        //- STAR-CD identifier for line shapes (1d elements)
-        static const int starcdLineShape_ = 2;
-
-        //- STAR-CD identifier for line type
-        static const int starcdLineType_  = 5;
-
-
     // Private Member Functions
 
-        static inline void writeLines
-        (
-            Ostream&,
-            const edgeList&
-        );
+        static inline void writeLines(Ostream&, const edgeList&);
+
 
         //- Disallow default bitwise copy construct
-        STARCDedgeFormat(const STARCDedgeFormat&);
+        STARCDedgeFormat(const STARCDedgeFormat&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const STARCDedgeFormat&);
+        void operator=(const STARCDedgeFormat&) = delete;
 
 
 protected:
diff --git a/src/fileFormats/Make/files b/src/fileFormats/Make/files
index 642d53dbade4266c5669ba640d92760bb34bb811..87fd35ee22b3c227489cbc79bad227c58ebc1051 100644
--- a/src/fileFormats/Make/files
+++ b/src/fileFormats/Make/files
@@ -1,6 +1,29 @@
-vtk/vtkUnstructuredReader.C
+ensight/file/ensightCase.C
+ensight/file/ensightCaseOptions.C
+ensight/file/ensightFile.C
+ensight/file/ensightGeoFile.C
+ensight/part/ensightCells.C
+ensight/part/ensightFaces.C
+ensight/read/ensightReadFile.C
+ensight/type/ensightPTraits.C
+
 nas/NASCore.C
+fire/FIRECore.C
 starcd/STARCDCore.C
+stl/STLCore.C
+stl/STLReader.C
+stl/STLReaderASCII.L
+
+vtk/foamVtkCore.C
+vtk/format/foamVtkAppendBase64Formatter.C
+vtk/format/foamVtkAppendRawFormatter.C
+vtk/format/foamVtkAsciiFormatter.C
+vtk/format/foamVtkBase64Formatter.C
+vtk/format/foamVtkLegacyFormatter.C
+vtk/format/foamVtkFormatter.C
+vtk/format/foamVtkOutputOptions.C
+vtk/read/vtkUnstructuredReader.C
+vtk/type/foamVtkPTraits.C
 
 coordSet/coordSet.C
 
@@ -8,7 +31,6 @@ setWriters = sampledSetWriters
 
 $(setWriters)/writers.C
 $(setWriters)/ensight/ensightSetWriterRunTime.C
-$(setWriters)/ensight/ensightPTraits.C
 $(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
 $(setWriters)/jplot/jplotSetWriterRunTime.C
 $(setWriters)/raw/rawSetWriterRunTime.C
diff --git a/src/fileFormats/ensight/file/ensightCase.C b/src/fileFormats/ensight/file/ensightCase.C
new file mode 100644
index 0000000000000000000000000000000000000000..dc803f5f990c393b791286dc55b2e5489d9ce57f
--- /dev/null
+++ b/src/fileFormats/ensight/file/ensightCase.C
@@ -0,0 +1,742 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightCase.H"
+#include "stringListOps.H"
+#include "Time.H"
+#include "cloud.H"
+#include "IOmanip.H"
+#include "globalIndex.H"
+
+#include "ensightFile.H"
+#include "ensightGeoFile.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::ensightCase::dataDirName  = "data";
+const char* Foam::ensightCase::geometryName = "geometry";
+
+
+// * * * * * * * * * * * * * Private Functions * * * * * * * * * * * * * * //
+
+Foam::fileName Foam::ensightCase::dataDir() const
+{
+    return ensightDir_/dataDirName;
+}
+
+
+void Foam::ensightCase::initialize()
+{
+    if (Pstream::master())
+    {
+        // EnSight and EnSight/data directories must exist
+
+        // We may wish to retain old data
+        // eg, convert new results or a particular time interva
+        // OR remove everything
+
+        if (isDir(ensightDir_))
+        {
+            if (options_->overwrite())
+            {
+                Foam::rmDir(ensightDir_);
+            }
+            else
+            {
+                Info<<"Warning: re-using existing directory" << nl
+                    << "    " << ensightDir_ << endl;
+            }
+        }
+
+        // Create ensight and data directories
+        mkDir(dataDir());
+
+        // The case file is always ASCII
+        os_ = new OFstream(ensightDir_/caseName_, IOstream::ASCII);
+
+        // Format options
+        os_->setf(ios_base::left);
+        os_->setf(ios_base::scientific, ios_base::floatfield);
+        os_->precision(5);
+
+        writeHeader();
+    }
+}
+
+
+Foam::label Foam::ensightCase::checkTimeset(const labelHashSet& lookup) const
+{
+    // assume the worst
+    label ts = -1;
+
+    // work on a copy
+    labelHashSet tsTimes(lookup);
+    tsTimes.erase(-1);
+
+    if (tsTimes.empty())
+    {
+        // no times needed
+        ts = 0;
+    }
+    else if (tsTimes.size() == timesUsed_.size())
+    {
+        forAllConstIter(Map<scalar>, timesUsed_, iter)
+        {
+            tsTimes.erase(iter.key());
+        }
+
+        // OR
+        // tsTimes -= timesUsed_.toc();
+        // tsTimes -= timesUsed_;
+
+        if (tsTimes.empty())
+        {
+            ts = 1; // can use timeset 1
+        }
+    }
+
+    return ts;
+}
+
+
+void Foam::ensightCase::writeHeader() const
+{
+    if (os_)  // master only
+    {
+        this->rewind();
+        *os_
+            << "FORMAT" << nl
+            << "type: ensight gold" << nl;
+    }
+}
+
+
+Foam::scalar Foam::ensightCase::writeTimeset() const
+{
+    const label ts = 1;
+
+    const labelList indices = timesUsed_.sortedToc();
+    label count = indices.size();
+
+    // correct for negative starting values
+    scalar timeCorrection = timesUsed_[indices[0]];
+    if (timeCorrection < 0)
+    {
+        timeCorrection = -timeCorrection;
+        Info<< "Correcting time values. Adding " << timeCorrection << endl;
+    }
+    else
+    {
+        timeCorrection = 0;
+    }
+
+
+    *os_
+        << "time set:               " << ts << nl
+        << "number of steps:        " << count << nl;
+
+    if (indices[0] == 0 && indices[count-1] == count-1)
+    {
+        // looks to be contiguous numbering
+        *os_
+            << "filename start number:  " << 0 << nl
+            << "filename increment:     " << 1 << nl;
+    }
+    else
+    {
+        *os_
+            << "filename numbers:" << nl;
+
+        count = 0;
+        forAll(indices, idx)
+        {
+            *os_ << " " << setw(12) << indices[idx];
+
+            if (++count % 6 == 0)
+            {
+                *os_ << nl;
+            }
+        }
+
+        if (count)
+        {
+            *os_ << nl;
+        }
+    }
+
+
+    *os_ << "time values:" << nl;
+
+    count = 0;
+    forAll(indices, idx)
+    {
+        *os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection;
+
+        if (++count % 6 == 0)
+        {
+            *os_ << nl;
+        }
+    }
+    if (count)
+    {
+        *os_ << nl;
+    }
+
+    return timeCorrection;
+}
+
+
+void Foam::ensightCase::writeTimeset
+(
+    const label ts,
+    const labelHashSet& lookup,
+    const scalar timeCorrection
+) const
+{
+    // make a copy
+    labelHashSet hashed(lookup);
+    hashed.erase(-1);
+
+    const labelList indices = hashed.sortedToc();
+    label count = indices.size();
+
+    *os_
+        << "time set:               " << ts << nl
+        << "number of steps:        " << count  << nl
+        << "filename numbers:" << nl;
+
+    count = 0;
+    forAll(indices, idx)
+    {
+        *os_ << " " << setw(12) << indices[idx];
+
+        if (++count % 6 == 0)
+        {
+            *os_ << nl;
+        }
+    }
+
+    if (count)
+    {
+        *os_ << nl;
+    }
+
+    *os_ << "time values:" << nl;
+
+    count = 0;
+    forAll(indices, idx)
+    {
+        *os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection;
+
+        if (++count % 6 == 0)
+        {
+            *os_ << nl;
+        }
+    }
+    if (count)
+    {
+        *os_ << nl;
+    }
+}
+
+
+void Foam::ensightCase::noteGeometry(const bool moving) const
+{
+    if (moving)
+    {
+        geomTimes_.insert(timeIndex_);
+    }
+    else
+    {
+        geomTimes_.insert(-1);
+    }
+
+    changed_ = true;
+}
+
+
+void Foam::ensightCase::noteCloud(const word& cloudName) const
+{
+    if (!cloudVars_.found(cloudName))
+    {
+        cloudVars_.insert(cloudName, HashTable<string>());
+    }
+    cloudTimes_.insert(timeIndex_);
+
+    changed_ = true;
+}
+
+
+void Foam::ensightCase::noteCloud
+(
+    const word& cloudName,
+    const word& varName,
+    const char* ensightType
+) const
+{
+    if (cloudVars_.found(cloudName))
+    {
+        if (cloudVars_[cloudName].insert(varName, ensightType))
+        {
+            changed_ = true;
+        }
+    }
+    else
+    {
+        FatalErrorInFunction
+            << "Tried to add a cloud variable for writing without having added a cloud"
+            << abort(FatalError);
+    }
+}
+
+
+void Foam::ensightCase::noteVariable
+(
+    const word& varName,
+    const char* ensightType
+) const
+{
+    if (variables_.insert(varName, ensightType))
+    {
+        changed_ = true;
+    }
+}
+
+
+Foam::autoPtr<Foam::ensightFile>
+Foam::ensightCase::createDataFile
+(
+    const word& name
+) const
+{
+    autoPtr<ensightFile> output;
+
+    if (Pstream::master())
+    {
+        // the data/ITER subdirectory must exist
+        // Note that data/ITER is indeed a valid ensight::FileName
+        const fileName outdir = dataDir()/padded(timeIndex_);
+        mkDir(outdir);
+
+        output.reset(new ensightFile(outdir, name, format()));
+    }
+
+    return output;
+}
+
+
+Foam::autoPtr<Foam::ensightFile>
+Foam::ensightCase::createCloudFile
+(
+    const word& cloudName,
+    const word& name
+) const
+{
+    autoPtr<Foam::ensightFile> output;
+
+    if (Pstream::master())
+    {
+        // Write
+        // eg -> "data/********/lagrangian/<cloudName>/positions"
+        // or -> "lagrangian/<cloudName>/********/positions"
+        // TODO? check that cloudName is a valid ensight filename
+        const fileName outdir =
+        (
+            separateCloud()
+          ? (ensightDir_ / cloud::prefix / cloudName / padded(timeIndex_))
+          : (dataDir() / padded(timeIndex_) / cloud::prefix / cloudName)
+        );
+
+        mkDir(outdir); // should be unnecessary after newCloud()
+
+        output.reset(new ensightFile(outdir, name, format()));
+    }
+
+    return output;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightCase::ensightCase
+(
+    const fileName& ensightDir,
+    const word& caseName,
+    const ensightCase::options& opts
+)
+:
+    options_(new options(opts)),
+    ensightDir_(ensightDir),
+    caseName_(caseName + ".case"),
+    os_(nullptr),
+    changed_(false),
+    timeIndex_(0),
+    timeValue_(0),
+    timesUsed_(),
+    geomTimes_(),
+    cloudTimes_(),
+    variables_(),
+    cloudVars_()
+{
+    initialize();
+}
+
+
+Foam::ensightCase::ensightCase
+(
+    const fileName& ensightDir,
+    const word& caseName,
+    const IOstream::streamFormat format
+)
+:
+    options_(new options(format)),
+    ensightDir_(ensightDir),
+    caseName_(caseName + ".case"),
+    os_(nullptr),
+    changed_(false),
+    timeIndex_(0),
+    timeValue_(0),
+    timesUsed_(),
+    geomTimes_(),
+    cloudTimes_(),
+    variables_(),
+    cloudVars_()
+{
+    initialize();
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ensightCase::~ensightCase()
+{
+    deleteDemandDrivenData(options_);
+    deleteDemandDrivenData(os_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::ensightCase::nextTime(const scalar value)
+{
+    // use next available index
+    setTime(value, timesUsed_.size());
+}
+
+
+void Foam::ensightCase::nextTime(const instant& t)
+{
+    nextTime(t.value());
+}
+
+
+void Foam::ensightCase::setTime(const scalar value, const label index)
+{
+    timeIndex_ = index;
+    timeValue_ = value;
+
+    if (Pstream::master())
+    {
+        // The data/ITER subdirectory must exist
+        // Note that data/ITER is indeed a valid ensight::FileName
+
+        const fileName outdir = dataDir()/padded(timeIndex_);
+        mkDir(outdir);
+
+        // place a timestamp in the directory for future reference
+        OFstream timeStamp(outdir/"time");
+        timeStamp
+            << "#  index  time" << nl
+            << outdir.name() << ' ' << timeValue_ << nl;
+    }
+
+    // Record of time index/value used
+    timesUsed_.set(index, value);
+}
+
+
+void Foam::ensightCase::setTime(const instant& t, const label index)
+{
+    setTime(t.value(), index);
+}
+
+
+void Foam::ensightCase::write() const
+{
+    if (!os_) return; // master only
+
+    // geometry timeset
+    bool staticGeom = (geomTimes_.size() == 1 && geomTimes_.found(-1));
+    label tsGeom = staticGeom ? 0 : checkTimeset(geomTimes_);
+
+    // cloud timeset
+    label tsCloud = checkTimeset(cloudTimes_);
+
+    // increment time-sets to the correct indices
+    if (tsGeom < 0)
+    {
+        tsGeom = 2;             // next available timeset
+    }
+    if (tsCloud < 0)
+    {
+        tsCloud = tsGeom + 1;   // next available timeset
+    }
+
+    writeHeader();
+
+
+    // data mask: eg "data/******"
+    const fileName dataMask = (dataDirName/mask());
+
+    //
+    // GEOMETRY
+    //
+    if (!geomTimes_.empty() || !cloudTimes_.empty())
+    {
+        // start of variables
+        *os_
+            << nl
+            << "GEOMETRY" << nl;
+    }
+
+    if (staticGeom)
+    {
+        // steady
+        *os_
+            << setw(16)  << "model:"
+            << geometryName
+            << nl;
+    }
+    else if (!geomTimes_.empty())
+    {
+        // moving
+        *os_
+            << Foam::name("model: %-9d", tsGeom)        // width 16
+            << (dataMask/geometryName).c_str()
+            << nl;
+    }
+
+    // clouds and cloud variables
+    const wordList cloudNames = cloudVars_.sortedToc();
+    forAll(cloudNames, cloudNo)
+    {
+        const word& cloudName = cloudNames[cloudNo];
+
+        const fileName masked =
+        (
+            separateCloud()
+          ? (cloud::prefix / cloudName / mask())
+          : (dataMask / cloud::prefix / cloudName)
+        );
+
+        *os_
+            << Foam::name("measured: %-6d", tsCloud)    // width 16
+            << (masked/"positions").c_str()
+            << nl;
+    }
+
+
+    //
+    // VARIABLE
+    //
+    if (variables_.size() || cloudVars_.size())
+    {
+        // start of variables
+        *os_
+            << nl
+            << "VARIABLE" << nl;
+    }
+
+
+    // field variables (always use timeset 1)
+    const wordList varNames = variables_.sortedToc();
+    forAll(varNames, vari)
+    {
+        const word&   varName = varNames[vari];
+        const string& ensType = variables_[varName];
+
+        *os_
+            << ensType.c_str()
+            <<
+            (
+                nodeValues()
+              ? " per node:    1  "  // time-set 1
+              : " per element: 1  "  // time-set 1
+            )
+            << setw(15) << varName << ' '
+            << (dataMask/varName).c_str() << nl;
+    }
+
+
+    // clouds and cloud variables (using cloud timeset)
+    // Write
+    // as -> "data/********/lagrangian/<cloudName>/positions"
+    // or -> "lagrangian/<cloudName>/********/positions"
+    forAll(cloudNames, cloudNo)
+    {
+        const word& cloudName = cloudNames[cloudNo];
+        const fileName masked =
+        (
+            separateCloud()
+          ? (cloud::prefix / cloudName / mask())
+          : (dataMask / cloud::prefix / cloudName)
+        );
+
+        const HashTable<string>& vars = cloudVars_[cloudName];
+        const wordList tocVars = vars.sortedToc();
+
+        forAll(tocVars, vari)
+        {
+            const word&   varName = tocVars[vari];
+            const string& ensType = vars[varName];
+
+            // prefix variables with 'c' (cloud) and cloud index
+            *os_
+                << ensType.c_str() << " per "
+                << Foam::name("measured node: %-5d", tsCloud) // width 20
+                << setw(15)
+                << ("c" + Foam::name(cloudNo) + varName).c_str() << ' '
+                << (masked/varName).c_str()
+                << nl;
+        }
+    }
+
+
+    //
+    // TIME
+    //
+
+    if (!timesUsed_.empty())
+    {
+        *os_
+            << nl << "TIME" << nl;
+
+        // timeset 1
+        const scalar timeCorrection = writeTimeset();
+
+        // timeset geometry
+        if (tsGeom > 1)
+        {
+            writeTimeset(tsGeom, geomTimes_, timeCorrection);
+        }
+
+        // timeset cloud
+        if (tsCloud > 1)
+        {
+            writeTimeset(tsCloud, cloudTimes_, timeCorrection);
+        }
+
+        *os_
+            << "# end" << nl;
+    }
+
+    *os_ << flush;
+    changed_ = false;
+}
+
+
+Foam::autoPtr<Foam::ensightGeoFile>
+Foam::ensightCase::newGeometry
+(
+    const bool moving
+) const
+{
+    autoPtr<Foam::ensightGeoFile> output;
+
+    if (Pstream::master())
+    {
+        // set the path of the ensight file
+        fileName path;
+
+        if (moving)
+        {
+            // Moving mesh: write as "data/********/geometry"
+            path = dataDir()/padded(timeIndex_);
+            mkDir(path);
+        }
+        else
+        {
+            // Static mesh: write as "geometry"
+            path = ensightDir_;
+        }
+
+        output.reset(new ensightGeoFile(path, geometryName, format()));
+
+        noteGeometry(moving);   // note for later use
+    }
+
+    return output;
+}
+
+
+Foam::autoPtr<Foam::ensightFile>
+Foam::ensightCase::newCloud
+(
+    const word& cloudName
+) const
+{
+    autoPtr<Foam::ensightFile> output;
+
+    if (Pstream::master())
+    {
+        output = createCloudFile(cloudName, "positions");
+
+        // tag binary format (just like geometry files)
+        output().writeBinaryHeader();
+
+        // description
+        output().write(cloud::prefix/cloudName);
+        output().newline();
+
+        noteCloud(cloudName);   // note for later use
+    }
+
+    return output;
+}
+
+
+void Foam::ensightCase::rewind() const
+{
+    if (os_)  // master only
+    {
+        os_->stdStream().seekp(0, std::ios_base::beg);
+    }
+}
+
+
+Foam::Ostream& Foam::ensightCase::printInfo(Ostream& os) const
+{
+    os  << "Ensight case:" << nl
+        << "   path: "   << ensightDir_ << nl
+        << "   name: "   << caseName_   << nl
+        << "   format: " << format()    << nl
+        << "   values per " << (nodeValues() ? "node" : "element") << nl;
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H
new file mode 100644
index 0000000000000000000000000000000000000000..e6603d9a104e85a76c8d5258def631282f7c4b21
--- /dev/null
+++ b/src/fileFormats/ensight/file/ensightCase.H
@@ -0,0 +1,405 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ensightCase
+
+Description
+    Supports writing of ensight cases as well as providing common factory
+    methods to open new files.
+
+SourceFiles
+    ensightCase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightCase_H
+#define ensightCase_H
+
+#include "autoPtr.H"
+#include "HashSet.H"
+#include "InfoProxy.H"
+#include "Map.H"
+#include "OSspecific.H"
+#include "Pstream.H"
+
+#include "ensightGeoFile.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class ensightCase;
+class instant;
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                         Class ensightCase Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightCase
+{
+public:
+
+    // Forward declarations
+    class options;
+
+    // Public Data
+
+        //- The name for "data" subdirectory
+        static const char* dataDirName;
+
+        //- The name for geometry files
+        static const char* geometryName;
+
+private:
+
+    // Private data
+
+        //- Case writing options
+        const options* options_;
+
+        //- Output path (absolute)
+        fileName ensightDir_;
+
+        //- Case name (with ".case" ending)
+        word caseName_;
+
+        //- Output stream
+        mutable OFstream* os_;
+
+        //- Track state changes since last write
+        mutable bool changed_;
+
+        //- Time index (timeset 1)
+        label timeIndex_;
+
+        //- Time value (timeset 1)
+        scalar timeValue_;
+
+        //- Record of time index/value used (eg, field values).
+        //  These values will be used for timeset 1.
+        Map<scalar> timesUsed_;
+
+        //- Record time indices when geometry is written.
+        //  These values will be used to decide if timeset 1
+        //  or a separate timeset are used.
+        //  The special index '-1' is used static geometry.
+        mutable labelHashSet geomTimes_;
+
+        //- Record time indices when clouds are written.
+        //  These values will be used to decide if timeset 1
+        //  or a separate timeset are used.
+        mutable labelHashSet cloudTimes_;
+
+        //- Fields/Variables with the ensight type
+        mutable HashTable<string> variables_;
+
+        //- Cloud names and variables
+        mutable HashTable<HashTable<string>> cloudVars_;
+
+
+    // Private Member Functions
+
+        //- The data directory
+        fileName dataDir() const;
+
+        //- Initial file management (master only)
+        void initialize();
+
+        //- Check if timeset uses different times than from time-set 1
+        label checkTimeset(const labelHashSet& lookup) const;
+
+        //- Write the header into the case file.
+        void writeHeader() const;
+
+        //- Write the timeset 1 into the case file.
+        //  Return the time correction in effect
+        scalar writeTimeset() const;
+
+        //- Write the timeset into the case file.
+        void writeTimeset
+        (
+            const label ts,
+            const labelHashSet& lookup,
+            const scalar timeCorrection = 0
+        ) const;
+
+
+        //- Note geometry being used
+        void noteGeometry(const bool moving) const;
+
+        //- Note cloud being used
+        void noteCloud(const word& cloudName) const;
+
+        //- Note cloud/variable being used
+        void noteCloud
+        (
+            const word& cloudName,
+            const word& varName,
+            const char* ensightType
+        ) const;
+
+        //- Note field variable being used
+        void noteVariable
+        (
+            const word& varName,
+            const char* ensightType
+        ) const;
+
+
+        //- Open stream for new data file (on master), using the current index.
+        //  File is without initial description lines.
+        autoPtr<ensightFile> createDataFile(const word&) const;
+
+        //- Open stream for new cloud file (on master).
+        //  File is without initial description lines.
+        autoPtr<ensightFile> createCloudFile
+        (
+            const word& cloudName,
+            const word& name
+        ) const;
+
+
+        //- Disallow default bitwise copy construct
+        ensightCase(const ensightCase&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightCase&) = delete;
+
+
+public:
+
+
+    // Constructors
+
+        //- Construct from components
+        ensightCase
+        (
+            const fileName& ensightDir,
+            const word& caseName,
+            const options& opts
+        );
+
+        //- Construct from components with all default options
+        ensightCase
+        (
+            const fileName& ensightDir,
+            const word& caseName,
+            const IOstream::streamFormat format = IOstream::BINARY
+        );
+
+
+
+    //- Destructor
+    ~ensightCase();
+
+
+    // Member Functions
+
+    // Access
+
+        //- Reference to the case options
+        inline const ensightCase::options& option() const;
+
+        //- Ascii/Binary file output
+        inline IOstream::streamFormat format() const;
+
+        //- The nominal path to the case file
+        inline const fileName& path() const;
+
+        //- The output '*' mask
+        inline const word& mask() const;
+
+        //- Consistent zero-padded integer value
+        inline word padded(const label i) const;
+
+        //- Use values per nodes instead of per element
+        inline bool nodeValues() const;
+
+        //- Write clouds into their own directory instead in "data" directory
+        inline bool separateCloud() const;
+
+
+    // Edit
+
+        //- Set time for time-set 1, using next available index.
+        //  Create corresponding sub-directory.
+        //  Do not mix between nextTime and setTime in an application.
+        void nextTime(const scalar t);
+
+        //- Set time for time-set 1, using next available index.
+        //  Create corresponding sub-directory.
+        //  Do not mix between nextTime and setTime in an application.
+        void nextTime(const instant& t);
+
+        //- Set current index and time for time-set 1.
+        //  Create corresponding sub-directory
+        //  Do not mix between nextTime and setTime in an application.
+        void setTime(const scalar t, const label index);
+
+        //- Set current index and time for time-set 1.
+        //  Create corresponding sub-directory
+        //  Do not mix between nextTime and setTime in an application.
+        void setTime(const instant& t, const label index);
+
+
+    // Addition of entries to case file
+
+        //- Open stream for new geometry file (on master).
+        autoPtr<ensightGeoFile> newGeometry(const bool moving = false) const;
+
+
+        //- Open stream for new cloud positions (on master).
+        //  Note the use of ensightFile, not ensightGeoFile.
+        autoPtr<ensightFile> newCloud
+        (
+            const word& cloudName
+        ) const;
+
+
+        //- Open stream for new data file (on master), using the current index.
+        template<class Type>
+        autoPtr<ensightFile> newData(const word& varName) const;
+
+
+        //- Open stream for new cloud data file (on master), using the current index.
+        template<class Type>
+        autoPtr<ensightFile> newCloudData
+        (
+            const word& cloudName,
+            const word& varName
+        ) const;
+
+
+    // Output
+
+        //- Rewind the output stream (master only).
+        void rewind() const;
+
+        //- Write the case file
+        void write() const;
+
+        //- Output stream (master only).
+        inline Ostream& operator()() const;
+
+        //- Print some general information.
+        Ostream& printInfo(Ostream&) const;
+};
+
+
+//- Configuration options for the ensightCase
+class ensightCase::options
+{
+private:
+
+    //- Ascii/Binary file output
+    IOstream::streamFormat format_;
+
+    //- Width of mask for subdirectories
+    label width_;
+
+    //- The '*' mask appropriate for subdirectories
+    word mask_;
+
+    //- The printf format for zero-padded subdirectory numbers
+    string printf_;
+
+    //- Remove existing directory and sub-directories on creation
+    bool overwrite_;
+
+    //- Write values at nodes
+    bool nodeValues_;
+
+    //- Write clouds into their own directory
+    bool separateCloud_;
+
+public:
+
+    // Constructors
+
+        //- Construct with the specified format (default is binary)
+        options(IOstream::streamFormat format = IOstream::BINARY);
+
+
+    // Member Functions
+
+    // Access
+
+        //- Ascii/Binary file output
+        IOstream::streamFormat format() const;
+
+        //- The '*' mask appropriate for sub-directories
+        const word& mask() const;
+
+        //- Consistent zero-padded integer value
+        word padded(const label i) const;
+
+        //- Return current width of mask and padded.
+        label width() const;
+
+        //- Remove existing directory and sub-directories on creation
+        bool overwrite() const;
+
+        //- Use values per nodes instead of per element
+        bool nodeValues() const;
+
+        //- Write clouds into their own directory instead in "data" directory
+        bool separateCloud() const;
+
+
+    // Edit
+
+        //- Set width of mask and padded.
+        //  Default width is 8 digits, max width is 31 digits.
+        void width(const label i);
+
+        //- Remove existing directory and sub-directories on creation
+        void overwrite(bool);
+
+        //- Use values per nodes instead of per element
+        void nodeValues(bool);
+
+        //- Write clouds into their own directory instead in "data" directory
+        void separateCloud(bool);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightCaseI.H"
+
+#ifdef NoRepository
+    #include "ensightCaseTemplates.C"
+#endif
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/file/ensightCaseI.H b/src/fileFormats/ensight/file/ensightCaseI.H
new file mode 100644
index 0000000000000000000000000000000000000000..b386f677b5b6e596b8d076d0bb3f08975f2adc96
--- /dev/null
+++ b/src/fileFormats/ensight/file/ensightCaseI.H
@@ -0,0 +1,78 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+inline const Foam::ensightCase::options& Foam::ensightCase::option() const
+{
+    return *options_;
+}
+
+
+inline Foam::IOstream::streamFormat Foam::ensightCase::format() const
+{
+    return options_->format();
+}
+
+
+inline const Foam::fileName& Foam::ensightCase::path() const
+{
+    return ensightDir_;
+}
+
+
+inline const Foam::word& Foam::ensightCase::mask() const
+{
+    return options_->mask();
+}
+
+
+inline Foam::word Foam::ensightCase::padded(const label i) const
+{
+    return options_->padded(i);
+}
+
+
+inline bool Foam::ensightCase::nodeValues() const
+{
+    return options_->nodeValues();
+}
+
+
+inline bool Foam::ensightCase::separateCloud() const
+{
+    return options_->separateCloud();
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+inline Foam::Ostream& Foam::ensightCase::operator()() const
+{
+    return *os_;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/file/ensightCaseOptions.C b/src/fileFormats/ensight/file/ensightCaseOptions.C
new file mode 100644
index 0000000000000000000000000000000000000000..7977334466c94fe98d43bf0aa6b38489a6fb0adc
--- /dev/null
+++ b/src/fileFormats/ensight/file/ensightCaseOptions.C
@@ -0,0 +1,129 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightCase.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightCase::options::options(IOstream::streamFormat format)
+:
+    format_(format),
+    width_(0),
+    mask_(),
+    printf_(),
+    overwrite_(false),
+    nodeValues_(false),
+    separateCloud_(false)
+{
+    width(8); // ensures that the mask and printf-format are also resized
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::IOstream::streamFormat Foam::ensightCase::options::format() const
+{
+    return format_;
+}
+
+const Foam::word& Foam::ensightCase::options::mask() const
+{
+    return mask_;
+}
+
+
+Foam::word Foam::ensightCase::options::padded(const label i) const
+{
+    // As per Foam::name, but with fixed length
+    char buf[32];
+
+    ::snprintf(buf, 32, printf_.c_str(), i);
+    buf[31] = 0;
+
+    // no stripping required
+    return word(buf, false);
+}
+
+
+Foam::label Foam::ensightCase::options::width() const
+{
+    return width_;
+}
+
+
+void Foam::ensightCase::options::width(const label n)
+{
+    // enforce min/max sanity limits
+    if (n < 1 || n > 31)
+    {
+        return;
+    }
+
+    // set mask accordingly
+    mask_.resize(n, '*');
+
+    // appropriate printf format
+    printf_ = "%0" + Foam::name(n) + "d";
+}
+
+
+
+bool Foam::ensightCase::options::overwrite() const
+{
+    return overwrite_;
+}
+
+
+void Foam::ensightCase::options::overwrite(bool b)
+{
+    overwrite_ = b;
+}
+
+
+bool Foam::ensightCase::options::nodeValues() const
+{
+    return nodeValues_;
+}
+
+
+void Foam::ensightCase::options::nodeValues(bool b)
+{
+    nodeValues_ = b;
+}
+
+
+bool Foam::ensightCase::options::separateCloud() const
+{
+    return separateCloud_;
+}
+
+
+void Foam::ensightCase::options::separateCloud(bool b)
+{
+    separateCloud_ = b;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/file/ensightCaseTemplates.C b/src/fileFormats/ensight/file/ensightCaseTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..48d7c03ec37e28de08a134aefded863721cd9869
--- /dev/null
+++ b/src/fileFormats/ensight/file/ensightCaseTemplates.C
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "cloud.H"
+#include "ensightPTraits.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+template<class Type>
+Foam::autoPtr<Foam::ensightFile>
+Foam::ensightCase::newData
+(
+    const word& name
+) const
+{
+    autoPtr<ensightFile> output;
+
+    if (Pstream::master())
+    {
+        const ensight::VarName varName(name);
+        output = createDataFile(varName);
+
+        // description
+        output().write
+        (
+            string
+            (
+                padded(timeIndex_) / varName
+              + " <" + pTraits<Type>::typeName + ">"
+            )
+        );
+        output().newline();
+
+        // note variable for later use
+        noteVariable(varName, ensightPTraits<Type>::typeName);
+    }
+
+    return output;
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::ensightFile>
+Foam::ensightCase::newCloudData
+(
+    const word& cloudName,
+    const word& name
+) const
+{
+    autoPtr<Foam::ensightFile> output;
+
+    if (Pstream::master())
+    {
+        const ensight::VarName varName(name);
+        output = createCloudFile(cloudName, varName);
+
+        // description
+        output().write
+        (
+            string
+            (
+                padded(timeIndex_) / cloudName / varName
+              + " <" + pTraits<Type>::typeName + ">"
+            )
+        );
+        output().newline();
+
+        // note cloud variable for later use
+        noteCloud(cloudName, varName, ensightPTraits<Type>::typeName);
+    }
+
+    return output;
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/file/ensightFile.C b/src/fileFormats/ensight/file/ensightFile.C
similarity index 84%
rename from src/conversion/ensight/file/ensightFile.C
rename to src/fileFormats/ensight/file/ensightFile.C
index 05003b2a0029dc54cb5661ecfc6ee04c1e4dbc3a..b106c6ecf4cbc22b7b6577929ef7a45bbfd9fab2 100644
--- a/src/conversion/ensight/file/ensightFile.C
+++ b/src/fileFormats/ensight/file/ensightFile.C
@@ -25,6 +25,7 @@ License
 
 #include "ensightFile.H"
 #include "error.H"
+#include "UList.H"
 
 #include <cstring>
 #include <sstream>
@@ -307,4 +308,76 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader()
 }
 
 
+//
+// Convenience Output Methods
+//
+
+void Foam::ensightFile::beginPart(const label index)
+{
+    write("part");
+    newline();
+    write(index+1); // Ensight starts with 1
+    newline();
+}
+
+
+void Foam::ensightFile::beginParticleCoordinates(const label nparticles)
+{
+    write("particle coordinates");
+    newline();
+    write(nparticles, 8); // unusual width
+    newline();
+}
+
+
+void Foam::ensightFile::writeList
+(
+    const UList<scalar>& field
+)
+{
+    forAll(field, i)
+    {
+        if (std::isnan(field[i]))
+        {
+            writeUndef();
+        }
+        else
+        {
+            write(field[i]);
+        }
+
+        newline();
+    }
+}
+
+
+void Foam::ensightFile::writeList
+(
+    const UList<scalar>& field,
+    const labelUList& idList
+)
+{
+    if (notNull(idList))
+    {
+        forAll(idList, i)
+        {
+            if (idList[i] >= field.size() || std::isnan(field[idList[i]]))
+            {
+                writeUndef();
+            }
+            else
+            {
+                write(field[idList[i]]);
+            }
+
+            newline();
+        }
+    }
+    else
+    {
+        // no idList => perNode
+        writeList(field);
+    }
+}
+
 // ************************************************************************* //
diff --git a/src/conversion/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H
similarity index 85%
rename from src/conversion/ensight/file/ensightFile.H
rename to src/fileFormats/ensight/file/ensightFile.H
index 03cbdcd7032503bb33039ffc9d879ead298ab2d1..78b09904e10bb6429004f55a9ea84c84509ceb45 100644
--- a/src/conversion/ensight/file/ensightFile.H
+++ b/src/fileFormats/ensight/file/ensightFile.H
@@ -38,6 +38,7 @@ Description
 
 #include "ensightFileName.H"
 #include "ensightVarName.H"
+#include "UList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -80,9 +81,13 @@ class ensightFile
 
 public:
 
-    // Forward declarations
-    class FileName;
-    class VarName;
+    // Static Member Functions
+
+        //- Return a null ensightFile
+        inline static const ensightFile& null()
+        {
+            return NullObjectRef<ensightFile>();
+        }
 
 
     // Constructors
@@ -172,6 +177,28 @@ public:
 
         //- Add carriage return to ascii stream
         void newline();
+
+
+    // Convenience Output Methods
+
+        //- Begin a part (0-based index).
+        void beginPart(const label index);
+
+        //- Begin a "particle coordinates" block (measured data)
+        void beginParticleCoordinates(const label nparticles);
+
+        //- Write a list of floats as "%12.5e" or as binary
+        //  With carriage return after each value (ascii stream)
+        void writeList(const UList<scalar>& field);
+
+        //- Write an indirect list of scalars as "%12.5e" or as binary
+        //  With carriage return after each value (ascii stream)
+        void writeList
+        (
+            const UList<scalar>& field,
+            const labelUList& idList
+        );
+
 };
 
 
diff --git a/src/conversion/ensight/file/ensightGeoFile.C b/src/fileFormats/ensight/file/ensightGeoFile.C
similarity index 76%
rename from src/conversion/ensight/file/ensightGeoFile.C
rename to src/fileFormats/ensight/file/ensightGeoFile.C
index 0119087e70f9dd17f8c009991a02ed20eeb88d92..27ce98282f764efd8d83adf4022c2ddd1955fb1a 100644
--- a/src/conversion/ensight/file/ensightGeoFile.C
+++ b/src/fileFormats/ensight/file/ensightGeoFile.C
@@ -35,17 +35,25 @@ License
 
 void Foam::ensightGeoFile::initialize()
 {
+    writeBinaryHeader();
+
+    // Description line 1
+    write("Ensight Geometry File");
+    newline();
+
+    // Description line 2
     #ifdef OPENFOAM_PLUS
-    string desc2("Written by OpenFOAM+ " STRING_QUOTE(OPENFOAM_PLUS));
+    write(string("Written by OpenFOAM+ " STRING_QUOTE(OPENFOAM_PLUS)));
     #else
-    string desc2("Written by OpenFOAM-" + string(Foam::FOAMversion));
+    write(string("Written by OpenFOAM-" + string(Foam::FOAMversion)));
     #endif
 
-    writeBinaryHeader();
-    write("Ensight Geometry File");  newline(); // description line 1
-    write(desc2);                    newline(); // description line 2
-    write("node id assign");         newline();
-    write("element id assign");      newline();
+    newline();
+    write("node id assign");
+    newline();
+
+    write("element id assign");
+    newline();
 }
 
 
@@ -87,10 +95,36 @@ Foam::ensightGeoFile::~ensightGeoFile()
 Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key)
 {
     // ensure we get ensightFile::write(const string&)
-    write(static_cast<const string&>(key)); newline();
+    write(static_cast<const string&>(key));
+    newline();
 
     return *this;
 }
 
 
+//
+// Convenience Output Methods
+//
+
+void Foam::ensightGeoFile::beginPart
+(
+    const label index,
+    const string& description
+)
+{
+    beginPart(index);
+    write(description);
+    newline();
+}
+
+
+void Foam::ensightGeoFile::beginCoordinates(const label npoints)
+{
+    write("coordinates");
+    newline();
+    write(npoints);
+    newline();
+}
+
+
 // ************************************************************************* //
diff --git a/src/conversion/ensight/file/ensightGeoFile.H b/src/fileFormats/ensight/file/ensightGeoFile.H
similarity index 85%
rename from src/conversion/ensight/file/ensightGeoFile.H
rename to src/fileFormats/ensight/file/ensightGeoFile.H
index 75cef26cd98407f5df7554c8e8c7ada04b37cc75..6b60c6e419554e12a5c4bfb404bd2493c06f95cc 100644
--- a/src/conversion/ensight/file/ensightGeoFile.H
+++ b/src/fileFormats/ensight/file/ensightGeoFile.H
@@ -61,6 +61,15 @@ class ensightGeoFile
 
 public:
 
+    // Static Member Functions
+
+        //- Return a null ensightGeoFile
+        inline static const ensightGeoFile& null()
+        {
+            return NullObjectRef<ensightGeoFile>();
+        }
+
+
     // Constructors
 
         //- Construct from pathname.
@@ -89,6 +98,18 @@ public:
 
         //- Write keyword with trailing newline
         virtual Ostream& writeKeyword(const keyType& key);
+
+
+    // Convenience Output Methods
+
+        using ensightFile::beginPart;
+
+        //- Begin a "part" (0-based index), with a description.
+        void beginPart(const label index, const string& description);
+
+        //- Begin a "coordinates" block
+        void beginCoordinates(const label npoints);
+
 };
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/conversion/ensight/name/ensightFileName.H b/src/fileFormats/ensight/name/ensightFileName.H
similarity index 88%
rename from src/conversion/ensight/name/ensightFileName.H
rename to src/fileFormats/ensight/name/ensightFileName.H
index 550a86f68c4d7745bcea4611358f24c47ebcaeb7..1452730107ae2772e89bf972f2ead996cc1c74d5 100644
--- a/src/conversion/ensight/name/ensightFileName.H
+++ b/src/fileFormats/ensight/name/ensightFileName.H
@@ -28,7 +28,7 @@ Description
     Specification of a valid Ensight file-name.
 
     Spaces must be quoted,
-    no '*' wildcards, not '%' (structured block continuation).
+    no '*' wildcards, no '%' (structured block continuation).
 
     Overall line length within case file is limited to 1024, but this is not
     yet addresssed.
@@ -80,15 +80,16 @@ public:
         //- Is this character valid for an ensight file-name
         inline static bool valid(char);
 
+
     // Member operators
 
-        // Assignment
+    // Assignment (disabled)
 
-            void operator=(const fileName&) = delete;
-            void operator=(const word&) = delete;
-            void operator=(const string&) = delete;
-            void operator=(const std::string&) = delete;
-            void operator=(const char*) = delete;
+        void operator=(const fileName&) = delete;
+        void operator=(const word&) = delete;
+        void operator=(const string&) = delete;
+        void operator=(const std::string&) = delete;
+        void operator=(const char*) = delete;
 
 };
 
diff --git a/src/conversion/ensight/name/ensightFileNameI.H b/src/fileFormats/ensight/name/ensightFileNameI.H
similarity index 100%
rename from src/conversion/ensight/name/ensightFileNameI.H
rename to src/fileFormats/ensight/name/ensightFileNameI.H
diff --git a/src/conversion/ensight/name/ensightVarName.H b/src/fileFormats/ensight/name/ensightVarName.H
similarity index 92%
rename from src/conversion/ensight/name/ensightVarName.H
rename to src/fileFormats/ensight/name/ensightVarName.H
index fe2c57aefbf50812b36e107c790c3e28a14db959..2ffff6ae193f930adeb188716cbdd38dee2c0cf9 100644
--- a/src/conversion/ensight/name/ensightVarName.H
+++ b/src/fileFormats/ensight/name/ensightVarName.H
@@ -63,10 +63,8 @@ class VarName
         //- Strip invalid characters
         inline void stripInvalid();
 
-
 public:
 
-
     // Constructors
 
         //- Construct as copy
@@ -87,12 +85,11 @@ public:
 
     // Member operators
 
-        // Assignment
-
-            void operator=(const word&) = delete;
-            void operator=(const string&) = delete;
-            void operator=(const std::string&) = delete;
-            void operator=(const char*) = delete;
+    // Assignment (disabled)
+        void operator=(const word&) = delete;
+        void operator=(const string&) = delete;
+        void operator=(const std::string&) = delete;
+        void operator=(const char*) = delete;
 
 };
 
diff --git a/src/conversion/ensight/name/ensightVarNameI.H b/src/fileFormats/ensight/name/ensightVarNameI.H
similarity index 100%
rename from src/conversion/ensight/name/ensightVarNameI.H
rename to src/fileFormats/ensight/name/ensightVarNameI.H
diff --git a/src/fileFormats/ensight/part/ensightCells.C b/src/fileFormats/ensight/part/ensightCells.C
new file mode 100644
index 0000000000000000000000000000000000000000..8db55a927ab557891357aa8726d9cfb3e0b8484d
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightCells.C
@@ -0,0 +1,288 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightCells.H"
+#include "error.H"
+#include "polyMesh.H"
+#include "cellModeller.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::label Foam::ensightCells::nTypes = 5;
+
+namespace Foam
+{
+    template<>
+    const char* Foam::NamedEnum
+    <
+        Foam::ensightCells::elemType,
+        5
+    >::names[] = { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
+}
+
+const Foam::NamedEnum<Foam::ensightCells::elemType, 5>
+    Foam::ensightCells::elemEnum;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+inline Foam::label Foam::ensightCells::offset
+(
+    const enum elemType what,
+    const label i
+) const
+{
+    label n = i;
+    for (label typeI = 0; typeI < label(what); ++typeI)
+    {
+        n += sizes_[typeI];
+    }
+
+    return n;
+}
+
+
+void Foam::ensightCells::resize()
+{
+    // overall required size
+    label n = 0;
+    forAll(sizes_, typeI)
+    {
+        n += sizes_[typeI];
+    }
+    address_.setSize(n, Zero);
+
+    // assign corresponding sub-lists
+    n = 0;
+    forAll(sizes_, typeI)
+    {
+        deleteDemandDrivenData(lists_[typeI]);
+
+        lists_[typeI] = new SubList<label>(address_, sizes_[typeI], n);
+
+        n += sizes_[typeI];
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightCells::ensightCells(const label partIndex)
+:
+    index_(partIndex),
+    address_(),
+    sizes_(Zero),
+    lists_()
+{
+    // Ensure sub-lists are properly initialized to nullptr
+    forAll(lists_, typeI)
+    {
+        lists_[typeI] = nullptr;
+    }
+
+    resize();   // adjust allocation
+}
+
+
+Foam::ensightCells::ensightCells(const ensightCells& obj)
+:
+    index_(obj.index_),
+    address_(obj.address_),
+    sizes_(),
+    lists_()
+{
+    // Ensure sub-lists are properly initialized to nullptr
+    forAll(lists_, typeI)
+    {
+        lists_[typeI] = nullptr;
+    }
+
+    // Total (reduced) sizes
+    FixedList<label, 5> totSizes = obj.sizes_;
+
+    // Local sizes
+    this->sizes_ = obj.sizes();
+
+    resize();   // adjust allocation
+
+    // Restore total (reduced) sizes
+    this->sizes_ = totSizes;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ensightCells::~ensightCells()
+{
+    forAll(lists_, typeI)
+    {
+        deleteDemandDrivenData(lists_[typeI]);
+    }
+    address_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
+{
+    FixedList<label, 5> count;
+    forAll(lists_, typeI)
+    {
+        count[typeI] = lists_[typeI]->size();
+    }
+
+    return count;
+}
+
+
+Foam::label Foam::ensightCells::total() const
+{
+    label n = 0;
+    forAll(sizes_, typeI)
+    {
+        n += sizes_[typeI];
+    }
+    return n;
+}
+
+
+void Foam::ensightCells::clear()
+{
+    sizes_ = Zero;  // reset sizes
+    resize();
+}
+
+
+void Foam::ensightCells::reduce()
+{
+    forAll(sizes_, typeI)
+    {
+        sizes_[typeI] = lists_[typeI]->size();
+        Foam::reduce(sizes_[typeI], sumOp<label>());
+    }
+}
+
+
+void Foam::ensightCells::sort()
+{
+    forAll(lists_, typeI)
+    {
+        if (lists_[typeI])
+        {
+            Foam::sort(*(lists_[typeI]));
+        }
+    }
+}
+
+
+void Foam::ensightCells::classify
+(
+    const polyMesh& mesh,
+    const labelUList& addressing
+)
+{
+    // References to cell shape models
+    const cellModel& tet   = *(cellModeller::lookup("tet"));
+    const cellModel& pyr   = *(cellModeller::lookup("pyr"));
+    const cellModel& prism = *(cellModeller::lookup("prism"));
+    const cellModel& hex   = *(cellModeller::lookup("hex"));
+
+    const cellShapeList& shapes = mesh.cellShapes();
+
+    const bool indirect = notNull(addressing);
+    const label sz = indirect ? addressing.size() : mesh.nCells();
+
+    // Count the shapes
+    // Can avoid double looping, but only at the expense of allocation
+
+    sizes_ = Zero;  // reset sizes
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        const label id = indirect ? addressing[listI] : listI;
+        const cellModel& model = shapes[id].model();
+
+        enum elemType what = NFACED;
+        if (model == tet)
+        {
+            what = TETRA4;
+        }
+        else if (model == pyr)
+        {
+            what = PYRAMID5;
+        }
+        else if (model == prism)
+        {
+            what = PENTA6;
+        }
+        else if (model == hex)
+        {
+            what = HEXA8;
+        }
+
+        sizes_[what]++;
+    }
+
+    resize();       // adjust allocation
+    sizes_ = Zero;  // reset sizes
+
+    // Assign cell-id per shape type
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        const label id = indirect ? addressing[listI] : listI;
+        const cellModel& model = shapes[id].model();
+
+        enum elemType what = NFACED;
+        if (model == tet)
+        {
+            what = TETRA4;
+        }
+        else if (model == pyr)
+        {
+            what = PYRAMID5;
+        }
+        else if (model == prism)
+        {
+            what = PENTA6;
+        }
+        else if (model == hex)
+        {
+            what = HEXA8;
+        }
+
+        // eg, the processor local cellId
+        lists_[what]->operator[](sizes_[what]++) = id;
+    }
+}
+
+
+Foam::label Foam::ensightCells::offset(const enum elemType what) const
+{
+    return offset(what, 0);
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightCells.H b/src/fileFormats/ensight/part/ensightCells.H
new file mode 100644
index 0000000000000000000000000000000000000000..a84de2ce9c27ea66951c84932976f079b8e20b42
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightCells.H
@@ -0,0 +1,206 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ensightCells
+
+Description
+    Sorting/classification of cells (3D) into corresponding ensight element
+    types.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightCells_H
+#define ensightCells_H
+
+#include "labelList.H"
+#include "FixedList.H"
+#include "SubList.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+                        Class ensightCells Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightCells
+{
+public:
+
+    // Public data
+
+        //- Addressable ensight element types
+        enum elemType
+        {
+            TETRA4,
+            PYRAMID5,
+            PENTA6,
+            HEXA8,
+            NFACED
+        };
+
+        //- Number of element types (5)
+        static const label nTypes;
+
+        //- The Ensight names for each element type
+        static const NamedEnum<elemType, 5> elemEnum;
+
+
+    // Static Member Functions
+
+        //- Return the ensight element name for the specified type
+        inline static const char* key(const enum elemType);
+
+
+private:
+
+    // Private data
+
+        //- Location within a list.
+        //  The ensight part number is typically this value +1.
+        label index_;
+
+        //- Linear list of ids, sub-sectioned per element type via SubLists
+        labelList address_;
+
+        //- List of sizes for each element type
+        FixedList<label, 5> sizes_;
+
+        //- List of ids for each element type
+        //  Managed via pointers, since a SubList cannot be relocated/resized.
+        FixedList<SubList<label>*, 5> lists_;
+
+
+    // Private Member Functions
+
+        //- Low-level offset routine
+        inline label offset(const enum elemType what, const label i) const;
+
+        //- Use current sizes to redimension the element lists
+        void resize();
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightCells&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null, optionally with index
+        ensightCells(label partIndex = 0);
+
+        //- Copy constructor. Needed for lists etc.
+        ensightCells(const ensightCells&);
+
+
+    //- Destructor
+    ~ensightCells();
+
+
+    // Member Functions
+
+    // Access
+
+        //- The index in a list.
+        inline label index() const;
+
+        //- The index in a list, non-const access.
+        inline label& index();
+
+        //- The processor local size of all elements.
+        inline label size() const;
+
+        //- The global number of the specified element type.
+        //  This value is only meaningful after a reduce operation.
+        inline label total(const enum elemType) const;
+
+        //- The global number of all element types.
+        //  This value is only meaningful after a reduce operation.
+        label total() const;
+
+        //- The processor local sizes per element type.
+        FixedList<label, 5> sizes() const;
+
+        //- The global numbers per element type.
+        //  This value is only meaningful after a reduce operation.
+        inline const FixedList<label, 5>& totals() const;
+
+
+        //- Return the (local) cell ids of the specified element type
+        inline const labelUList& cellIds(const enum elemType) const;
+
+        //- Return the cell ids of all elements
+        inline const labelUList& cellIds() const;
+
+        //- Starting offset of element type.
+        label offset(const enum elemType what) const;
+
+
+    // Edit
+
+        //- Classify cell types and set the element lists.
+        //  The optional indirect addressing can be used when classifying
+        //  groups of cells (eg, from a cellZone etc).
+        void classify
+        (
+            const polyMesh&,
+            const labelUList& addressing = labelUList::null()
+        );
+
+
+        //- Set addressable sizes to zero, free up addressing memory.
+        void clear();
+
+        //- Sum element counts across all processes.
+        void reduce();
+
+        //- Sort element lists numerically.
+        void sort();
+
+
+    // Member operators
+
+        //- Return id from linear list of addressing.
+        inline label operator[](const label i) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightCellsI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightCellsI.H b/src/fileFormats/ensight/part/ensightCellsI.H
new file mode 100644
index 0000000000000000000000000000000000000000..88e016832220ff94ee17033a2da7d06be4adc51e
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightCellsI.H
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "error.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+inline const char* Foam::ensightCells::key(const enum elemType what)
+{
+    return elemEnum[what];
+}
+
+
+inline Foam::label Foam::ensightCells::index() const
+{
+    return index_;
+}
+
+
+inline Foam::label& Foam::ensightCells::index()
+{
+    return index_;
+}
+
+
+inline Foam::label Foam::ensightCells::size() const
+{
+    return address_.size();
+}
+
+
+inline const Foam::FixedList<Foam::label,5>& Foam::ensightCells::totals() const
+{
+    return sizes_;
+}
+
+
+inline Foam::label Foam::ensightCells::total(const enum elemType what) const
+{
+    return sizes_[what];
+}
+
+
+inline const Foam::labelUList& Foam::ensightCells::cellIds
+(
+    const enum elemType what
+) const
+{
+    if (!lists_[what])
+    {
+        FatalErrorInFunction
+            << "Accessing unallocated sublist for elem-type: "
+            << elemEnum[what]
+            << exit(FatalError);
+    }
+
+    return *(lists_[what]);
+}
+
+
+inline const Foam::labelUList& Foam::ensightCells::cellIds() const
+{
+    return address_;
+}
+
+
+inline Foam::label Foam::ensightCells::operator[](const label i) const
+{
+    return address_[i];
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightFaces.C b/src/fileFormats/ensight/part/ensightFaces.C
new file mode 100644
index 0000000000000000000000000000000000000000..e1e67153fdb6206d9dc69fe1b963816df376e74b
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightFaces.C
@@ -0,0 +1,363 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightFaces.H"
+#include "error.H"
+#include "polyMesh.H"
+#include "ListOps.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::label Foam::ensightFaces::nTypes = 3;
+
+namespace Foam
+{
+    template<>
+    const char* Foam::NamedEnum
+    <
+        Foam::ensightFaces::elemType,
+        3
+    >::names[] = { "tria3", "quad4", "nsided" };
+}
+
+const Foam::NamedEnum<Foam::ensightFaces::elemType, 3>
+    Foam::ensightFaces::elemEnum;
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// only used in this file-scope
+inline Foam::ensightFaces::elemType
+Foam::ensightFaces::whatType(const face& f)
+{
+    return
+    (
+        f.size() == 3
+      ? Foam::ensightFaces::elemType::TRIA3
+      : f.size() == 4
+      ? Foam::ensightFaces::elemType::QUAD4
+      : Foam::ensightFaces::elemType::NSIDED
+    );
+}
+
+
+// only used in this file-scope
+inline void Foam::ensightFaces::add
+(
+    const face& f,
+    const label id,
+    const bool flip
+)
+{
+    const enum elemType what = whatType(f);
+
+    label n = sizes_[what]++;
+    lists_[what]->operator[](n) = id;
+
+    if (flipMap_.size())
+    {
+        flipMap_[offset(what, n)] = flip;
+    }
+}
+
+
+// only used in this file-scope
+inline Foam::label Foam::ensightFaces::offset
+(
+    const enum elemType what,
+    const label i
+) const
+{
+    label n = i;
+    for (label typeI = 0; typeI < label(what); ++typeI)
+    {
+        n += sizes_[typeI];
+    }
+
+    return n;
+}
+
+
+void Foam::ensightFaces::resize()
+{
+    // overall required size
+    label n = 0;
+    forAll(sizes_, typeI)
+    {
+        n += sizes_[typeI];
+    }
+    address_.setSize(n, Zero);
+
+    // assign corresponding sub-lists
+    n = 0;
+    forAll(sizes_, typeI)
+    {
+        deleteDemandDrivenData(lists_[typeI]);
+
+        lists_[typeI] = new SubList<label>(address_, sizes_[typeI], n);
+
+        n += sizes_[typeI];
+    }
+
+    // normally assume no flipMap
+    flipMap_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightFaces::ensightFaces(label partIndex)
+:
+    index_(partIndex),
+    address_(),
+    flipMap_(),
+    sizes_(Zero),
+    lists_()
+{
+    // Ensure sub-lists are properly initialized to nullptr
+    forAll(lists_, typeI)
+    {
+        lists_[typeI] = nullptr;
+    }
+
+    resize();   // adjust allocation
+}
+
+
+Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
+:
+    index_(obj.index_),
+    address_(obj.address_),
+    flipMap_(obj.flipMap_),
+    sizes_(),
+    lists_()
+{
+    // Ensure sub-lists are properly initialized to nullptr
+    forAll(lists_, typeI)
+    {
+        lists_[typeI] = nullptr;
+    }
+
+    // Total (reduced) sizes
+    FixedList<label, 3> totSizes = obj.sizes_;
+
+    // Local sizes
+    this->sizes_ = obj.sizes();
+
+    resize();   // adjust allocation
+
+    // Restore total (reduced) sizes
+    this->sizes_ = totSizes;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::ensightFaces::~ensightFaces()
+{
+    forAll(lists_, typeI)
+    {
+        deleteDemandDrivenData(lists_[typeI]);
+    }
+    address_.clear();
+    flipMap_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
+{
+    FixedList<label, 3> count;
+    forAll(lists_, typeI)
+    {
+        count[typeI] = lists_[typeI]->size();
+    }
+
+    return count;
+}
+
+
+Foam::label Foam::ensightFaces::total() const
+{
+    label n = 0;
+    forAll(sizes_, typeI)
+    {
+        n += sizes_[typeI];
+    }
+    return n;
+}
+
+
+void Foam::ensightFaces::clear()
+{
+    sizes_ = Zero;  // reset sizes
+    resize();
+}
+
+
+void Foam::ensightFaces::reduce()
+{
+    forAll(sizes_, typeI)
+    {
+        sizes_[typeI] = lists_[typeI]->size();
+        Foam::reduce(sizes_[typeI], sumOp<label>());
+    }
+}
+
+
+void Foam::ensightFaces::sort()
+{
+    if (flipMap_.size() == address_.size())
+    {
+        // sort flip too
+
+        labelList order;
+        label start = 0;
+
+        forAll(lists_, typeI)
+        {
+            if (lists_[typeI])
+            {
+                SubList<label>& idLst = *(lists_[typeI]);
+                const label sz = idLst.size();
+
+                if (sz)
+                {
+                    SubList<bool> flip(flipMap_, sz, start);
+                    start += sz; // for next sub-list
+
+                    sortedOrder(idLst, order);
+
+                    idLst = reorder<labelList>(order, idLst);
+                    flip  = reorder<boolList>(order,  flip);
+                }
+            }
+        }
+    }
+    else
+    {
+        // no flip-maps, simpler to sort
+        forAll(lists_, typeI)
+        {
+            if (lists_[typeI])
+            {
+                SubList<label>& idLst = *(lists_[typeI]);
+                const label sz = idLst.size();
+                if (sz)
+                {
+                    Foam::sort(idLst);
+                }
+            }
+        }
+    }
+}
+
+
+void Foam::ensightFaces::classify(const faceList& faces)
+{
+    const label sz = faces.size();
+
+    // Count the shapes
+    // Can avoid double looping, but only at the expense of allocation
+
+    sizes_ = Zero;  // reset sizes
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        const enum elemType what = whatType(faces[listI]);
+        sizes_[what]++;
+    }
+
+    resize();       // adjust allocation
+    sizes_ = Zero;  // reset sizes
+
+    // Assign face-id per shape type
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        add(faces[listI], listI);
+    }
+}
+
+
+void Foam::ensightFaces::classify
+(
+    const faceList& faces,
+    const labelUList& addressing,
+    const boolList& flipMap,
+    const PackedBoolList& exclude
+)
+{
+    // Note: Since PackedList::operator[] returns zero (false) for out-of-range
+    // indices, can skip our own bounds checking here.
+
+    const label sz = addressing.size();
+    const bool useFlip = (addressing.size() == flipMap.size());
+
+    // Count the shapes
+    // Can avoid double looping, but only at the expense of allocation
+
+    sizes_ = Zero;  // reset sizes
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        const label faceId = addressing[listI];
+
+        if (!exclude[faceId])
+        {
+            const enum elemType what = whatType(faces[faceId]);
+            sizes_[what]++;
+        }
+    }
+
+    resize();       // adjust allocation
+    sizes_ = Zero;  // reset sizes
+
+    if (useFlip)
+    {
+        flipMap_.setSize(address_.size(), false);
+        flipMap_ = false;
+    }
+
+    // Assign face-id per shape type
+    for (label listI = 0; listI < sz; ++listI)
+    {
+        const label faceId = addressing[listI];
+        const bool flip = useFlip && flipMap[listI];
+
+        if (!exclude[faceId])
+        {
+            add(faces[faceId], faceId, flip);
+        }
+    }
+}
+
+
+Foam::label Foam::ensightFaces::offset(const enum elemType what) const
+{
+    return offset(what, 0);
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
new file mode 100644
index 0000000000000000000000000000000000000000..dfb16859c0732da4edb5efa1b54231da46978a46
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -0,0 +1,225 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::ensightFaces
+
+Description
+    Sorting/classification of faces (2D) into corresponding ensight types
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightFaces_H
+#define ensightFaces_H
+
+#include "boolList.H"
+#include "labelList.H"
+#include "faceList.H"
+#include "FixedList.H"
+#include "PackedBoolList.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                        Class ensightFaces Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightFaces
+{
+public:
+
+    // Public data
+
+        //- Addressable ensight element types
+        enum elemType
+        {
+            TRIA3,
+            QUAD4,
+            NSIDED
+        };
+
+        //- Number of element types (3)
+        static const label nTypes;
+
+        //- The Ensight names for each element type
+        static const NamedEnum<elemType, 3> elemEnum;
+
+
+    // Static Member Functions
+
+        //- Return the ensight element name for the specified type
+        static inline const char* key(const enum elemType);
+
+
+private:
+
+    // Private data
+
+        //- Location within a list.
+        //  The ensight part number is typically this value +1.
+        label index_;
+
+        //- Linear list of ids, sub-sectioned per element type via SubLists
+        labelList address_;
+
+        //- Linear list of face-flips
+        boolList flipMap_;
+
+        //- List of global sizes for each element type
+        FixedList<label, 3> sizes_;
+
+        //- SubLists of ids for each element type.
+        //  Managed via pointers, since a SubList cannot be relocated/resized.
+        FixedList<SubList<label>*, 3> lists_;
+
+
+    // Private Member Functions
+
+        //- Simple classifier
+        inline static elemType whatType(const face&);
+
+        //- Low-level addition routine
+        inline void add(const face&, const label id, const bool flip = false);
+
+        //- Low-level offset routine
+        inline label offset(const enum elemType what, const label i) const;
+
+        //- Use current sizes to redimension the element lists
+        void resize();
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightFaces&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null, optionally with index
+        ensightFaces(label partIndex = 0);
+
+        //- Copy constructor. Needed for lists etc.
+        ensightFaces(const ensightFaces&);
+
+
+    //- Destructor
+    ~ensightFaces();
+
+
+    // Member Functions
+
+    // Access
+
+        //- The index in a list.
+        inline label index() const;
+
+        //- The index in a list, non-const access.
+        inline label& index();
+
+        //- The processor local size of all elements.
+        inline label size() const;
+
+        //- The global number of the specified element type.
+        //  This value is only meaningful after a reduce operation.
+        inline label total(const enum elemType) const;
+
+        //- The global number of all element types.
+        //  This value is only meaningful after a reduce operation.
+        label total() const;
+
+
+        //- The processor local sizes per element type.
+        FixedList<label, 3> sizes() const;
+
+        //- The global numbers per element type.
+        //  This value is only meaningful after a reduce operation.
+        const FixedList<label, 3>& totals() const;
+
+
+        //- Return the (local) face ids of the specified element type
+        inline const labelUList& faceIds(const enum elemType) const;
+
+        //- Return the face ids of all elements
+        inline const labelUList& faceIds() const;
+
+        //- Return the flip-map of all elements
+        inline const boolList& flipMap() const;
+
+
+        //- Starting offset of element type.
+        label offset(const enum elemType what) const;
+
+
+    // Edit
+
+        //- Classify the face types, set element list.
+        void classify(const faceList& faces);
+
+
+        //- Classify the face types, set element list.
+        //  The indirect addressing can be used when classifying groups of
+        //  face (eg, from a faceZone etc) with an optional flipMap.
+        //  The optional exclude marker can be used to skip faces on particular
+        //  boundary types or regions.
+        void classify
+        (
+            const faceList& faces,
+            const labelUList& addressing,
+            const boolList& flipMap = boolList(),
+            const PackedBoolList& exclude = PackedBoolList()
+        );
+
+
+        //- Set addressable sizes to zero, free up addressing memory.
+        void clear();
+
+        //- Sum element counts across all processes.
+        void reduce();
+
+        //- Sort element lists numerically.
+        void sort();
+
+
+    // Member operators
+
+        //- Return element from linear-list.
+        inline label operator[](const label i) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightFacesI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightFacesI.H b/src/fileFormats/ensight/part/ensightFacesI.H
new file mode 100644
index 0000000000000000000000000000000000000000..4b32a373dbe23082fde720b58a3c6568396fca68
--- /dev/null
+++ b/src/fileFormats/ensight/part/ensightFacesI.H
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "error.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+inline const char* Foam::ensightFaces::key(const enum elemType what)
+{
+    return elemEnum[what];
+}
+
+
+inline Foam::label Foam::ensightFaces::index() const
+{
+    return index_;
+}
+
+
+inline Foam::label& Foam::ensightFaces::index()
+{
+    return index_;
+}
+
+
+inline Foam::label Foam::ensightFaces::size() const
+{
+    return address_.size();
+}
+
+
+inline const Foam::FixedList<Foam::label,3>& Foam::ensightFaces::totals() const
+{
+    return sizes_;
+}
+
+
+inline Foam::label Foam::ensightFaces::total(const enum elemType what) const
+{
+    return sizes_[what];
+}
+
+
+inline const Foam::labelUList& Foam::ensightFaces::faceIds
+(
+    const enum elemType what
+) const
+{
+    if (!lists_[what])
+    {
+        FatalErrorInFunction
+            << "Accessing unallocated sublist for elem-type: "
+            << elemEnum[what]
+            << exit(FatalError);
+    }
+
+    return *(lists_[what]);
+}
+
+
+inline const Foam::labelUList& Foam::ensightFaces::faceIds() const
+{
+    return address_;
+}
+
+
+inline const Foam::boolList& Foam::ensightFaces::flipMap() const
+{
+    return flipMap_;
+}
+
+
+inline Foam::label Foam::ensightFaces::operator[](const label i) const
+{
+    return address_[i];
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/readFile/ensightReadFile.C b/src/fileFormats/ensight/read/ensightReadFile.C
similarity index 100%
rename from src/conversion/ensight/readFile/ensightReadFile.C
rename to src/fileFormats/ensight/read/ensightReadFile.C
diff --git a/src/conversion/ensight/readFile/ensightReadFile.H b/src/fileFormats/ensight/read/ensightReadFile.H
similarity index 100%
rename from src/conversion/ensight/readFile/ensightReadFile.H
rename to src/fileFormats/ensight/read/ensightReadFile.H
diff --git a/src/fileFormats/sampledSetWriters/ensight/ensightPTraits.C b/src/fileFormats/ensight/type/ensightPTraits.C
similarity index 77%
rename from src/fileFormats/sampledSetWriters/ensight/ensightPTraits.C
rename to src/fileFormats/ensight/type/ensightPTraits.C
index bf29a96820d70ccf36fac64c36a6817f0fdb7f92..a6b70129af593741cf9382e8878be3629a9968c6 100644
--- a/src/fileFormats/sampledSetWriters/ensight/ensightPTraits.C
+++ b/src/fileFormats/ensight/type/ensightPTraits.C
@@ -28,56 +28,51 @@ License
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 template<>
-const char* const Foam::ensightPTraits<Foam::scalar>::typeName =
-    Foam::pTraits<Foam::scalar>::typeName;
+const char* const
+Foam::ensightPTraits<Foam::scalar>::typeName = "scalar";
 
 template<>
 const Foam::direction
 Foam::ensightPTraits<Foam::scalar>::componentOrder[] = {0};
 
+
 template<>
-const char* const Foam::ensightPTraits<Foam::vector>::typeName =
-    Foam::pTraits<Foam::vector>::typeName;
+const char* const
+Foam::ensightPTraits<Foam::vector>::typeName = "vector";
 
 template<>
 const Foam::direction
 Foam::ensightPTraits<Foam::vector>::componentOrder[] = {0, 1, 2};
 
+
+// use mag(sphericalTensor) instead
 template<>
-const char* const Foam::ensightPTraits<Foam::sphericalTensor>::typeName =
-    Foam::pTraits<Foam::scalar>::typeName;
+const char* const
+Foam::ensightPTraits<Foam::sphericalTensor>::typeName = "scalar";
+
 
 template<>
 const Foam::direction
 Foam::ensightPTraits<Foam::sphericalTensor>::componentOrder[] = {0};
 
 template<>
-const char* const Foam::ensightPTraits<Foam::symmTensor>::typeName =
-    "tensor symm";
+const char* const
+Foam::ensightPTraits<Foam::symmTensor>::typeName = "tensor symm";
 
 
 template<>
 const Foam::direction
 Foam::ensightPTraits<Foam::symmTensor>::componentOrder[] = {0, 3, 5, 1, 2, 4};
 
+
 template<>
-const char* const Foam::ensightPTraits<Foam::tensor>::typeName =
-    "tensor asym";
+const char* const
+Foam::ensightPTraits<Foam::tensor>::typeName = "tensor asym";
 
 template<>
 const Foam::direction
 Foam::ensightPTraits<Foam::tensor>::componentOrder[] =
-{
-    0,
-    1,
-    2,
-    3,
-    4,
-    5,
-    6,
-    7,
-    8
-};
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
 
 
 // ************************************************************************* //
diff --git a/src/fileFormats/sampledSetWriters/ensight/ensightPTraits.H b/src/fileFormats/ensight/type/ensightPTraits.H
similarity index 100%
rename from src/fileFormats/sampledSetWriters/ensight/ensightPTraits.H
rename to src/fileFormats/ensight/type/ensightPTraits.H
diff --git a/src/fileFormats/fire/FIRECore.C b/src/fileFormats/fire/FIRECore.C
new file mode 100644
index 0000000000000000000000000000000000000000..ab576116348cdc4d698b2966e16b4b1a7b69b051
--- /dev/null
+++ b/src/fileFormats/fire/FIRECore.C
@@ -0,0 +1,370 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "FIRECore.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::NamedEnum<Foam::fileFormats::FIRECore::fileExt3d, 4>
+    Foam::fileFormats::FIRECore::file3dExtensions;
+
+namespace Foam
+{
+    template<>
+    const char* Foam::NamedEnum
+    <
+        Foam::fileFormats::FIRECore::fileExt3d,
+        4
+    >::names[] =
+    {
+        "fpma",
+        "fpmb",
+        "fpmaz",
+        "fpmbz"
+    };
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::FIRECore::FIRECore()
+{}
+
+
+// * * * * * * * * * * *  Protected Member Functions * * * * * * * * * * * * //
+
+Foam::label Foam::fileFormats::FIRECore::readPoints
+(
+    ISstream& is,
+    pointField& points
+)
+{
+    const label n = getFireLabel(is);
+
+    if (n > 0)
+    {
+        points.setSize(n);
+
+        // read the coordinates
+        forAll(points, pointI)
+        {
+            points[pointI] = getFirePoint(is);
+        }
+    }
+    else
+    {
+        FatalErrorInFunction
+            << "no points in file " << is.name()
+            << abort(FatalError);
+    }
+
+    return n;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::fileName Foam::fileFormats::FIRECore::fireFileName
+(
+    const fileName& base,
+    const enum fileExt3d ext
+)
+{
+    return base + '.' + file3dExtensions[ext];
+}
+
+
+Foam::label Foam::fileFormats::FIRECore::getFireLabel(ISstream& is)
+{
+    if (is.format() == IOstream::BINARY)
+    {
+        fireInt_t ivalue;
+
+        is.stdStream().read
+        (
+            reinterpret_cast<char *>(&ivalue),
+            sizeof(ivalue)
+        );
+
+        return ivalue;
+    }
+    else
+    {
+        return readLabel(is);
+    }
+}
+
+
+Foam::point Foam::fileFormats::FIRECore::getFirePoint(ISstream& is)
+{
+    point pt;
+
+    if (is.format() == IOstream::BINARY)
+    {
+        fireReal_t coord[3];
+
+        is.stdStream().read
+        (
+            reinterpret_cast<char *>(&coord),
+            sizeof(coord)
+        );
+
+        pt.x() = coord[0];
+        pt.y() = coord[1];
+        pt.z() = coord[2];
+    }
+    else
+    {
+        pt.x() = readScalar(is);
+        pt.y() = readScalar(is);
+        pt.z() = readScalar(is);
+    }
+
+    return pt;
+}
+
+
+std::string Foam::fileFormats::FIRECore::getFireString(ISstream& is)
+{
+    std::string str;
+
+    if (is.format() == IOstream::BINARY)
+    {
+        long len;
+
+        is.stdStream().read
+        (
+            reinterpret_cast<char *>(&len),
+            sizeof(len)
+        );
+
+        str.resize(len);
+
+        for (std::size_t pos = 0; pos < str.size(); ++pos)
+        {
+            is.stdStream().read(&(str[pos]), sizeof(char));
+        }
+    }
+    else
+    {
+        const std::string whitespace(" \t\f\v\n\r");
+
+        string s;
+
+        // use a low-level getline, but this means we must handle
+        // blank lines manually
+        while (s.empty())
+        {
+            is.getLine(s);
+            if (!s.empty())
+            {
+                // remove prefix whitespace
+                size_t pos = s.find_first_not_of(whitespace);
+
+                if (pos != std::string::npos)
+                {
+                    s.erase(0, pos);
+
+                    // remove suffix whitespace
+                    pos = s.find_last_not_of(whitespace);
+                    if (pos != std::string::npos)
+                    {
+                        s.erase(pos + 1);
+                    }
+                }
+
+                if (pos == std::string::npos)
+                {
+                    s.clear();
+                }
+            }
+        }
+
+        str.swap(s);
+    }
+
+    return str;
+}
+
+
+void Foam::fileFormats::FIRECore::putFireLabel
+(
+    OSstream& os,
+    const label value
+)
+{
+    if (os.format() == Foam::IOstream::BINARY)
+    {
+        fireInt_t ivalue(value);
+
+        os.stdStream().write
+        (
+            reinterpret_cast<char const *>(&ivalue),
+            sizeof(ivalue)
+        );
+    }
+    else
+    {
+        os  << value;
+    }
+}
+
+
+void Foam::fileFormats::FIRECore::putFireLabels
+(
+    OSstream& os,
+    const labelUList& lst
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        fireInt_t ivalue(lst.size());
+
+        os.stdStream().write
+        (
+            reinterpret_cast<char const *>(&ivalue),
+            sizeof(ivalue)
+        );
+
+        forAll(lst, i)
+        {
+            ivalue = lst[i];
+
+            os.stdStream().write
+            (
+                reinterpret_cast<char const *>(&ivalue),
+                sizeof(ivalue)
+            );
+        }
+    }
+    else
+    {
+        os  << ' ' << lst.size();
+        forAll(lst, i)
+        {
+            os  << ' ' << lst[i];
+        }
+        os  << '\n';
+    }
+}
+
+
+void Foam::fileFormats::FIRECore::putFireLabels
+(
+    OSstream& os,
+    const label count,
+    const label start
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        fireInt_t ivalue(count);
+
+        os.stdStream().write
+        (
+            reinterpret_cast<char const *>(&ivalue),
+            sizeof(ivalue)
+        );
+
+        ivalue = start;
+        for (label i=0; i < count; ++i, ++ivalue)
+        {
+            os.stdStream().write
+            (
+                reinterpret_cast<char const *>(&ivalue),
+                sizeof(ivalue)
+            );
+        }
+    }
+    else
+    {
+        os  << ' ' << count;
+
+        label ivalue = start;
+        for (label i = 0; i < count; ++i, ++ivalue)
+        {
+            os  << ' ' << ivalue;
+        }
+        os  << '\n';
+    }
+}
+
+
+void Foam::fileFormats::FIRECore::putFirePoint
+(
+    OSstream& os,
+    const point& value
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        fireReal_t fvalue[3];
+        fvalue[0] = value.x();
+        fvalue[1] = value.y();
+        fvalue[2] = value.z();
+
+        os.stdStream().write
+        (
+            reinterpret_cast<char const *>(&fvalue),
+            sizeof(fvalue)
+        );
+    }
+    else
+    {
+        os  << ' '
+            << value.x() << ' '
+            << value.y() << ' '
+            << value.z() << '\n';
+    }
+}
+
+
+void Foam::fileFormats::FIRECore::putFireString
+(
+    OSstream& os,
+    const std::string& value
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        long len(value.size());
+
+        os.stdStream().write
+        (
+            reinterpret_cast<char const *>(&len),
+            sizeof(len)
+        );
+
+        os.stdStream().write(value.data(), len);
+    }
+    else
+    {
+        // output without surrounding quotes
+        os.stdStream() << value << '\n';
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/fire/FIRECore.H b/src/fileFormats/fire/FIRECore.H
new file mode 100644
index 0000000000000000000000000000000000000000..3f9c654cc1ea1acdf0b5027a140d2014a3e44859
--- /dev/null
+++ b/src/fileFormats/fire/FIRECore.H
@@ -0,0 +1,179 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::fileFormats::FIRECore
+
+Description
+    Core routines used when reading/writing AVL/FIRE files.
+
+SourceFiles
+    FIRECore.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FIRECore_H
+#define FIRECore_H
+
+#include "point.H"
+#include "string.H"
+#include "labelList.H"
+#include "pointField.H"
+#include "IOstreams.H"
+#include "NamedEnum.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+// forward declarations
+class polyMesh;
+
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class fileFormats::FIRECore Declaration
+\*---------------------------------------------------------------------------*/
+
+class FIRECore
+{
+public:
+
+    // Public Data, Declarations
+
+        //- Selection Types
+        enum selectionType
+        {
+            cellSelection = 2,
+            faceSelection = 3
+        };
+
+        //- Shape-Type for FIRE (FLMA) files
+        enum shapeType
+        {
+            fireLine  = 1,
+            fireTri   = 2,
+            fireQuad  = 3,
+            fireTet   = 4,
+            fireHex   = 5,
+            firePyr   = 6,
+            firePrism = 8
+        };
+
+        //- Enumeration defining the file extensions for 3D types
+        enum fileExt3d
+        {
+            POLY_ASCII,
+            POLY_BINARY,
+            POLY_ASCII_COMPRESSED,
+            POLY_BINARY_COMPRESSED
+        };
+
+
+        //- Integer type (binary format)
+        typedef int32_t fireInt_t;
+
+        //- Float type (binary format)
+        typedef double  fireReal_t;
+
+protected:
+
+    // Protected Data
+
+        static const NamedEnum<fileExt3d, 4>  file3dExtensions;
+
+
+    // Protected Member Functions
+
+        //- Construct null
+        FIRECore();
+
+
+        //- Read points.
+        // This is the first thing to do when reading FPMA,FPMB,FLMA files.
+        // Return the number of points read.
+        //
+        // The file format is as follows:
+        // \verbatim
+        // NUMBER_OF_VERTICES
+        // x0 y0 z0 x1 y1 z1 ... xN-1 yN-1 zN-1
+        // \endverbatim
+        static label readPoints(ISstream&, pointField&);
+
+public:
+
+    // Public Member Functions
+
+        //- Resolve base file-name for the given file-type
+        static fileName fireFileName
+        (
+            const fileName& baseName,
+            const enum fileExt3d
+        );
+
+
+        //- Get an integer (ascii or binary)
+        static label getFireLabel(ISstream&);
+
+        //- Get an point x/y/z (ascii or binary)
+        static point getFirePoint(ISstream&);
+
+        //- Extract a string (ascii or binary)
+        static std::string getFireString(ISstream&);
+
+
+        //- Write an integer (ascii or binary)
+        static void putFireLabel(OSstream&, const label);
+
+        //- Write multiple integers (ascii or binary)
+        static void putFireLabels(OSstream&, const labelUList&);
+
+        //- Write an on-the-fly list of integers (ascii or binary)
+        static void putFireLabels
+        (
+            OSstream&,
+            const label count,
+            const label start
+        );
+
+
+        //- Write a point x/y/z (ascii or binary)
+        static void putFirePoint(OSstream&, const point&);
+
+        //- Write a string (ascii or binary)
+        static void putFireString(OSstream&, const std::string&);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/fire/README b/src/fileFormats/fire/README
new file mode 100644
index 0000000000000000000000000000000000000000..1cf217d220506c415045a070a582653de5786cc8
--- /dev/null
+++ b/src/fileFormats/fire/README
@@ -0,0 +1,124 @@
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                              AVL/FIRE fpma/fpmb
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+fpma/fpmb are polyhedral formats (ASCII and BINARY).
+The fpmaz/fpmbz are the same, but in compressed format.
+
+The fpma/fpmb format can exported directly from within the FIRE GUI.
+However, it is not recommended to import them directly.
+Instead use the utility fire_wm_convert_file, fire_wm_convert_mesh
+(or equivalents)
+are used to rewrite the fpma/fpmb into the internal FIRE format.
+
+
+~~~~~~
+FORMAT
+~~~~~~
+
+NUMBER_OF_VERTICES
+x0 y0 z0 x1 y1 z1 ... xN-1 yN-1 zN-1
+
+
+NUMBER_OF_FACES
+face-stream0
+...
+face-streamN-1
+
+
+NUMBER_OF_CELLS
+cell-face-stream0
+..
+cell-face-streamN-1
+
+
+NUMBER_OF_SELECTIONS
+selectionName[0]
+selectionType[0] (2 = cells, 3 = faces)
+numberOfIDs
+id0 .. indN-1
+<blank-line>
+
+
+
+The face-stream:
+    nvert vert0 .. vertN
+
+The cell-face-stream:
+    nface faceId0 .. faceIdN
+
+
+CAUTION:
+    The FIRE faces have inward-facing normals.
+    The OPENFOAM faces have outward-facing normals!
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                                 AVL/FIRE flma
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The AVL/FIRE flma format is very simple, but can only be used for 1D/2D shapes
+and for 3D primitive shapes.
+
+it is fairly easy to write and to parse.
+For 3D polyhedra, the cell-types are non-obvious and not easily determined
+- the fpma/fpmb format is preferred for that.
+
+
+~~~~~~
+FORMAT
+~~~~~~
+NUMBER_OF_VERTICES
+x0 y0 z0 x1 y1 z1 ... xN-1 yN-1 zN-1
+
+NUMBER_OF_CELLS
+nv[0]
+verts[0]
+nv[N-1]
+...
+verts[N-1]
+<blank-line>
+NUMBER_OF_CELLS
+type0 type1 ... type2
+<blank-line>
+NUMBER_OF_SELECTIONS
+selectionName[0]
+selectionType[0] (2 = cells, 3 = faces)
+numberOfIDs
+id0 .. indN-1
+<blank-line>
+...
+selectionName[N-1]
+selectionType[N-1] (2 = cells, 3 = faces)
+numberOfIDs
+id0 .. indN-1
+<blank-line>
+
+
+-- NOTES (flma) --
+# vertex/cells are zero-based
+
+    cell-types:
+      1 = line
+      2 = tri
+      3 = quad
+      4 = tet
+      5 = hex
+      6 = pyr
+      8 = prism
+
+    +---------------+---------------+
+    |  shape        |  face-order   |
+    +---------------+---------------+
+    +  Tet(FIRE)    |  0 1 2 3      |
+    +  Tet(FOAM)    |  3 2 0 1      |
+    +---------------+---------------+
+    +  Hex(FIRE)    |  0 1 2 3 4 5  |
+    +  Hex(FOAM)    |  4 5 0 1 2 3  |
+    +---------------+---------------+
+    +  Pyr(FIRE)    |  0 1 2 3 4    |
+    +  Pyr(FOAM)    |  0 4 3 2 1    |
+    +---------------+---------------+
+    +  Prism(FIRE)  |  0 1 2 3 4    |
+    +  Prism(FOAM)  |  0 1 4 3 2    |
+    +---------------+---------------+
+
diff --git a/src/fileFormats/starcd/STARCDCore.C b/src/fileFormats/starcd/STARCDCore.C
index 5e1ef1fb08aba3ff745dda43e7e37ddf1aa9207e..612b9c30911fb2913314787a888cdcb0ee7ea1bf 100644
--- a/src/fileFormats/starcd/STARCDCore.C
+++ b/src/fileFormats/starcd/STARCDCore.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  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,6 +28,72 @@ License
 #include "clock.H"
 #include "PackedBoolList.H"
 #include "IStringStream.H"
+#include "OSspecific.H"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::NamedEnum<Foam::fileFormats::STARCDCore::fileHeader, 3>
+    Foam::fileFormats::STARCDCore::fileHeaders_;
+
+const Foam::NamedEnum<Foam::fileFormats::STARCDCore::fileExt, 4>
+    Foam::fileFormats::STARCDCore::fileExtensions_;
+
+namespace Foam
+{
+    template<>
+    const char* Foam::NamedEnum
+    <
+        Foam::fileFormats::STARCDCore::fileHeader,
+        3
+    >::names[] =
+    {
+        "PROSTAR_CELL",
+        "PROSTAR_VERTEX",
+        "PROSTAR_BOUNDARY"
+    };
+
+    template<>
+    const char* Foam::NamedEnum
+    <
+        Foam::fileFormats::STARCDCore::fileExt,
+        4
+    >::names[] =
+    {
+        "cel",
+        "vrt",
+        "bnd",
+        "inp"
+    };
+}
+
+
+const char* const Foam::fileFormats::STARCDCore::defaultBoundaryName =
+    "Default_Boundary_Region";
+
+const char* const Foam::fileFormats::STARCDCore::defaultSolidBoundaryName =
+    "Default_Boundary_Solid";
+
+
+const Foam::Map<Foam::FixedList<int, 6>>
+Foam::fileFormats::STARCDCore::foamToStarFaceAddr =
+{
+    { starcdHex,   { 4, 5, 2, 3, 0, 1 } },
+    { starcdPrism, { 0, 1, 4, 5, 2, -1 } },
+    { starcdTet,   { 5, 4, 2, 0, -1, -1 } },
+    { starcdPyr,   { 0, 4, 3, 5, 2, -1 } }
+};
+
+
+const Foam::Map<Foam::FixedList<int, 6>>
+Foam::fileFormats::STARCDCore::starToFoamFaceAddr =
+{
+    { starcdHex,   { 4, 5, 2, 3, 0, 1 } },
+    { starcdPrism, { 0, 1, 4, -1, 2, 3 } },
+    { starcdTet,   { 3, -1, 2, -1, 1, 0 } },
+    { starcdPyr,   { 0, -1, 4, 2, 1, 3 } }
+};
+
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -40,7 +106,7 @@ Foam::fileFormats::STARCDCore::STARCDCore()
 bool Foam::fileFormats::STARCDCore::readHeader
 (
     IFstream& is,
-    const word& signature
+    const enum fileHeader header
 )
 {
     if (!is.good())
@@ -49,22 +115,25 @@ bool Foam::fileFormats::STARCDCore::readHeader
             << abort(FatalError);
     }
 
-    word header;
+    word  magic;
     label majorVersion;
 
     string line;
 
     is.getLine(line);
-    IStringStream(line)() >> header;
+    IStringStream(line)() >> magic;
 
     is.getLine(line);
     IStringStream(line)() >> majorVersion;
 
     // add other checks ...
-    if (header != signature)
+    if (magic != fileHeaders_[header])
     {
-        Info<< "header mismatch " << signature << "  " << is.name()
+        Info<< "header mismatch " << fileHeaders_[header]
+            << "  " << is.name()
             << endl;
+
+        return false;
     }
 
     return true;
@@ -74,10 +143,10 @@ bool Foam::fileFormats::STARCDCore::readHeader
 void Foam::fileFormats::STARCDCore::writeHeader
 (
     Ostream& os,
-    const word& filetype
+    const enum fileHeader header
 )
 {
-    os  << "PROSTAR_" << filetype << nl
+    os  << fileHeaders_[header] << nl
         << 4000
         << " " << 0
         << " " << 0
@@ -92,13 +161,34 @@ void Foam::fileFormats::STARCDCore::writeHeader
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::fileFormats::STARCDCore::readPoints
+Foam::fileName Foam::fileFormats::STARCDCore::starFileName
+(
+    const fileName& base,
+    const enum fileExt ext
+)
+{
+    return base + '.' + fileExtensions_[ext];
+}
+
+
+void Foam::fileFormats::STARCDCore::removeFiles(const fileName& base)
+{
+    Foam::rm(starFileName(base, VRT_FILE));
+    Foam::rm(starFileName(base, CEL_FILE));
+    Foam::rm(starFileName(base, BND_FILE));
+    Foam::rm(starFileName(base, INP_FILE));
+}
+
+
+Foam::label Foam::fileFormats::STARCDCore::readPoints
 (
     IFstream& is,
     pointField& points,
     labelList& ids
 )
 {
+    label maxId = 0;
+
     if (!is.good())
     {
         FatalErrorInFunction
@@ -106,8 +196,7 @@ bool Foam::fileFormats::STARCDCore::readPoints
             << exit(FatalError);
     }
 
-    readHeader(is, "PROSTAR_VERTEX");
-
+    readHeader(is, HEADER_VRT);
 
     // reuse memory if possible
     DynamicList<point> dynPoints(points.xfer());
@@ -116,31 +205,35 @@ bool Foam::fileFormats::STARCDCore::readPoints
     dynPoints.clear();
     dynPointId.clear();
 
-    label lineLabel;
-    while ((is >> lineLabel).good())
     {
+        label lineLabel;
         scalar x, y, z;
 
-        is >> x >> y >> z;
+        while ((is >> lineLabel).good())
+        {
+            maxId = max(maxId, lineLabel);
+            is >> x >> y >> z;
 
-        dynPoints.append(point(x, y, z));
-        dynPointId.append(lineLabel);
+            dynPoints.append(point(x, y, z));
+            dynPointId.append(lineLabel);
+        }
     }
 
     points.transfer(dynPoints);
     ids.transfer(dynPointId);
 
-    return true;
+    return maxId;
 }
 
 
 void Foam::fileFormats::STARCDCore::writePoints
 (
     Ostream& os,
-    const pointField& pointLst
+    const pointField& points,
+    const double scaleFactor
 )
 {
-    writeHeader(os, "VERTEX");
+    writeHeader(os, HEADER_VRT);
 
     // Set the precision of the points data to 10
     os.precision(10);
@@ -148,18 +241,17 @@ void Foam::fileFormats::STARCDCore::writePoints
     // force decimal point for Fortran input
     os.setf(std::ios::showpoint);
 
-    forAll(pointLst, ptI)
+    forAll(points, ptI)
     {
+        // convert [m] -> [mm] etc
         os
-            << ptI + 1 << " "
-            << pointLst[ptI].x() << " "
-            << pointLst[ptI].y() << " "
-            << pointLst[ptI].z() << nl;
+            << ptI + 1 << ' '
+            << scaleFactor * points[ptI].x() << ' '
+            << scaleFactor * points[ptI].y() << ' '
+            << scaleFactor * points[ptI].z() << '\n';
     }
     os.flush();
 }
 
 
-
-
 // ************************************************************************* //
diff --git a/src/fileFormats/starcd/STARCDCore.H b/src/fileFormats/starcd/STARCDCore.H
index 25920cdda26ebebb9a5e2cd3d141c0c1519d5e7d..cae3d1e7c0de7a8e7a6a3e6d305f49642f354cff 100644
--- a/src/fileFormats/starcd/STARCDCore.H
+++ b/src/fileFormats/starcd/STARCDCore.H
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,7 +36,10 @@ SourceFiles
 #define STARCDCore_H
 
 #include "IFstream.H"
+#include "NamedEnum.H"
 #include "pointField.H"
+#include "Map.H"
+#include "FixedList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -52,20 +55,29 @@ namespace fileFormats
 
 class STARCDCore
 {
-protected:
-
-    // Protected Member Functions
-
-        //- Read header
-        static bool readHeader(IFstream&, const word& fileSignature);
+public:
 
-        //- Write header for fileType (CELL|VERTEX|BOUNDARY)
-        static void writeHeader(Ostream&, const word& fileType);
+    // Public Data, Declarations
 
+        //- Enumeration defining the file headers
+        enum fileHeader
+        {
+            HEADER_CEL,
+            HEADER_VRT,
+            HEADER_BND
+        };
 
-protected:
+        //- Enumeration defining the file extensions
+        enum fileExt
+        {
+            CEL_FILE,
+            VRT_FILE,
+            BND_FILE,
+            INP_FILE
+        };
 
-        enum cellType
+        //- Basic material type for STARCD/PROSTAR files
+        enum matlType
         {
             starcdFluidType   = 1,
             starcdSolidType   = 2,
@@ -75,6 +87,7 @@ protected:
             starcdPointType   = 6
         };
 
+        //- Shape-Type for STARCD/PROSTAR files
         enum shapeType
         {
             starcdPoint = 1,
@@ -88,11 +101,61 @@ protected:
         };
 
 
+        //- The name for default (unassigned) boundaries
+        static const char* const defaultBoundaryName;
+
+        //- The name we have chosen for default (unassigned) solid boundaries.
+        //  Slightly distinguished from the regular default name.
+        static const char* const defaultSolidBoundaryName;
+
+
+private:
+
+    // Private Data
+
+        static const NamedEnum<fileHeader, 3> fileHeaders_;
+        static const NamedEnum<fileExt, 4>    fileExtensions_;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Face addressing from pro-STAR faces to OpenFOAM faces.
+        //  For hex, prism, tet, pyr primitive shapes.
+        static const Map<FixedList<int, 6>> starToFoamFaceAddr;
+
+        //- Face addressing from OpenFOAM faces to pro-STAR faces.
+        //  For hex, prism, tet, pyr primitive shapes.
+        static const Map<FixedList<int, 6>> foamToStarFaceAddr;
+
+
+    // Constructors
+
+        //- Construct null
+        STARCDCore();
+
+        //- Read header and check signature PROSTAR_(CELL|VERTEX|BOUNDARY)
+        static bool readHeader(IFstream&, const enum fileHeader);
+
+        //- Write header for fileType (CELL|VERTEX|BOUNDARY)
+        static void writeHeader(Ostream&, const enum fileHeader);
+
+
 public:
 
     // Public Member Functions
 
-        //- Read points from a (.vrt) file
+        //- Resolve base file-name for the given file-type
+        static fileName starFileName(const fileName& baseName, const enum fileExt);
+
+
+        //- Remove existing PROSTAR files for the given base file-name
+        static void removeFiles(const fileName& baseName);
+
+
+        //- Read points from a (.vrt) file, return the max prostar id used.
+        //
         // The file format is as follows:
         // \verbatim
         // Line 1:
@@ -104,16 +167,20 @@ public:
         // Body:
         //   {vertexId}  {x}  {y}  {z}  newline
         // \endverbatim
-        static bool readPoints(IFstream&, pointField&, labelList& ids);
-
-        //- Write header and points to (.vrt) file
-        static void writePoints(Ostream&, const pointField&);
-
-
-    // Constructors
-
-        //- Construct null
-        STARCDCore();
+        static label readPoints
+        (
+            IFstream&,
+            pointField&,
+            labelList& ids
+        );
+
+        //- Write header and points to (.vrt) file, optionally with scaling
+        static void writePoints
+        (
+            Ostream&,
+            const pointField&,
+            const scalar scaleFactor = 1.0
+        );
 
 };
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C b/src/fileFormats/stl/STLCore.C
similarity index 51%
rename from src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
rename to src/fileFormats/stl/STLCore.C
index 022b6df5a9e802abde0ea4bbf2a6cf797647df1f..a38d3a3cdf919407e8570e3b35204994e2959ab2 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
+++ b/src/fileFormats/stl/STLCore.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -23,36 +23,75 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "STLsurfaceFormatCore.H"
+#include "STLCore.H"
 #include "gzstream.h"
 #include "OSspecific.H"
-#include "Map.H"
 #include "IFstream.H"
-#include "Ostream.H"
 
-#undef DEBUG_STLBINARY
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+//! \cond fileScope
 
-// check binary by getting the header and number of facets
+//  The number of bytes in the STL binary header
+static const unsigned STLHeaderSize = 80;
+
+//! \endcond
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::STLCore::STLCore()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::fileFormats::STLCore::isBinaryName
+(
+    const fileName& filename,
+    const STLFormat& format
+)
+{
+    return (format == DETECT ? (filename.ext() == "stlb") : format == BINARY);
+}
+
+
+// Check binary by getting the header and number of facets
 // this seems to work better than the old token-based method
 // - some programs (eg, pro-STAR) have 'solid' as the first word in
 //   the binary header.
 // - using wordToken can cause an abort if non-word (binary) content
 //   is detected ... this is not exactly what we want.
-int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
+int Foam::fileFormats::STLCore::detectBinaryHeader
 (
     const fileName& filename
 )
 {
-    off_t dataFileSize = Foam::fileSize(filename);
+    bool compressed = false;
+    autoPtr<istream> streamPtr
+    (
+        new ifstream(filename.c_str(), std::ios::binary)
+    );
+
+    // If the file is compressed, decompress it before further checking.
+    if (!streamPtr->good() && isFile(filename + ".gz", false))
+    {
+        compressed = true;
+        streamPtr.reset(new igzstream((filename + ".gz").c_str()));
+    }
+    istream& is = streamPtr();
 
-    IFstream str(filename, IOstream::BINARY);
-    istream& is = str().stdStream();
+    if (!is.good())
+    {
+        FatalErrorInFunction
+            << "Cannot read file " << filename
+            << " or file " << filename + ".gz"
+            << exit(FatalError);
+    }
 
     // Read the STL header
-    char header[headerSize];
-    is.read(header, headerSize);
+    char header[STLHeaderSize];
+    is.read(header, STLHeaderSize);
 
     // Check that stream is OK, if not this may be an ASCII file
     if (!is.good())
@@ -60,7 +99,7 @@ int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
         return 0;
     }
 
-    // Read the number of triangles in the STl file
+    // Read the number of triangles in the STL file
     // (note: read as int so we can check whether >2^31)
     int nTris;
     is.read(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
@@ -74,33 +113,73 @@ int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
     (
         !is
      || nTris < 0
-     || nTris < (dataFileSize - headerSize)/50
-     || nTris > (dataFileSize - headerSize)/25
     )
     {
         return 0;
     }
+    else if (!compressed)
+    {
+        const off_t dataFileSize = Foam::fileSize(filename);
+
+        if
+        (
+            nTris < int(dataFileSize - STLHeaderSize)/50
+         || nTris > int(dataFileSize - STLHeaderSize)/25
+        )
+        {
+            return 0;
+        }
+    }
 
     // looks like it might be BINARY, return number of triangles
     return nTris;
 }
 
 
-bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
+Foam::autoPtr<std::istream>
+Foam::fileFormats::STLCore::readBinaryHeader
 (
-    istream& is,
-    const off_t dataFileSize
+    const fileName& filename,
+    label& nTrisEstimated
 )
 {
-    sorted_ = true;
+    bool bad = false;
+    bool compressed = false;
+    nTrisEstimated = 0;
+
+    autoPtr<istream> streamPtr
+    (
+        new ifstream(filename.c_str(), std::ios::binary)
+    );
+
+    // If the file is compressed, decompress it before reading.
+    if (!streamPtr->good() && isFile(filename + ".gz", false))
+    {
+        compressed = true;
+        streamPtr.reset(new igzstream((filename + ".gz").c_str()));
+    }
+    istream& is = streamPtr();
+
+    if (!is.good())
+    {
+        streamPtr.clear();
+
+        FatalErrorInFunction
+            << "Cannot read file " << filename
+            << " or file " << filename + ".gz"
+            << exit(FatalError);
+    }
+
 
     // Read the STL header
-    char header[headerSize];
-    is.read(header, headerSize);
+    char header[STLHeaderSize];
+    is.read(header, STLHeaderSize);
 
     // Check that stream is OK, if not this may be an ASCII file
     if (!is.good())
     {
+        streamPtr.clear();
+
         FatalErrorInFunction
             << "problem reading header, perhaps file is not binary "
             << exit(FatalError);
@@ -116,156 +195,56 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
     //
     // Also compare the file size with that expected from the number of tris
     // If the comparison is not sensible then it may be an ASCII file
-    if
-    (
-        !is
-     || nTris < 0
-     || nTris < int(dataFileSize - headerSize)/50
-     || nTris > int(dataFileSize - headerSize)/25
-    )
+    if (!is || nTris < 0)
     {
-        FatalErrorInFunction
-            << "problem reading number of triangles, perhaps file is not binary"
-            << exit(FatalError);
+        bad = true;
     }
-
-#ifdef DEBUG_STLBINARY
-    Info<< "# " << nTris << " facets" << endl;
-    label prevZone = -1;
-#endif
-
-    points_.setSize(3*nTris);
-    zoneIds_.setSize(nTris);
-
-    Map<label> lookup;
-    DynamicList<label> dynSizes;
-
-    label ptI = 0;
-    label zoneI = -1;
-    forAll(zoneIds_, facei)
+    else if (!compressed)
     {
-        // Read an STL triangle
-        STLtriangle stlTri(is);
-
-        // transcribe the vertices of the STL triangle -> points
-        points_[ptI++] = stlTri.a();
-        points_[ptI++] = stlTri.b();
-        points_[ptI++] = stlTri.c();
-
-        // interprete stl attribute as a zone
-        const label origId = stlTri.attrib();
+        const off_t dataFileSize = Foam::fileSize(filename);
 
-        Map<label>::const_iterator fnd = lookup.find(origId);
-        if (fnd != lookup.end())
-        {
-            if (zoneI != fnd())
-            {
-                // group appeared out of order
-                sorted_ = false;
-            }
-            zoneI = fnd();
-        }
-        else
-        {
-            zoneI = dynSizes.size();
-            lookup.insert(origId, zoneI);
-            dynSizes.append(0);
-        }
-
-        zoneIds_[facei] = zoneI;
-        dynSizes[zoneI]++;
-
-#ifdef DEBUG_STLBINARY
-        if (prevZone != zoneI)
+        if
+        (
+            nTris < int(dataFileSize - STLHeaderSize)/50
+         || nTris > int(dataFileSize - STLHeaderSize)/25
+        )
         {
-            if (prevZone != -1)
-            {
-                Info<< "endsolid zone" << prevZone << nl;
-            }
-            prevZone = zoneI;
-
-            Info<< "solid zone" << prevZone << nl;
+            bad = true;
         }
-
-        Info<< " facet normal " << stlTri.normal() << nl
-            << "  outer loop" << nl
-            << "   vertex " << stlTri.a() << nl
-            << "   vertex " << stlTri.b() << nl
-            << "   vertex " << stlTri.c() << nl
-            << "  outer loop" << nl
-            << " endfacet" << endl;
-#endif
     }
 
-    names_.clear();
-    sizes_.transfer(dynSizes);
-
-    return true;
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
-(
-    const fileName& filename
-)
-:
-    sorted_(true),
-    points_(0),
-    zoneIds_(0),
-    names_(0),
-    sizes_(0)
-{
-    off_t dataFileSize = Foam::fileSize(filename);
-
-    // auto-detect ascii/binary
-    if (detectBINARY(filename))
-    {
-        readBINARY
-        (
-            IFstream(filename, IOstream::BINARY)().stdStream(),
-            dataFileSize
-        );
-    }
-    else
+    if (bad)
     {
-        readASCII
-        (
-            IFstream(filename)().stdStream(),
-            dataFileSize
-        );
-    }
-}
-
+        streamPtr.clear();
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::fileFormats::STLsurfaceFormatCore::~STLsurfaceFormatCore()
-{}
+        FatalErrorInFunction
+            << "problem reading number of triangles, perhaps file is not binary"
+            << exit(FatalError);
+    }
 
+    nTrisEstimated = nTris;
+    return streamPtr;
+}
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::fileFormats::STLsurfaceFormatCore::writeHeaderBINARY
+void Foam::fileFormats::STLCore::writeBinaryHeader
 (
     ostream& os,
     unsigned int nTris
 )
 {
     // STL header with extra information about nTris
-    char header[headerSize];
+    char header[STLHeaderSize];
     sprintf(header, "STL binary file %u facets", nTris);
 
     // avoid trailing junk
-    for (size_t i = strlen(header); i < headerSize; ++i)
+    for (size_t i = strlen(header); i < STLHeaderSize; ++i)
     {
         header[i] = 0;
     }
 
-    os.write(header, headerSize);
+    os.write(header, STLHeaderSize);
     os.write(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
-
 }
 
 
diff --git a/src/fileFormats/stl/STLCore.H b/src/fileFormats/stl/STLCore.H
new file mode 100644
index 0000000000000000000000000000000000000000..548cfabde206b862f5c3ee433ca5c0e45ba5e703
--- /dev/null
+++ b/src/fileFormats/stl/STLCore.H
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::fileFormats::STLCore
+
+Description
+    Core routines used when reading/writing STL files.
+
+SourceFiles
+    STLCore.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef STLCore_H
+#define STLCore_H
+
+#include "STLpoint.H"
+#include "STLtriangle.H"
+#include "autoPtr.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class fileFormats::STLCore Declaration
+\*---------------------------------------------------------------------------*/
+
+class STLCore
+{
+public:
+
+    // Public data types
+
+        //- Enumeration for the format of data in the stream
+        enum STLFormat
+        {
+            ASCII,  //!< ASCII
+            BINARY, //!< BINARY
+            DETECT  //!< Detect based on (input) content or (output) extension
+        };
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Detect 'stlb' extension as binary
+        static bool isBinaryName
+        (
+            const fileName& filename,
+            const STLFormat& format
+        );
+
+
+        //- Check contents to detect if the file is a binary STL.
+        //  Return the estimated number of triangles or 0 on error.
+        static int detectBinaryHeader(const fileName&);
+
+
+        //- Read STL binary file header.
+        //  Return the opened file stream and estimated number of triangles.
+        //  The stream is invalid and number of triangles is 0 on error.
+        static autoPtr<std::istream> readBinaryHeader
+        (
+            const fileName& filename,
+            label& nTrisEstimated
+        );
+
+        //- Write STL binary file and number of triangles to stream
+        static void writeBinaryHeader(ostream&, unsigned int);
+
+
+    // Constructors
+
+        //- Construct null
+        STLCore();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/stl/STLReader.C b/src/fileFormats/stl/STLReader.C
new file mode 100644
index 0000000000000000000000000000000000000000..c507b026735658d30e25ccd14375cc4083d9f8e4
--- /dev/null
+++ b/src/fileFormats/stl/STLReader.C
@@ -0,0 +1,188 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 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 "STLReader.H"
+#include "Map.H"
+#include "IFstream.H"
+
+#undef DEBUG_STLBINARY
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+bool Foam::fileFormats::STLReader::readBINARY
+(
+    const fileName& filename
+)
+{
+    sorted_ = true;
+
+    label nTris = 0;
+    autoPtr<istream> streamPtr = readBinaryHeader(filename, nTris);
+
+    if (!streamPtr.valid())
+    {
+        FatalErrorInFunction
+            << "Error reading file " << filename
+            << " or file " << filename + ".gz"
+            << exit(FatalError);
+    }
+
+    istream& is = streamPtr();
+
+#ifdef DEBUG_STLBINARY
+    Info<< "# " << nTris << " facets" << endl;
+    label prevZone = -1;
+#endif
+
+    points_.setSize(3*nTris);
+    zoneIds_.setSize(nTris);
+
+    Map<label> lookup;
+    DynamicList<label> dynSizes;
+
+    label ptI = 0;
+    label zoneI = -1;
+    forAll(zoneIds_, facei)
+    {
+        // Read STL triangle
+        STLtriangle stlTri(is);
+
+        // transcribe the vertices of the STL triangle -> points
+        points_[ptI++] = stlTri.a();
+        points_[ptI++] = stlTri.b();
+        points_[ptI++] = stlTri.c();
+
+        // interpret STL attribute as a zone
+        const label origId = stlTri.attrib();
+
+        Map<label>::const_iterator fnd = lookup.find(origId);
+        if (fnd != lookup.end())
+        {
+            if (zoneI != fnd())
+            {
+                // group appeared out of order
+                sorted_ = false;
+            }
+            zoneI = fnd();
+        }
+        else
+        {
+            zoneI = dynSizes.size();
+            lookup.insert(origId, zoneI);
+            dynSizes.append(0);
+        }
+
+        zoneIds_[facei] = zoneI;
+        dynSizes[zoneI]++;
+
+#ifdef DEBUG_STLBINARY
+        if (prevZone != zoneI)
+        {
+            if (prevZone != -1)
+            {
+                Info<< "endsolid zone" << prevZone << nl;
+            }
+            prevZone = zoneI;
+
+            Info<< "solid zone" << prevZone << nl;
+        }
+
+        stlTri.print(Info);
+#endif
+    }
+
+#ifdef DEBUG_STLBINARY
+    if (prevZone != -1)
+    {
+        Info<< "endsolid zone" << prevZone << nl;
+    }
+#endif
+
+    names_.clear();
+    sizes_.transfer(dynSizes);
+
+    return true;
+}
+
+
+bool Foam::fileFormats::STLReader::readFile
+(
+    const fileName& filename,
+    const STLFormat& format
+)
+{
+    if (format == DETECT ? detectBinaryHeader(filename) : format == BINARY)
+    {
+        return readBINARY(filename);
+    }
+    else
+    {
+        return readASCII(filename);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::STLReader::STLReader
+(
+    const fileName& filename
+)
+:
+    sorted_(true),
+    points_(),
+    zoneIds_(),
+    names_(),
+    sizes_()
+{
+    // Auto-detect ASCII/BINARY format
+    readFile(filename, STLCore::DETECT);
+}
+
+
+Foam::fileFormats::STLReader::STLReader
+(
+    const fileName& filename,
+    const STLFormat& format
+)
+:
+    sorted_(true),
+    points_(),
+    zoneIds_(),
+    names_(),
+    sizes_()
+{
+    // Manually specified ASCII/BINARY format
+    readFile(filename, format);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::fileFormats::STLReader::~STLReader()
+{}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H b/src/fileFormats/stl/STLReader.H
similarity index 78%
rename from src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
rename to src/fileFormats/stl/STLReader.H
index a5aba97cfd930664cc7f15d2cf4a82a896127fc9..db985181d0b2384c935c3944da9279ebd7a79f32 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
+++ b/src/fileFormats/stl/STLReader.H
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -22,22 +22,22 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::fileFormats::STLsurfaceFormatCore
+    Foam::fileFormats::STLReader
 
 Description
     Internal class used by the STLsurfaceFormat
 
 SourceFiles
-    STLsurfaceFormatCore.C
+    STLReader.C
     STLsurfaceFormatASCII.L
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef STLsurfaceFormatCore_H
-#define STLsurfaceFormatCore_H
+#ifndef STLReader_H
+#define STLReader_H
 
-#include "STLtriangle.H"
-#include "triFace.H"
+#include "STLCore.H"
+#include "labelledTri.H"
 #include "IFstream.H"
 #include "Ostream.H"
 
@@ -49,10 +49,12 @@ namespace fileFormats
 {
 
 /*---------------------------------------------------------------------------*\
-                    Class STLsurfaceFormatCore Declaration
+                   Class fileFormats::STLReader Declaration
 \*---------------------------------------------------------------------------*/
 
-class STLsurfaceFormatCore
+class STLReader
+:
+    public STLCore
 {
     // Private Data
 
@@ -73,44 +75,37 @@ class STLsurfaceFormatCore
 
     // Private Member Functions
 
-        //- Disallow default bitwise copy construct
-        STLsurfaceFormatCore(const STLsurfaceFormatCore&);
-
-        //- Disallow default bitwise assignment
-        void operator=(const STLsurfaceFormatCore&);
-
-        //- Determine the file type
-        static int detectBINARY(const fileName&);
-
         //- Read ASCII
-        bool readASCII(istream&, const off_t);
+        bool readASCII(const fileName&);
 
         //- Read BINARY
-        bool readBINARY(istream&, const off_t);
-
+        bool readBINARY(const fileName&);
 
-public:
-
-    // Static Data
+        //- Read ASCII or BINARY
+        bool readFile(const fileName&, const STLFormat&);
 
-        //- The number of bytes in the STL binary header
-        static const unsigned int headerSize = 80;
 
+        //- Disallow default bitwise copy construct
+        STLReader(const STLReader&) = delete;
 
-    // Static Member Functions
+        //- Disallow default bitwise assignment
+        void operator=(const STLReader&) = delete;
 
-        //- Write "STL binary file" and number of triangles to stream
-        static void writeHeaderBINARY(ostream&, unsigned int);
 
+public:
 
     // Constructors
 
         //- Read from file, filling in the information
-        STLsurfaceFormatCore(const fileName&);
+        STLReader(const fileName&);
+
+        //- Read from file, filling in the information.
+        //  Manually selected choice of ascii/binary/detect.
+        STLReader(const fileName&, const STLFormat&);
 
 
     //- Destructor
-    ~STLsurfaceFormatCore();
+    ~STLReader();
 
 
     // Member Functions
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L b/src/fileFormats/stl/STLReaderASCII.L
similarity index 93%
rename from src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
rename to src/fileFormats/stl/STLReaderASCII.L
index a3f9e47a6ce06cfb629bf7b78c2ab5fe01b9791e..515a1be90d8f3b5c2ec69c7d9cb1698f7486256b 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
+++ b/src/fileFormats/stl/STLReaderASCII.L
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -31,7 +31,8 @@ License
    ------ local definitions
  \* ------------------------------------------------------------------------ */
 
-#include "STLsurfaceFormatCore.H"
+#include "STLReader.H"
+#include "OSspecific.H"
 
 using namespace Foam;
 
@@ -97,32 +98,32 @@ public:
     // Access
 
         //- Do all the solid groups appear in order
-        bool sorted() const
+        inline bool sorted() const
         {
             return sorted_;
         }
 
         //- A list of points corresponding to a pointField
-        DynamicList<point>& points()
+        inline DynamicList<point>& points()
         {
             return points_;
         }
 
         //- A list of facet IDs (group IDs)
         //  corresponds to the number of triangles
-        DynamicList<label>& facets()
+        inline DynamicList<label>& facets()
         {
             return facets_;
         }
 
         //- Names
-        DynamicList<word>& names()
+        inline DynamicList<word>& names()
         {
             return names_;
         }
 
         //- Sizes
-        DynamicList<label>& sizes()
+        inline DynamicList<label>& sizes()
         {
             return sizes_;
         }
@@ -390,20 +391,27 @@ endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
 //
 // member function
 //
-bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
+bool Foam::fileFormats::STLReader::readASCII
 (
-    istream& is,
-    const off_t dataFileSize
+    const fileName& filename
 )
 {
+    IFstream is(filename);
+    if (!is)
+    {
+        FatalErrorInFunction
+            << "file " << filename << " not found"
+            << exit(FatalError);
+    }
+
     // Create the lexer with the approximate number of vertices in the STL
     // from the file size
-    STLASCIILexer lexer(&is, dataFileSize/400);
+    STLASCIILexer lexer(&(is.stdStream()), Foam::fileSize(filename)/400);
     while (lexer.lex() != 0) {}
 
     sorted_ = lexer.sorted();
 
-    // transfer to normal lists
+    // Transfer to normal lists
     points_.transfer(lexer.points());
     zoneIds_.transfer(lexer.facets());
     names_.transfer(lexer.names());
@@ -413,5 +421,5 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
 }
 
  /* ------------------------------------------------------------------------ *\
-    ------ End of STLfileFormatASCII.L
+    ------ End of STLReaderASCII.L
  \* ------------------------------------------------------------------------ */
diff --git a/src/surfMesh/surfaceFormats/stl/STLpoint.H b/src/fileFormats/stl/STLpoint.H
similarity index 91%
rename from src/surfMesh/surfaceFormats/stl/STLpoint.H
rename to src/fileFormats/stl/STLpoint.H
index 157e832ba5a66581799ac4049f1b30ef792929f3..c9862eaf9442d8a9755206616f1a9aa99ef630ec 100644
--- a/src/surfMesh/surfaceFormats/stl/STLpoint.H
+++ b/src/fileFormats/stl/STLpoint.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-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,14 +27,13 @@ Class
 Description
     A vertex point representation for STL files.
 
-SourceFiles
-
 \*---------------------------------------------------------------------------*/
 
 #ifndef STLpoint_H
 #define STLpoint_H
 
 #include "point.H"
+#include "floatVector.H"
 #include "Istream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -80,11 +79,13 @@ public:
 
     // Member Operators
 
-        //- Conversion to point
+        #ifdef WM_DP
+        //- Conversion to double-precision point
         inline operator point() const
         {
             return point(x(), y(), z());
         }
+        #endif
 };
 
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLtriangle.H b/src/fileFormats/stl/STLtriangle.H
similarity index 80%
rename from src/surfMesh/surfaceFormats/stl/STLtriangle.H
rename to src/fileFormats/stl/STLtriangle.H
index 17783047f2107ad507a01d7d16b4dae6efbd3749..a80f5498c53f3e90cd4acb474b266d5f92d57881 100644
--- a/src/surfMesh/surfaceFormats/stl/STLtriangle.H
+++ b/src/fileFormats/stl/STLtriangle.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,12 +45,9 @@ namespace Foam
 {
 
 // Forward declaration of friend functions and operators
-
 class STLtriangle;
-
 Ostream& operator<<(Ostream&, const STLtriangle&);
 
-
 /*---------------------------------------------------------------------------*\
                          Class STLtriangle Declaration
 \*---------------------------------------------------------------------------*/
@@ -62,7 +59,7 @@ class STLtriangle
         //- Attribute is 16-bit
         typedef unsigned short STLattrib;
 
-        //- The face normal, many programs write zore or other junk
+        //- The face normal, many programs write zero or other junk
         STLpoint normal_;
 
         //- The three points defining the triangle
@@ -113,7 +110,30 @@ public:
         // Write
 
             //- Write to ostream (binary)
-            inline void write(ostream&);
+            inline void write(ostream&) const;
+
+            //- Write to Ostream (ASCII)
+            inline Ostream& print(Ostream& os) const;
+
+
+            //- Write components to Ostream (ASCII)
+            inline static void write
+            (
+                Ostream& os,
+                const vector& norm,
+                const point& pt0,
+                const point& pt1,
+                const point& pt2
+            );
+
+            //- Write components to Ostream (ASCII), calculating the normal
+            inline static void write
+            (
+                Ostream& os,
+                const point& pt0,
+                const point& pt1,
+                const point& pt2
+            );
 
 
     // Ostream operator
diff --git a/src/surfMesh/surfaceFormats/stl/STLtriangleI.H b/src/fileFormats/stl/STLtriangleI.H
similarity index 61%
rename from src/surfMesh/surfaceFormats/stl/STLtriangleI.H
rename to src/fileFormats/stl/STLtriangleI.H
index c6d17f4a832473b13041394a54d1d441d4cf8abf..85e02be3d483602e41944832275eb9c60b6812ac 100644
--- a/src/surfMesh/surfaceFormats/stl/STLtriangleI.H
+++ b/src/fileFormats/stl/STLtriangleI.H
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -23,6 +23,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
+#include "triPointRef.H"
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 inline Foam::STLtriangle::STLtriangle()
@@ -91,10 +93,61 @@ inline void Foam::STLtriangle::read(istream& is)
 }
 
 
-inline void Foam::STLtriangle::write(ostream& os)
+inline void Foam::STLtriangle::write(ostream& os) const
+{
+    os.write(reinterpret_cast<const char*>(this), 4*sizeof(STLpoint));
+    os.write(reinterpret_cast<const char*>(&attrib_), sizeof(STLattrib));
+}
+
+
+inline Foam::Ostream& Foam::STLtriangle::print(Ostream& os) const
+{
+    os  << " facet normal "
+        << normal_.x() << ' ' << normal_.y() << ' ' << normal_.z() << nl
+        << "  outer loop" << nl
+        << "   vertex " << a_.x() << ' ' << a_.y() << ' ' << a_.z() << nl
+        << "   vertex " << b_.x() << ' ' << b_.y() << ' ' << b_.z() << nl
+        << "   vertex " << c_.x() << ' ' << c_.y() << ' ' << c_.z() << nl
+        << "  endloop" << nl
+        << " endfacet" << nl;
+
+    return os;
+}
+
+
+inline void Foam::STLtriangle::write
+(
+    Ostream& os,
+    const vector& norm,
+    const point& pt0,
+    const point& pt1,
+    const point& pt2
+)
+{
+    os  << " facet normal "
+        << norm.x() << ' ' << norm.y() << ' ' << norm.z() << nl
+        << "  outer loop" << nl
+        << "   vertex " << pt0.x() << ' ' << pt0.y() << ' ' << pt0.z() << nl
+        << "   vertex " << pt1.x() << ' ' << pt1.y() << ' ' << pt1.z() << nl
+        << "   vertex " << pt2.x() << ' ' << pt2.y() << ' ' << pt2.z() << nl
+        << "  endloop" << nl
+        << " endfacet" << nl;
+}
+
+
+inline void Foam::STLtriangle::write
+(
+    Ostream& os,
+    const point& pt0,
+    const point& pt1,
+    const point& pt2
+)
 {
-    os.write(reinterpret_cast<char*>(this), 4*sizeof(STLpoint));
-    os.write(reinterpret_cast<char*>(&attrib_), sizeof(STLattrib));
+    // calculate the normal ourselves
+    vector norm = triPointRef(pt0, pt1, pt2).normal();
+    norm /= mag(norm) + VSMALL;
+
+    write(os, norm, pt0, pt1, pt2);
 }
 
 
diff --git a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatRunTime.C b/src/fileFormats/vtk/foamVtkCore.C
similarity index 69%
rename from src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatRunTime.C
rename to src/fileFormats/vtk/foamVtkCore.C
index 737cb11053ddb25ecb6ec7a05302ac91d98eca98..2450c02b7b2d0c1c7acc86c9a1c7f6395410bbc0 100644
--- a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatRunTime.C
+++ b/src/fileFormats/vtk/foamVtkCore.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,39 +23,32 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "WRLsurfaceFormat.H"
-
-#include "addToRunTimeSelectionTable.H"
-#include "addToMemberFunctionSelectionTable.H"
+#include "foamVtkCore.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-namespace Foam
-{
-namespace fileFormats
-{
 
-// write MeshedSurfaceProxy
-addNamedTemplatedToMemberFunctionSelectionTable
-(
-    MeshedSurfaceProxy,
-    WRLsurfaceFormat,
-    face,
-    write,
-    fileExtension,
-    wrl
-);
-addNamedTemplatedToMemberFunctionSelectionTable
-(
-    MeshedSurfaceProxy,
-    WRLsurfaceFormat,
-    triFace,
-    write,
-    fileExtension,
-    wrl
-);
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::fileFormats::foamVtkCore::foamVtkCore()
+{}
+
+
+// * * * * * * * * * * *  Protected Member Functions * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+/*
+Foam::fileName Foam::fileFormats::foamVtkCore::vtkFileName
+(
+    const fileName& base,
+    const enum fileExt ext
+)
+{
+    return base + '.' + fileExtensions_[ext];
 }
-}
+*/
+
 
 // ************************************************************************* //
diff --git a/src/fileFormats/vtk/foamVtkCore.H b/src/fileFormats/vtk/foamVtkCore.H
new file mode 100644
index 0000000000000000000000000000000000000000..adcdc00871a5300fb0e5ddb4e12345473d40b1f8
--- /dev/null
+++ b/src/fileFormats/vtk/foamVtkCore.H
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::foamVtkCore
+
+Description
+    Core routines for dealing with VTK files.
+
+SourceFiles
+    foamVtkCore.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkCore_H
+#define foamVtkCore_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class fileFormats::foamVtkCore Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkCore
+{
+public:
+
+    // Public Data, Declarations
+
+        //- The context when outputting a VTK file (XML or legacy).
+        enum OutputContext
+        {
+            INLINE,     //<! Generate header and inline data
+            HEADER,     //<! Generate header only
+            APPEND      //<! Generate append-data
+        };
+
+
+        //- Equivalent to enumeration in "vtkCellType.h"
+        enum vtkTypes
+        {
+            VTK_EMPTY_CELL       = 0,
+            VTK_VERTEX           = 1,
+            VTK_POLY_VERTEX      = 2,
+            VTK_LINE             = 3,
+            VTK_POLY_LINE        = 4,
+            VTK_TRIANGLE         = 5,
+            VTK_TRIANGLE_STRIP   = 6,
+            VTK_POLYGON          = 7,
+            VTK_PIXEL            = 8,
+            VTK_QUAD             = 9,
+            VTK_TETRA            = 10,
+            VTK_VOXEL            = 11,
+            VTK_HEXAHEDRON       = 12,
+            VTK_WEDGE            = 13,
+            VTK_PYRAMID          = 14,
+            VTK_PENTAGONAL_PRISM = 15,
+            VTK_HEXAGONAL_PRISM  = 16,
+            VTK_POLYHEDRON       = 42
+        };
+
+
+protected:
+
+    // Constructors
+
+        //- Construct null
+        foamVtkCore();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..ee8b84200f0aaa5b8d333d2e577b44c2d5289be3
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.C
@@ -0,0 +1,65 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkAppendBase64Formatter.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAppendBase64Formatter::name_     = "append";
+const char* Foam::foamVtkAppendBase64Formatter::encoding_ = "base64";
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkAppendBase64Formatter::foamVtkAppendBase64Formatter
+(
+    std::ostream& os
+)
+:
+    foamVtkBase64Formatter(os)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkAppendBase64Formatter::~foamVtkAppendBase64Formatter()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAppendBase64Formatter::name() const
+{
+    return name_;
+}
+
+
+const char* Foam::foamVtkAppendBase64Formatter::encoding() const
+{
+    return encoding_;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightStream.H b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H
similarity index 59%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightStream.H
rename to src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H
index 89146e11023a703e3cfe8087864f2f1e7a215935..b7239ee7c66ffc637441b4504eb69a9a74f52a24 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/ensightStream.H
+++ b/src/fileFormats/vtk/format/foamVtkAppendBase64Formatter.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -22,83 +22,72 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::ensightStream
+    foamVtkAppendBase64Formatter
 
 Description
-    Abstract base class for writing Ensight data
+    Appended base-64 encoded binary output.
+    Uses an output filter layer to write base-64 encoded content.
 
 SourceFiles
-    ensightStream.C
+    foamVtkAppendBase64Formatter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef ensightStream_H
-#define ensightStream_H
+#ifndef foamVtkAppendBase64Formatter_H
+#define foamVtkAppendBase64Formatter_H
 
-#include "fileName.H"
-#include "scalarField.H"
+#include "foamVtkBase64Formatter.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-
 /*---------------------------------------------------------------------------*\
-                         Class ensightStream Declaration
+                Class foamVtkAppendBase64Formatter Declaration
 \*---------------------------------------------------------------------------*/
 
-class ensightStream
+class foamVtkAppendBase64Formatter
+:
+    public foamVtkBase64Formatter
 {
-    // Private data
+    // Private Data Members
+
+        static const char* name_;
+        static const char* encoding_;
 
-        const fileName name_;
 
     // Private Member Functions
 
-        //- Disallow default bitwise copy construct
-        ensightStream(const ensightStream&) = delete;
+    //- Disallow default bitwise copy construct
+    foamVtkAppendBase64Formatter(const foamVtkAppendBase64Formatter&) = delete;
 
-        //- Disallow default bitwise assignment
-        void operator=(const ensightStream&) = delete;
+    //- Disallow default bitwise assignment
+    void operator=(const foamVtkAppendBase64Formatter&) = delete;
 
 
 public:
 
     // Constructors
 
-        //- Construct from components
-        ensightStream(const fileName& f)
-        :
-            name_(f)
-        {}
+        //- Construct and attach to an output stream
+        foamVtkAppendBase64Formatter(std::ostream&);
 
 
     //- Destructor
-    virtual ~ensightStream()
-    {}
+    virtual ~foamVtkAppendBase64Formatter();
 
 
     // Member Functions
 
-        const fileName& name() const
-        {
-            return name_;
-        }
-
-        virtual void write(const char*) = 0;
-
-        virtual void write(const int) = 0;
+        //- Output name for XML type ("append")
+        virtual const char* name() const;
 
-        virtual void write(const scalarField&) = 0;
-
-        virtual void write(const List<int>&) = 0;
-
-        virtual void writePartHeader(const label) = 0;
+        //- Name for the XML append encoding ("base64").
+        virtual const char* encoding() const;
 
 };
 
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..9933970495ea2e8a920659bf6f61edd680933914
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.C
@@ -0,0 +1,112 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkAppendRawFormatter.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAppendRawFormatter::name_     = "append";
+const char* Foam::foamVtkAppendRawFormatter::encoding_ = "raw";
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::foamVtkAppendRawFormatter::write
+(
+    const char* s,
+    std::streamsize n
+)
+{
+    os().write(s, n);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkAppendRawFormatter::foamVtkAppendRawFormatter(std::ostream& os)
+:
+    foamVtkFormatter(os)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkAppendRawFormatter::~foamVtkAppendRawFormatter()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAppendRawFormatter::name() const
+{
+    return name_;
+}
+
+
+const char* Foam::foamVtkAppendRawFormatter::encoding() const
+{
+    return encoding_;
+}
+
+
+void Foam::foamVtkAppendRawFormatter::writeSize(const uint64_t val)
+{
+    write(reinterpret_cast<const char*>(&val), sizeof(uint64_t));
+}
+
+
+void Foam::foamVtkAppendRawFormatter::write(const uint8_t val)
+{
+    write(reinterpret_cast<const char*>(&val), sizeof(uint8_t));
+}
+
+
+void Foam::foamVtkAppendRawFormatter::write(const label val)
+{
+    // std::cerr<<"label is:" << sizeof(val) << '\n';
+    write(reinterpret_cast<const char*>(&val), sizeof(label));
+}
+
+
+void Foam::foamVtkAppendRawFormatter::write(const float val)
+{
+    // std::cerr<<"float is:" << sizeof(val) << '\n';
+    write(reinterpret_cast<const char*>(&val), sizeof(float));
+}
+
+
+void Foam::foamVtkAppendRawFormatter::write(const double val)
+{
+    // std::cerr<<"write double as float:" << val << '\n';
+    float copy(val);
+    write(copy);
+}
+
+
+void Foam::foamVtkAppendRawFormatter::flush()
+{}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H
new file mode 100644
index 0000000000000000000000000000000000000000..abc3db09293f7baccc6c1796ef4ba3ffe40d2e1d
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkAppendRawFormatter.H
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkAppendRawFormatter
+
+Description
+    Appended raw binary output.
+
+SourceFiles
+    foamVtkAppendRawFormatter.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkAppendRawFormatter_H
+#define foamVtkAppendRawFormatter_H
+
+#include "foamVtkFormatter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class foamVtkAppendRawFormatter Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkAppendRawFormatter
+:
+    public foamVtkFormatter
+{
+    // Private Data Members
+
+        static const char* name_;
+        static const char* encoding_;
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        foamVtkAppendRawFormatter(const foamVtkAppendRawFormatter&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const foamVtkAppendRawFormatter&) = delete;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Write
+        void write(const char* s, std::streamsize n);
+
+
+public:
+
+    // Constructors
+
+        //- Construct and attach to an output stream
+        foamVtkAppendRawFormatter(std::ostream&);
+
+
+    //- Destructor
+    virtual ~foamVtkAppendRawFormatter();
+
+
+    // Member Functions
+
+        //- Output name for XML type ("append")
+        virtual const char* name() const;
+
+        //- Output name for append encoding type ("raw")
+        virtual const char* encoding() const;
+
+
+        //- Write leading size for binary output
+        virtual void writeSize(const uint64_t);
+
+        virtual void write(const uint8_t);
+        virtual void write(const label);
+        virtual void write(const float);
+        virtual void write(const double);
+        virtual void flush();
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..6a78f73f53cbf19db657bda92e828c282329d4ab
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.C
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkAsciiFormatter.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAsciiFormatter::name_ = "ascii";
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+inline void Foam::foamVtkAsciiFormatter::next()
+{
+    if (pos_ == 6)
+    {
+        os()<< '\n';
+        pos_ = 0;
+    }
+    else if (pos_)
+    {
+        os()<< ' ';
+    }
+    ++pos_;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkAsciiFormatter::foamVtkAsciiFormatter(std::ostream& os)
+:
+    foamVtkFormatter(os),
+    pos_(0)
+{}
+
+
+Foam::foamVtkAsciiFormatter::foamVtkAsciiFormatter
+(
+    std::ostream& os,
+    unsigned precision
+)
+:
+    foamVtkFormatter(os),
+    pos_(0)
+{
+    os.precision(precision);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkAsciiFormatter::~foamVtkAsciiFormatter()
+{
+    flush();
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkAsciiFormatter::name() const
+{
+    return name_;
+}
+
+
+const char* Foam::foamVtkAsciiFormatter::encoding() const
+{
+    return name_;
+}
+
+
+void Foam::foamVtkAsciiFormatter::writeSize(const uint64_t)
+{/*nop*/}
+
+
+void Foam::foamVtkAsciiFormatter::write(const uint8_t val)
+{
+    next();
+    os()<< int(val);
+}
+
+
+void Foam::foamVtkAsciiFormatter::write(const label val)
+{
+    next();
+    os()<< val;
+}
+
+
+void Foam::foamVtkAsciiFormatter::write(const float val)
+{
+    next();
+    os()<< val;
+}
+
+
+void Foam::foamVtkAsciiFormatter::write(const double val)
+{
+    next();
+    os()<< float(val);
+}
+
+
+void Foam::foamVtkAsciiFormatter::flush()
+{
+    if (pos_)
+    {
+        os()<< '\n';
+    }
+    pos_ = 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H
new file mode 100644
index 0000000000000000000000000000000000000000..009d776f89f1d85cf3cd5335e2feb5cde8695047
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkAsciiFormatter.H
@@ -0,0 +1,120 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkAsciiFormatter
+
+Description
+    Inline ASCII binary output.
+    Adds spaces between entries and a newline every 6 items
+    (for consistency with what VTK itself outputs).
+
+SourceFiles
+    foamVtkAsciiFormatter.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkAsciiFormatter_H
+#define foamVtkAsciiFormatter_H
+
+#include "foamVtkFormatter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class foamVtkAsciiFormatter Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkAsciiFormatter
+:
+    public foamVtkFormatter
+{
+    // Private Data Members
+
+        static const char* name_;
+
+        //- Track the current output position
+        unsigned short pos_;
+
+
+    // Private Member Functions
+
+        //- Advance to next position, adding space or newline as required
+        inline void next();
+
+
+        //- Disallow default bitwise copy construct
+        foamVtkAsciiFormatter(const foamVtkAsciiFormatter&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const foamVtkAsciiFormatter&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct and attach to an output stream, use default precision
+        foamVtkAsciiFormatter(std::ostream&);
+
+        //- Construct and attach to an output stream, use specified precision
+        foamVtkAsciiFormatter(std::ostream&, unsigned precision);
+
+
+    //- Destructor
+    virtual ~foamVtkAsciiFormatter();
+
+
+    // Member Functions
+
+        //- Name for the XML output type ("ascii")
+        //  The legacy output type is an uppercase version of this.
+        virtual const char* name() const;
+
+        //- Name for the XML append encoding - unused.
+        //  Currently simply "ASCII", but this should not be relied upon.
+        virtual const char* encoding() const;
+
+
+        //- Write leading size - this is a no-op for ascii output
+        virtual void writeSize(const uint64_t);
+
+        virtual void write(const uint8_t);
+        virtual void write(const label);
+        virtual void write(const float);
+        virtual void write(const double);
+        virtual void flush();
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkBase64Formatter.C b/src/fileFormats/vtk/format/foamVtkBase64Formatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..a11d97bd49e573d318700e6e56f66802364daf51
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkBase64Formatter.C
@@ -0,0 +1,120 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkBase64Formatter.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkBase64Formatter::name_     = "binary";
+const char* Foam::foamVtkBase64Formatter::encoding_ = "base64";
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::foamVtkBase64Formatter::write
+(
+    const char* s,
+    std::streamsize n
+)
+{
+    base64Layer::write(s, n);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkBase64Formatter::foamVtkBase64Formatter(std::ostream& os)
+:
+    foamVtkFormatter(os),
+    base64Layer(os)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkBase64Formatter::~foamVtkBase64Formatter()
+{
+    flush();
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkBase64Formatter::name() const
+{
+    return name_;
+}
+
+
+const char* Foam::foamVtkBase64Formatter::encoding() const
+{
+    return encoding_;
+}
+
+
+void Foam::foamVtkBase64Formatter::writeSize(const uint64_t val)
+{
+    write(reinterpret_cast<const char*>(&val), sizeof(uint64_t));
+}
+
+
+void Foam::foamVtkBase64Formatter::write(const uint8_t val)
+{
+    base64Layer::add(val);
+}
+
+
+void Foam::foamVtkBase64Formatter::write(const label val)
+{
+    // std::cerr<<"label is:" << sizeof(val) << '\n';
+    write(reinterpret_cast<const char*>(&val), sizeof(label));
+}
+
+
+void Foam::foamVtkBase64Formatter::write(const float val)
+{
+    // std::cerr<<"float is:" << sizeof(val) << '\n';
+    write(reinterpret_cast<const char*>(&val), sizeof(float));
+}
+
+
+void Foam::foamVtkBase64Formatter::write(const double val)
+{
+    // std::cerr<<"write double as float:" << val << '\n';
+    float copy(val);
+    write(copy);
+}
+
+
+void Foam::foamVtkBase64Formatter::flush()
+{
+    if (base64Layer::close())
+    {
+        os().put('\n');
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkBase64Formatter.H b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H
new file mode 100644
index 0000000000000000000000000000000000000000..f01bec3d9aa343159749834e47cc0f7ff14e62fe
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkBase64Formatter.H
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkBase64Formatter
+
+Description
+    Inline base-64 encoded binary output.
+    Uses an output filter layer to write base-64 encoded content.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkBase64Formatter_H
+#define foamVtkBase64Formatter_H
+
+#include "foamVtkFormatter.H"
+#include "base64Layer.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class foamVtkBase64Formatter Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkBase64Formatter
+:
+    public foamVtkFormatter,
+    private base64Layer
+{
+    // Private Data Members
+
+        static const char* name_;
+        static const char* encoding_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        foamVtkBase64Formatter(const foamVtkBase64Formatter&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const foamVtkBase64Formatter&) = delete;
+
+protected:
+
+    // Protected Member Functions
+
+        //- Write
+        void write(const char* s, std::streamsize n);
+
+
+public:
+
+    // Constructors
+
+        //- Construct and attach to an output stream
+        foamVtkBase64Formatter(std::ostream&);
+
+
+    //- Destructor
+    virtual ~foamVtkBase64Formatter();
+
+
+    // Member Functions
+
+        //- Name for the XML output type ("binary")
+        //  The lowercase version of the Legacy output type.
+        virtual const char* name() const;
+
+        //- Name for the XML append encoding.
+        virtual const char* encoding() const;
+
+
+        //- Write leading size for binary output
+        virtual void writeSize(const uint64_t);
+
+        virtual void write(const uint8_t);
+        virtual void write(const label);
+        virtual void write(const float);
+        virtual void write(const double);
+        virtual void flush();
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.C b/src/fileFormats/vtk/format/foamVtkFormatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..b204ad22795410165c657f553ea44b8b63b52cff
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkFormatter.C
@@ -0,0 +1,315 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkFormatter.H"
+#include "foamVtkPTraits.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* const Foam::foamVtkFormatter::byteOrder
+    = Foam::foamVtkPTraits<endian>::typeName;
+
+const char* const Foam::foamVtkFormatter::headerType =
+    Foam::foamVtkPTraits<uint64_t>::typeName;
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkFormatter::foamVtkFormatter(std::ostream& os)
+:
+    os_(os),
+    xmlTags_(),
+    inTag_(false)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkFormatter::~foamVtkFormatter()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::foamVtkFormatter::indent()
+{
+    label n = xmlTags_.size() * 2;
+    while (n--)
+    {
+        os_ << ' ';
+    }
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::xmlHeader()
+{
+    if (inTag_)
+    {
+        WarningInFunction
+            << "xml header, but already within a tag!"
+            << endl;
+    }
+
+    os_ << "<?xml version='1.0'?>" << nl;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::comment(const std::string& text)
+{
+    if (inTag_)
+    {
+        WarningInFunction
+            << "adding xml comment inside a tag??"
+            << endl;
+    }
+
+    indent();
+    os_ << "<!-- " << text << " -->" << nl;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::openTag(const word& tag)
+{
+    if (inTag_)
+    {
+        WarningInFunction
+            << "open XML tag '" << tag << "', but already within a tag!"
+            << endl;
+    }
+
+    indent();
+    os_ << '<' << tag;
+
+    xmlTags_.push(tag);
+    inTag_ = true;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::closeTag(bool isEmpty)
+{
+    if (!inTag_)
+    {
+        WarningInFunction
+            << "close XML tag, but not within a tag!"
+            << endl;
+    }
+
+    if (isEmpty)
+    {
+        // eg, <tag ... />
+        xmlTags_.pop();
+        os_ << " /";
+    }
+    os_ << '>' << nl;
+
+    inTag_ = false;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::tag(const word& tag)
+{
+    openTag(tag);
+    closeTag();
+
+    return *this;
+}
+
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::endTag(const word& tag)
+{
+    const word curr = xmlTags_.pop();
+    indent();
+
+    if (inTag_)
+    {
+        WarningInFunction
+            << "adding XML endTag '" << curr
+            << "' but already in another tag!"
+            << endl;
+    }
+
+    // verify inTag_
+    if (!tag.empty() && tag != curr)
+    {
+        WarningInFunction
+            << "expected to end xml-tag '" << tag
+            << "' but found '" << curr << "' instead"
+            << endl;
+    }
+
+    os_  << "</" << curr << '>' << nl;
+
+    inTag_ = false;
+
+    return *this;
+}
+
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::xmlAttr
+(
+    const word& k,
+    const std::string& v,
+    const char quote
+)
+{
+    if (!inTag_)
+    {
+        WarningInFunction
+            << "xml attribute '" << k << "' but not within a tag!"
+            << endl;
+    }
+
+    os_ << ' ' << k << '=' << quote << v.c_str() << quote;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::xmlAttr
+(
+    const word& k,
+    const label v,
+    const char quote
+)
+{
+    if (!inTag_)
+    {
+        WarningInFunction
+            << "xml attribute '" << k << "' but not within a tag!"
+            << endl;
+    }
+
+    os_ << ' ' << k << '=' << quote << v << quote;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::xmlAttr
+(
+    const word& k,
+    const uint64_t v,
+    const char quote
+)
+{
+    if (!inTag_)
+    {
+        WarningInFunction
+            << "xml attribute '" << k << "' but not within a tag!"
+            << endl;
+    }
+
+    os_ << ' ' << k << '=' << quote << v << quote;
+
+    return *this;
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::xmlAttr
+(
+    const word& k,
+    const scalar v,
+    const char quote
+)
+{
+    if (!inTag_)
+    {
+        WarningInFunction
+            << "xml attribute '" << k << "' but not within a tag!"
+            << endl;
+    }
+
+    os_ << ' ' << k << '=' << quote << v << quote;
+
+    return *this;
+}
+
+
+// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::operator()
+(
+    const word& k,
+    const std::string& v
+)
+{
+    return xmlAttr(k, v);
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::operator()
+(
+    const word& k,
+    const label v
+)
+{
+    return xmlAttr(k, v);
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::operator()
+(
+    const word& k,
+    const uint64_t v
+)
+{
+    return xmlAttr(k, v);
+}
+
+
+Foam::foamVtkFormatter&
+Foam::foamVtkFormatter::operator()
+(
+    const word& k,
+    const scalar v
+)
+{
+    return xmlAttr(k, v);
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkFormatter.H b/src/fileFormats/vtk/format/foamVtkFormatter.H
new file mode 100644
index 0000000000000000000000000000000000000000..4fe0cb997773461de2a049b087af731126b359ee
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkFormatter.H
@@ -0,0 +1,233 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkFormatter
+
+Description
+    Abstract class for a VTK output stream formatter.
+
+    Includes very simple support for writing XML tags.
+
+SourceFiles
+    foamVtkFormatter.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkFormatter_H
+#define foamVtkFormatter_H
+
+#include "int.H"
+#include "uint64.H"
+#include "label.H"
+#include "word.H"
+#include "UList.H"
+#include "LIFOStack.H"
+#include "foamVtkPTraits.H"
+
+#include <iostream>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class foamVtkFormatter Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkFormatter
+{
+    // Private Data
+
+        //- The output stream for the formatter
+        std::ostream& os_;
+
+        //- Stack of current XML tags
+        LIFOStack<word> xmlTags_;
+
+        //- Tag open/closed/ended state
+        mutable bool inTag_;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Construct and attach to an output stream
+        foamVtkFormatter(std::ostream& os);
+
+public:
+
+    // Static Data
+
+        //- VTK name for the 'byte_order' attribute
+        static const char* const byteOrder;
+
+        //- VTK name for the 'header_type' attribute (UInt64)
+        static const char* const headerType;
+
+
+    //- Destructor
+    virtual ~foamVtkFormatter();
+
+
+    // Member Functions
+
+        //- Access to the underlying output stream
+        inline std::ostream& os()
+        {
+            return os_;
+        }
+
+
+        //- Name for the XML output type.
+        //  Possibly the lowercase version of the Legacy output type
+        virtual const char* name() const = 0;
+
+        //- Name for the XML append encoding
+        virtual const char* encoding() const = 0;
+
+
+        //- Write leading size for binary output
+        virtual void writeSize(const uint64_t) = 0;
+
+        virtual void write(const uint8_t) = 0;
+        virtual void write(const label) = 0;
+        virtual void write(const float) = 0;
+        virtual void write(const double) = 0;
+        virtual void flush() = 0;
+
+
+    // Member Functions
+
+        //- Indent according to the currently nested XML tags
+        void indent();
+
+        //- Write XML header
+        foamVtkFormatter& xmlHeader();
+
+        //- Write XML comment (at the current indentation level)
+        foamVtkFormatter& comment(const std::string&);
+
+
+        //- Open XML tag
+        foamVtkFormatter& openTag(const word& tag);
+
+        //- Close XML tag, optional as an empty container.
+        //  Always adds a trailing newline.
+        foamVtkFormatter& closeTag(bool isEmpty = false);
+
+        //- End XML tag, optional with sanity check
+        //  Always adds a trailing newline.
+        foamVtkFormatter& endTag(const word& tag = word::null);
+
+        //- Write XML tag without any attributes. Combines openTag/closeTag.
+        foamVtkFormatter& tag(const word& tag);
+
+
+        //- Open "DataArray" XML tag
+        template<class Type, int nComp=0>
+        foamVtkFormatter& openDataArray(const word& dataName);
+
+
+        //- Insert a single "PDataArray" XML entry tag.
+        //  For some entries, the name is optional.
+        template<class Type, int nComp=0>
+        foamVtkFormatter& PDataArray(const word& dataName);
+
+
+        //- End "DataArray" XML tag
+        foamVtkFormatter& endDataArray()
+        {
+            return endTag("DataArray");
+        }
+
+
+
+        //- Write XML attribute
+        foamVtkFormatter& xmlAttr
+        (
+            const word&,
+            const std::string&,
+            const char quote='\''
+        );
+
+        //- Write XML attribute
+        foamVtkFormatter& xmlAttr
+        (
+            const word&,
+            const label,
+            const char quote='\''
+        );
+
+        //- Write XML attribute
+        foamVtkFormatter& xmlAttr
+        (
+            const word&,
+            const uint64_t,
+            const char quote='\''
+        );
+
+        //- Write XML attribute
+        foamVtkFormatter& xmlAttr
+        (
+            const word&,
+            const scalar,
+            const char quote='\''
+        );
+
+
+
+    // Member Operators
+
+        //- Write XML attribute
+        foamVtkFormatter& operator()(const word&, const std::string&);
+
+        //- Write XML attribute
+        foamVtkFormatter& operator()(const word&, const label);
+
+        //- Write XML attribute
+        foamVtkFormatter& operator()(const word&, const uint64_t);
+
+        //- Write XML attribute
+        foamVtkFormatter& operator()(const word&, const scalar);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "foamVtkFormatterTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/triSurface/tools/hashSignedLabel/hashSignedLabel.H b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C
similarity index 60%
rename from src/triSurface/tools/hashSignedLabel/hashSignedLabel.H
rename to src/fileFormats/vtk/format/foamVtkFormatterTemplates.C
index 992a8202903975604f71fc93f78e5618f33a28a6..6e0830e2b1fab52f022a8ef6cfd81dbf15581d03 100644
--- a/src/triSurface/tools/hashSignedLabel/hashSignedLabel.H
+++ b/src/fileFormats/vtk/format/foamVtkFormatterTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -20,48 +20,51 @@ License
 
     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::hashSignedLabel
-
-Description
-    hash for signed integers (Hash\<label\> only works for unsigned ints)
-
 \*---------------------------------------------------------------------------*/
 
-#ifndef HashSignedLabel_H
-#define HashSignedLabel_H
+#include "foamVtkPTraits.H"
 
-#include "List.H"
-#include "word.H"
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                           Class hashSignedLabel Declaration
-\*---------------------------------------------------------------------------*/
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-class hashSignedLabel
+template<class Type, int nComp>
+Foam::foamVtkFormatter& Foam::foamVtkFormatter::openDataArray
+(
+    const word& dataName
+)
 {
+    openTag("DataArray");
+    xmlAttr("type", foamVtkPTraits<Type>::typeName);
+    xmlAttr("Name", dataName);
+    if (nComp > 1)
+    {
+        xmlAttr("NumberOfComponents", nComp);
+    }
+    xmlAttr("format", name());
 
-public:
-
-    hashSignedLabel()
-    {}
+    return *this;
+}
 
 
-    label operator()(const label key, const label tableSize) const
+template<class Type, int nComp>
+Foam::foamVtkFormatter& Foam::foamVtkFormatter::PDataArray
+(
+    const word& dataName
+)
+{
+    openTag("PDataArray");
+    xmlAttr("type", foamVtkPTraits<Type>::typeName);
+    if (dataName.size())
     {
-        return mag(key)%tableSize;
+        xmlAttr("Name", dataName);
+    }
+    if (nComp > 1)
+    {
+        xmlAttr("NumberOfComponents", nComp);
     }
-};
-
-} // End namespace Foam
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+    closeTag(true);
 
-#endif
+    return *this;
+}
 
 // ************************************************************************* //
-
diff --git a/src/fileFormats/vtk/format/foamVtkLegacyFormatter.C b/src/fileFormats/vtk/format/foamVtkLegacyFormatter.C
new file mode 100644
index 0000000000000000000000000000000000000000..177249b306a84daf44531ffb39668beb836b9a0e
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkLegacyFormatter.C
@@ -0,0 +1,139 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkLegacyFormatter.H"
+#include "endian.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkLegacyFormatter::name_ = "BINARY";
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::foamVtkLegacyFormatter::write
+(
+    const char* s,
+    std::streamsize n
+)
+{
+    os().write(s, n);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::foamVtkLegacyFormatter::foamVtkLegacyFormatter(std::ostream& os)
+:
+    foamVtkFormatter(os)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::foamVtkLegacyFormatter::~foamVtkLegacyFormatter()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const char* Foam::foamVtkLegacyFormatter::name() const
+{
+    return name_;
+}
+
+
+const char* Foam::foamVtkLegacyFormatter::encoding() const
+{
+    return name_;
+}
+
+
+void Foam::foamVtkLegacyFormatter::writeSize(const uint64_t)
+{}
+
+
+void Foam::foamVtkLegacyFormatter::write(const uint8_t val)
+{
+    // Can only handle integers
+    int copy(val);
+    write(copy);
+}
+
+
+void Foam::foamVtkLegacyFormatter::write(const label val)
+{
+    // std::cerr<<"label is:" << sizeof(val) << '\n';
+
+    // Not entirely correct: the legacy format only supports 32-bit integers.
+    // Either limit size for 64-bit label, or simply do not support for 64-bit.
+#ifdef WM_LITTLE_ENDIAN
+# if WM_LABEL_SIZE == 32
+    uint32_t swapped = endian::swap32(val);
+    write(reinterpret_cast<const char*>(&swapped), sizeof(uint32_t));
+# elif WM_LABEL_SIZE == 64
+    uint64_t swapped = endian::swap64(val);
+    write(reinterpret_cast<const char*>(&swapped), sizeof(uint64_t));
+#endif
+#else
+    write(reinterpret_cast<const char*>(&val), sizeof(label));
+#endif
+}
+
+
+void Foam::foamVtkLegacyFormatter::write(const float val)
+{
+    // std::cerr<<"float is:" << sizeof(val) << '\n';
+
+#ifdef WM_LITTLE_ENDIAN
+    // De-reference in two stages to avoid the warning
+    //     dereferencing type-punned pointer will break strict-aliasing rules
+    //     [-Wstrict-aliasing]
+
+    const uint32_t* ptr = reinterpret_cast<const uint32_t*>(&val);
+    uint32_t swapped = endian::swap32(*ptr);
+    write(reinterpret_cast<const char*>(&swapped), sizeof(uint32_t));
+#else
+    write(reinterpret_cast<const char*>(&val), sizeof(float));
+#endif
+}
+
+
+void Foam::foamVtkLegacyFormatter::write(const double val)
+{
+    // Legacy cannot support Float64 anyhow.
+    // std::cerr<<"write double as float:" << val << '\n';
+    float copy(val);
+    write(copy);
+}
+
+
+void Foam::foamVtkLegacyFormatter::flush()
+{
+    os()<< '\n';
+}
+
+
+// ************************************************************************* //
diff --git a/src/triSurface/triSurface/surfacePatch/surfacePatchIOList.H b/src/fileFormats/vtk/format/foamVtkLegacyFormatter.H
similarity index 51%
rename from src/triSurface/triSurface/surfacePatch/surfacePatchIOList.H
rename to src/fileFormats/vtk/format/foamVtkLegacyFormatter.H
index 5dca93d6f02e3cbfcbd6f73b9bf8dff4b9fca6b1..fe2395add4d143085d854c987d040b6ed051caaa 100644
--- a/src/triSurface/triSurface/surfacePatch/surfacePatchIOList.H
+++ b/src/fileFormats/vtk/format/foamVtkLegacyFormatter.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,109 +22,91 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::surfacePatchIOList
+    foamVtkLegacyFormatter
 
 Description
-    IOobject for a surfacePatchList
+    Binary output for the VTK legacy format, always written as big-endian.
+
+    The legacy files are always written as big endian.
+    Since integers in the legacy format are limited to 32-bit,
+    this format should not be used for OpenFOAM with 64-bit label sizes.
 
 SourceFiles
-    surfacePatchIOList.C
+    foamVtkLegacyFormatter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfacePatchIOList_H
-#define surfacePatchIOList_H
+#ifndef foamVtkLegacyFormatter_H
+#define foamVtkLegacyFormatter_H
 
-#include "surfacePatchList.H"
-#include "regIOobject.H"
-#include "faceList.H"
-#include "className.H"
+#include "foamVtkFormatter.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// Forward declaration of friend functions and operators
-
-class surfacePatchIOList;
-
-Ostream& operator<<(Ostream&, const surfacePatchIOList&);
-
-
 /*---------------------------------------------------------------------------*\
-                           Class surfacePatchIOList Declaration
+                   Class foamVtkLegacyFormatter Declaration
 \*---------------------------------------------------------------------------*/
 
-class surfacePatchIOList
+class foamVtkLegacyFormatter
 :
-    public surfacePatchList,
-    public regIOobject
+    public foamVtkFormatter
 {
-    // Private data
+    // Private Data Members
+
+        static const char* name_;
 
 
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        surfacePatchIOList(const surfacePatchIOList&);
+        foamVtkLegacyFormatter(const foamVtkLegacyFormatter&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const surfacePatchIOList&);
+        void operator=(const foamVtkLegacyFormatter&) = delete;
 
 
-public:
+protected:
 
-    //- Runtime type information
-    TypeName("surfacePatchIOList");
+    // Protected Member Functions
 
+        //- Write
+        void write(const char* s, std::streamsize n);
 
-    // Static data members
 
-        //- Static data someStaticData
+public:
 
     // Constructors
 
-        //- Construct from IOobject
-        explicit surfacePatchIOList(const IOobject& io);
+        //- Construct and attach to an output stream
+        foamVtkLegacyFormatter(std::ostream&);
 
-        //- Construct from IOobject
-        surfacePatchIOList(const IOobject& io, const surfacePatchList&);
 
     //- Destructor
-    ~surfacePatchIOList();
+    virtual ~foamVtkLegacyFormatter();
 
 
     // Member Functions
 
-        //- writeData member function required by regIOobject
-        bool writeData(Ostream&) const;
-
-        //- Is object global
-        virtual bool global() const
-        {
-            return true;
-        }
-        //- Return complete path + object name if the file exists
-        //  either in the case/processor or case otherwise null
-        virtual fileName filePath() const
-        {
-            return globalFilePath();
-        }
-
-    // IOstream Operators
+        //- Name for the Legacy output type ("BINARY")
+        virtual const char* name() const;
 
-        friend Ostream& operator<<(Ostream&, const surfacePatchIOList&);
-};
+        //- Name for the XML append encoding (unused)
+        //  Currently simply "BINARY", but this should not be relied upon.
+        virtual const char* encoding() const;
 
 
-//- Template function for obtaining global status
-template<>
-inline bool typeGlobal<surfacePatchIOList>()
-{
-    return true;
-}
+        //- Write leading size - a no-op for legacy binary output
+        virtual void writeSize(const uint64_t);
 
+        virtual void write(const uint8_t);
+        virtual void write(const label);
+        virtual void write(const float);
+        virtual void write(const double);
+        virtual void flush();
+};
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/fileFormats/vtk/format/foamVtkOutputOptions.C b/src/fileFormats/vtk/format/foamVtkOutputOptions.C
new file mode 100644
index 0000000000000000000000000000000000000000..816cbe90b906762658ce94dac8db39f39c9d7e86
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkOutputOptions.C
@@ -0,0 +1,240 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkOutputOptions.H"
+
+#include "foamVtkAppendBase64Formatter.H"
+#include "foamVtkAppendRawFormatter.H"
+#include "foamVtkAsciiFormatter.H"
+#include "foamVtkBase64Formatter.H"
+#include "foamVtkLegacyFormatter.H"
+
+#include "IOstream.H"
+
+
+// * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * //
+
+Foam::foamVtkOutputOptions::foamVtkOutputOptions()
+:
+    type_(ASCII),
+    style_(NONE),
+    precision_(IOstream::defaultPrecision())
+{}
+
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::foamVtkFormatter>
+Foam::foamVtkOutputOptions::newFormatter
+(
+    std::ostream& os
+) const
+{
+    switch (type_)
+    {
+        case (LEGACY | BINARY):
+            return autoPtr<foamVtkFormatter>
+            (
+                new foamVtkLegacyFormatter(os)
+            );
+
+        case BASE64:  // xml insitu
+            return autoPtr<foamVtkFormatter>
+            (
+                new foamVtkBase64Formatter(os)
+            );
+
+        case (APPEND | BASE64):
+            return autoPtr<foamVtkFormatter>
+            (
+                new foamVtkAppendBase64Formatter(os)
+            );
+
+        case (APPEND | BINARY):
+            return autoPtr<foamVtkFormatter>
+            (
+                new foamVtkAppendRawFormatter(os)
+            );
+
+        default:   // ASCII (legacy or xml) must always work
+            return autoPtr<foamVtkFormatter>
+            (
+                new foamVtkAsciiFormatter(os, precision_)
+            );
+    }
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::foamVtkOutputOptions::ascii(bool b)
+{
+    if (b)
+    {
+        // Force ASCII:
+
+        if (type_ & APPEND)
+        {
+            // Append: ascii = base64 (vs raw binary)
+            type_ = (APPEND | BASE64);
+        }
+        else if (type_ & LEGACY)
+        {
+            // Legacy: ascii = ascii
+            type_ = (LEGACY | ASCII);
+        }
+        else
+        {
+            // XML: ascii = ascii
+            type_ = ASCII;
+        }
+    }
+    else
+    {
+        // Non-ASCII:
+
+        if (type_ & APPEND)
+        {
+            // Append: binary == (raw) binary
+            type_ = APPEND | BINARY;
+        }
+        else if (type_ & LEGACY)
+        {
+            // Legacy: binary = binary
+            type_ = LEGACY | BINARY;
+        }
+        else
+        {
+            // XML: binary == (inline) binary == base64
+            type_ = BASE64;
+        }
+    }
+}
+
+
+void Foam::foamVtkOutputOptions::append(bool b)
+{
+    if (b)
+    {
+        if (!(type_ & APPEND))
+        {
+            // XML:    base64 -> raw binary, ascii -> base64
+            // Legacy: binary -> raw binary, ascii -> base64
+            type_ = APPEND | ((type_ & (BASE64 | BINARY)) ? BINARY : BASE64);
+        }
+    }
+    else if (type_ & APPEND)
+    {
+        // Only revert back to inline XML base64 versions
+        // ASCII needs another step.
+
+        type_ = BASE64;
+    }
+}
+
+
+void Foam::foamVtkOutputOptions::legacy(bool b)
+{
+    if (b)
+    {
+        if (type_ & APPEND)
+        {
+            // Append: base64 -> ascii, binary -> binary
+            type_ = (LEGACY | ((type_ & BINARY) ? BINARY : ASCII));
+        }
+        else if (type_ & LEGACY)
+        {
+            // no-op
+        }
+        else
+        {
+            // XML: ascii -> ascii, base64 -> binary
+            type_ = (LEGACY | ((type_ & BASE64) ? BINARY : ASCII));
+        }
+    }
+    else if (type_ & LEGACY)
+    {
+        // Legacy: ascii -> xml ascii, binary -> xml base64
+        type_ = (type_ & BINARY) ? BASE64 : ASCII;
+    }
+}
+
+
+void Foam::foamVtkOutputOptions::precision(unsigned val) const
+{
+    precision_ = val;
+}
+
+
+Foam::Ostream&
+Foam::foamVtkOutputOptions::info(Ostream& os) const
+{
+    os << "type: " << type_;
+
+    switch (type_)
+    {
+        case (LEGACY | ASCII):
+            os << " legacy ascii";
+            break;
+
+        case (LEGACY | BINARY):
+            os << " legacy binary";
+            break;
+
+        case BASE64:
+            os << " xml insitu base64";
+            break;
+
+        case (APPEND | BASE64):
+            os << " xml-append base64";
+            break;
+
+        case (APPEND | BINARY):
+            os << " xml-append binary";
+            break;
+
+        case ASCII:
+            os << " xml insitu ascii";
+            break;
+
+        case BINARY:
+            os << " xml insitu binary - WRONG";
+            break;
+
+        default:
+            os << " unknown";
+            break;
+    }
+
+    if (legacy()) os << " legacy";
+    if (xml())    os << " xml";
+    if (append()) os << " append";
+    if (ascii())  os << " ascii";
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/format/foamVtkOutputOptions.H b/src/fileFormats/vtk/format/foamVtkOutputOptions.H
new file mode 100644
index 0000000000000000000000000000000000000000..43a3ee0918e89350419ab3fda802fb18fb8c3acc
--- /dev/null
+++ b/src/fileFormats/vtk/format/foamVtkOutputOptions.H
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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
+    foamVtkOutputOptions
+
+Description
+    Encapsulate combinations of output format options.
+
+SourceFiles
+    foamVtkOutputOptions.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkOutputOptions_H
+#define foamVtkOutputOptions_H
+
+#include "autoPtr.H"
+#include "foamVtkFormatter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+class Ostream;
+
+/*---------------------------------------------------------------------------*\
+                    Class foamVtkOutputOptions Declaration
+\*---------------------------------------------------------------------------*/
+
+class foamVtkOutputOptions
+{
+    // Private data
+
+        //- The supported output/format types
+        enum foamVtkOptionTypes
+        {
+            ASCII  = 0x0000,    //!< ASCII formatting for data
+            BINARY = 0x0001,    //!< Raw binary formatting for data
+            BASE64 = 0x0002,    //!< Base64 encoding for data
+            LEGACY = 0x0100,    //!< Legacy vtk file format
+            APPEND = 0x0200     //!< XML append format
+        };
+
+        //- The output style tuning
+        enum foamVtkStyleOptions
+        {
+            NONE   = 0x0000,    //!< Normal
+            HEADER = 0x0001     //!< Emit xml header
+        };
+
+
+        //- The output format type
+        unsigned short type_;
+
+        //- The output style tuning
+        unsigned short style_;
+
+
+        //- ASCII write precision
+        mutable unsigned precision_;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null - XML insitu ASCII format with default precision
+        foamVtkOutputOptions();
+
+
+    // Selectors
+
+        //- Return new data formatter based on the writer options
+        autoPtr<foamVtkFormatter> newFormatter(std::ostream&) const;
+
+
+    // Member Functions
+
+    // Access
+
+        //- True if writer uses legacy file format
+        inline bool legacy() const;
+
+        //- True if writer uses XML file format (non-legacy)
+        inline bool xml() const;
+
+        //- True if output format uses an append mode
+        inline bool append() const;
+
+        //- True if output format does not use an append mode
+        inline bool insitu() const;
+
+        //- True if output format is ASCII
+        inline bool ascii() const;
+
+
+    // Edit
+
+        //- Toggle ASCII mode on/off.
+        //  In append mode, this switches between base64 and raw binary.
+        //  In XML mode, this switches between ASCII and base64.
+        //  In legacy mode, this switches between ASCII and binary.
+        void ascii(bool);
+
+        //- Toggle append mode on/off.
+        void append(bool);
+
+        //- Toggle legacy mode on/off.
+        void legacy(bool);
+
+        //- Set the write precision to be used for new ASCII formatters
+        void precision(unsigned val) const;
+
+
+    // Other
+
+        //- Report information about the options
+        Ostream& info(Ostream&) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "foamVtkOutputOptionsI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMTupleRemap.H b/src/fileFormats/vtk/format/foamVtkOutputOptionsI.H
similarity index 61%
rename from applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMTupleRemap.H
rename to src/fileFormats/vtk/format/foamVtkOutputOptionsI.H
index 79f3ab3127f610497faa1f2bd7f817f613ed5018..0205f2f98ec87c5dba88223afb604310eb13407b 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/vtkOpenFOAMTupleRemap.H
+++ b/src/fileFormats/vtk/format/foamVtkOutputOptionsI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,39 +21,36 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-InClass
-    vtkPV3Foam
-
 \*---------------------------------------------------------------------------*/
 
-#ifndef vtkOpenFOAMTupleRemap_H
-#define vtkOpenFOAMTupleRemap_H
-
-// OpenFOAM includes
-#include "Swap.H"
+inline bool Foam::foamVtkOutputOptions::legacy() const
+{
+    return (type_ & LEGACY);
+}
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<class Type>
-inline void vtkOpenFOAMTupleRemap(float vec[]);
+inline bool Foam::foamVtkOutputOptions::xml() const
+{
+    return !legacy();
+}
 
 
-// Template specialization for symmTensor
-template<>
-inline void vtkOpenFOAMTupleRemap<Foam::symmTensor>(float vec[])
+inline bool Foam::foamVtkOutputOptions::append() const
 {
-    Foam::Swap(vec[1], vec[3]);   // swap XY <-> YY
-    Foam::Swap(vec[2], vec[5]);   // swap XZ <-> ZZ
+    return (type_ & APPEND);
 }
 
 
-template<class Type>
-inline void vtkOpenFOAMTupleRemap(float vec[])
-{}
+inline bool Foam::foamVtkOutputOptions::insitu() const
+{
+    return !(type_ & APPEND);
+}
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+inline bool Foam::foamVtkOutputOptions::ascii() const
+{
+    return !(type_ & (BINARY | BASE64));
+}
 
-#endif
 
 // ************************************************************************* //
diff --git a/src/fileFormats/vtk/vtkUnstructuredReader.C b/src/fileFormats/vtk/read/vtkUnstructuredReader.C
similarity index 98%
rename from src/fileFormats/vtk/vtkUnstructuredReader.C
rename to src/fileFormats/vtk/read/vtkUnstructuredReader.C
index 3edf53ee3d813f550a473f0da708ac73d0eba925..d834f4d5ebab183b171a2053f929833d1cec1106 100644
--- a/src/fileFormats/vtk/vtkUnstructuredReader.C
+++ b/src/fileFormats/vtk/read/vtkUnstructuredReader.C
@@ -136,7 +136,7 @@ void Foam::vtkUnstructuredReader::extractCells
     {
         switch (cellTypes[i])
         {
-            case VTK_VERTEX:
+            case foamVtkCore::VTK_VERTEX:
             {
                 warnUnhandledType(inFile, cellTypes[i], warningGiven);
                 label nRead = cellVertData[dataIndex++];
@@ -152,7 +152,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_POLY_VERTEX:
+            case foamVtkCore::VTK_POLY_VERTEX:
             {
                 warnUnhandledType(inFile, cellTypes[i], warningGiven);
                 label nRead = cellVertData[dataIndex++];
@@ -160,7 +160,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_LINE:
+            case foamVtkCore::VTK_LINE:
             {
                 //warnUnhandledType(inFile, cellTypes[i], warningGiven);
                 label nRead = cellVertData[dataIndex++];
@@ -180,7 +180,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_POLY_LINE:
+            case foamVtkCore::VTK_POLY_LINE:
             {
                 //warnUnhandledType(inFile, cellTypes[i], warningGiven);
                 label nRead = cellVertData[dataIndex++];
@@ -194,7 +194,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_TRIANGLE:
+            case foamVtkCore::VTK_TRIANGLE:
             {
                 faceMap_[facei] = i;
                 face& f = faces_[facei++];
@@ -214,7 +214,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_QUAD:
+            case foamVtkCore::VTK_QUAD:
             {
                 faceMap_[facei] = i;
                 face& f = faces_[facei++];
@@ -235,7 +235,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_POLYGON:
+            case foamVtkCore::VTK_POLYGON:
             {
                 faceMap_[facei] = i;
                 face& f = faces_[facei++];
@@ -248,7 +248,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_TETRA:
+            case foamVtkCore::VTK_TETRA:
             {
                 label nRead = cellVertData[dataIndex++];
                 if (nRead != 4)
@@ -268,7 +268,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_PYRAMID:
+            case foamVtkCore::VTK_PYRAMID:
             {
                 label nRead = cellVertData[dataIndex++];
                 if (nRead != 5)
@@ -289,7 +289,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_WEDGE:
+            case foamVtkCore::VTK_WEDGE:
             {
                 label nRead = cellVertData[dataIndex++];
                 if (nRead != 6)
@@ -311,7 +311,7 @@ void Foam::vtkUnstructuredReader::extractCells
             }
             break;
 
-            case VTK_HEXAHEDRON:
+            case foamVtkCore::VTK_HEXAHEDRON:
             {
                 label nRead = cellVertData[dataIndex++];
                 if (nRead != 8)
diff --git a/src/fileFormats/vtk/vtkUnstructuredReader.H b/src/fileFormats/vtk/read/vtkUnstructuredReader.H
similarity index 90%
rename from src/fileFormats/vtk/vtkUnstructuredReader.H
rename to src/fileFormats/vtk/read/vtkUnstructuredReader.H
index db2391bc3bc92705af4461eeff8b6ad025783032..77bd71b4aac8f6ebcbaf9b90e1e1023871bae610 100644
--- a/src/fileFormats/vtk/vtkUnstructuredReader.H
+++ b/src/fileFormats/vtk/read/vtkUnstructuredReader.H
@@ -25,8 +25,8 @@ Class
     Foam::vtkUnstructuredReader
 
 Description
-    Reader for vtk unstructured_grid legacy files. Supports single CELLS, POINTS
-    etc. entry only.
+    Reader for vtk UNSTRUCTURED_GRID legacy files.
+    Supports single CELLS, POINTS etc. entry only.
 
     - all integer types (int, unsigned_int, long etc.) become Foam::label
     - all real types (float, double) become Foam::scalar
@@ -47,6 +47,7 @@ SourceFiles
 #ifndef vtkUnstructuredReader_H
 #define vtkUnstructuredReader_H
 
+#include "foamVtkCore.H"
 #include "objectRegistry.H"
 #include "cellShapeList.H"
 #include "HashSet.H"
@@ -62,6 +63,8 @@ namespace Foam
 \*---------------------------------------------------------------------------*/
 
 class vtkUnstructuredReader
+:
+    public fileFormats::foamVtkCore
 {
 public:
 
@@ -108,29 +111,6 @@ public:
         static const NamedEnum<parseMode, 5> parseModeNames;
 
 
-        //- Enumeration defining the cell types
-        enum vtkTypes
-        {
-            VTK_EMPTY_CELL       = 0,
-            VTK_VERTEX           = 1,
-            VTK_POLY_VERTEX      = 2,
-            VTK_LINE             = 3,
-            VTK_POLY_LINE        = 4,
-            VTK_TRIANGLE         = 5,
-            VTK_TRIANGLE_STRIP   = 6,
-            VTK_POLYGON          = 7,
-            VTK_PIXEL            = 8,
-            VTK_QUAD             = 9,
-            VTK_TETRA            = 10,
-            VTK_VOXEL            = 11,
-            VTK_HEXAHEDRON       = 12,
-            VTK_WEDGE            = 13,
-            VTK_PYRAMID          = 14,
-            VTK_PENTAGONAL_PRISM = 15,
-            VTK_HEXAGONAL_PRISM  = 16,
-        };
-
-
 private:
 
     //- Header
diff --git a/src/fileFormats/vtk/vtkUnstructuredReaderTemplates.C b/src/fileFormats/vtk/read/vtkUnstructuredReaderTemplates.C
similarity index 98%
rename from src/fileFormats/vtk/vtkUnstructuredReaderTemplates.C
rename to src/fileFormats/vtk/read/vtkUnstructuredReaderTemplates.C
index eb1e5f5273eeea792e32ee14aac739ade81a8026..86f6f6d89544c0a8f28e3f14aee6fe20ee127287 100644
--- a/src/fileFormats/vtk/vtkUnstructuredReaderTemplates.C
+++ b/src/fileFormats/vtk/read/vtkUnstructuredReaderTemplates.C
@@ -56,7 +56,7 @@ void Foam::vtkUnstructuredReader::printFieldStats
 {
     wordList fieldNames(obj.names(Type::typeName));
 
-    if (fieldNames.size() > 0)
+    if (fieldNames.size())
     {
         Info<< "Read " << fieldNames.size() << " " << Type::typeName
             << " fields:" << endl;
diff --git a/src/fileFormats/vtk/type/foamVtkPTraits.C b/src/fileFormats/vtk/type/foamVtkPTraits.C
new file mode 100644
index 0000000000000000000000000000000000000000..91bf1f3a33b647663c9077245b8252efa4d0c76a
--- /dev/null
+++ b/src/fileFormats/vtk/type/foamVtkPTraits.C
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "foamVtkPTraits.H"
+#include "endian.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template<>
+const char* const
+Foam::foamVtkPTraits<uint8_t>::typeName = "UInt8";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<int32_t>::typeName = "Int32";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<uint32_t>::typeName = "UInt32";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<int64_t>::typeName = "Int64";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<uint64_t>::typeName = "UInt64";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<float>::typeName = "Float32";
+
+template<>
+const char * const
+Foam::foamVtkPTraits<double>::typeName = "Float64";
+
+#ifdef WM_LITTLE_ENDIAN
+template<>
+const char* const
+Foam::foamVtkPTraits<::Foam::endian>::typeName = "LittleEndian";
+#else
+template<>
+const char* const
+Foam::foamVtkPTraits<::Foam::endian>::typeName = "BigEndian";
+#endif
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/type/foamVtkPTraits.H b/src/fileFormats/vtk/type/foamVtkPTraits.H
new file mode 100644
index 0000000000000000000000000000000000000000..ea95c0820d1f61f8190336f0c7dd092013ffd98d
--- /dev/null
+++ b/src/fileFormats/vtk/type/foamVtkPTraits.H
@@ -0,0 +1,93 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::foamVtkPTraits
+
+Description
+    Names for VTK primitive types.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkPTraits_H
+#define foamVtkPTraits_H
+
+#include <cstdint>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class endian;
+
+/*---------------------------------------------------------------------------*\
+                         Class foamVtkPTraits Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class PrimitiveType>
+class foamVtkPTraits
+{
+public:
+
+    // Static data members
+
+        static const char* const typeName;
+};
+
+
+template<>
+const char* const foamVtkPTraits<uint8_t>::typeName;  // = UInt8
+
+template<>
+const char* const foamVtkPTraits<int32_t>::typeName;  // = Int32
+
+template<>
+const char* const foamVtkPTraits<int32_t>::typeName;  // = UInt32
+
+template<>
+const char* const foamVtkPTraits<int32_t>::typeName;  // = Int64
+
+template<>
+const char* const foamVtkPTraits<int64_t>::typeName;  // = UInt64
+
+template<>
+const char* const foamVtkPTraits<float>::typeName;    // = Float32
+
+template<>
+const char* const foamVtkPTraits<double>::typeName;   // = Float64
+
+template<>
+const char* const foamVtkPTraits<::Foam::endian>::typeName;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/functionObjects/field/blendingFactor/blendingFactor.C b/src/functionObjects/field/blendingFactor/blendingFactor.C
index f631b7e851ec9a0a8333d7fb2993301b2ca1b63e..3861e809a2d0382108fcd105a326233164d7b4b9 100644
--- a/src/functionObjects/field/blendingFactor/blendingFactor.C
+++ b/src/functionObjects/field/blendingFactor/blendingFactor.C
@@ -114,6 +114,7 @@ Foam::functionObjects::blendingFactor::~blendingFactor()
 bool Foam::functionObjects::blendingFactor::read(const dictionary& dict)
 {
     fieldExpression::read(dict);
+    writeFile::read(dict);
 
     phiName_ = dict.lookupOrDefault<word>("phi", "phi");
     dict.readIfPresent("tolerance", tolerance_);
diff --git a/src/functionObjects/field/externalCoupled/externalCoupled.C b/src/functionObjects/field/externalCoupled/externalCoupled.C
index 727aa595f5d2302cc6a2cb7e05c56c2b15b1f758..999e311f202ce4c9092d4ff5e1e06a453f154aae 100644
--- a/src/functionObjects/field/externalCoupled/externalCoupled.C
+++ b/src/functionObjects/field/externalCoupled/externalCoupled.C
@@ -936,37 +936,33 @@ bool Foam::functionObjects::externalCoupled::read(const dictionary& dict)
     }
 
 
-    // Print a bit
-    if (log)
+    Info<< type() << ": Communicating with regions:" << endl;
+    forAll(regionGroupNames_, rgi)
     {
-        Info<< type() << ": Communicating with regions:" << endl;
-        forAll(regionGroupNames_, rgi)
-        {
-            //const wordList& regionNames = regionGroupRegions_[rgi];
-            const word& compName = regionGroupNames_[rgi];
+        //const wordList& regionNames = regionGroupRegions_[rgi];
+        const word& compName = regionGroupNames_[rgi];
 
-            Info<< "Region: " << compName << endl << incrIndent;
-            const labelList& groups = regionToGroups_[compName];
-            forAll(groups, i)
-            {
-                label groupi = groups[i];
-                const wordRe& groupName = groupNames_[groupi];
+        Info<< "Region: " << compName << endl << incrIndent;
+        const labelList& groups = regionToGroups_[compName];
+        forAll(groups, i)
+        {
+            label groupi = groups[i];
+            const wordRe& groupName = groupNames_[groupi];
 
-                Info<< indent << "patchGroup: " << groupName << "\t"
-                    << endl
-                    << incrIndent
-                    << indent << "Reading fields: "
-                    << groupReadFields_[groupi]
-                    << endl
-                    << indent << "Writing fields: "
-                    << groupWriteFields_[groupi]
-                    << endl
-                    << decrIndent;
-            }
-            Info<< decrIndent;
+            Info<< indent << "patchGroup: " << groupName << "\t"
+                << endl
+                << incrIndent
+                << indent << "Reading fields: "
+                << groupReadFields_[groupi]
+                << endl
+                << indent << "Writing fields: "
+                << groupWriteFields_[groupi]
+                << endl
+                << decrIndent;
         }
-        Info<< endl;
+        Info<< decrIndent;
     }
+    Info<< endl;
 
 
     // Note: we should not have to make directories since the geometry
diff --git a/src/functionObjects/field/fieldAverage/fieldAverage.C b/src/functionObjects/field/fieldAverage/fieldAverage.C
index d7cd691bf224be836685d70b21da89c5d8287e24..46c30fbc973859f7faa505f2072aff4badb523f2 100644
--- a/src/functionObjects/field/fieldAverage/fieldAverage.C
+++ b/src/functionObjects/field/fieldAverage/fieldAverage.C
@@ -108,8 +108,7 @@ void Foam::functionObjects::fieldAverage::initialize()
 
 void Foam::functionObjects::fieldAverage::restart()
 {
-    Log
-        << "    Restarting averaging at time " << obr_.time().timeName()
+    Log << "    Restarting averaging at time " << obr_.time().timeName()
         << nl << endl;
 
     totalIter_.clear();
@@ -159,8 +158,7 @@ void Foam::functionObjects::fieldAverage::calcAverages()
         restart();
     }
 
-    Log
-        << type() << " " << name() << " write:" << nl
+    Log << type() << " " << name() << " write:" << nl
         << "    Calculating averages" << nl;
 
     addMeanSqrToPrime2Mean<scalar, scalar>();
@@ -221,14 +219,14 @@ void Foam::functionObjects::fieldAverage::readAveragingProperties()
     totalTime_.clear();
     totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue());
 
-    if ((restartOnRestart_ || restartOnOutput_) && log)
+    if (restartOnRestart_ || restartOnOutput_)
     {
         Info<< "    Starting averaging at time " << obr_.time().timeName()
             << nl;
     }
     else
     {
-        Log << "    Restarting averaging for fields:" << nl;
+        Info<< "    Restarting averaging for fields:" << nl;
 
 
         forAll(faItems_, fieldi)
@@ -242,15 +240,13 @@ void Foam::functionObjects::fieldAverage::readAveragingProperties()
                 totalIter_[fieldi] = readLabel(fieldDict.lookup("totalIter"));
                 totalTime_[fieldi] = readScalar(fieldDict.lookup("totalTime"));
 
-                Log
-                    << "        " << fieldName
+                Info<< "        " << fieldName
                     << " iters = " << totalIter_[fieldi]
                     << " time = " << totalTime_[fieldi] << nl;
             }
             else
             {
-                Log
-                    << "        " << fieldName
+                Info<< "        " << fieldName
                     << ": starting averaging at time "
                     << obr_.time().timeName() << endl;
             }
@@ -299,7 +295,7 @@ bool Foam::functionObjects::fieldAverage::read(const dictionary& dict)
 
     initialised_ = false;
 
-    Log << type() << " " << name() << ":" << nl;
+    Info<< type() << " " << name() << ":" << nl;
 
     dict.readIfPresent("restartOnRestart", restartOnRestart_);
     dict.readIfPresent("restartOnOutput", restartOnOutput_);
@@ -309,8 +305,7 @@ bool Foam::functionObjects::fieldAverage::read(const dictionary& dict)
     if (periodicRestart_)
     {
         dict.lookup("restartPeriod") >> restartPeriod_;
-        Log
-            << "    Restart period " << restartPeriod_
+        Info<< "    Restart period " << restartPeriod_
             << nl << endl;
     }
 
@@ -324,15 +319,14 @@ bool Foam::functionObjects::fieldAverage::read(const dictionary& dict)
         }
         else
         {
-            Log
-                << "    Restart scheduled at time " << restartTime_
+            Info<< "    Restart scheduled at time " << restartTime_
                 << nl << endl;
         }
     }
 
     readAveragingProperties();
 
-    Log << endl;
+    Info<< endl;
 
     return true;
 }
diff --git a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
index 4d16100f9212601fb387cdca1eb0485b2c5975a7..c9aabb275c4653da6204d7014bc30eaeca1ac207 100644
--- a/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
+++ b/src/functionObjects/field/fieldCoordinateSystemTransform/fieldCoordinateSystemTransform.C
@@ -60,7 +60,7 @@ fieldCoordinateSystemTransform
 {
     read(dict);
 
-    Log << type() << " " << name << ":" << nl
+    Info<< type() << " " << name << ":" << nl
         << "   Applying transformation from global Cartesian to local "
         << coordSys_ << nl << endl;
 }
diff --git a/src/functionObjects/field/fieldMinMax/fieldMinMax.C b/src/functionObjects/field/fieldMinMax/fieldMinMax.C
index 5c6f4f4d6af66c8c35ec7c1199a48753ccf40892..c2f6b643a6333f72891d7a480bc2179dded645a0 100644
--- a/src/functionObjects/field/fieldMinMax/fieldMinMax.C
+++ b/src/functionObjects/field/fieldMinMax/fieldMinMax.C
@@ -122,6 +122,7 @@ Foam::functionObjects::fieldMinMax::~fieldMinMax()
 bool Foam::functionObjects::fieldMinMax::read(const dictionary& dict)
 {
     fvMeshFunctionObject::read(dict);
+    writeFile::read(dict);
 
     location_ = dict.lookupOrDefault<Switch>("location", true);
 
diff --git a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C b/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C
index 90010c4669e97062a2698e1ab6144ac0411ac69a..ca24bdad368348cce2d594a8c14ea327cd21bb27 100644
--- a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C
+++ b/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C
@@ -128,7 +128,6 @@ bool Foam::functionObjects::fieldValues::fieldValueDelta::read
 )
 {
     fvMeshFunctionObject::read(dict);
-
     writeFile::read(dict);
 
     region1Ptr_.reset
@@ -210,9 +209,9 @@ bool Foam::functionObjects::fieldValues::fieldValueDelta::write()
         applyOperation<symmTensor>(type1, name1, name2, entry1, entry2, found);
         applyOperation<tensor>(type1, name1, name2, entry1, entry2, found);
 
-        if (log && !found)
+        if (!found)
         {
-            Info<< "Operation between "
+            Log << "Operation between "
                 << name1 << " with result " << entry1 << " and "
                 << name2 << " with result " << entry2 << " not applied"
                 << endl;
diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C
index 907d365d5c97ff67b0751a263d095cd3f57dfb45..578cf6884bd1be5d5ca673270268091eac4706a8 100644
--- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C
+++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C
@@ -488,7 +488,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
         if (weightFieldName_ == "none")
         {
             dict.lookup("orientedWeightField") >>  weightFieldName_;
-            Log << "    weight field = " << weightFieldName_ << nl;
+            Info<< "    weight field = " << weightFieldName_ << nl;
             orientWeightField_ = true;
         }
         else
diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C
index 68158b58ffd05dd97593c18a8d293e7087908a87..5272714d95781c3a10710c061248aafafd0b44bc 100644
--- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C
+++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C
@@ -328,8 +328,11 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
                 (
                     outputDir(),
                     regionTypeNames_[regionType_] + ("_" + regionName_),
-                    points,
-                    faces,
+                    meshedSurfRef
+                    (
+                        points,
+                        faces
+                    ),
                     fieldName,
                     allValues,
                     false
diff --git a/src/functionObjects/field/flowType/flowType.C b/src/functionObjects/field/flowType/flowType.C
index 1451154bb0d7bbb693a5d4b2ce6e81b136627858..b74616a7f3b54fd8b9b84dec98633ea9755a556e 100644
--- a/src/functionObjects/field/flowType/flowType.C
+++ b/src/functionObjects/field/flowType/flowType.C
@@ -21,28 +21,6 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Class
-    flowType
-
-Group
-    grpPostProcessingUtilities
-
-Description
-    Calculates and writes the flowType of velocity field U.
-
-    The -noWrite option has no meaning.
-
-    The flow type parameter is obtained according to the following equation:
-    \verbatim
-                 |D| - |Omega|
-        lambda = -------------
-                 |D| + |Omega|
-
-        -1 = rotational flow
-         0 = simple shear flow
-         1 = planar extensional flow
-    \endverbatim
-
 \*---------------------------------------------------------------------------*/
 
 #include "flowType.H"
diff --git a/src/functionObjects/field/fluxSummary/fluxSummary.C b/src/functionObjects/field/fluxSummary/fluxSummary.C
index deb45d77f19c753c2f8a6cae59f4093b9fbca2c8..7a27f185272e0a30c783392827006f3726ba3107 100644
--- a/src/functionObjects/field/fluxSummary/fluxSummary.C
+++ b/src/functionObjects/field/fluxSummary/fluxSummary.C
@@ -727,22 +727,18 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
         }
     }
 
-    // Provide some output
-    if (log)
-    {
-        Info<< type() << " " << name() << " output:" << nl;
+    Info<< type() << " " << name() << " output:" << nl;
 
-        forAll(faceZoneName_, zonei)
-        {
-            const word& zoneName = faceZoneName_[zonei];
-            scalar zoneArea = faceArea_[zonei];
-
-            Info<< "    Zone: " << zoneName << ", area: " << zoneArea << nl;
-        }
+    forAll(faceZoneName_, zonei)
+    {
+        const word& zoneName = faceZoneName_[zonei];
+        scalar zoneArea = faceArea_[zonei];
 
-        Info<< endl;
+        Info<< "    Zone: " << zoneName << ", area: " << zoneArea << nl;
     }
 
+    Info<< endl;
+
     return true;
 }
 
diff --git a/src/functionObjects/field/histogram/histogram.C b/src/functionObjects/field/histogram/histogram.C
index 63e2abcf0a88239f9db45cfa8ea08dfe9a87d6b7..064fb9dded1917aae67d973ca1f2f8293f888e4a 100644
--- a/src/functionObjects/field/histogram/histogram.C
+++ b/src/functionObjects/field/histogram/histogram.C
@@ -93,6 +93,7 @@ Foam::functionObjects::histogram::~histogram()
 bool Foam::functionObjects::histogram::read(const dictionary& dict)
 {
     fvMeshFunctionObject::read(dict);
+    writeFile::read(dict);
 
     dict.lookup("field") >> fieldName_;
     dict.lookup("max") >> max_;
diff --git a/src/functionObjects/field/mapFields/mapFields.C b/src/functionObjects/field/mapFields/mapFields.C
index 3f3ff47ab58d25d13f4f73b8fd98979826ffdb51..00a387ad6e32265cda85d875f4275cdc722230e9 100644
--- a/src/functionObjects/field/mapFields/mapFields.C
+++ b/src/functionObjects/field/mapFields/mapFields.C
@@ -55,7 +55,7 @@ void Foam::functionObjects::mapFields::createInterpolation
     const fvMesh& meshTarget = mesh_;
     const word mapRegionName(dict.lookup("mapRegion"));
 
-    Log << name() << ':' << nl
+    Info<< name() << ':' << nl
         << "    Reading mesh " << mapRegionName << endl;
 
     mapRegionPtr_.reset
@@ -97,12 +97,12 @@ void Foam::functionObjects::mapFields::createInterpolation
     // Optionally override
     if (dict.readIfPresent("patchMapMethod", patchMapMethodName))
     {
-        Log << "    Patch mapping method: " << patchMapMethodName << endl;
+        Info<< "    Patch mapping method: " << patchMapMethodName << endl;
     }
 
     bool consistent = readBool(dict.lookup("consistent"));
 
-    Log << "    Creating mesh to mesh interpolation" << endl;
+    Info<< "    Creating mesh to mesh interpolation" << endl;
 
     if (consistent)
     {
diff --git a/src/functionObjects/field/nearWallFields/nearWallFields.C b/src/functionObjects/field/nearWallFields/nearWallFields.C
index 1cb3f0684ecca3188b8cda80d44c8238749bf227..061aca85e974e041d74c8ed818ccac9c94089305 100644
--- a/src/functionObjects/field/nearWallFields/nearWallFields.C
+++ b/src/functionObjects/field/nearWallFields/nearWallFields.C
@@ -281,7 +281,7 @@ bool Foam::functionObjects::nearWallFields::read(const dictionary& dict)
         reverseFieldMap_.insert(sampleFldName, fldName);
     }
 
-    Log  << type() << " " << name()
+    Info<< type() << " " << name()
         << ": Sampling " << fieldMap_.size() << " fields" << endl;
 
     // Do analysis
diff --git a/src/functionObjects/field/reactionSensitivityAnalysis/reactionsSensitivityAnalysis.C b/src/functionObjects/field/reactionSensitivityAnalysis/reactionsSensitivityAnalysis.C
index 8664497061df151553461d0a33447ff3c80cd8db..939de3548f02ec872f71952cbd063946f323fd88 100644
--- a/src/functionObjects/field/reactionSensitivityAnalysis/reactionsSensitivityAnalysis.C
+++ b/src/functionObjects/field/reactionSensitivityAnalysis/reactionsSensitivityAnalysis.C
@@ -138,10 +138,10 @@ writeSpeciesRR()
     prodFilePtr_() << "delta T : "<< mesh_.time().deltaT().value() << nl << nl;
 
     consIntFilePtr_() << "start time : " << startTime_ << tab
-            << "end time :" <<  endTime_ << nl;
+        << "end time :" <<  endTime_ << nl;
 
     prodIntFilePtr_() << "start time : " << startTime_ << tab
-            << "end time :" <<  endTime_ << nl;
+        << "end time :" <<  endTime_ << nl;
 
     for (label reactioni = 0; reactioni < nReactions_; ++reactioni)
     {
@@ -202,7 +202,7 @@ reactionsSensitivityAnalysis
     if (mesh_.nCells() != 1)
     {
         FatalErrorInFunction
-            << "Function object only applicable to single cell cases "
+            << "Function object only applicable to single cell cases"
             << abort(FatalError);
     }
 
@@ -243,9 +243,9 @@ reactionsSensitivityAnalysis
     }
     else
     {
-         FatalErrorInFunction
-            << " Not chemistry model found. "
-            << " Object available are : " << mesh_.names()
+        FatalErrorInFunction
+            << " No chemistry model found. "
+            << " Objects available are : " << mesh_.names()
             << exit(FatalError);
     }
 }
diff --git a/src/functionObjects/field/readFields/readFieldsTemplates.C b/src/functionObjects/field/readFields/readFieldsTemplates.C
index fee32c56272a9ce7727890226de7c464f82c82bc..07d73044c796d8e54dc70c286dc832a1a003cfcd 100644
--- a/src/functionObjects/field/readFields/readFieldsTemplates.C
+++ b/src/functionObjects/field/readFields/readFieldsTemplates.C
@@ -60,7 +60,7 @@ bool Foam::functionObjects::readFields::loadField(const word& fieldName)
             IOobject::NO_WRITE
         );
 
-        if (fieldHeader.typeHeaderOk<VolFieldType>(false))
+        if (fieldHeader.typeHeaderOk<VolFieldType>(true))
         {
             // Store field on mesh database
             Log << "    Reading " << fieldName << endl;
@@ -68,7 +68,7 @@ bool Foam::functionObjects::readFields::loadField(const word& fieldName)
             mesh_.objectRegistry::store(vfPtr);
             return true;
         }
-        else if (fieldHeader.typeHeaderOk<SurfaceFieldType>(false))
+        else if (fieldHeader.typeHeaderOk<SurfaceFieldType>(true))
         {
             // Store field on mesh database
             Log << "    Reading " << fieldName << endl;
diff --git a/src/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C b/src/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
index fccc1b9cd168750ab4e42f4dc99974f6a4cf59dc..48504de23d74eb317d493b6ae58719f18b6b07ee 100644
--- a/src/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
+++ b/src/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C
@@ -354,6 +354,7 @@ Foam::functionObjects::regionSizeDistribution::~regionSizeDistribution()
 bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
 {
     fvMeshFunctionObject::read(dict);
+    writeFile::read(dict);
 
     dict.lookup("field") >> alphaName_;
     dict.lookup("patches") >> patchNames_;
@@ -371,7 +372,7 @@ bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
     {
         coordSysPtr_.reset(new coordinateSystem(obr_, dict));
 
-        Log << "Transforming all vectorFields with coordinate system "
+        Info<< "Transforming all vectorFields with coordinate system "
             << coordSysPtr_().name() << endl;
     }
 
diff --git a/src/functionObjects/field/streamLine/streamLine.C b/src/functionObjects/field/streamLine/streamLine.C
index 1edbba13e6a0be9e083b0fd921cb37d3bfe1bb45..8f0bd5cc9ae875bd6bf2688b555981f9c9c4d27c 100644
--- a/src/functionObjects/field/streamLine/streamLine.C
+++ b/src/functionObjects/field/streamLine/streamLine.C
@@ -162,7 +162,7 @@ bool Foam::functionObjects::streamLine::read(const dictionary& dict)
             nSubCycle_ = max(nSubCycle_, 1);
 
 
-            Log << "    automatic track length specified through"
+            Info<< "    automatic track length specified through"
                 << " number of sub cycles : " << nSubCycle_ << nl
                 << endl;
         }
diff --git a/src/functionObjects/field/turbulenceFields/turbulenceFields.C b/src/functionObjects/field/turbulenceFields/turbulenceFields.C
index 29c1facb0e8aa22aa8b31867bc598c7b4b07dddd..b09c20ad5f37a58d61e5ee2347933f361683be13 100644
--- a/src/functionObjects/field/turbulenceFields/turbulenceFields.C
+++ b/src/functionObjects/field/turbulenceFields/turbulenceFields.C
@@ -157,19 +157,19 @@ bool Foam::functionObjects::turbulenceFields::read(const dictionary& dict)
         fieldSet_.insert(wordList(dict.lookup("fields")));
     }
 
-    Log << type() << " " << name() << ": ";
+    Info<< type() << " " << name() << ": ";
     if (fieldSet_.size())
     {
-        Log << "storing fields:" << nl;
+        Info<< "storing fields:" << nl;
         forAllConstIter(wordHashSet, fieldSet_, iter)
         {
-            Log << "    " << modelName << ':' << iter.key() << nl;
+            Info<< "    " << modelName << ':' << iter.key() << nl;
         }
-        Log << endl;
+        Info<< endl;
     }
     else
     {
-        Log << "no fields requested to be stored" << nl << endl;
+        Info<< "no fields requested to be stored" << nl << endl;
     }
 
     return true;
diff --git a/src/functionObjects/field/wallShearStress/wallShearStress.C b/src/functionObjects/field/wallShearStress/wallShearStress.C
index 39b4a5ed3d56326d51f0cc238796920fc7c3ab60..13911234410e4df35e54c11a9cd641d08d3ca1ee 100644
--- a/src/functionObjects/field/wallShearStress/wallShearStress.C
+++ b/src/functionObjects/field/wallShearStress/wallShearStress.C
@@ -143,7 +143,7 @@ bool Foam::functionObjects::wallShearStress::read(const dictionary& dict)
             wordReList(dict.lookupOrDefault("patches", wordReList()))
         );
 
-    Log << type() << " " << name() << ":" << nl;
+    Info<< type() << " " << name() << ":" << nl;
 
     if (patchSet_.empty())
     {
@@ -155,7 +155,7 @@ bool Foam::functionObjects::wallShearStress::read(const dictionary& dict)
             }
         }
 
-        Log << "    processing all wall patches" << nl << endl;
+        Info<< "    processing all wall patches" << nl << endl;
     }
     else
     {
@@ -177,7 +177,7 @@ bool Foam::functionObjects::wallShearStress::read(const dictionary& dict)
             }
         }
 
-        Log << endl;
+        Info<< endl;
 
         patchSet_ = filteredPatchSet;
     }
diff --git a/src/functionObjects/forces/forces/forces.C b/src/functionObjects/forces/forces/forces.C
index 1a7018fb4cab8a1fef900d68a021182d0ba12970..97de38581f28c37ba7fa76e93f8996b639b82cf2 100644
--- a/src/functionObjects/forces/forces/forces.C
+++ b/src/functionObjects/forces/forces/forces.C
@@ -180,7 +180,7 @@ void Foam::functionObjects::forces::initialise()
         if (!foundObject<volVectorField>(fDName_))
         {
             FatalErrorInFunction
-                << "Could not find " << fDName_ << " in database."
+                << "Could not find " << fDName_ << " in database"
                 << exit(FatalError);
         }
     }
@@ -194,14 +194,15 @@ void Foam::functionObjects::forces::initialise()
         )
         {
             FatalErrorInFunction
-                << "Could not find " << UName_ << ", " << pName_
+                << "Could not find U: " << UName_ << " or p:" << pName_
+                << " in database"
                 << exit(FatalError);
         }
 
         if (rhoName_ != "rhoInf" && !foundObject<volScalarField>(rhoName_))
         {
             FatalErrorInFunction
-                << "Could not find " << rhoName_
+                << "Could not find rho:" << rhoName_
                 << exit(FatalError);
         }
     }
@@ -269,13 +270,13 @@ void Foam::functionObjects::forces::initialiseBins()
         {
             binPoints_[i] = (i + 0.5)*binDir_*binDx_;
         }
+    }
 
-        // Allocate storage for forces and moments
-        forAll(force_, i)
-        {
-            force_[i].setSize(nBin_, vector::zero);
-            moment_[i].setSize(nBin_, vector::zero);
-        }
+    // Allocate storage for forces and moments
+    forAll(force_, i)
+    {
+        force_[i].setSize(nBin_, vector::zero);
+        moment_[i].setSize(nBin_, vector::zero);
     }
 }
 
@@ -732,7 +733,7 @@ Foam::functionObjects::forces::forces
 )
 :
     fvMeshFunctionObject(name, runTime, dict),
-    writeFile(mesh_, name, name, dict),
+    writeFile(mesh_, name),
     force_(3),
     moment_(3),
     forceFilePtr_(),
@@ -780,7 +781,7 @@ Foam::functionObjects::forces::forces
 )
 :
     fvMeshFunctionObject(name, obr, dict),
-    writeFile(mesh_, name, name, dict),
+    writeFile(mesh_, name),
     force_(3),
     moment_(3),
     forceFilePtr_(),
@@ -845,7 +846,7 @@ bool Foam::functionObjects::forces::read(const dictionary& dict)
 
     initialised_ = false;
 
-    Info << type() << " " << name() << ":" << nl;
+    Info<< type() << " " << name() << ":" << nl;
 
     directForceDensity_ = dict.lookupOrDefault("directForceDensity", false);
 
@@ -888,11 +889,11 @@ bool Foam::functionObjects::forces::read(const dictionary& dict)
     dict.readIfPresent("porosity", porosity_);
     if (porosity_)
     {
-        Info << "    Including porosity effects" << endl;
+        Info<< "    Including porosity effects" << endl;
     }
     else
     {
-        Info << "    Not including porosity effects" << endl;
+        Info<< "    Not including porosity effects" << endl;
     }
 
     if (dict.found("binData"))
@@ -908,9 +909,10 @@ bool Foam::functionObjects::forces::read(const dictionary& dict)
         }
         else if (nBin_ == 0)
         {
+            // Case of no bins equates to a single bin to collect all data
             nBin_ = 1;
         }
-        else if ((nBin_ == 0) || (nBin_ == 1))
+        else
         {
             binDict.lookup("cumulative") >> binCumulative_;
             binDict.lookup("direction") >> binDir_;
@@ -918,21 +920,11 @@ bool Foam::functionObjects::forces::read(const dictionary& dict)
         }
     }
 
-    if (nBin_ == 1)
-    {
-        // Allocate storage for forces and moments
-        forAll(force_, i)
-        {
-            force_[i].setSize(1, vector::zero);
-            moment_[i].setSize(1, vector::zero);
-        }
-    }
-
     writeFields_ = dict.lookupOrDefault("writeFields", false);
 
     if (writeFields_)
     {
-        Info << "    Fields will be written" << endl;
+        Info<< "    Fields will be written" << endl;
 
         volVectorField* forcePtr
         (
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
index 28ec2c91d58a2e5e885dce0a7b97654799494f9f..db5f1619e7849a4b636f9c6b4e3b97b95e1ea7dc 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
@@ -89,20 +89,23 @@ addGeometryToScene
         return;
     }
 
-    const dictionary dict =
-        geometryBase::parent_.getObjectProperty
-        (
-            functionObject_,
-            fieldName_,
-            dictionary::null
-        );
+    dictionary dict;
+    if (!geometryBase::parent_.getObjectDict(functionObject_, fieldName_, dict))
+    {
+        WarningInFunction
+            << "Unable to find function object " << functionObject_
+            << " output for field " << fieldName_
+            << ". Line will not be processed"
+            << endl;
+        return;
+    }
 
     fileName fName;
     if (!dict.readIfPresent("file", fName))
     {
         WarningInFunction
-            << "Unable to find function object " << functionObject_
-            << " output for field " << fieldName_
+            << "Unable to read file name from function object "
+            << functionObject_ << " for field " << fieldName_
             << ". Line will not be processed"
             << endl;
         return;
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
index b7b11e69456567002377354f34adb6c01ec11440..cfa91bf2487fa5480a3fee8645b5020304c6249f 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
@@ -93,21 +93,24 @@ addGeometryToScene
         return;
     }
 
-    const dictionary dict =
-        geometryBase::parent_.getObjectProperty
-        (
-            functionObject_,
-            fieldName_,
-            dictionary::null
-        );
+    dictionary dict;
+    if (!geometryBase::parent_.getObjectDict(functionObject_, fieldName_, dict))
+    {
+        WarningInFunction
+            << "Unable to find function object " << functionObject_
+            << " output for field " << fieldName_
+            << ". Surface will not be processed"
+            << endl;
+        return;
+    }
 
     fileName fName;
     if (!dict.readIfPresent("file", fName))
     {
         WarningInFunction
-            << "Unable to find function object " << functionObject_
-            << " output for field " << fieldName_
-            << ". functionObjectSurface will not be processed"
+            << "Unable to read file name from function object "
+            << functionObject_ << " for field " << fieldName_
+            << ". Surface will not be processed"
             << endl;
         return;
     }
diff --git a/src/functionObjects/lagrangian/icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C b/src/functionObjects/lagrangian/icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C
index c37307c377fe1bcf7c66a8ffa7ace5f2f52dec3e..4cce300a4d0fd9ad8779de412c5c862956983b74 100644
--- a/src/functionObjects/lagrangian/icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C
+++ b/src/functionObjects/lagrangian/icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C
@@ -120,9 +120,7 @@ bool Foam::functionObjects::icoUncoupledKinematicCloud::read
     const dictionary& dict
 )
 {
-    fvMeshFunctionObject::read(dict);
-
-    return true;
+    return fvMeshFunctionObject::read(dict);
 }
 
 
diff --git a/src/functionObjects/utilities/Make/files b/src/functionObjects/utilities/Make/files
index dbf879893867177d305fbb7b1a982e8a4b812415..e2f72c06cfe35edc354c239f6006bd35fb00082c 100644
--- a/src/functionObjects/utilities/Make/files
+++ b/src/functionObjects/utilities/Make/files
@@ -1,6 +1,7 @@
 abort/abort.C
 
 codedFunctionObject/codedFunctionObject.C
+ensightWrite/ensightWrite.C
 
 removeRegisteredObject/removeRegisteredObject.C
 
diff --git a/src/functionObjects/utilities/Make/options b/src/functionObjects/utilities/Make/options
index 0efefc46fce4978407baeee2f03a9e49a038733c..9e14e74355ba6987440ab51398b328e938322075 100644
--- a/src/functionObjects/utilities/Make/options
+++ b/src/functionObjects/utilities/Make/options
@@ -1,5 +1,7 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude \
+    -I$(LIB_SRC)/conversion/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
     -I$(LIB_SRC)/ODE/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
@@ -7,6 +9,8 @@ EXE_INC = \
 
 LIB_LIBS = \
     -lfiniteVolume \
+    -lconversion \
+    -lsampling \
     -lfluidThermophysicalModels \
     -lcompressibleTransportModels \
     -lODE
diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.C b/src/functionObjects/utilities/ensightWrite/ensightWrite.C
new file mode 100644
index 0000000000000000000000000000000000000000..02a17215a71cb8ccc98d2b50c45e30b0dbbd0dbe
--- /dev/null
+++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.C
@@ -0,0 +1,329 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "ensightWrite.H"
+#include "Time.H"
+#include "polyMesh.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionObjects
+{
+    defineTypeNameAndDebug(ensightWrite, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        ensightWrite,
+        dictionary
+    );
+}
+}
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::functionObjects::ensightWrite::uniqWords(wordReList& lst)
+{
+    boolList retain(lst.size());
+    wordHashSet uniq;
+    forAll(lst, i)
+    {
+        const wordRe& select = lst[i];
+
+        retain[i] =
+        (
+            select.isPattern()
+         || uniq.insert(static_cast<const word&>(select))
+        );
+    }
+
+    inplaceSubset(retain, lst);
+}
+
+
+int Foam::functionObjects::ensightWrite::process(const word& fieldName)
+{
+    int state = 0;
+
+    writeVolField<scalar>(fieldName, state);
+    writeVolField<vector>(fieldName, state);
+    writeVolField<sphericalTensor>(fieldName, state);
+    writeVolField<symmTensor>(fieldName, state);
+    writeVolField<tensor>(fieldName, state);
+
+    return state;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::functionObjects::ensightWrite::ensightWrite
+(
+    const word& name,
+    const Time& runTime,
+    const dictionary& dict
+)
+:
+    fvMeshFunctionObject(name, runTime, dict),
+    writeOpts_
+    (
+        dict.found("format")
+      ? IOstream::formatEnum(dict.lookup("format"))
+      : runTime.writeFormat()
+    ),
+    caseOpts_(writeOpts_.format()),
+    selectFields_(),
+    dirName_("ensightWrite"),
+    consecutive_(false)
+{
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::functionObjects::ensightWrite::~ensightWrite()
+{
+    if (ensCase_.valid())
+    {
+        // finalize case
+        ensCase().write();
+        ensCase_.clear();
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
+{
+    fvMeshFunctionObject::read(dict);
+
+    //
+    // writer options
+    //
+    writeOpts_.noPatches
+    (
+        dict.lookupOrDefault<Switch>("noPatches", false)
+    );
+
+    writeOpts_.deprecatedOrder
+    (
+        dict.lookupOrDefault<Switch>("deprecatedOrder", false)
+    );
+
+    if (dict.found("patches"))
+    {
+        wordReList lst(dict.lookup("patches"));
+        uniqWords(lst);
+
+        writeOpts_.patchSelection(lst);
+    }
+
+    if (dict.found("faceZones"))
+    {
+        wordReList lst(dict.lookup("faceZones"));
+        uniqWords(lst);
+
+        writeOpts_.faceZoneSelection(lst);
+    }
+
+
+    //
+    // case options
+    //
+    caseOpts_.width(dict.lookupOrDefault<label>("width", 8));
+
+    // remove existing output directory
+    caseOpts_.overwrite(dict.lookupOrDefault<Switch>("overwrite", false));
+
+
+    //
+    // other options
+    //
+    dict.readIfPresent("directory", dirName_);
+    consecutive_ = dict.lookupOrDefault<Switch>("consecutive", false);
+
+
+    //
+    // output fields
+    //
+    dict.lookup("fields") >> selectFields_;
+    uniqWords(selectFields_);
+
+    return true;
+}
+
+
+bool Foam::functionObjects::ensightWrite::execute()
+{
+    return true;
+}
+
+
+bool Foam::functionObjects::ensightWrite::write()
+{
+    const Time& t = obr_.time();
+
+    if (!ensCase_.valid())
+    {
+        // Define sub-directory name to use for EnSight data.
+        // The path to the ensight directory is at case level only
+        // - For parallel cases, data only written from master
+
+        fileName ensightDir = dirName_;
+        if (!ensightDir.isAbsolute())
+        {
+            ensightDir = t.rootPath()/t.globalCaseName()/ensightDir;
+        }
+
+        ensCase_.reset
+        (
+            new ensightCase
+            (
+                ensightDir,
+                t.globalCaseName(),
+                caseOpts_
+            )
+        );
+    }
+
+    if (!ensMesh_.valid())
+    {
+        ensMesh_.reset(new ensightMesh(mesh_, writeOpts_));
+
+        if (ensMesh_().needsUpdate())
+        {
+            ensMesh_().correct();
+        }
+
+        // assume static geometry - need to fix later
+        autoPtr<ensightGeoFile> os = ensCase_().newGeometry(false);
+        ensMesh_().write(os);
+    }
+    else if (ensMesh_().needsUpdate())
+    {
+        // appears to have moved
+        ensMesh_().correct();
+
+        autoPtr<ensightGeoFile> os = ensCase_().newGeometry(true);
+        ensMesh_().write(os);
+    }
+
+    Log << type() << " " << name() << " write: (";
+
+    if (consecutive_)
+    {
+        ensCase().nextTime(t.value());
+    }
+    else
+    {
+        ensCase().setTime(t.value(), t.timeIndex());
+    }
+
+    wordHashSet candidates = subsetStrings(selectFields_, mesh_.names());
+    DynamicList<word> missing(selectFields_.size());
+    DynamicList<word> ignored(selectFields_.size());
+
+    // check exact matches first
+    forAll(selectFields_, i)
+    {
+        const wordRe& select = selectFields_[i];
+        if (!select.isPattern())
+        {
+            const word& fieldName = static_cast<const word&>(select);
+
+            if (!candidates.erase(fieldName))
+            {
+                missing.append(fieldName);
+            }
+            else if (process(fieldName) < 1)
+            {
+                ignored.append(fieldName);
+            }
+        }
+    }
+
+    forAllConstIter(wordHashSet, candidates, iter)
+    {
+        process(iter.key());
+    }
+
+    Log << " )" << endl;
+
+    if (missing.size())
+    {
+        WarningInFunction
+            << "Missing field " << missing << endl;
+    }
+    if (ignored.size())
+    {
+        WarningInFunction
+            << "Unprocessed field " << ignored << endl;
+    }
+
+    return true;
+}
+
+
+bool Foam::functionObjects::ensightWrite::end()
+{
+    if (ensCase_.valid())
+    {
+        // finalize case
+        ensCase().write();
+        ensCase_.clear();
+    }
+
+    return true;
+}
+
+
+void Foam::functionObjects::ensightWrite::updateMesh(const mapPolyMesh& mpm)
+{
+    // fvMeshFunctionObject::updateMesh(mpm);
+
+    if (ensMesh_.valid())
+    {
+        ensMesh_().expire();
+    }
+}
+
+
+void Foam::functionObjects::ensightWrite::movePoints(const polyMesh& mpm)
+{
+    // fvMeshFunctionObject::updateMesh(mpm);
+
+    if (ensMesh_.valid())
+    {
+        ensMesh_().expire();
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H
new file mode 100644
index 0000000000000000000000000000000000000000..edba7c8535a7cafaf3571fbff0b4a4e7497d92a2
--- /dev/null
+++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H
@@ -0,0 +1,227 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::functionObjects::ensightWrite
+
+Group
+    grpUtilitiesFunctionObjects
+
+Description
+    Writes fields in ensight format.
+
+    Example of function object specification:
+    \verbatim
+    ensight
+    {
+        type            ensightWrite;
+        libs            ("libutilityFunctionObjects.so");
+        writeControl    writeTime;
+        writeInterval   1;
+        format          binary;
+
+        overwrite       true;
+        width           12;
+        directory       "EnSight";
+
+        fields
+        (
+            U
+            p
+        );
+    }
+    \endverbatim
+
+    \heading Function object usage
+    \table
+        Property     | Description                  | Required  | Default value
+        type         | Type name: ensightWrite      | yes       |
+        fields       | Fields to output             | yes       |
+        writeControl | Output control               | recommended | timeStep
+        directory    | The output directory name    | no        | "ensightWrite"
+        overwrite    | Remove existing directory    | no        | false
+        format       | ASCII or binary format       | no        | same as simulation
+        width        | Mask width for \c data/XXXX  | no        | 8
+        noPatches    | Suppress writing patches     | no        | false
+        patches      | Select patches to write      | no        |
+        faceZones    | Select faceZones to write    | no        |
+        deprecatedOrder | Old ordering of volume cells  | no    | false
+        consecutive  | Consecutive output numbering | no    | false
+    \endtable
+
+    Note that if the \c patches entry is an empty list, this will select all
+    patches and suppress writing the internalMesh.
+    Consecutive output numbering can be used in conjunction with \c overwrite.
+
+SourceFiles
+    ensightWrite.C
+    ensightWriteTemplates.C
+
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef functionObjects_ensightWrite_H
+#define functionObjects_ensightWrite_H
+
+#include "fvMeshFunctionObject.H"
+#include "ensightCase.H"
+#include "ensightMesh.H"
+
+#include "wordReList.H"
+#include "interpolation.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class dictionary;
+
+namespace functionObjects
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class ensightWrite Declaration
+\*---------------------------------------------------------------------------*/
+
+class ensightWrite
+:
+    public fvMeshFunctionObject
+{
+    // Private data
+
+        //- Writer options
+        ensightMesh::options writeOpts_;
+        ensightCase::options caseOpts_;
+
+        //- Name of fields to process
+        wordReList selectFields_;
+
+        //- Output directory name
+        fileName dirName_;
+
+        //- Consecutive output numbering
+        bool consecutive_;
+
+        //- Ensight case handler
+        autoPtr<ensightCase> ensCase_;
+
+        //- Ensight mesh handler
+        autoPtr<ensightMesh> ensMesh_;
+
+
+    // Private Member Functions
+
+        //- Eliminate duplicate 'word' entries
+        static void uniqWords(wordReList&);
+
+        //- Ensight case handler
+        ensightCase& ensCase()
+        {
+            return ensCase_();
+        }
+
+        //- Ensight mesh handler
+        ensightMesh& ensMesh()
+        {
+            return ensMesh_();
+        }
+
+
+        //- Apply for the volume field type
+        template<class Type>
+        int writeVolField(const word& inputName, int& state);
+
+
+        //- Process by trying to apply for various volume field types.
+        int process(const word& inputName);
+
+
+        //- Disallow default bitwise copy construct
+        ensightWrite(const ensightWrite&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const ensightWrite&) = delete;
+
+public:
+
+    //- Runtime type information
+    TypeName("ensightWrite");
+
+
+    // Constructors
+
+        //- Construct from runTime and dictionary.
+        ensightWrite
+        (
+            const word& name,
+            const Time& runTime,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~ensightWrite();
+
+
+    // Member Functions
+
+        //- Read the ensightWrite specification
+        virtual bool read(const dictionary&);
+
+        //- Do nothing
+        virtual bool execute();
+
+        //- Write fields
+        virtual bool write();
+
+        //- Execute at the final time-loop, flush case file
+        virtual bool end();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&);
+
+        //- Update for mesh point-motion
+        virtual void movePoints(const polyMesh&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace functionObjects
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ensightWriteTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..e9ff3a98eba98f4c00d11bba624af35adb3a726b
--- /dev/null
+++ b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C
@@ -0,0 +1,62 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "Time.H"
+#include "ensightOutput.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+template<class Type>
+int Foam::functionObjects::ensightWrite::writeVolField
+(
+    const word& inputName,
+    int& state
+)
+{
+    // State: return 0 (not-processed), -1 (skip), +1 ok
+    typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
+
+    // Already done, or not available
+    if (state || !foundObject<VolFieldType>(inputName))
+    {
+        return state;
+    }
+
+    autoPtr<ensightFile> os = ensCase().newData<Type>(inputName);
+    ensightOutput::writeField<Type>
+    (
+        lookupObject<VolFieldType>(inputName),
+        ensMesh(),
+        os
+    );
+
+    Log << " " << inputName;
+
+    state = +1;
+    return state;
+}
+
+
+// ************************************************************************* //
diff --git a/src/functionObjects/utilities/thermoCoupleProbes/thermoCoupleProbes.C b/src/functionObjects/utilities/thermoCoupleProbes/thermoCoupleProbes.C
index 740856a5a8d15cb177c417cfcfa2180df5dc8317..f247a9528ee93864ab42ef7fb293c417e1b2873b 100644
--- a/src/functionObjects/utilities/thermoCoupleProbes/thermoCoupleProbes.C
+++ b/src/functionObjects/utilities/thermoCoupleProbes/thermoCoupleProbes.C
@@ -67,9 +67,9 @@ Foam::functionObjects::thermoCoupleProbes::thermoCoupleProbes
     }
 
     // Check if the property exist (resume old calculation)
-    // or of it is new.
+    // or of it is new
     dictionary probeDict;
-    if (getDict(typeName, probeDict))
+    if (getDict(name, probeDict))
     {
         probeDict.lookup("Tc") >> Ttc_;
     }
@@ -172,7 +172,7 @@ bool Foam::functionObjects::thermoCoupleProbes::write()
 
         dictionary probeDict;
         probeDict.add("Tc", Ttc_);
-        setProperty(typeName, probeDict);
+        setProperty(name(), probeDict);
         return true;
     }
 
diff --git a/src/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C b/src/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
index d6dc1d10400199b608e1e4e3795d0402a6f0fddd..640fb58d103aefb545140843697c98872c00a6ea 100644
--- a/src/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
+++ b/src/functionObjects/utilities/timeActivatedFileUpdate/timeActivatedFileUpdate.C
@@ -111,7 +111,7 @@ bool Foam::functionObjects::timeActivatedFileUpdate::read
     lastIndex_ = -1;
     fileToUpdate_.expand();
 
-    Log << type() << " " << name() << " output:" << nl
+    Info<< type() << " " << name() << " output:" << nl
         << "    time vs file list:" << endl;
 
     forAll(timeVsFile_, i)
@@ -124,7 +124,7 @@ bool Foam::functionObjects::timeActivatedFileUpdate::read
                 << nl << exit(FatalError);
         }
 
-        Log << "    " << timeVsFile_[i].first() << tab
+        Info<< "    " << timeVsFile_[i].first() << tab
             << timeVsFile_[i].second() << endl;
     }
 
diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options
index dc893c1148def8bdc4d1b3388691a6ed4cb48a56..a94e947f6790a21592b4ada355306eac76d41b95 100644
--- a/src/lagrangian/intermediate/Make/options
+++ b/src/lagrangian/intermediate/Make/options
@@ -17,6 +17,7 @@ EXE_INC = \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude
 
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
index adc6a30ca10d9677b8a96c69f28919cfd74a02a0..2d2ac4d45a85801f051e725bc6ddcf38d730cb2e 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -204,8 +204,7 @@ void Foam::FacePostProcessing<CloudType>::write()
                 (
                     this->writeTimeDir(),
                     fZone.name(),
-                    allPoints,
-                    allFaces,
+                    meshedSurfRef(allPoints, allFaces),
                     "massTotal",
                     zoneMassTotal[zoneI],
                     false
@@ -215,8 +214,7 @@ void Foam::FacePostProcessing<CloudType>::write()
                 (
                     this->writeTimeDir(),
                     fZone.name(),
-                    allPoints,
-                    allFaces,
+                    meshedSurfRef(allPoints, allFaces),
                     "massFlowRate",
                     zoneMassFlowRate[zoneI],
                     false
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C
index ffa42aaf4ed88a9aebf89cf659a5ca6490f51593..8ea2b51386d3a29d1ed8d49fa4306889ddccc761 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -409,10 +409,10 @@ void Foam::ParticleCollector<CloudType>::write()
 
     Info<< type() << " output:" << nl;
 
-    Field<scalar> faceMassTotal(mass_.size(), 0.0);
+    Field<scalar> faceMassTotal(mass_.size(), Zero);
     this->getModelProperty("massTotal", faceMassTotal);
 
-    Field<scalar> faceMassFlowRate(massFlowRate_.size(), 0.0);
+    Field<scalar> faceMassFlowRate(massFlowRate_.size(), Zero);
     this->getModelProperty("massFlowRate", faceMassFlowRate);
 
 
@@ -467,8 +467,7 @@ void Foam::ParticleCollector<CloudType>::write()
             (
                 this->writeTimeDir(),
                 "collector",
-                points_,
-                faces_,
+                meshedSurfRef(points_, faces_),
                 "massTotal",
                 faceMassTotal,
                 false
@@ -478,8 +477,7 @@ void Foam::ParticleCollector<CloudType>::write()
             (
                 this->writeTimeDir(),
                 "collector",
-                points_,
-                faces_,
+                meshedSurfRef(points_, faces_),
                 "massFlowRate",
                 faceMassFlowRate,
                 false
@@ -490,7 +488,7 @@ void Foam::ParticleCollector<CloudType>::write()
 
     if (resetOnWrite_)
     {
-        Field<scalar> dummy(faceMassTotal.size(), 0.0);
+        Field<scalar> dummy(faceMassTotal.size(), Zero);
         this->setModelProperty("massTotal", dummy);
         this->setModelProperty("massFlowRate", dummy);
 
diff --git a/src/lagrangian/spray/Make/options b/src/lagrangian/spray/Make/options
index b45129b83860fd9cc2c03834908a61ae5b55e1c6..34e92f4b47f08c643ecc8f3ce0fbcbc75208f6c0 100644
--- a/src/lagrangian/spray/Make/options
+++ b/src/lagrangian/spray/Make/options
@@ -22,6 +22,7 @@ EXE_INC = \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
     -I$(LIB_SRC)/sampling/lnInclude \
+    -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude
 
diff --git a/src/mesh/snappyHexMesh/Make/options b/src/mesh/snappyHexMesh/Make/options
index 88577d6c825c3afabd897d9744e2fd8a43f8b621..42f1b1d19f93c5f28deb5eccfe2a9f8e52840185 100644
--- a/src/mesh/snappyHexMesh/Make/options
+++ b/src/mesh/snappyHexMesh/Make/options
@@ -14,7 +14,6 @@ LIB_LIBS = \
     -lfiniteVolume \
     -llagrangian \
     -lmeshTools \
-    -lfileFormats \
     -ledgeMesh \
     -lsurfMesh \
     -ltriSurface \
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index c187a63d80c5a3cf32367b54808ea436965af591..d6dd0ec9f27c1609037c2b9f04f32bf3fe117393 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -149,6 +149,7 @@ momentOfInertia/momentOfInertia.C
 
 surfaceSets/surfaceSets.C
 
+triSurface/faceTriangulation/faceTriangulation.C
 triSurface/orientedSurface/orientedSurface.C
 triSurface/surfaceLocation/surfaceLocation.C
 
diff --git a/src/meshTools/Make/options b/src/meshTools/Make/options
index 1713152e9e502c6789d21eefb44ffd4904e08f91..98853e61fbbda0f1c48b945d89a0b56ee9e2c939 100644
--- a/src/meshTools/Make/options
+++ b/src/meshTools/Make/options
@@ -5,5 +5,4 @@ EXE_INC = \
 
 LIB_LIBS = \
     -ltriSurface \
-    -lsurfMesh \
-    -lfileFormats
+    -lsurfMesh
diff --git a/src/triSurface/tools/labelPair/labelPairLookup.H b/src/meshTools/triSurface/containers/labelPairLookup.H
similarity index 100%
rename from src/triSurface/tools/labelPair/labelPairLookup.H
rename to src/meshTools/triSurface/containers/labelPairLookup.H
diff --git a/src/triSurface/faceTriangulation/faceTriangulation.C b/src/meshTools/triSurface/faceTriangulation/faceTriangulation.C
similarity index 100%
rename from src/triSurface/faceTriangulation/faceTriangulation.C
rename to src/meshTools/triSurface/faceTriangulation/faceTriangulation.C
diff --git a/src/triSurface/faceTriangulation/faceTriangulation.H b/src/meshTools/triSurface/faceTriangulation/faceTriangulation.H
similarity index 100%
rename from src/triSurface/faceTriangulation/faceTriangulation.H
rename to src/meshTools/triSurface/faceTriangulation/faceTriangulation.H
diff --git a/src/parallel/decompose/Allwmake b/src/parallel/decompose/Allwmake
index 6652ef62867774d8a062aef9799e73ea61fbfbc5..c32e09fc7e0fb87c58ea85dbb7e9dc9614766d89 100755
--- a/src/parallel/decompose/Allwmake
+++ b/src/parallel/decompose/Allwmake
@@ -4,77 +4,175 @@ cd ${0%/*} || exit 1    # Run from this directory
 # Parse arguments for library compilation
 . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
 
-# get SCOTCH_VERSION, SCOTCH_ARCH_PATH
-if settings=`$WM_PROJECT_DIR/bin/foamEtcFile config.sh/scotch`
-then
+# Test for metis.
+# - return 0 and export METIS_ARCH_PATH on success
+hasMetis()
+{
+    echo
+    echo "Metis decomposition"
+
+    unset METIS_ARCH_PATH METIS_VERSION
+    settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/metis) || {
+        echo
+        echo "Error: no config.sh/metis settings"
+        echo
+        return 1
+    }
+
     . $settings
-    echo "using SCOTCH_ARCH_PATH=$SCOTCH_ARCH_PATH"
-else
+    if [ -z "$METIS_ARCH_PATH" -o "${METIS_ARCH_PATH##*-}" = none ]
+    then
+        echo "   skipping - no metis"
+        echo
+        return 1
+    fi
+
+    # Header
+    local header=$METIS_ARCH_PATH/include/metis.h
+    if [ "${METIS_ARCH_PATH##*-}" = system ]
+    then
+        [ -f "$header" ] || header=/usr/include/metis.h
+    fi
+    [ -f "$header" ] || {
+        echo "    skipping - no metis header"
+        echo
+        return 2  # file not found
+    }
+
+    # Library
+    [ -r $FOAM_EXT_LIBBIN/libmetis.so ] || \
+    [ -r $METIS_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH/libmetis.so ] || \
+    [ "${METIS_ARCH_PATH##*-}" = system ] || {
+        echo "   skipping - missing library"
+        echo
+        return 2
+    }
+
+    # Ensure consistent sizes between OpenFOAM and metis header
+    # Extract IDXTYPEWIDTH from metis.h: regex as per ThirdParty Allwmake
+    local label=$(sed -ne 's/^.*#define  *IDXTYPEWIDTH  *\([1-9][0-9]\).*/\1/p' $header)
+    [ "$WM_LABEL_SIZE" = "$label" ] || {
+        echo "   skipping - label=$WM_LABEL_SIZE, metis.h has '$label'"
+        echo
+        return 1
+    }
+
+    echo "using METIS_ARCH_PATH=$METIS_ARCH_PATH"
+    echo "    label=$label"
     echo
-    echo "Error: no config.sh/scotch settings"
+    export METIS_ARCH_PATH
+    return 0 # success
+}
+
+
+# Test for scotch.
+# - return 0 and export SCOTCH_ARCH_PATH, SCOTCH_VERSION on success
+hasScotch()
+{
     echo
-fi
+    echo "Scotch decomposition"
+
+    unset SCOTCH_ARCH_PATH SCOTCH_VERSION
+    settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/scotch) || {
+        echo
+        echo "Error: no config.sh/scotch settings"
+        echo
+        return 1
+    }
+
+    . $settings
+    if [ -z "$SCOTCH_ARCH_PATH" -o "${SCOTCH_ARCH_PATH##*-}" = none ]
+    then
+        echo "    skipping - no scotch"
+        echo
+        return 1
+    fi
+
+    # Header
+    local header=$SCOTCH_ARCH_PATH/include/scotch.h
+    if [ "${SCOTCH_ARCH_PATH##*-}" = system ]
+    then
+        [ -f "$header" ] || header=/usr/include/scotch.h
+    fi
+    [ -f "$header" ] || {
+        echo "    skipping - no scotch header"
+        echo
+        return 2  # file not found
+    }
+
+    # Library
+    [ -r $FOAM_EXT_LIBBIN/libscotch.so ] || \
+    [ -r $SCOTCH_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH/libscotch.so ] || \
+    [ "${SCOTCH_ARCH_PATH##*-}" = system ] || {
+        echo "    skipping - missing library"
+        echo
+        return 2
+    }
+
+    # Ensure consistent sizes between OpenFOAM and scotch header
+    # extract 'typedef int64_t SCOTCH_Num' or equivalent
+    local label=$(sed -ne \
+        's/^.*typedef *\([^ ]*\) *SCOTCH_Num.*/\1/ip' \
+        "$header")
+
+    : ${label:=unknown}
+    [ "$WM_LABEL_SIZE" = 32 -a \( "$label" = int32_t -o "$label" = int  \) ] || \
+    [ "$WM_LABEL_SIZE" = 64 -a \( "$label" = int64_t -o "$label" = long \) ] || {
+        echo "   skipping - label='$WM_LABEL_SIZE', scotch.h has '$label'"
+        echo
+        return 1
+    }
+
+    echo "using SCOTCH_ARCH_PATH=$SCOTCH_ARCH_PATH"
+    echo "    label=$label ($WM_LABEL_SIZE)"
+    echo
+    export SCOTCH_ARCH_PATH SCOTCH_VERSION
+    return 0 # success
+}
 
 
 #
-# define how to create an mpi-versioned library of $targetType
+# Define how to create an mpi-versioned library of $targetType
 # compile into qualified directory
-# use sentinel file to handle version changes
+# use sentinel file(s) to handle version changes
 #
 wmakeMpiLib()
 {
-    set +x
+    local decompName="$1"
+    shift
     for libName
     do
     (
         WM_OPTIONS="$WM_OPTIONS$WM_MPLIB"
         libDir="$WM_PROJECT_DIR/platforms/$WM_OPTIONS/src/parallel/decompose/$libName"
         whichmpi="$libDir/using:$FOAM_MPI"
-        whichscotch="$libDir/using:$SCOTCH_VERSION"
-        [ -e "$whichmpi" -a -e "$whichscotch" ] || wclean $libName
+        whichdecomp="$libDir/using:$decompName"
+        [ -e "$whichmpi" -a -e "$whichdecomp" ] || wclean $libName
         echo "wmake $targetType $libName"
         wmake $targetType $libName
         mkdir -p "$libDir"
-        touch "$whichmpi" "$whichscotch"
+        touch "$whichdecomp" "$whichmpi"
     )
     done
-    set -x
 }
 
-set -x
-
 wmakeLnInclude decompositionMethods
 
-if [ -n "$SCOTCH_ARCH_PATH" ]
+if hasScotch
 then
     wmake $targetType scotchDecomp
-
     if [ -d "$FOAM_LIBBIN/$FOAM_MPI" ]
     then
-        #- Bit of a hack: ptscotch 6 requires scotch linked as well as. Can be
-        #  removed once ptscotch declares dependency on scotch itself.
-        case "$SCOTCH_VERSION" in
-        scotch_6.*)
-            export LINK_FLAGS="-lscotch"
-            ;;
-        esac
-
-
-        wmakeMpiLib ptscotchDecomp
+        wmakeMpiLib "$SCOTCH_VERSION" ptscotchDecomp
     fi
-else
-    echo
-    echo "Skipping scotchDecomp (ptscotchDecomp)"
-    echo
 fi
 
-
-# Try and build metisDecomp (has own logic)
-(cd metisDecomp && ./Allwmake $targetType)
-
+if hasMetis
+then
+    wmake $targetType metisDecomp
+fi
 
 wmake $targetType decompositionMethods
-
 wmake $targetType decompose
 
 #------------------------------------------------------------------------------
diff --git a/src/parallel/decompose/metisDecomp/Allwmake b/src/parallel/decompose/metisDecomp/Allwmake
deleted file mode 100755
index 2f666aba2bb31c2c61e2d945562732b074b8bc2f..0000000000000000000000000000000000000000
--- a/src/parallel/decompose/metisDecomp/Allwmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-
-# Parse arguments for library compilation
-. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
-
-# get METIS_VERSION, METIS_ARCH_PATH
-if settings=`$WM_PROJECT_DIR/bin/foamEtcFile config.sh/metis`
-then
-    . $settings
-    echo "using METIS_ARCH_PATH=$METIS_ARCH_PATH"
-    if [ -r $METIS_ARCH_PATH/lib/libmetis.so ]
-    then
-        wmake $targetType
-    fi
-else
-    echo
-    echo "Error: no config.sh/metis settings"
-    echo
-fi
-
-
-#------------------------------------------------------------------------------
diff --git a/src/parallel/decompose/metisDecomp/Make/options b/src/parallel/decompose/metisDecomp/Make/options
index 8acd678fd3f2dacf7f6fdceb5aa7b120ba19876a..b1cce000a224b0c26b948b45f8f2ff35b76083ba 100644
--- a/src/parallel/decompose/metisDecomp/Make/options
+++ b/src/parallel/decompose/metisDecomp/Make/options
@@ -3,5 +3,11 @@ EXE_INC = \
     -I$(METIS_ARCH_PATH)/include \
     -I../decompositionMethods/lnInclude
 
+/*
+ * The $(METIS_ARCH_PATH)/lib$WM_COMPILER_LIB_ARCH path is provided
+ * to support central, non-thirdparty installations
+ */
 LIB_LIBS = \
-    -L$(METIS_ARCH_PATH)/lib -lmetis
+    -L$(METIS_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+    -L$(FOAM_EXT_LIBBIN) \
+    -lmetis
diff --git a/src/parallel/decompose/metisDecomp/metisDecomp.C b/src/parallel/decompose/metisDecomp/metisDecomp.C
index 735ce49c0d14a0695a4da17222d6824e95297129..8e27852ecc2a03295c1b1a4a592d895cb6d7f808 100644
--- a/src/parallel/decompose/metisDecomp/metisDecomp.C
+++ b/src/parallel/decompose/metisDecomp/metisDecomp.C
@@ -67,7 +67,7 @@ Foam::label Foam::metisDecomp::decompose
 
     // Processor weights initialised with no size, only used if specified in
     // a file
-    Field<scalar> processorWeights;
+    Field<real_t> processorWeights;
 
     // Cell weights (so on the vertices of the dual)
     List<label> cellWeights;
diff --git a/src/parallel/decompose/ptscotchDecomp/Make/options b/src/parallel/decompose/ptscotchDecomp/Make/options
index cb407ec6b5c8646d634e0d4bc169a3e40c4946b5..9dab60dab532e6a17060875beb81a7fe6f6316a8 100644
--- a/src/parallel/decompose/ptscotchDecomp/Make/options
+++ b/src/parallel/decompose/ptscotchDecomp/Make/options
@@ -8,8 +8,16 @@ EXE_INC = \
     -I/usr/include/scotch \
     -I../decompositionMethods/lnInclude
 
+/*
+ * The '-lscotch' is a slight hack:
+ * ptscotch 6 requires scotch linked in, but does not declare the dependency
+ *
+ * The $(SCOTCH_ARCH_PATH)/lib$WM_COMPILER_LIB_ARCH path is provided
+ * to support central, non-thirdparty installations
+ */
 LIB_LIBS = \
-    -L$(SCOTCH_ARCH_PATH)/lib \
+    -L$(SCOTCH_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+    -L$(FOAM_EXT_LIBBIN) \
     -L$(FOAM_EXT_LIBBIN)/$(FOAM_MPI) \
     -lptscotch \
     -lptscotcherrexit \
diff --git a/src/parallel/decompose/scotchDecomp/Make/options b/src/parallel/decompose/scotchDecomp/Make/options
index d2cc770692ce384821691c05ef08cd3d47e9a9a5..5cc3e25d8c19332e66727b17a67ee5b1d7cacca3 100644
--- a/src/parallel/decompose/scotchDecomp/Make/options
+++ b/src/parallel/decompose/scotchDecomp/Make/options
@@ -11,8 +11,12 @@ EXE_INC = \
     -I/usr/include/scotch \
     -I../decompositionMethods/lnInclude
 
+/*
+ * The $(SCOTCH_ARCH_PATH)/lib$WM_COMPILER_LIB_ARCH path is provided
+ * to support central, non-thirdparty installations
+ */
 LIB_LIBS = \
-    -L$(SCOTCH_ARCH_PATH)/lib \
+    -L$(SCOTCH_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
     -L$(FOAM_EXT_LIBBIN) \
     -lscotch \
     -lscotcherrexit \
diff --git a/src/randomProcesses/Make/options b/src/randomProcesses/Make/options
index e1eddd51d2e71217d6f2143c9258a3d396d4f7ea..4d1c505daed6c9e5189349b734e2965e25eb785b 100644
--- a/src/randomProcesses/Make/options
+++ b/src/randomProcesses/Make/options
@@ -7,5 +7,4 @@ EXE_INC = \
 LIB_LIBS = \
     -L$(FFTW_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) -lfftw3 \
     -lfiniteVolume \
-    -lsampling \
-    -lsurfMesh
+    -lsampling
diff --git a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C
index 92a3df57fd3adfe80e6a55d231c3c2fb1120db31..f24289c49573d6c7f861c487463197a0f4194f1a 100644
--- a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C
+++ b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C
@@ -46,6 +46,11 @@ addToRunTimeSelectionTable(noiseModel, surfaceNoise, dictionary);
 
 void surfaceNoise::initialise(const dictionary& dict)
 {
+    dict.lookup("inputFile") >> inputFileName_;
+    inputFileName_.expand();
+
+    dict.readIfPresent("fftWriteInterval", fftWriteInterval_);
+
     label nAvailableTimes = 0;
 
     // All reading performed on the master processor only
@@ -285,25 +290,23 @@ Foam::scalar surfaceNoise::writeSurfaceData
                 }
             }
 
+            // could also have meshedSurface implement meshedSurf
             fileName outFileName = writerPtr_->write
             (
                 outDir,
                 fName,
-                surf.points(),
-                surf.faces(),
+                meshedSurfRef
+                (
+                    surf.points(),
+                    surf.surfFaces()
+                ),
                 title,
                 allData,
                 false
             );
 
-            // TODO: Move faceAreas to demand-driven function in MeshedSurface
-            // scalarField faceAreas(surf.faces().size());
-            // forAll(faceAreas, i)
-            // {
-            //     faceAreas[i] = surf.faces()[i].mag(surf.points());
-            // }
-            //
-            // areaAverage = sum(allData*faceAreas)/sum(faceAreas);
+            // TO BE VERIFIED: area-averaged values
+            // areaAverage = sum(allData*surf.magSf())/sum(surf.magSf());
             areaAverage = sum(allData)/allData.size();
         }
         Pstream::scatter(areaAverage);
@@ -314,25 +317,23 @@ Foam::scalar surfaceNoise::writeSurfaceData
     {
         const meshedSurface& surf = readerPtr_->geometry();
 
+        // could also have meshedSurface implement meshedSurf
         writerPtr_->write
         (
             outDir,
             fName,
-            surf.points(),
-            surf.faces(),
+            meshedSurfRef
+            (
+                surf.points(),
+                surf.surfFaces()
+            ),
             title,
             data,
             false
         );
 
-        // TODO: Move faceAreas to demand-driven function in MeshedSurface
-        // scalarField faceAreas(surf.faces().size());
-        // forAll(faceAreas, i)
-        // {
-        //     faceAreas[i] = surf.faces()[i].mag(surf.points());
-        // }
-        //
-        // return sum(data*faceAreas)/sum(faceAreas);
+        // TO BE VERIFIED: area-averaged values
+        // return sum(data*surf.magSf())/sum(surf.magSf());
         return sum(data)/data.size();
     }
 }
@@ -382,14 +383,8 @@ Foam::scalar surfaceNoise::surfaceAverage
                 }
             }
 
-            // TODO: Move faceAreas to demand-driven function in MeshedSurface
-            scalarField faceAreas(surf.faces().size());
-            forAll(faceAreas, i)
-            {
-                faceAreas[i] = surf.faces()[i].mag(surf.points());
-            }
-
-//            areaAverage = sum(allData*faceAreas)/sum(faceAreas);
+            // TO BE VERIFIED: area-averaged values
+            // areaAverage = sum(allData*surf.magSf())/sum(surf.magSf());
             areaAverage = sum(allData)/allData.size();
         }
         Pstream::scatter(areaAverage);
@@ -398,16 +393,10 @@ Foam::scalar surfaceNoise::surfaceAverage
     }
     else
     {
-        const meshedSurface& surf = readerPtr_->geometry();
-
-        // TODO: Move faceAreas to demand-driven function in MeshedSurface
-        scalarField faceAreas(surf.faces().size());
-        forAll(faceAreas, i)
-        {
-            faceAreas[i] = surf.faces()[i].mag(surf.points());
-        }
 
-//        return sum(data*faceAreas)/sum(faceAreas);
+        // TO BE VERIFIED: area-averaged values
+        // const meshedSurface& surf = readerPtr_->geometry();
+        // return sum(data*surf.magSf())/sum(surf.magSf());
         return sum(data)/data.size();
     }
 }
@@ -418,13 +407,13 @@ Foam::scalar surfaceNoise::surfaceAverage
 surfaceNoise::surfaceNoise(const dictionary& dict)
 :
     noiseModel(dict),
-    inputFileName_(dict.lookup("inputFile")),
+    inputFileName_("unknown-inputFile"),
     pIndex_(0),
     times_(),
     deltaT_(0),
     startTimeIndex_(0),
     nFace_(0),
-    fftWriteInterval_(dict.lookupOrDefault("fftWriteInterval", 1))
+    fftWriteInterval_(1)
 {
     initialise(dict);
 }
@@ -545,9 +534,6 @@ void surfaceNoise::calculate()
             surfPSD13f[freqI][faceI] = PSD13f.y()[freqI];
             surfPrms13f2[freqI][faceI] = Prms13f2.y()[freqI];
         }
-
-        // Free the storage for p
-//        p.clear();
     }
 
     // Output directory for graphs
diff --git a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H
index 1ba1772df4e1c40bf5008a15966bdf0c548bb6e8..054944a1589765e455b203e958fb4a199842d58b 100644
--- a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H
+++ b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H
@@ -116,7 +116,7 @@ protected:
     // Protected Data
 
         //- Input file name
-        const fileName inputFileName_;
+        fileName inputFileName_;
 
         //- Index of pressure field in reader field list
         label pIndex_;
diff --git a/src/renumber/Allwmake b/src/renumber/Allwmake
index 14191c9526787f66f030515498760be4613ae226..66d9bfd5366c8f66e74b55adda50298aafeaf50e 100755
--- a/src/renumber/Allwmake
+++ b/src/renumber/Allwmake
@@ -20,8 +20,8 @@ set -x
 
 wmake $targetType renumberMethods
 
-if [ -d "$BOOST_ARCH_PATH/include/boost" ] || \
-   [ "${BOOST_ARCH_PATH##*-}" = system -a -d /usr/include/boost ]
+if [ -f "$BOOST_ARCH_PATH/include/boost/version.hpp" ] || \
+   [ "${BOOST_ARCH_PATH##*-}" = system -a -f /usr/include/boost/version.hpp ]
 then
     wmake $targetType SloanRenumber
 else
diff --git a/src/renumber/SloanRenumber/Make/options b/src/renumber/SloanRenumber/Make/options
index cf6e548615177465eba855341de032020bd5c2b4..2c8f956a611718051304f5c066175e83e469ea3c 100644
--- a/src/renumber/SloanRenumber/Make/options
+++ b/src/renumber/SloanRenumber/Make/options
@@ -5,7 +5,7 @@ EXE_INC = \
     -I$(LIB_SRC)/renumber/renumberMethods/lnInclude
 
 LIB_LIBS = \
-    -L$(BOOST_ARCH_PATH)/lib -lboost_system \
+    -L$(BOOST_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) -lboost_system \
     -lmeshTools \
     -ldecompositionMethods \
     -lrenumberMethods
diff --git a/src/sampling/Make/options b/src/sampling/Make/options
index 0cf5b268b66ff3328432eae842b61c2b1bc557a5..00d418481bcf4eefeb539353f61b60f620b25f58 100644
--- a/src/sampling/Make/options
+++ b/src/sampling/Make/options
@@ -13,7 +13,6 @@ LIB_LIBS = \
     -lfiniteVolume \
     -lmeshTools \
     -lsurfMesh \
-    -lfileFormats \
     -ltriSurface \
     -llagrangian \
     -ldynamicMesh \
diff --git a/src/sampling/meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethod.C b/src/sampling/meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethod.C
index 2614f81db674ba1c48f31957ac882ce79a57f2b1..63c8a58d7a4fff2585e39bb6626ca9c0a9ad54aa 100644
--- a/src/sampling/meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethod.C
+++ b/src/sampling/meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethod.C
@@ -205,7 +205,7 @@ bool Foam::meshToMeshMethod::initialise
     {
         if (debug)
         {
-            Pout<< "mesh interpolation: hhave " << src_.nCells() << " source "
+            Pout<< "mesh interpolation: have " << src_.nCells() << " source "
                 << " cells but no target cells" << endl;
         }
 
diff --git a/src/sampling/sampledSet/cloud/cloudSet.C b/src/sampling/sampledSet/cloud/cloudSet.C
index 43d7f11fe70a646bd66b48a06b0014b67e3e0f31..79b7f8f4a9bd461db0d2e3e268a8355b33844146 100644
--- a/src/sampling/sampledSet/cloud/cloudSet.C
+++ b/src/sampling/sampledSet/cloud/cloudSet.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,6 +30,7 @@ License
 #include "polyMesh.H"
 #include "addToRunTimeSelectionTable.H"
 #include "word.H"
+#include "DynamicField.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -53,6 +54,7 @@ void Foam::cloudSet::calcSamples
 {
     const meshSearch& queryMesh = searchEngine();
 
+    labelList foundProc(sampleCoords_.size(), -1);
     forAll(sampleCoords_, sampleI)
     {
         label celli = queryMesh.findCell(sampleCoords_[sampleI]);
@@ -64,6 +66,72 @@ void Foam::cloudSet::calcSamples
             samplingFaces.append(-1);
             samplingSegments.append(0);
             samplingCurveDist.append(1.0 * sampleI);
+
+            foundProc[sampleI] = Pstream::myProcNo();
+        }
+    }
+
+    // Check that all have been found
+    labelList maxFoundProc(foundProc);
+    Pstream::listCombineGather(maxFoundProc, maxEqOp<label>());
+    Pstream::listCombineScatter(maxFoundProc);
+
+    labelList minFoundProc(foundProc.size(), labelMax);
+    forAll(foundProc, i)
+    {
+        if (foundProc[i] != -1)
+        {
+            minFoundProc[i] = foundProc[i];
+        }
+    }
+    Pstream::listCombineGather(minFoundProc, minEqOp<label>());
+    Pstream::listCombineScatter(minFoundProc);
+
+
+    DynamicField<point> missingPoints(sampleCoords_.size());
+
+    forAll(sampleCoords_, sampleI)
+    {
+        if (maxFoundProc[sampleI] == -1)
+        {
+            // No processor has found the location.
+            missingPoints.append(sampleCoords_[sampleI]);
+        }
+        else if (minFoundProc[sampleI] != maxFoundProc[sampleI])
+        {
+            WarningInFunction
+                << "For sample set " << name()
+                << " location " << sampleCoords_[sampleI]
+                << " seems to be on multiple domains: "
+                << minFoundProc[sampleI] << " and " << maxFoundProc[sampleI]
+                << nl
+                << "This might happen if the location is on"
+                << " a processor patch. Change the location slightly"
+                << " to prevent this." << endl;
+        }
+    }
+
+
+    if (missingPoints.size() > 0)
+    {
+        if (missingPoints.size() < 100 || debug)
+        {
+            WarningInFunction
+                << "For sample set " << name()
+                << " did not found " << missingPoints.size()
+                << " points out of " << sampleCoords_.size()
+                << nl
+                << "Missing points:" << missingPoints << endl;
+        }
+        else
+        {
+            WarningInFunction
+                << "For sample set " << name()
+                << " did not found " << missingPoints.size()
+                << " points out of " << sampleCoords_.size()
+                << nl
+                << "Print missing points by setting the debug flag"
+                << " for " << cloudSet::typeName << endl;
         }
     }
 }
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
index 755eb818e487d80537efc1488d2aa1010192f964..0ca56d080836fce03694b002a1d396c0e1ce47c3 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -193,6 +193,32 @@ public:
             return facesPtr_;
         }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
+
+        //- Face area vectors
+        virtual const vectorField& Sf() const
+        {
+            return surface().Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return surface().magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return surface().Cf();
+        }
+
+
+        //- The underlying surface
         const triSurface& surface() const
         {
             if (cell_)
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
index a0ea5063372400010a10e310ab82d7b9d3f13917..8be9053eea667b28ebee2c3aac1922667ad3717c 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -158,6 +158,11 @@ public:
 
     // Member Functions
 
+        const isoSurface& surface() const
+        {
+            return surfPtr_();
+        }
+
         //- Does the surface need an update?
         virtual bool needsUpdate() const;
 
@@ -194,16 +199,38 @@ public:
             return facesPtr_;
         }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
 
-        const isoSurface& surface() const
+        //- Face area magnitudes
+        virtual const vectorField& Sf() const
         {
-            return surfPtr_();
+            return surface().Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return surface().magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return surface().Cf();
         }
 
-        //- Lookup or read isoField. Sets volFieldPtr_ and pointFieldPtr_.
+
+        //- Lookup or read isoField.
+        //  Sets volFieldPtr_ and pointFieldPtr_.
         void getIsoField();
 
 
+    // Sample
+
         //- Sample field on surface
         virtual tmp<scalarField> sample
         (
@@ -235,6 +262,8 @@ public:
         ) const;
 
 
+    // Interpolate
+
         //- Interpolate field on surface
         virtual tmp<scalarField> interpolate
         (
@@ -265,6 +294,9 @@ public:
             const interpolation<tensor>&
         ) const;
 
+
+    // Output
+
         //- Write
         virtual void print(Ostream&) const;
 };
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
index b404976ee07192b091a75b838decf47eb09d98a7..4d0952b2e65b05d69b9104ad19999a9dec7dcc7b 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -54,6 +54,9 @@ class sampledIsoSurfaceCell
     public sampledSurface,
     public triSurface
 {
+    //- Private typedef for convenience
+    typedef triSurface MeshStorage;
+
     // Private data
 
         //- Field to get isoSurface of
@@ -145,7 +148,7 @@ public:
         //- Points of surface
         virtual const pointField& points() const
         {
-            return triSurface::points();
+            return MeshStorage::points();
         }
 
         //- Faces of surface
@@ -165,6 +168,30 @@ public:
             return facesPtr_;
         }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
+
+        //- Face area magnitudes
+        virtual const vectorField& Sf() const
+        {
+            return MeshStorage::Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return MeshStorage::magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return MeshStorage::Cf();
+        }
+
 
         //- Sample field on surface
         virtual tmp<scalarField> sample
diff --git a/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReader.C b/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReader.C
index 16390847143593e0665b2094b4b79a385974083b..bd026f2b91e68eafa22e34441bcc74c8a9f6e84a 100644
--- a/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReader.C
+++ b/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReader.C
@@ -333,7 +333,7 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
                 Info<< "binary" << endl;
             }
         }
-            
+
 
         ensightReadFile is(baseDir_/meshFileName_, streamFormat_);
 
@@ -343,7 +343,7 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
         }
 
         readGeometryHeader(is);
-        
+
         label nPoints;
         is.read(nPoints);
 
diff --git a/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReaderTemplates.C b/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReaderTemplates.C
index dace0703200ddf109ead4409c642943feef53db2..5b8b3f555921e9e19fcede384aaa7c169a06c6ac 100644
--- a/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReaderTemplates.C
+++ b/src/sampling/sampledSurface/readers/ensight/ensightSurfaceReaderTemplates.C
@@ -88,7 +88,7 @@ Foam::tmp<Foam::Field<Type> > Foam::ensightSurfaceReader::readField
     const word indexStr = oss.str();
     fieldFileName.replace(maskStr, indexStr);
 
-    
+
     ensightReadFile is(baseDir_/fieldFileName, streamFormat_);
 
     if (!is.good())
@@ -102,7 +102,7 @@ Foam::tmp<Foam::Field<Type> > Foam::ensightSurfaceReader::readField
     // Check that data type is as expected
     string primitiveType;
     is.read(primitiveType);
-    
+
 
     if (debug)
     {
diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H
index eb50106b59a5732d45b425bce607e6756a38813a..6af60649219ac9a301034f507405bd5be3bb1d04 100644
--- a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H
+++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -141,6 +141,12 @@ public:
 
     // Member Functions
 
+        //const isoSurfaceCell& surface() const
+        const isoSurface& surface() const
+        {
+            return isoSurfPtr_();
+        }
+
         //- Does the surface need an update?
         virtual bool needsUpdate() const;
 
@@ -176,13 +182,33 @@ public:
             return facesPtr_;
         }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
 
-        //const isoSurfaceCell& surface() const
-        const isoSurface& surface() const
+        //- Face area magnitudes
+        virtual const vectorField& Sf() const
         {
-            return isoSurfPtr_();
+            return surface().Sf();
         }
 
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return surface().magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return surface().Cf();
+        }
+
+
+    // Sample
+
         //- Sample field on surface
         virtual tmp<scalarField> sample
         (
@@ -214,6 +240,8 @@ public:
         ) const;
 
 
+    // Interpolate
+
         //- Interpolate field on surface
         virtual tmp<scalarField> interpolate
         (
@@ -244,6 +272,9 @@ public:
             const interpolation<tensor>&
         ) const;
 
+
+    // Output
+
         //- Write
         virtual void print(Ostream&) const;
 };
diff --git a/src/sampling/sampledSurface/sampledPatch/sampledPatch.H b/src/sampling/sampledSurface/sampledPatch/sampledPatch.H
index b16ddef634e82ec3667fa609a5137109dbaa29b6..76800d8c62d59ab2dda5b5016d1b6141065492e3 100644
--- a/src/sampling/sampledSurface/sampledPatch/sampledPatch.H
+++ b/src/sampling/sampledSurface/sampledPatch/sampledPatch.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -177,11 +177,36 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            return MeshStorage::faces();
+            return MeshStorage::surfFaces();
+        }
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
+
+        //- Face area vectors
+        virtual const vectorField& Sf() const
+        {
+            return MeshStorage::Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return MeshStorage::magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return MeshStorage::Cf();
         }
 
 
         // Sample
+
             //- Sample field on surface
             virtual tmp<scalarField> sample
             (
diff --git a/src/sampling/sampledSurface/sampledPlane/sampledPlane.H b/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
index 6746361c1ed6788bda0a175d89210737fcee8219..4171cb3e36b27604b1b2979146573566ed7f72ba 100644
--- a/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
+++ b/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -137,9 +137,35 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            return cuttingPlane::faces();
+            return cuttingPlane::surfFaces();
         }
 
+        //- Const access to per-face zone/region information
+        //  Could instead return meshCells or cellZoneId of the meshCells.
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
+
+        //- Face area magnitudes
+        virtual const vectorField& Sf() const
+        {
+            return cuttingPlane::Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return cuttingPlane::magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return cuttingPlane::Cf();
+        }
+
+
         //- For every face original cell in mesh
         const labelList& meshCells() const
         {
diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
index d1281cfb457cd542804eb1213faebdcc7771e3f9..ddaea516a07d549cbcca84d743481d154d6c2d4d 100644
--- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
+++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
@@ -41,76 +41,10 @@ namespace Foam
 
 void Foam::sampledSurface::clearGeom() const
 {
-    deleteDemandDrivenData(SfPtr_);
-    deleteDemandDrivenData(magSfPtr_);
-    deleteDemandDrivenData(CfPtr_);
     area_ = -1;
 }
 
 
-void Foam::sampledSurface::makeSf() const
-{
-    // It is an error to recalculate if the pointer is already set
-    if (SfPtr_)
-    {
-        FatalErrorInFunction
-            << "face area vectors already exist"
-            << abort(FatalError);
-    }
-
-    const faceList& theFaces = faces();
-    SfPtr_ = new vectorField(theFaces.size());
-
-    vectorField& values = *SfPtr_;
-    forAll(theFaces, facei)
-    {
-        values[facei] = theFaces[facei].normal(points());
-    }
-}
-
-
-void Foam::sampledSurface::makeMagSf() const
-{
-    // It is an error to recalculate if the pointer is already set
-    if (magSfPtr_)
-    {
-        FatalErrorInFunction
-            << "mag face areas already exist"
-            << abort(FatalError);
-    }
-
-    const faceList& theFaces = faces();
-    magSfPtr_ = new scalarField(theFaces.size());
-
-    scalarField& values = *magSfPtr_;
-    forAll(theFaces, facei)
-    {
-        values[facei] = theFaces[facei].mag(points());
-    }
-}
-
-
-void Foam::sampledSurface::makeCf() const
-{
-    // It is an error to recalculate if the pointer is already set
-    if (CfPtr_)
-    {
-        FatalErrorInFunction
-            << "face centres already exist"
-            << abort(FatalError);
-    }
-
-    const faceList& theFaces = faces();
-    CfPtr_ = new vectorField(theFaces.size());
-
-    vectorField& values = *CfPtr_;
-    forAll(theFaces, facei)
-    {
-        values[facei] = theFaces[facei].centre(points());
-    }
-}
-
-
 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
 
 Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New
@@ -156,9 +90,6 @@ Foam::sampledSurface::sampledSurface
     name_(name),
     mesh_(mesh),
     interpolate_(interpolate),
-    SfPtr_(nullptr),
-    magSfPtr_(nullptr),
-    CfPtr_(nullptr),
     area_(-1)
 {}
 
@@ -173,9 +104,6 @@ Foam::sampledSurface::sampledSurface
     name_(name),
     mesh_(mesh),
     interpolate_(dict.lookupOrDefault("interpolate", false)),
-    SfPtr_(nullptr),
-    magSfPtr_(nullptr),
-    CfPtr_(nullptr),
     area_(-1)
 {
     dict.readIfPresent("name", name_);
@@ -192,39 +120,6 @@ Foam::sampledSurface::~sampledSurface()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const Foam::vectorField& Foam::sampledSurface::Sf() const
-{
-    if (!SfPtr_)
-    {
-        makeSf();
-    }
-
-    return *SfPtr_;
-}
-
-
-const Foam::scalarField& Foam::sampledSurface::magSf() const
-{
-    if (!magSfPtr_)
-    {
-        makeMagSf();
-    }
-
-    return *magSfPtr_;
-}
-
-
-const Foam::vectorField& Foam::sampledSurface::Cf() const
-{
-    if (!CfPtr_)
-    {
-        makeCf();
-    }
-
-    return *CfPtr_;
-}
-
-
 Foam::scalar Foam::sampledSurface::area() const
 {
     if (area_ < 0)
diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
index b0a19707a96dc7ed50f0c2460d68e95b524ddb4c..b625675eff24ab7e28d232ba254fd7b64ab15056 100644
--- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
+++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,7 +52,7 @@ SourceFiles
 #ifndef sampledSurface_H
 #define sampledSurface_H
 
-#include "pointField.H"
+#include "meshedSurf.H"
 #include "word.H"
 #include "labelList.H"
 #include "faceList.H"
@@ -83,6 +83,8 @@ Ostream& operator<<(Ostream&, const sampledSurface&);
 \*---------------------------------------------------------------------------*/
 
 class sampledSurface
+:
+    public meshedSurf
 {
     // Private data
 
@@ -98,31 +100,10 @@ class sampledSurface
 
     // Demand-driven data
 
-        //- Face area vectors
-        mutable vectorField* SfPtr_;
-
-        //- Mag face area vectors
-        mutable scalarField* magSfPtr_;
-
-        //- Face centres
-        mutable vectorField* CfPtr_;
-
         //- Total surface area
         mutable scalar area_;
 
 
-    // Make geometric data
-
-        //- Make Sf
-        void makeSf() const;
-
-        //- Make magSf
-        void makeMagSf() const;
-
-        //- Make Cf
-        void makeCf() const;
-
-
     // Service methods
 
         //- Check field size matches surface size
@@ -284,18 +265,19 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const = 0;
 
-        //- Return face area vectors
-        virtual const vectorField& Sf() const;
+        //- Face area vectors
+        virtual const vectorField& Sf() const = 0;
 
-        //- Return face area magnitudes
-        virtual const scalarField& magSf() const;
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const = 0;
 
-        //- Return face centres as vectorField
-        virtual const vectorField& Cf() const;
+        //- Face centres
+        virtual const vectorField& Cf() const = 0;
 
         //- The total surface area
         scalar area() const;
 
+
         //- Integration of a field across the surface
         template<class Type>
         Type integrate(const Field<Type>&) const;
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
index 88eb52b09194a2fc4cb858e5d0f710b02218000f..f15c61b36315f0d3bd89dcdb14334c7bbc6d7e70 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
@@ -66,26 +66,19 @@ void Foam::sampledSurfaces::writeGeometry() const
 
         if (Pstream::parRun())
         {
-            if (Pstream::master() && mergeList_[surfI].faces.size())
+            if (Pstream::master() && mergedList_[surfI].size())
             {
                 formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    mergeList_[surfI].points,
-                    mergeList_[surfI].faces
+                    mergedList_[surfI]
                 );
             }
         }
         else if (s.faces().size())
         {
-            formatter_->write
-            (
-                outputDir,
-                s.name(),
-                s.points(),
-                s.faces()
-            );
+            formatter_->write(outputDir, s.name(), s);
         }
     }
 }
@@ -107,7 +100,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     if (Pstream::parRun())
@@ -138,7 +131,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     read(dict);
@@ -239,7 +232,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
 
         if (Pstream::parRun())
         {
-            mergeList_.setSize(size());
+            mergedList_.setSize(size());
         }
 
         // Ensure all surfaces and merge information are expired
@@ -329,7 +322,7 @@ bool Foam::sampledSurfaces::expire()
         // Clear merge information
         if (Pstream::parRun())
         {
-            mergeList_[surfI].clear();
+            mergedList_[surfI].clear();
         }
     }
 
@@ -377,24 +370,8 @@ bool Foam::sampledSurfaces::update()
         if (s.update())
         {
             updated = true;
+            mergedList_[surfI].merge(s, mergeDim);
         }
-        else
-        {
-            continue;
-        }
-
-        PatchTools::gatherAndMerge
-        (
-            mergeDim,
-            primitivePatch
-            (
-                SubList<face>(s.faces(), s.faces().size()),
-                s.points()
-            ),
-            mergeList_[surfI].points,
-            mergeList_[surfI].faces,
-            mergeList_[surfI].pointsMap
-        );
     }
 
     return updated;
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
index 5d817632b5bc0e8ddaeea194188fa18632e36be2..1d9c9e730b91a668999fa9b5292804f22c0d2128 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,6 +40,7 @@ SourceFiles
 #include "regionFunctionObject.H"
 #include "sampledSurface.H"
 #include "surfaceWriter.H"
+#include "mergedSurf.H"
 #include "volFieldsFwd.H"
 #include "surfaceFieldsFwd.H"
 #include "wordReList.H"
@@ -64,26 +65,6 @@ class sampledSurfaces
     public functionObjects::regionFunctionObject,
     public PtrList<sampledSurface>
 {
-    // Private classes
-
-        //- Class used for surface merging information
-        class mergeInfo
-        {
-        public:
-            pointField points;
-            faceList   faces;
-            labelList  pointsMap;
-
-            //- Clear all storage
-            void clear()
-            {
-                points.clear();
-                faces.clear();
-                pointsMap.clear();
-            }
-        };
-
-
     // Static data members
 
         //- Output verbosity
@@ -116,8 +97,8 @@ class sampledSurfaces
 
         // surfaces
 
-            //- Information for merging surfaces
-            List<mergeInfo> mergeList_;
+            //- Merged meshed surfaces (parallel only)
+            List<mergedSurf> mergedList_;
 
 
         // Calculated
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
index 7925cf25f00c33bfa7ff119713db0b4cdac8ee99..ba39848aad2bd0d809c3e56b2d0a0e615f43b679 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
@@ -65,22 +65,21 @@ void Foam::sampledSurfaces::writeSurface
             );
 
             // Renumber (point data) to correspond to merged points
-            if (mergeList_[surfI].pointsMap.size() == allValues.size())
+            if (mergedList_[surfI].pointsMap().size() == allValues.size())
             {
-                inplaceReorder(mergeList_[surfI].pointsMap, allValues);
-                allValues.setSize(mergeList_[surfI].points.size());
+                inplaceReorder(mergedList_[surfI].pointsMap(), allValues);
+                allValues.setSize(mergedList_[surfI].points().size());
             }
 
             // Write to time directory under outputPath_
             // skip surface without faces (eg, a failed cut-plane)
-            if (mergeList_[surfI].faces.size())
+            if (mergedList_[surfI].size())
             {
                 sampleFile = formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    mergeList_[surfI].points,
-                    mergeList_[surfI].faces,
+                    mergedList_[surfI],
                     fieldName,
                     allValues,
                     s.interpolate()
@@ -106,8 +105,7 @@ void Foam::sampledSurfaces::writeSurface
             (
                 outputDir,
                 s.name(),
-                s.points(),
-                s.faces(),
+                s,
                 fieldName,
                 values,
                 s.interpolate()
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
index e0f9eb757bfd2cd9f07541464a67f424d3372977..c1c08006d4542c0dc3caf1f5e41d78bb9d23f851 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -305,16 +305,21 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
     // Create faces and points for subsetted surface
     faceList& faces = this->storedFaces();
     faces.setSize(faceMap.size());
+
+    labelList& zoneIds = this->storedZoneIds();
+    zoneIds.setSize(faceMap.size());
+
     forAll(faceMap, i)
     {
-        const triFace& f = s[faceMap[i]];
+        const labelledTri& f = s[faceMap[i]];
         triFace newF
         (
             reversePointMap[f[0]],
             reversePointMap[f[1]],
             reversePointMap[f[2]]
         );
-        faces[i] = newF.triFaceFace();
+        faces[i]   = newF.triFaceFace();
+        zoneIds[i] = f.region(); // preserve zone information
 
         forAll(newF, fp)
         {
@@ -773,9 +778,10 @@ Foam::tmp<Foam::tensorField> Foam::sampledTriSurfaceMesh::interpolate
 void Foam::sampledTriSurfaceMesh::print(Ostream& os) const
 {
     os  << "sampledTriSurfaceMesh: " << name() << " :"
-        << "  surface:" << surface_.objectRegistry::name()
-        << "  faces:" << faces().size()
-        << "  points:" << points().size();
+        << " surface:" << surface_.objectRegistry::name()
+        << " faces:"   << faces().size()
+        << " points:"  << points().size()
+        << " zoneids:" << zoneIds().size();
 }
 
 
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
index 6a41255075237d01ec63bac6dc6a290733949695..7403bfc65e24a4888b7b1fb18282646e3d1d4b3d 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -87,7 +87,7 @@ class meshSearch;
 class sampledTriSurfaceMesh
 :
     public sampledSurface,
-    public MeshedSurface<face>
+    public UnsortedMeshedSurface<face>
 {
 public:
         //- Types of communications
@@ -101,7 +101,7 @@ public:
 private:
 
     //- Private typedefs for convenience
-        typedef MeshedSurface<face> MeshStorage;
+        typedef UnsortedMeshedSurface<face> MeshStorage;
 
 
     // Private data
@@ -213,7 +213,31 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            return MeshStorage::faces();
+            return MeshStorage::surfFaces();
+        }
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return MeshStorage::zoneIds();
+        }
+
+        //- Face area vectors
+        virtual const vectorField& Sf() const
+        {
+            return MeshStorage::Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return MeshStorage::magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return MeshStorage::Cf();
         }
 
 
diff --git a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
index 840a9920ad1c1a051c62afd256656ea3ae6055ff..8f097f426272267bef0b9f1a647b3ad7c4584b26 100644
--- a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
+++ b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -145,9 +145,34 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            return MeshStorage::faces();
+            return MeshStorage::surfFaces();
         }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return Foam::emptyLabelList;
+        }
+
+        //- Face area vectors (normals)
+        virtual const vectorField& Sf() const
+        {
+            return MeshStorage::Sf();
+        }
+
+        //- Face area magnitudes
+        virtual const scalarField& magSf() const
+        {
+            return MeshStorage::magSf();
+        }
+
+        //- Face centres
+        virtual const vectorField& Cf() const
+        {
+            return MeshStorage::Cf();
+        }
+
+
         //- Sample field on surface
         virtual tmp<scalarField> sample(const volScalarField&) const;
 
diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C
index 076a9a42260dc1ecf0c4894d903fd4dcfc2c2574..aaf7aebd7879685f84e2c9e3ad085a23c582c732 100644
--- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C
@@ -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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,14 +53,14 @@ Foam::fileName Foam::boundaryDataSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
     const fileName baseDir(outputDir.path()/surfaceName);
     const fileName timeName(outputDir.name());
 
+    const pointField& points = surf.points();
 
     // Construct dummy time to use as an objectRegistry
     const fileName caseDir(getEnv("FOAM_CASE"));
@@ -110,6 +110,8 @@ Foam::fileName Foam::boundaryDataSurfaceWriter::write
 }
 
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 // create write methods
 defineSurfaceWriterWriteFields(Foam::boundaryDataSurfaceWriter);
 
diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
index b70b4d47c5b0be71102b019f25baa1baf7d4eea6..57da092b71ad15f8e6cce4742bc7d69bfc6b5912 100644
--- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2015 OpenCFD Ltd.
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2015-2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -98,8 +98,7 @@ class boundaryDataSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -130,10 +129,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 
         //- Write scalarField for a single surface to file.
@@ -142,13 +140,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -156,13 +153,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -170,13 +166,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -184,13 +179,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -198,13 +192,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C
index ec0db202d584d3ad82c8126b28721cfc80d60e5f..dcc9452d00bf1b1731326f60a135279512db2e58 100644
--- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C
@@ -37,8 +37,7 @@ Foam::fileName Foam::boundaryDataSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -48,6 +47,9 @@ Foam::fileName Foam::boundaryDataSurfaceWriter::writeTemplate
     const fileName baseDir(outputDir.path()/surfaceName);
     const fileName timeName(outputDir.name());
 
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
 
     // Construct dummy time to use as an objectRegistry
     const fileName caseDir(getEnv("FOAM_CASE"));
diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
index 27015fe21e9baebb8b9159ded7e4ced1a52b4e52..6f060732570df4b8219498e4138264a5d0004b2f 100644
--- a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,10 +39,12 @@ namespace Foam
 void Foam::dxSurfaceWriter::writeGeometry
 (
     Ostream& os,
-    const pointField& points,
-    const faceList& faces
+    const meshedSurf& surf
 )
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
     // Write vertex coordinates
 
     os  << "# The irregular positions" << nl
diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
index 51eceeda3e5e765d6172b8bef02a8bc08d5efc25..8a169d3beb41c289599e09a76b9d5716e1d8c762 100644
--- a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,7 +53,7 @@ class dxSurfaceWriter
 
     // Private Member Functions
 
-        static void writeGeometry(Ostream&, const pointField&, const faceList&);
+        static void writeGeometry(Ostream&, const meshedSurf&);
         static void writeTrailer(Ostream&, const bool isNodeValues);
 
         template<class Type>
@@ -65,8 +65,7 @@ class dxSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -98,13 +97,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -112,13 +110,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -126,13 +123,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -140,13 +136,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -154,13 +149,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C
index 835f2b2b952f1cbf1a72539f70ba4f8de9144411..f9bb67c99a089038d4e8e326a0c12deda667c0e1 100644
--- a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.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  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,8 +50,7 @@ Foam::fileName Foam::dxSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -70,7 +69,7 @@ Foam::fileName Foam::dxSurfaceWriter::writeTemplate
         Info<< "Writing field " << fieldName << " to " << os.name() << endl;
     }
 
-    writeGeometry(os, points, faces);
+    writeGeometry(os, surf);
     writeData(os, values);
     writeTrailer(os, isNodeValues);
 
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
index ac2457010d9d69cdb5e9a68dcdc5f7bd6b40a746..fd89f72f5a3e89b0b4375e898fdad39abca0a4e2 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
@@ -84,11 +84,12 @@ Foam::fileName Foam::ensightSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
+    const pointField& points = surf.points();
+    const faceList&   faces  = surf.faces();
     const ensight::FileName surfName(surfaceName);
 
     if (!isDir(outputDir))
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H
index 9d5ff392b41f92fb7fab3ddc59e9b25a179a3c51..58325c1a2640e006269b2cdfd890917c6648dc54 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H
@@ -67,8 +67,7 @@ class ensightSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -81,8 +80,7 @@ class ensightSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -95,8 +93,7 @@ class ensightSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -135,10 +132,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 
         //- Write scalarField for a single surface to file.
@@ -147,13 +143,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -161,13 +156,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -175,13 +169,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -189,13 +182,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -203,13 +195,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
index 41c404deb6e96c53e5ae1f3f3098eb16b0295f41..34d218dac8d79d625e348c010d38b22ac23850f1 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
@@ -28,6 +28,7 @@ License
 #include "OFstream.H"
 #include "OSspecific.H"
 #include "ensightPartFaces.H"
+#include "ensightSerialOutput.H"
 #include "ensightPTraits.H"
 #include "OStringStream.H"
 #include "regExp.H"
@@ -39,8 +40,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -116,12 +116,25 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
         << "    " << timeValue
         << nl << nl << "# end" << nl;
 
-    ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true);
+    ensightPartFaces ensPart
+    (
+        0,
+        osGeom.name().name(),
+        surf.points(),
+        surf.faces(),
+        true // contiguous points
+    );
     osGeom << ensPart;
 
     // Write field
     osField.writeKeyword(ensightPTraits<Type>::typeName);
-    ensPart.writeField(osField, values, isNodeValues);
+    ensightSerialOutput::writeField
+    (
+        values,
+        ensPart,
+        osField,
+        isNodeValues
+    );
 
     return osCase.name();
 }
@@ -132,8 +145,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -303,7 +315,14 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
 
 
     // Write geometry
-    ensightPartFaces ensPart(0, meshFile.name(), points, faces, true);
+    ensightPartFaces ensPart
+    (
+        0,
+        meshFile.name(),
+        surf.points(),
+        surf.faces(),
+        true // contiguous points
+    );
     if (!exists(meshFile))
     {
         if (verbose)
@@ -337,12 +356,21 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
         varName,
         writeFormat_
     );
+
     if (verbose)
     {
         Info<< "Writing field file to " << osField.name() << endl;
     }
+
+    // Write field
     osField.writeKeyword(ensightPTraits<Type>::typeName);
-    ensPart.writeField(osField, values, isNodeValues);
+    ensightSerialOutput::writeField
+    (
+        values,
+        ensPart,
+        osField,
+        isNodeValues
+    );
 
     // place a timestamp in the directory for future reference
     {
@@ -361,8 +389,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -375,8 +402,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeTemplate
         (
             outputDir,
             surfaceName,
-            points,
-            faces,
+            surf,
             fieldName,
             values,
             isNodeValues,
@@ -389,8 +415,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeTemplate
         (
             outputDir,
             surfaceName,
-            points,
-            faces,
+            surf,
             fieldName,
             values,
             isNodeValues,
diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C
index 4471a002ee758f33cc7701664f2a467418dcb25a..4a59a92347557edcd6340f604095ff1a7182bd40 100644
--- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C
@@ -24,10 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "foamSurfaceWriter.H"
-
 #include "OFstream.H"
-#include "OSspecific.H"
-
 #include "makeSurfaceWriterMethods.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -58,11 +55,13 @@ Foam::fileName Foam::foamSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
     fileName surfaceDir(outputDir/surfaceName);
 
     if (!isDir(surfaceDir))
diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H
index 8b541c6162a0007cc92e498338fd1a8b64593d4d..cc9bdc661e6f1c88249d947f092027ed23e9521b 100644
--- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,7 +43,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                    Class foamSurfaceWriter Declaration
+                      Class foamSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 class foamSurfaceWriter
@@ -58,8 +58,7 @@ class foamSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -97,10 +96,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 
         //- Write scalarField for a single surface to file.
@@ -109,13 +107,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -123,13 +120,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -137,13 +133,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -151,13 +146,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -165,13 +159,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterTemplates.C
index c21909d653dd7ec5ea8607b3a950b838b721c3ab..1a9f1736a5bfd84d1199f17913a5409a3804ffaf 100644
--- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterTemplates.C
@@ -33,8 +33,7 @@ Foam::fileName Foam::foamSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
diff --git a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H b/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H
index 448cff18c5a8d36190af7dc9af7305bf11cdae7b..fadcf23ad2f335e5ecf7fc7f6f9af9ab712e3bc4 100644
--- a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H
+++ b/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -51,20 +51,18 @@ namespace Foam
     (                                                                          \
         const fileName& outputDir,                                             \
         const fileName& surfaceName,                                           \
-        const pointField& points,                                              \
-        const faceList& faces,                                                 \
+        const meshedSurf& surf,                                                \
         const word& fieldName,                                                 \
         const Field<FieldType>& values,                                        \
         const bool isNodeValues,                                               \
         const bool verbose                                                     \
     ) const                                                                    \
     {                                                                          \
-        return writeTemplate                                                          \
+        return writeTemplate                                                   \
         (                                                                      \
             outputDir,                                                         \
             surfaceName,                                                       \
-            points,                                                            \
-            faces,                                                             \
+            surf,                                                              \
             fieldName,                                                         \
             values,                                                            \
             isNodeValues,                                                      \
diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C
index 11c6dcff47d3801990773dd92214a09c5b6577e9..384192756d1beeabe484600a3c2e77fef2ebaf17 100644
--- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,7 +25,8 @@ License
 
 #include "nastranSurfaceWriter.H"
 #include "IOmanip.H"
-#include "Tuple2.H"
+#include "Pair.H"
+#include "HashSet.H"
 #include "makeSurfaceWriterMethods.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -64,7 +65,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const
+void Foam::nastranSurfaceWriter::formatOS(Ostream& os) const
 {
     os.setf(ios_base::scientific);
 
@@ -75,19 +76,23 @@ void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const
     label offset = 7;
     switch (writeFormat_)
     {
-        case (wfShort):
+        case wfShort:
         {
             prec = 8 - offset;
             break;
         }
-        case (wfFree):
-        case (wfLong):
+
+        case wfFree:
+        case wfLong:
         {
             prec = 16 - offset;
             break;
         }
+
         default:
         {
+            FatalErrorInFunction
+                << "Unknown writeFormat enumeration" << abort(FatalError);
         }
     }
 
@@ -95,10 +100,10 @@ void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const
 }
 
 
-void Foam::nastranSurfaceWriter::writeKeyword
+Foam::Ostream& Foam::nastranSurfaceWriter::writeKeyword
 (
-    const word& keyword,
-    Ostream& os
+    Ostream& os,
+    const word& keyword
 ) const
 {
     os.setf(ios_base::left);
@@ -110,11 +115,13 @@ void Foam::nastranSurfaceWriter::writeKeyword
             os  << setw(8) << keyword;
             break;
         }
+
         case wfLong:
         {
             os  << setw(8) << word(keyword + '*');
             break;
         }
+
         case wfFree:
         {
             os  << keyword;
@@ -123,14 +130,16 @@ void Foam::nastranSurfaceWriter::writeKeyword
     }
 
     os.unsetf(ios_base::left);
+
+    return os;
 }
 
 
 void Foam::nastranSurfaceWriter::writeCoord
 (
+    Ostream& os,
     const point& p,
-    const label pointi,
-    OFstream& os
+    const label pointI
 ) const
 {
     // Fixed short/long formats:
@@ -144,21 +153,14 @@ void Foam::nastranSurfaceWriter::writeCoord
     // 8 PS   : single point constraints             (blank)
     // 9 SEID : super-element ID
 
-
-    writeKeyword("GRID", os);
-
-    os  << separator_;
+    writeKeyword(os, "GRID")    << separator_;
 
     os.setf(ios_base::right);
 
-    writeValue(pointi + 1, os);
-    os  << separator_;
-    writeValue("", os);
-    os  << separator_;
-    writeValue(p.x(), os);
-    os  << separator_;
-    writeValue(p.y(), os);
-    os  << separator_;
+    writeValue(os, pointI+1)    << separator_;
+    writeValue(os, "")          << separator_;
+    writeValue(os, p.x())       << separator_;
+    writeValue(os, p.y())       << separator_;
 
     switch (writeFormat_)
     {
@@ -167,27 +169,26 @@ void Foam::nastranSurfaceWriter::writeCoord
             os  << setw(8) << p.z()
                 << nl;
             os.unsetf(ios_base::right);
-
             break;
         }
+
         case wfLong:
         {
             os  << nl;
             os.unsetf(ios_base::right);
-            writeKeyword("", os);
+            writeKeyword(os, "");
             os.setf(ios_base::right);
-            writeValue(p.z(), os);
-            os  << nl;
 
+            writeValue(os, p.z())  << nl;
             break;
         }
+
         case wfFree:
         {
-            writeValue(p.z(), os);
-            os  << nl;
-
+            writeValue(os, p.z())  << nl;
             break;
         }
+
         default:
         {
             FatalErrorInFunction
@@ -201,10 +202,11 @@ void Foam::nastranSurfaceWriter::writeCoord
 
 void Foam::nastranSurfaceWriter::writeFace
 (
+    Ostream& os,
     const word& faceType,
-    const labelList& facePts,
-    label& nFace,
-    OFstream& os
+    const labelUList& facePts,
+    const label nFace,
+    const label PID
 ) const
 {
     // Only valid surface elements are CTRIA3 and CQUAD4
@@ -221,19 +223,12 @@ void Foam::nastranSurfaceWriter::writeFace
 
     // For CTRIA3 elements, cols 7 onwards are not used
 
-    label PID = 1;
-
-    writeKeyword(faceType, os);
-
-    os  << separator_;
+    writeKeyword(os, faceType)   << separator_;
 
     os.setf(ios_base::right);
 
-    writeValue(nFace++, os);
-
-    os  << separator_;
-
-    writeValue(PID, os);
+    writeValue(os, nFace)        << separator_;
+    writeValue(os, PID);
 
     switch (writeFormat_)
     {
@@ -241,7 +236,7 @@ void Foam::nastranSurfaceWriter::writeFace
         {
             forAll(facePts, i)
             {
-                writeValue(facePts[i] + 1, os);
+                writeValue(os, facePts[i] + 1);
             }
 
             break;
@@ -250,12 +245,12 @@ void Foam::nastranSurfaceWriter::writeFace
         {
             forAll(facePts, i)
             {
-                writeValue(facePts[i] + 1, os);
+                writeValue(os, facePts[i] + 1);
                 if (i == 1)
                 {
                     os  << nl;
                     os.unsetf(ios_base::right);
-                    writeKeyword("", os);
+                    writeKeyword(os, "");
                     os.setf(ios_base::right);
                 }
             }
@@ -267,7 +262,7 @@ void Foam::nastranSurfaceWriter::writeFace
             forAll(facePts, i)
             {
                 os  << separator_;
-                writeValue(facePts[i] + 1, os);
+                writeValue(os, facePts[i] + 1);
             }
 
             break;
@@ -286,12 +281,15 @@ void Foam::nastranSurfaceWriter::writeFace
 
 void Foam::nastranSurfaceWriter::writeGeometry
 (
-    const pointField& points,
-    const faceList& faces,
-    List<DynamicList<face>>& decomposedFaces,
-    OFstream& os
+    Ostream& os,
+    const meshedSurf& surf,
+    List<DynamicList<face>>& decomposedFaces
 ) const
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+    const labelList&   zones = surf.zoneIds();
+
     // Write points
 
     os  << "$" << nl
@@ -300,31 +298,33 @@ void Foam::nastranSurfaceWriter::writeGeometry
 
     forAll(points, pointi)
     {
-        writeCoord(points[pointi], pointi, os);
+        writeCoord(os, points[pointi], pointi);
     }
 
-
     // Write faces
+    decomposedFaces.clear();
+    decomposedFaces.setSize(faces.size());
 
     os  << "$" << nl
         << "$ Faces" << nl
         << "$" << nl;
 
-    label nFace = 1;
-
+    label nFace = 0; // the element-id
     forAll(faces, facei)
     {
         const face& f = faces[facei];
+        // 1-offset for PID
+        const label PID = 1 + (facei < zones.size() ? zones[facei] : 0);
 
         if (f.size() == 3)
         {
-            writeFace("CTRIA3", faces[facei], nFace, os);
-            decomposedFaces[facei].append(faces[facei]);
+            writeFace(os, "CTRIA3", f, ++nFace, PID);
+            decomposedFaces[facei].append(f);
         }
         else if (f.size() == 4)
         {
-            writeFace("CQUAD4", faces[facei], nFace, os);
-            decomposedFaces[facei].append(faces[facei]);
+            writeFace(os, "CQUAD4", f, ++nFace, PID);
+            decomposedFaces[facei].append(f);
         }
         else
         {
@@ -335,7 +335,7 @@ void Foam::nastranSurfaceWriter::writeGeometry
 
             forAll(triFaces, trii)
             {
-                writeFace("CTRIA3", triFaces[trii], nFace, os);
+                writeFace(os, "CTRIA3", triFaces[trii], ++nFace, PID);
                 decomposedFaces[facei].append(triFaces[trii]);
             }
         }
@@ -343,39 +343,51 @@ void Foam::nastranSurfaceWriter::writeGeometry
 }
 
 
-void Foam::nastranSurfaceWriter::writeFooter(Ostream& os) const
+Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter
+(
+    Ostream& os,
+    const meshedSurf& surf
+) const
 {
-    label PID = 1;
-
-    writeKeyword("PSHELL", os);
-
-    os  << separator_;
+    // zone id have been used for the PID. Find unique values.
 
-    writeValue(PID, os);
+    labelList pidsUsed = labelHashSet(surf.zoneIds()).sortedToc();
+    if (pidsUsed.empty())
+    {
+        pidsUsed.setSize(1, Zero); // fallback
+    }
 
-    for (label i = 0; i < 7; i++)
+    for (auto pid : pidsUsed)
     {
-        // Dummy values
-        os  << separator_;
-        writeValue(1, os);
+        writeKeyword(os, "PSHELL")  << separator_;
+        writeValue(os, pid+1);  // 1-offset for PID
+
+        for (label i = 0; i < 7; ++i)
+        {
+            // Dummy values
+            os  << separator_;
+            writeValue(os, 1);
+        }
+        os  << nl;
     }
 
-    os  << nl;
-    writeKeyword("MAT1", os);
-    os  << separator_;
+
+    // use single material ID
 
     label MID = 1;
 
-    writeValue(MID, os);
+    writeKeyword(os, "MAT1")    << separator_;
+    writeValue(os, MID);
 
-    for (label i = 0; i < 7; i++)
+    for (label i = 0; i < 7; ++i)
     {
         // Dummy values
         os  << separator_;
-        writeValue("", os);
+        writeValue(os, "");
     }
-
     os << nl;
+
+    return os;
 }
 
 
@@ -400,7 +412,10 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options)
 {
     if (options.found("format"))
     {
-        writeFormat_ = writeFormatNames_.read(options.lookup("format"));
+        writeFormat_ = writeFormatNames_.read
+        (
+            options.lookup("format")
+        );
     }
 
     if (writeFormat_ == wfFree)
@@ -408,7 +423,7 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options)
         separator_ = ",";
     }
 
-    List<Tuple2<word, word>> fieldSet(options.lookup("fields"));
+    List<Pair<word>> fieldSet(options.lookup("fields"));
 
     forAll(fieldSet, i)
     {
@@ -431,8 +446,7 @@ Foam::fileName Foam::nastranSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
@@ -449,22 +463,16 @@ Foam::fileName Foam::nastranSurfaceWriter::write
         Info<< "Writing nastran file to " << os.name() << endl;
     }
 
-    os  << "TITLE=OpenFOAM " << surfaceName.c_str() << " mesh" << nl
+    os  << "TITLE=OpenFOAM " << surfaceName.c_str()
+        << " mesh" << nl
         << "$" << nl
         << "BEGIN BULK" << nl;
 
-    List<DynamicList<face>> decomposedFaces(faces.size());
-
-    writeGeometry(points, faces, decomposedFaces, os);
-
-    if (!isDir(outputDir))
-    {
-        mkDir(outputDir);
-    }
-
-    writeFooter(os);
+    List<DynamicList<face>> decomposedFaces;
+    writeGeometry(os, surf, decomposedFaces);
 
-    os  << "ENDDATA" << endl;
+    writeFooter(os, surf)
+        << "ENDDATA" << endl;
 
     return os.name();
 }
diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H
index ae0cc8c8390daf07d9cf9b51147c11a43bc414d4..921182af987ff1bf1eae33cca473ee450903fe3a 100644
--- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,6 +27,7 @@ Class
 Description
     A surface writer for the Nastran file format - both surface mesh and fields
 
+    \verbatim
     formatOptions
     {
         nastran
@@ -43,6 +44,7 @@ Description
             format free;    //short, long, free
         }
     };
+    \endverbatim
 
 SourceFiles
     nastranSurfaceWriter.C
@@ -80,26 +82,25 @@ public:
         wfFree
     };
 
-    static const NamedEnum<writeFormat, 3> writeFormatNames_;
-
     enum dataFormat
     {
         dfPLOAD2,
         dfPLOAD4
     };
 
-    static const NamedEnum<dataFormat, 2> dataFormatNames_;
-
 
 private:
 
     // Private data
 
+        static const NamedEnum<writeFormat, 3> writeFormatNames_;
+        static const NamedEnum<dataFormat,  2> dataFormatNames_;
+
         //- Write option
         writeFormat writeFormat_;
 
         //- Mapping from field name to data format enumeration
-        HashTable<dataFormat, word> fieldMap_;
+        HashTable<dataFormat> fieldMap_;
 
         //- Scale to apply to values (default = 1.0)
         scalar scale_;
@@ -110,71 +111,67 @@ private:
 
     // Private Member Functions
 
-        //- Initialise the output stream format params
-        void formatOS(OFstream& os) const;
+        //- Initialise the output stream format parameters
+        void formatOS(Ostream& os) const;
 
-        //- Write a co-ordinate
+        //- Write a coordinate
         void writeCoord
         (
+            Ostream& os,
             const point& p,
-            const label pointi,
-            OFstream& os
+            const label pointI  //!< 0-based Point Id
         ) const;
 
         //- Write a face element (CTRIA3 or CQUAD4)
         void writeFace
         (
+            Ostream& os,
             const word& faceType,
-            const labelList& facePts,
-            label& nFace,
-            OFstream& os
+            const labelUList& facePts,
+            const label EID,    //!< 1-based Element Id
+            const label PID     //!< 1-based Property Id
         ) const;
 
         //- Main driver to write the surface mesh geometry
         void writeGeometry
         (
-            const pointField& points,
-            const faceList& faces,
-            List<DynamicList<face>>& decomposedFaces,
-            OFstream& os
+            Ostream& os,
+            const meshedSurf& surf,
+            List<DynamicList<face>>& decomposedFaces
         ) const;
 
         //- Write the formatted keyword to the output stream
-        void writeKeyword
+        Ostream& writeKeyword
         (
-            const word& keyword,
-            Ostream& os
+            Ostream& os,
+            const word& keyword
         ) const;
 
         //- Write the footer information
-        void writeFooter(Ostream& os) const;
+        Ostream& writeFooter(Ostream& os, const meshedSurf& surf) const;
 
         //- Write a formatted value to the output stream
         template<class Type>
-        void writeValue
-        (
-            const Type& value,
-            Ostream& os
-        ) const;
+        Ostream& writeValue(Ostream& os, const Type& value) const;
 
         //- Write a face-based value
         template<class Type>
-        void writeFaceValue
+        Ostream& writeFaceValue
         (
+            Ostream& os,
             const dataFormat& format,
             const Type& value,
-            const label EID,
-            Ostream& os
+            const label EID     //!< 1-based Element Id
         ) const;
 
+
         //- Templated write operation
         template<class Type>
         fileName writeTemplate
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -215,10 +212,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write scalarField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -226,13 +222,12 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -240,13 +235,12 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -254,13 +248,12 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -268,13 +261,12 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -282,13 +274,12 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C
index 412bbeb0f30c0f6c635d1ef636555840487e517e..048088791c86cd4529eeef3f5de7ad0cf134e68f 100644
--- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,10 +30,10 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type>
-void Foam::nastranSurfaceWriter::writeValue
+Foam::Ostream& Foam::nastranSurfaceWriter::writeValue
 (
-    const Type& value,
-    Ostream& os
+    Ostream& os,
+    const Type& value
 ) const
 {
     switch (writeFormat_)
@@ -54,16 +54,18 @@ void Foam::nastranSurfaceWriter::writeValue
             break;
         }
     }
+
+    return os;
 }
 
 
 template<class Type>
-void Foam::nastranSurfaceWriter::writeFaceValue
+Foam::Ostream& Foam::nastranSurfaceWriter::writeFaceValue
 (
+    Ostream& os,
     const dataFormat& format,
     const Type& value,
-    const label EID,
-    Ostream& os
+    const label EID
 ) const
 {
     // Fixed short/long formats supporting PLOAD2 and PLOAD4:
@@ -84,16 +86,13 @@ void Foam::nastranSurfaceWriter::writeFaceValue
 
     Type scaledValue = scale_*value;
 
-    // Write Keyword
-    writeKeyword(dataFormatNames_[format], os);
-
-    os  << separator_;
+    // Write keyword
+    writeKeyword(os, dataFormatNames_[format])  << separator_;
 
     // Write load set ID
     os.setf(ios_base::right);
-    writeValue(SID, os);
 
-    os  << separator_;
+    writeValue(os, SID) << separator_;
 
     switch (format)
     {
@@ -101,7 +100,7 @@ void Foam::nastranSurfaceWriter::writeFaceValue
         {
             if (pTraits<Type>::nComponents == 1)
             {
-                writeValue(scaledValue, os);
+                writeValue(os, scaledValue) << separator_;
             }
             else
             {
@@ -110,25 +109,25 @@ void Foam::nastranSurfaceWriter::writeFaceValue
                     << "and cannot be used for higher rank values"
                     << endl;
 
-                writeValue(scalar(0), os);
+                writeValue(os, scalar(0)) << separator_;
             }
 
-            os  << separator_;
-            writeValue(EID, os);
-
+            writeValue(os, EID);
             break;
         }
+
         case dfPLOAD4:
         {
-            writeValue(EID, os);
+            writeValue(os, EID);
 
-            for (direction dirI = 0; dirI < pTraits<Type>::nComponents; dirI++)
+            for (direction dirI = 0; dirI < pTraits<Type>::nComponents; ++dirI)
             {
                 os  << separator_;
-                writeValue(component(scaledValue, dirI), os);
+                writeValue(os, component(scaledValue, dirI));
             }
             break;
         }
+
         default:
         {
             FatalErrorInFunction
@@ -140,6 +139,8 @@ void Foam::nastranSurfaceWriter::writeFaceValue
     os.unsetf(ios_base::right);
 
     os << nl;
+
+    return os;
 }
 
 
@@ -148,8 +149,7 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -185,17 +185,15 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
         Info<< "Writing nastran file to " << os.name() << endl;
     }
 
-    os  << "TITLE=OpenFOAM " << surfaceName.c_str() << " " << fieldName
-        << " data" << nl
+    os  << "TITLE=OpenFOAM " << surfaceName.c_str()
+        << " " << fieldName << " data" << nl
         << "$" << nl
         << "TIME " << timeValue << nl
         << "$" << nl
         << "BEGIN BULK" << nl;
 
-    List<DynamicList<face>> decomposedFaces(faces.size());
-
-    writeGeometry(points, faces, decomposedFaces, os);
-
+    List<DynamicList<face>> decomposedFaces;
+    writeGeometry(os, surf, decomposedFaces);
 
     os  << "$" << nl
         << "$ Field data" << nl
@@ -203,7 +201,7 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
 
     if (isNodeValues)
     {
-        label n = 0;
+        label elemId = 0;
 
         forAll(decomposedFaces, i)
         {
@@ -219,28 +217,26 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
                 }
                 v /= f.size();
 
-                writeFaceValue(format, v, ++n, os);
+                writeFaceValue(os, format, v, ++elemId);
             }
         }
     }
     else
     {
-        label n = 0;
+        label elemId = 0;
 
         forAll(decomposedFaces, i)
         {
             const DynamicList<face>& dFaces = decomposedFaces[i];
-
             forAll(dFaces, facei)
             {
-                writeFaceValue(format, values[facei], ++n, os);
+                writeFaceValue(os, format, values[facei], ++elemId);
             }
         }
     }
 
-    writeFooter(os);
-
-    os  << "ENDDATA" << endl;
+    writeFooter(os, surf)
+        << "ENDDATA" << endl;
 
     return os.name();
 }
diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C
index c92c09d8f679a1a0b026fb082a3f0b52e9f1cc60..2ec4dae0a0bad2bd0c10155630a4df351bb845dc 100644
--- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,8 +60,7 @@ Foam::fileName Foam::proxySurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
@@ -83,7 +82,7 @@ Foam::fileName Foam::proxySurfaceWriter::write
         Info<< "Writing geometry to " << outName << endl;
     }
 
-    MeshedSurfaceProxy<face>(points, faces).write(outName);
+    MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write(outName);
 
     return outName;
 }
diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H
index 3ace22ea84c06b5e054815c7d7abb956cf16e5c5..62ba62705ec09007a1fdccdf2b5279382041ee8d 100644
--- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -89,10 +89,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
index b5e93dc6cbc20354bb2cf23bb676255cffa084e1..364b0a4270ebb6c2eb67031fdfff4dd275713be6 100644
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,11 +40,9 @@ namespace Foam
 inline void Foam::rawSurfaceWriter::writeLocation
 (
     Ostream& os,
-    const pointField& points,
-    const label pointi
+    const point& pt
 )
 {
-    const point& pt = points[pointi];
     os  << pt.x() << ' ' << pt.y() << ' ' << pt.z() << ' ';
 }
 
@@ -53,12 +51,10 @@ inline void Foam::rawSurfaceWriter::writeLocation
 (
     Ostream& os,
     const pointField& points,
-    const faceList& faces,
-    const label facei
+    const face& f
 )
 {
-    const point& ct = faces[facei].centre(points);
-    os  << ct.x() << ' ' << ct.y() << ' ' << ct.z() << ' ';
+    writeLocation(os, f.centre(points));
 }
 
 
@@ -238,11 +234,13 @@ Foam::fileName Foam::rawSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
     if (!isDir(outputDir))
     {
         mkDir(outputDir);
@@ -269,7 +267,7 @@ Foam::fileName Foam::rawSurfaceWriter::write
     // Write faces centres
     forAll(faces, elemI)
     {
-        writeLocation(os, points, faces, elemI);
+        writeLocation(os, points, faces[elemI]);
         os  << nl;
     }
 
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H
index a679251af41f2c33259e6d46278a481546bca3ac..986b588862796b877ec20bd8d8e80786ddaeba72 100644
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -59,19 +59,13 @@ class rawSurfaceWriter
 
     // Private Member Functions
 
-        static inline void writeLocation
-        (
-            Ostream&,
-            const pointField&,
-            const label pointi
-        );
+        static inline void writeLocation(Ostream&, const point&);
 
         static inline void writeLocation
         (
             Ostream&,
             const pointField&,
-            const faceList&,
-            const label facei
+            const face&
         );
 
         template<class Type>
@@ -92,8 +86,7 @@ class rawSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -127,10 +120,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 
         //- Write scalarField for a single surface to file.
@@ -139,13 +131,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -153,13 +144,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -167,13 +157,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -181,13 +170,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -195,13 +183,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C
index 3341378838da7020dd62f4e445953d322ae859e8..bf0cb44f22f5a11c91edf21ee851a8a5fa8c7e89 100644
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.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  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,14 +34,16 @@ Foam::fileName Foam::rawSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
     const bool verbose
 ) const
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
     if (!isDir(outputDir))
     {
         mkDir(outputDir);
@@ -73,7 +75,7 @@ Foam::fileName Foam::rawSurfaceWriter::writeTemplate
     {
         forAll(values, elemI)
         {
-            writeLocation(os, points, elemI);
+            writeLocation(os, points[elemI]);
             writeData(os, values[elemI]);
         }
     }
@@ -81,7 +83,7 @@ Foam::fileName Foam::rawSurfaceWriter::writeTemplate
     {
         forAll(values, elemI)
         {
-            writeLocation(os, points, faces, elemI);
+            writeLocation(os, points, faces[elemI]);
             writeData(os, values[elemI]);
         }
     }
diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C
index 2b58417a5bf0f8b9e11455cb278375c80f274518..3f79e3891c106d4d53948c9ca689bbe9050e0ada 100644
--- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -94,8 +94,7 @@ Foam::fileName Foam::starcdSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
@@ -111,7 +110,7 @@ Foam::fileName Foam::starcdSurfaceWriter::write
         Info<< "Writing geometry to " << outName << endl;
     }
 
-    MeshedSurfaceProxy<face>(points, faces).write(outName);
+    MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write(outName);
 
     return outName;
 }
diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H
index aeaed7d30b7780614ed42e6003620956fb50e0ab..d5a9d87552623485217700aa0b18a9e640601dcd 100644
--- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -81,8 +81,7 @@ class starcdSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -119,11 +118,10 @@ public:
         virtual fileName write
         (
             const fileName& outputDir,
-            const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const fileName& surfaceName,    // name of surface
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write scalarField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -131,13 +129,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -145,13 +142,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -159,13 +155,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 };
 
 
diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C
index 026b5b7425a14112fac988efd04ac0242f9db843..d14b3da6fbe570912e50c14d76e2d914196f9c49 100644
--- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.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  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -42,8 +42,7 @@ Foam::fileName Foam::starcdSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf&,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.H b/src/sampling/sampledSurface/writers/surfaceWriter.H
index bd4c40420353f43376801e3913f8e3cb085d3975..a640fb5a053b0bf3504933fbecbb75e671716e71 100644
--- a/src/sampling/sampledSurface/writers/surfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/surfaceWriter.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,10 +37,8 @@ SourceFiles
 
 #include "typeInfo.H"
 #include "autoPtr.H"
-#include "pointField.H"
-#include "faceList.H"
 #include "fileName.H"
-
+#include "meshedSurfRef.H"
 #include "runTimeSelectionTables.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -120,8 +118,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
         ) const
         {
@@ -134,8 +131,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
@@ -151,8 +147,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
@@ -168,8 +163,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
@@ -185,8 +179,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
@@ -202,8 +195,7 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
index f7d8c0fd69a626f9abbd6de4d3507540e1649c0c..9b4c28c1ed0e5dee6d9908e24347d0b9c00196f8 100644
--- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
@@ -40,10 +40,12 @@ namespace Foam
 void Foam::vtkSurfaceWriter::writeGeometry
 (
     Ostream& os,
-    const pointField& points,
-    const faceList& faces
+    const meshedSurf& surf
 )
 {
+    const pointField& points = surf.points();
+    const faceList&    faces = surf.faces();
+
     // header
     os
         << "# vtk DataFile Version 2.0" << nl
@@ -131,8 +133,9 @@ namespace Foam
         forAll(values, elemI)
         {
             const vector& v = values[elemI];
-            os  << float(v[0]) << ' ' << float(v[1]) << ' ' << float(v[2])
-                << nl;
+            os  << float(v[0]) << ' '
+                << float(v[1]) << ' '
+                << float(v[2]) << nl;
         }
     }
 
@@ -234,8 +237,7 @@ Foam::fileName Foam::vtkSurfaceWriter::write
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const bool verbose
 ) const
 {
@@ -252,7 +254,7 @@ Foam::fileName Foam::vtkSurfaceWriter::write
         Info<< "Writing geometry to " << os.name() << endl;
     }
 
-    writeGeometry(os, points, faces);
+    writeGeometry(os, surf);
 
     return os.name();
 }
diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
index f3d17fc2b9950fda4ec4196ee8f36339aaf54d74..85ab3026e914a09db083f23aa60ad62a33181544 100644
--- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
@@ -57,7 +57,7 @@ class vtkSurfaceWriter
 
     // Private Member Functions
 
-        static void writeGeometry(Ostream&, const pointField&, const faceList&);
+        static void writeGeometry(Ostream&, const meshedSurf&);
 
         template<class Type>
         static void writeData(Ostream&, const Field<Type>&);
@@ -69,8 +69,7 @@ class vtkSurfaceWriter
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,
             const Field<Type>& values,
             const bool isNodeValues,
@@ -104,10 +103,9 @@ public:
         (
             const fileName& outputDir,
             const fileName& surfaceName,
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 
         //- Write scalarField for a single surface to file.
@@ -116,13 +114,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<scalar>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write vectorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -130,13 +127,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<vector>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write sphericalTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -144,13 +140,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<sphericalTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write symmTensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -158,13 +153,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<symmTensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
         //- Write tensorField for a single surface to file.
         //  One value per face or vertex (isNodeValues = true)
@@ -172,13 +166,12 @@ public:
         (
             const fileName& outputDir,      // <case>/surface/TIME
             const fileName& surfaceName,    // name of surface
-            const pointField& points,
-            const faceList& faces,
+            const meshedSurf& surf,
             const word& fieldName,          // name of field
             const Field<tensor>& values,
             const bool isNodeValues,
             const bool verbose = false
-        ) const;
+        ) const; // override
 
 };
 
diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C
index 6ceb45e464395ca1385c317033dfde79abe16c0e..ee7c129d520ca17c21773ce43655f6ae6f6df156 100644
--- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.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  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,8 +49,7 @@ Foam::fileName Foam::vtkSurfaceWriter::writeTemplate
 (
     const fileName& outputDir,
     const fileName& surfaceName,
-    const pointField& points,
-    const faceList& faces,
+    const meshedSurf& surf,
     const word& fieldName,
     const Field<Type>& values,
     const bool isNodeValues,
@@ -70,7 +69,7 @@ Foam::fileName Foam::vtkSurfaceWriter::writeTemplate
         Info<< "Writing field " << fieldName << " to " << os.name() << endl;
     }
 
-    writeGeometry(os, points, faces);
+    writeGeometry(os, surf);
 
     // start writing data
     if (isNodeValues)
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index f86024310449ba7bf2207d713c716b92fd4cb7e0..e0a2b486e47e03a30422031786fc12372a61fd10 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -1,6 +1,5 @@
 surfZone/surfZone/surfZone.C
 surfZone/surfZone/surfZoneIOList.C
-surfZone/surfZoneIdentifier/surfZoneIdentifier.C
 
 MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.C
 
@@ -8,7 +7,9 @@ MeshedSurface/MeshedSurfaceCore.C
 MeshedSurface/MeshedSurfaces.C
 UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
 
-MeshedSurfaceProxy/MeshedSurfaceProxyCore.C
+MeshedSurfaceProxy/MeshedSurfaceProxys.C
+
+mergedSurf/mergedSurf.C
 
 surfaceRegistry/surfaceRegistry.C
 surfMesh/surfMesh.C
@@ -22,25 +23,20 @@ $(surfaceFormats)/surfaceFormatsCore.C
 
 $(surfaceFormats)/ac3d/AC3DsurfaceFormatCore.C
 $(surfaceFormats)/ac3d/AC3DsurfaceFormatRunTime.C
+$(surfaceFormats)/fire/FLMAsurfaceFormatRunTime.C
 $(surfaceFormats)/gts/GTSsurfaceFormatRunTime.C
 $(surfaceFormats)/nas/NASsurfaceFormatRunTime.C
 $(surfaceFormats)/obj/OBJsurfaceFormatRunTime.C
 $(surfaceFormats)/obj/OBJstream.C
 $(surfaceFormats)/off/OFFsurfaceFormatRunTime.C
-$(surfaceFormats)/ofs/OFSsurfaceFormatCore.C
-$(surfaceFormats)/ofs/OFSsurfaceFormatRunTime.C
 $(surfaceFormats)/smesh/SMESHsurfaceFormatRunTime.C
 $(surfaceFormats)/starcd/STARCDsurfaceFormatCore.C
 $(surfaceFormats)/starcd/STARCDsurfaceFormatRunTime.C
-$(surfaceFormats)/stl/STLsurfaceFormatCore.C
 $(surfaceFormats)/stl/STLsurfaceFormatRunTime.C
-$(surfaceFormats)/stl/STLsurfaceFormatASCII.L
 $(surfaceFormats)/tri/TRIsurfaceFormatCore.C
 $(surfaceFormats)/tri/TRIsurfaceFormatRunTime.C
 $(surfaceFormats)/vtk/VTKsurfaceFormatCore.C
 $(surfaceFormats)/vtk/VTKsurfaceFormatRunTime.C
-$(surfaceFormats)/wrl/WRLsurfaceFormatCore.C
-$(surfaceFormats)/wrl/WRLsurfaceFormatRunTime.C
 $(surfaceFormats)/x3d/X3DsurfaceFormatCore.C
 $(surfaceFormats)/x3d/X3DsurfaceFormatRunTime.C
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 825949ebd43313b6079531a5f1a026df39117271..a51428f8b47c6408460670ace46a14c18be27d76 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -209,7 +209,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
     const MeshedSurface<Face>& surf
 )
 :
-    ParentType(surf.faces(), surf.points()),
+    ParentType(surf.surfFaces(), surf.points()),
     zones_(surf.surfZones())
 {}
 
@@ -225,7 +225,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
     labelList faceMap;
     this->storedZones() = surf.sortedZones(faceMap);
 
-    const List<Face>& origFaces = surf.faces();
+    const List<Face>& origFaces = surf;
     List<Face> newFaces(origFaces.size());
 
     forAll(newFaces, facei)
@@ -431,7 +431,9 @@ Foam::MeshedSurface<Face>::MeshedSurface
 
 template<class Face>
 Foam::MeshedSurface<Face>::~MeshedSurface()
-{}
+{
+    clear();
+}
 
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
@@ -500,6 +502,9 @@ void Foam::MeshedSurface<Face>::clear()
 template<class Face>
 void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
 {
+    // Changes areas, normals etc.
+    ParentType::clearGeom();
+
     // Adapt for new point position
     ParentType::movePoints(newPoints);
 
@@ -511,9 +516,12 @@ void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
 template<class Face>
 void Foam::MeshedSurface<Face>::scalePoints(const scalar scaleFactor)
 {
-    // avoid bad scaling
+    // Avoid bad scaling
     if (scaleFactor > 0 && scaleFactor != 1.0)
     {
+        // Changes areas, normals etc.
+        ParentType::clearGeom();
+
         pointField newPoints(scaleFactor*this->points());
 
         // Adapt for new point position
@@ -524,6 +532,16 @@ void Foam::MeshedSurface<Face>::scalePoints(const scalar scaleFactor)
 }
 
 
+template<class Face>
+void Foam::MeshedSurface<Face>::reset
+(
+    const Xfer<MeshedSurface<Face>>& surf
+)
+{
+    transfer(surf());
+}
+
+
 template<class Face>
 void Foam::MeshedSurface<Face>::reset
 (
@@ -586,7 +604,7 @@ void Foam::MeshedSurface<Face>::reset
 template<class Face>
 void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
 {
-    // merge points (already done for STL, TRI)
+    // Merge points (already done for STL, TRI)
     stitchFaces(SMALL, verbose);
 
     checkFaces(verbose);
@@ -829,6 +847,61 @@ bool Foam::MeshedSurface<Face>::checkFaces
 }
 
 
+template<class Face>
+Foam::label Foam::MeshedSurface<Face>::nTriangles() const
+{
+    return nTriangles
+    (
+        const_cast<List<label>&>(List<label>::null())
+    );
+}
+
+
+template<class Face>
+Foam::label Foam::MeshedSurface<Face>::nTriangles
+(
+    List<label>& faceMap
+) const
+{
+    label nTri = 0;
+    const List<Face>& faceLst = surfFaces();
+
+    // Count triangles needed
+    forAll(faceLst, facei)
+    {
+        nTri += faceLst[facei].nTriangles();
+    }
+
+    // Nothing to do
+    if (nTri <= faceLst.size())
+    {
+        if (notNull(faceMap))
+        {
+            faceMap.clear();
+        }
+    }
+    else if (notNull(faceMap))
+    {
+        // face map requested
+        faceMap.setSize(nTri);
+
+        nTri = 0;
+        forAll(faceLst, facei)
+        {
+            label n = faceLst[facei].nTriangles();
+            while (n-- > 0)
+            {
+                faceMap[nTri++] = facei;
+            }
+        }
+
+        faceMap.setSize(nTri);
+    }
+
+    return nTri;
+}
+
+
 template<class Face>
 Foam::label Foam::MeshedSurface<Face>::triangulate()
 {
@@ -880,14 +953,11 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
     }
     faceMap.setSize(nTri);
 
-    // remember the number of *additional* faces
-    nTri -= faceLst.size();
-
     if (this->points().empty())
     {
         // triangulate without points
         // simple face triangulation around f[0]
-        label newFacei = 0;
+        nTri = 0;
         forAll(faceLst, facei)
         {
             const Face& f = faceLst[facei];
@@ -896,9 +966,9 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
             {
                 label fp1 = f.fcIndex(fp);
 
-                newFaces[newFacei] = triFace(f[0], f[fp], f[fp1]);
-                faceMap[newFacei] = facei;
-                newFacei++;
+                newFaces[nTri] = triFace(f[0], f[fp], f[fp1]);
+                faceMap[nTri] = facei;
+                nTri++;
             }
         }
     }
@@ -907,7 +977,7 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
         // triangulate with points
         List<face> tmpTri(maxTri);
 
-        label newFacei = 0;
+        nTri = 0;
         forAll(faceLst, facei)
         {
             // 'face' not '<Face>'
@@ -917,16 +987,19 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
             f.triangles(this->points(), nTmp, tmpTri);
             for (label triI = 0; triI < nTmp; triI++)
             {
-                newFaces[newFacei] = Face
+                newFaces[nTri] = Face
                 (
                     static_cast<labelUList&>(tmpTri[triI])
                 );
-                faceMap[newFacei] = facei;
-                newFacei++;
+                faceMap[nTri] = facei;
+                nTri++;
             }
         }
     }
 
+    // The number of *additional* faces
+    nTri -= faceLst.size();
+
     faceLst.transfer(newFaces);
     remapFaces(faceMap);
 
@@ -939,12 +1012,11 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
 
     // Topology can change because of renumbering
     ParentType::clearOut();
+
     return nTri;
 }
 
 
-
-
 template<class Face>
 Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
 (
@@ -1050,12 +1122,13 @@ void Foam::MeshedSurface<Face>::transfer
     MeshedSurface<Face>& surf
 )
 {
-    reset
-    (
-        xferMove(surf.storedPoints()),
-        xferMove(surf.storedFaces()),
-        xferMove(surf.storedZones())
-    );
+    ParentType::clearOut();
+
+    this->storedPoints().transfer(surf.storedPoints());
+    this->storedFaces().transfer(surf.storedFaces());
+    this->storedZones().transfer(surf.storedZones());
+
+    surf.clear();
 }
 
 
@@ -1103,12 +1176,43 @@ void Foam::MeshedSurface<Face>::transfer
 
 
 template<class Face>
-Foam::Xfer<Foam::MeshedSurface<Face>> Foam::MeshedSurface<Face>::xfer()
+Foam::Xfer<Foam::MeshedSurface<Face>>
+Foam::MeshedSurface<Face>::xfer()
 {
     return xferMove(*this);
 }
 
 
+template<class Face>
+Foam::Xfer<Foam::List<Face>>
+Foam::MeshedSurface<Face>::xferFaces()
+{
+    // Topology changed because of transfer
+    ParentType::clearOut();
+
+    return this->storedFaces().xfer();
+}
+
+
+template<class Face>
+Foam::Xfer<Foam::List<Foam::point>>
+Foam::MeshedSurface<Face>::xferPoints()
+{
+    // Topology changed because of transfer
+    ParentType::clearOut();
+
+    return this->storedPoints().xfer();
+}
+
+
+template<class Face>
+Foam::Xfer<Foam::surfZoneList>
+Foam::MeshedSurface<Face>::xferZones()
+{
+    return this->storedZones().xfer();
+}
+
+
 // Read from file, determine format from extension
 template<class Face>
 bool Foam::MeshedSurface<Face>::read(const fileName& name)
@@ -1161,7 +1265,7 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
     clear();
 
     this->storedPoints() = surf.points();
-    this->storedFaces()  = surf.faces();
+    this->storedFaces()  = surf.surfFaces();
     this->storedZones()  = surf.surfZones();
 }
 
@@ -1172,7 +1276,7 @@ Foam::MeshedSurface<Face>::operator Foam::MeshedSurfaceProxy<Face>() const
     return MeshedSurfaceProxy<Face>
     (
         this->points(),
-        this->faces(),
+        this->surfFaces(),
         this->surfZones()
     );
 }
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index 1362197d8c1c1c5c3d988e24718f57c1863ce5a6..513a813597ca1fe5de1a174ff751db4680bc4ff5 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -51,7 +51,7 @@ SourceFiles
 #include "PatchTools.H"
 #include "pointField.H"
 #include "face.H"
-#include "triFace.H"
+#include "labelledTri.H"
 
 #include "surfZoneList.H"
 #include "surfaceFormatsCore.H"
@@ -134,7 +134,10 @@ protected:
 
     // Protected Member functions
 
-        //- Transfer points/zones and transcribe face -> triFace
+        //- Transfer points/zones from 'face' to other other shapes.
+        //  Eg, transcribe face to triFace, or face -> labelledTri, including
+        //  any addZonesToFaces adjustment.
+        //  No general form, only specializations.
         void transcribe(MeshedSurface<face>&);
 
         //- Basic sanity check on zones
@@ -326,7 +329,7 @@ public:
             }
 
             //- Return const access to the faces
-            inline const List<Face>& faces() const
+            inline const List<Face>& surfFaces() const
             {
                 return static_cast<const List<Face>&>(*this);
             }
@@ -339,6 +342,31 @@ public:
                 return zones_;
             }
 
+            //- Face area vectors (normals)
+            inline const vectorField& Sf() const
+            {
+                return ParentType::faceAreas();
+            }
+
+            //- Face area magnitudes
+            inline const scalarField& magSf() const
+            {
+                return ParentType::magFaceAreas();
+            }
+
+            //- Face centres
+            inline const vectorField& Cf() const
+            {
+                return ParentType::faceCentres();
+            }
+
+
+        // Edit
+
+            //- Clear all storage
+            virtual void clear();
+
+
             //- Add surface zones
             virtual void addZones
             (
@@ -361,14 +389,15 @@ public:
                 const bool cullEmpty=false
             );
 
-            //- Remove surface zones
-            virtual void removeZones();
+            //- Propagate zone information on face regions.
+            //  Normally a no-op, only used by the labelledTri specialization.
+            //  Specializations return true, others return false.
+            bool addZonesToFaces();
 
 
-        // Edit
+            //- Remove surface zones
+            virtual void removeZones();
 
-            //- Clear all storage
-            virtual void clear();
 
             //- Move points
             virtual void movePoints(const pointField&);
@@ -376,6 +405,12 @@ public:
             //- Scale points. A non-positive factor is ignored
             virtual void scalePoints(const scalar);
 
+            //- Reset by transferring contents of the argument and annul it
+            virtual void reset
+            (
+                const Xfer<MeshedSurface<Face>>&
+            );
+
             //- Reset primitive data (points, faces and zones)
             //  Note, optimized to avoid overwriting data (with Xfer::null)
             virtual void reset
@@ -408,7 +443,14 @@ public:
                 const bool verbose=false
             );
 
-            //- Triangulate in-place, returning the number of triangles added
+            //- Count number of triangles.
+            virtual label nTriangles() const;
+
+            //- Count number of triangles, returning a face map of original ids.
+            //  The faceMap is zero-sized when no triangulation would be needed.
+            virtual label nTriangles(List<label>& faceMap) const;
+
+            //- Triangulate in-place, returning the number of triangles added.
             virtual label triangulate();
 
             //- Triangulate in-place, returning the number of triangles added
@@ -416,7 +458,6 @@ public:
             //  The faceMap is zero-sized when no triangulation was done.
             virtual label triangulate(List<label>& faceMap);
 
-
             //- Return new surface.
             //  Returns return pointMap, faceMap from subsetMeshMap
             MeshedSurface subsetMesh
@@ -441,6 +482,15 @@ public:
             //- Transfer contents to the Xfer container
             Xfer<MeshedSurface<Face>> xfer();
 
+            //- Transfer stored faces to an Xfer container
+            Xfer<List<Face>> xferFaces();
+
+            //- Transfer stored points to an Xfer container
+            Xfer<List<point>> xferPoints();
+
+            //- Transfer stored zones to an Xfer container
+            Xfer<surfZoneList> xferZones();
+
 
         // Read
 
@@ -480,6 +530,7 @@ public:
     // IOstream Operators
 
         //- Read MeshedSurface from Istream.
+        //  Avoid using to read/write file content (fragile).
         friend Istream& operator>> <Face>
         (
             Istream&,
@@ -488,6 +539,7 @@ public:
 
 
         //- Write MeshedSurface to Ostream.
+        //  Avoid using to read/write file content (fragile).
         friend Ostream& operator<< <Face>
         (
             Ostream&,
@@ -499,33 +551,10 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-//- Specialization for holding triangulated information
+//- Specialization for labelledTri.
 template<>
-inline bool MeshedSurface<triFace>::isTri()
-{
-    return true;
-}
-
+bool MeshedSurface<labelledTri>::addZonesToFaces();
 
-//- Specialization for holding triangulated information
-template<>
-inline label MeshedSurface<triFace>::triangulate()
-{
-    return 0;
-}
-
-
-//- Specialization for holding triangulated information
-template<>
-inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
-{
-    if (notNull(faceMap))
-    {
-        faceMap.clear();
-    }
-
-    return 0;
-}
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -534,6 +563,8 @@ inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#include "MeshedSurfaceI.H"
+
 #ifdef NoRepository
     #include "MeshedSurface.C"
 #endif
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
index 08851de6278ae63055a3014f9b35de6791969910..8640b6e5aeb0aa571943318c1bc20f016a7b2321 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,18 +30,34 @@ License
 namespace Foam
 {
 
-    // specialization: from face -> triFace
+    // Transcribe 'face' to 'face' (ie, just transfer)
     template<>
-    void Foam::MeshedSurface<triFace>::transcribe(MeshedSurface<face>& surf)
+    void Foam::MeshedSurface<Foam::face>::transcribe
+    (
+        MeshedSurface<face>& surf
+    )
     {
-        // first triangulate
+        this->transfer(surf);
+        this->addZonesToFaces(); // currently a no-op
+    }
+
+    // Transcribe 'face' to 'triFace'
+    // Transfer points/zones and triangulate faces
+    template<>
+    void Foam::MeshedSurface<Foam::triFace>::transcribe
+    (
+        MeshedSurface<face>& surf
+    )
+    {
+        // First triangulate
+        // - slightly wasteful for space, but manages adjusts the zones too!
         surf.triangulate();
         this->storedPoints().transfer(surf.storedPoints());
         this->storedZones().transfer(surf.storedZones());
 
         // transcribe from face -> triFace
-        List<face>&    origFaces = surf.storedFaces();
-        List<triFace>  newFaces(origFaces.size());
+        const List<face>& origFaces = surf.surfFaces();
+        List<triFace> newFaces(origFaces.size());
         forAll(origFaces, facei)
         {
             newFaces[facei] = triFace
@@ -52,18 +68,65 @@ namespace Foam
         surf.clear();
 
         this->storedFaces().transfer(newFaces);
+        this->addZonesToFaces(); // currently a no-op
     }
 
 
-    // specialization: from face -> face
+    // Transcribe 'face' to 'labelledTri'
+    // Transfer points/zones and triangulate faces
     template<>
-    void Foam::MeshedSurface<face>::transcribe(MeshedSurface<face>& surf)
+    void Foam::MeshedSurface<Foam::labelledTri>::transcribe
+    (
+        MeshedSurface<face>& surf
+    )
     {
-        this->transfer(surf);
+        // First triangulate
+        // - slightly wasteful for space, but manages adjusts the zones too!
+        surf.triangulate();
+        this->storedPoints().transfer(surf.storedPoints());
+        this->storedZones().transfer(surf.storedZones());
+
+        // transcribe from face -> triFace
+        const List<face>& origFaces = surf.surfFaces();
+        List<labelledTri> newFaces(origFaces.size());
+        forAll(origFaces, facei)
+        {
+            newFaces[facei] = triFace
+            (
+                static_cast<const labelUList&>(origFaces[facei])
+            );
+        }
+        surf.clear();
+
+        this->storedFaces().transfer(newFaces);
+        this->addZonesToFaces(); // for labelledTri
+    }
+
+
+    // Propagate zone information on face regions for labelledTri.
+    template<>
+    bool Foam::MeshedSurface<Foam::labelledTri>::addZonesToFaces()
+    {
+        List<labelledTri>& faceLst = this->storedFaces();
+        const surfZoneList& zones = this->surfZones();
+
+        forAll(zones, zoneI)
+        {
+            const surfZone& zone = zones[zoneI];
+
+            label faceI = zone.start();
+            forAll(zone, i)
+            {
+                faceLst[faceI++].region() = zoneI;
+            }
+        }
+
+        return true;
     }
 
 
 }  // end of namespace Foam
 
 
+
 // ************************************************************************* //
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceI.H b/src/surfMesh/MeshedSurface/MeshedSurfaceI.H
new file mode 100644
index 0000000000000000000000000000000000000000..a7415f7b4b69e8ef8a15731bdfc2e4598090c20b
--- /dev/null
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceI.H
@@ -0,0 +1,103 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// A triFace surface only handles triangulated faces
+template<>
+inline bool MeshedSurface<triFace>::isTri()
+{
+    return true;
+}
+
+
+// A labelledTri surface only handles triangulated faces
+template<>
+inline bool MeshedSurface<labelledTri>::isTri()
+{
+    return true;
+}
+
+
+// Number of triangles for a triFace surface
+template<>
+inline label MeshedSurface<triFace>::nTriangles() const
+{
+    return ParentType::size();
+}
+
+// Number of triangles for a labelledTri surface
+template<>
+inline label MeshedSurface<labelledTri>::nTriangles() const
+{
+    return ParentType::size();
+}
+
+
+// Inplace triangulation of triFace surface = no-op
+template<>
+inline label MeshedSurface<triFace>::triangulate()
+{
+    return 0;
+}
+
+// Inplace triangulation of labelledTri surface = no-op
+template<>
+inline label MeshedSurface<labelledTri>::triangulate()
+{
+    return 0;
+}
+
+// Inplace triangulation of triFace surface (with face map) = no-op
+template<>
+inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
+{
+    if (notNull(faceMap))
+    {
+        faceMap.clear();
+    }
+    return 0;
+}
+
+// Inplace triangulation of labelledTri surface (with face map) = no-op
+template<>
+inline label MeshedSurface<labelledTri>::triangulate(List<label>& faceMap)
+{
+    if (notNull(faceMap))
+    {
+        faceMap.clear();
+    }
+    return 0;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
index 89204c063b852e033b7c7a940f82af18da09e740..9d8c5dd0912b8c9259657d5a936a5d9b225c3330 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
@@ -47,7 +47,7 @@ Foam::Ostream& Foam::MeshedSurface<Face>::write(Ostream& os) const
 {
     os  << this->surfZones()
         << this->points()
-        << this->faces();
+        << this->surfFaces();
 
     os.check("MeshedSurface::write(Ostream&) const");
     return os;
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C b/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
index 767d1e5b9c62d8d72590ad26d53a23f9c721b841..512746741833dfdcc1e65a5edbe6731bd9d2f650 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -131,7 +131,7 @@ void Foam::MeshedSurface<Face>::addZones
     const bool cullEmpty
 )
 {
-    label start   = 0;
+    label start = 0;
     label nZone = 0;
 
     surfZoneList& zones = this->storedZones();
@@ -162,7 +162,7 @@ void Foam::MeshedSurface<Face>::addZones
     const bool cullEmpty
 )
 {
-    label start   = 0;
+    label start = 0;
     label nZone = 0;
 
     surfZoneList& zones = this->storedZones();
@@ -186,6 +186,14 @@ void Foam::MeshedSurface<Face>::addZones
 }
 
 
+template<class Face>
+bool Foam::MeshedSurface<Face>::addZonesToFaces()
+{
+    // Normally a no-op, only the specializations are used.
+    return false;
+}
+
+
 template<class Face>
 void Foam::MeshedSurface<Face>::removeZones()
 {
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaces.C b/src/surfMesh/MeshedSurface/MeshedSurfaces.C
index 999c755c7e5faaceeddbf6a2236b9d4dcf57333b..8795a37e2525bc16f7dfeaa21a678e9e7261f8f1 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaces.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaces.C
@@ -46,6 +46,7 @@ namespace Foam
 
 makeSurface(MeshedSurface, face)
 makeSurface(MeshedSurface, triFace)
+makeSurface(MeshedSurface, labelledTri)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.H b/src/surfMesh/MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.H
index 0e9d481cb494b9b16efb0bc3b134ed97e9f36ffd..6c8aa07e2a843db822111bf2c62dc085e3c457ef 100644
--- a/src/surfMesh/MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.H
+++ b/src/surfMesh/MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.H
@@ -65,10 +65,10 @@ class MeshedSurfaceIOAllocator
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        MeshedSurfaceIOAllocator(const MeshedSurfaceIOAllocator&);
+        MeshedSurfaceIOAllocator(const MeshedSurfaceIOAllocator&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const MeshedSurfaceIOAllocator&);
+        void operator=(const MeshedSurfaceIOAllocator&) = delete;
 
 
 public:
@@ -152,7 +152,7 @@ public:
             //- Clear primitive data (points, faces and zones)
             void clear();
 
-            //- Reset primitive data (points, faces and zones)
+            //- Reset primitive data (faces and zones)
             //  Note, optimized to avoid overwriting data (with Xfer::null)
             void resetFaces
             (
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
index 4b8a754bcaa66afb1696f4e2b1cab24c845fdd6d..d7c92fa620ff84ce14d8b1fd4b5eacf56f8c81c3 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -171,11 +171,11 @@ void Foam::MeshedSurfaceProxy<Face>::write
         if (this->useFaceMap())
         {
             // this is really a bit annoying (and wasteful) but no other way
-            os  << reorder(this->faceMap(), this->faces());
+            os  << reorder(this->faceMap(), this->surfFaces());
         }
         else
         {
-            os  << this->faces();
+            os  << this->surfFaces();
         }
 
         io.writeEndDivider(os);
@@ -235,4 +235,41 @@ Foam::MeshedSurfaceProxy<Face>::~MeshedSurfaceProxy()
 {}
 
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+namespace Foam
+{
+
+// Number of triangles for a triFace surface
+template<>
+inline label MeshedSurfaceProxy<triFace>::nTriangles() const
+{
+    return this->size();
+}
+
+// Number of triangles for a labelledTri surface
+template<>
+inline label MeshedSurfaceProxy<labelledTri>::nTriangles() const
+{
+    return this->size();
+}
+
+}
+
+
+template<class Face>
+inline Foam::label Foam::MeshedSurfaceProxy<Face>::nTriangles() const
+{
+    label nTri = 0;
+    const List<Face>& faceLst = this->surfFaces();
+    forAll(faceLst, facei)
+    {
+        nTri += faceLst[facei].nTriangles();
+    }
+
+    return nTri;
+}
+
+
 // ************************************************************************* //
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
index 9338f7dd68cc9f1619d2d5970ec0066cbef6a489..3bedc3f0767f90fea6c792158c60676764be8469 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
@@ -30,7 +30,7 @@ Description
 
 SourceFiles
     MeshedSurfaceProxy.C
-    MeshedSurfaceProxyCore.C
+    MeshedSurfaceProxys.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -38,8 +38,7 @@ SourceFiles
 #define MeshedSurfaceProxy_H
 
 #include "pointField.H"
-#include "face.H"
-#include "triFace.H"
+#include "labelledTri.H"
 
 #include "surfZoneList.H"
 #include "surfaceFormatsCore.H"
@@ -139,6 +138,12 @@ public:
 
         // Access
 
+            //- The surface size is the number of faces
+            inline label size() const
+            {
+                return faces_.size();
+            }
+
             //- Return const access to the points
             inline const pointField& points() const
             {
@@ -146,7 +151,7 @@ public:
             }
 
             //- Return const access to the faces
-            inline const List<Face>& faces() const
+            inline const List<Face>& surfFaces() const
             {
                 return faces_;
             }
@@ -171,6 +176,10 @@ public:
                 return faceMap_.size() == faces_.size();
             }
 
+            //- Count number of triangles.
+            inline label nTriangles() const;
+
+
         // Write
 
             //- Generic write routine. Chooses writer based on extension.
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxyCore.C b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxys.C
similarity index 95%
rename from src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxyCore.C
rename to src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxys.C
index 76750a14d448ebe715f89bed5cc1c9c31eb30c8e..1fd0bfa7e403b1b44424a79003d7333b7b367022 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxyCore.C
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxys.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,6 +46,7 @@ namespace Foam
 
 makeSurface(MeshedSurfaceProxy, face)
 makeSurface(MeshedSurfaceProxy, triFace)
+makeSurface(MeshedSurfaceProxy, labelledTri)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.H b/src/surfMesh/ModifiableMeshedSurface/ModifiableMeshedSurface.H
similarity index 59%
rename from src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.H
rename to src/surfMesh/ModifiableMeshedSurface/ModifiableMeshedSurface.H
index 191da0738605df350ace64ea9af79855cd95c404..160198dff1faa24f0b110a77677fb0d7787ba805 100644
--- a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.H
+++ b/src/surfMesh/ModifiableMeshedSurface/ModifiableMeshedSurface.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,90 +22,89 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::fileFormats::WRLsurfaceFormat
+    Foam::ModifiableMeshedSurface
 
 Description
-    Provide a means of writing VRML97 (wrl) format.
+    A special purpose MeshedSurface that exposes the stored values
+    for direct modification.
 
-SourceFiles
-    WRLsurfaceFormat.C
+    Its usage should be restricted to special cases where the surface
+    needs modifications as an atomic operation.
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef WRLsurfaceFormat_H
-#define WRLsurfaceFormat_H
+#ifndef ModifiableMeshedSurface_H
+#define ModifiableMeshedSurface_H
 
 #include "MeshedSurface.H"
-#include "MeshedSurfaceProxy.H"
-#include "UnsortedMeshedSurface.H"
-#include "WRLsurfaceFormatCore.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-namespace fileFormats
-{
 
 /*---------------------------------------------------------------------------*\
-                      Class WRLsurfaceFormat Declaration
+                   Class ModifiableMeshedSurface Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Face>
-class WRLsurfaceFormat
+class ModifiableMeshedSurface
 :
-    public MeshedSurface<Face>,
-    public WRLsurfaceFormatCore
-
+    public MeshedSurface<Face>
 {
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        WRLsurfaceFormat(const WRLsurfaceFormat<Face>&);
+        ModifiableMeshedSurface(const ModifiableMeshedSurface<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const WRLsurfaceFormat<Face>&);
+        void operator=(const ModifiableMeshedSurface<Face>&) = delete;
+
 
 public:
 
     // Constructors
 
-        //- Construct null
-        WRLsurfaceFormat();
+        //- Construct null, use reset/transfer to adjust contents
+        ModifiableMeshedSurface()
+        :
+            MeshedSurface<Face>()
+        {}
+
+
+        //- Construct by transferring the contents from a MeshedSurface
+        explicit ModifiableMeshedSurface
+        (
+            const Xfer<MeshedSurface<Face>>& surf
+        )
+        :
+            MeshedSurface<Face>(surf)
+        {}
 
 
     //- Destructor
-    virtual ~WRLsurfaceFormat()
+    virtual ~ModifiableMeshedSurface()
     {}
 
 
     // Member Functions
 
-        //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        // Edit
 
-        //- Write object file
-        virtual void write(const fileName& name) const
-        {
-            write(name, MeshedSurfaceProxy<Face>(*this));
-        }
+            // Expose protected methods
+            using MeshedSurface<Face>::storedFaces;
+            using MeshedSurface<Face>::storedPoints;
+            using MeshedSurface<Face>::storedZones;
 
 };
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace fileFormats
 } // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#ifdef NoRepository
-    #include "WRLsurfaceFormat.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index 2848beafc0a2a6ab2b24d191f0a71ef7437874ae..e3975c6b8b1be8cbb20b5d36af6413a1591b53ce 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -202,7 +202,7 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
     ParentType
     (
         xferCopy(surf.points()),
-        xferCopy(surf.faces())
+        xferCopy(surf.surfFaces())
     ),
     zoneIds_(surf.zoneIds()),
     zoneToc_(surf.zoneToc())
@@ -218,7 +218,7 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
     ParentType
     (
         xferCopy(surf.points()),
-        xferCopy(surf.faces())
+        xferCopy(surf.surfFaces())
     )
 {
     setZones(surf.surfZones());
@@ -456,7 +456,7 @@ Foam::Ostream& Foam::UnsortedMeshedSurface<Face>::write(Ostream& os) const
 {
     os  << this->zoneIds()
         << this->points()
-        << this->faces();
+        << this->surfFaces();
 
     os.check("UnsortedMeshedSurface::write(Ostream&) const");
     return os;
@@ -722,6 +722,14 @@ Foam::UnsortedMeshedSurface<Face>::xfer()
 }
 
 
+template<class Face>
+Foam::Xfer<Foam::labelList>
+Foam::UnsortedMeshedSurface<Face>::xferZoneIds()
+{
+    return this->storedZoneIds().xfer();
+}
+
+
 // Read from file, determine format from extension
 template<class Face>
 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
@@ -777,7 +785,7 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
     clear();
 
     this->storedPoints() = surf.points();
-    this->storedFaces()  = surf.faces();
+    this->storedFaces()  = surf.surfFaces();
     zoneIds_ = surf.zoneIds_;
     zoneToc_ = surf.zoneToc_;
 }
@@ -793,7 +801,7 @@ Foam::MeshedSurfaceProxy<Face>() const
     return MeshedSurfaceProxy<Face>
     (
         this->points(),
-        this->faces(),
+        this->surfFaces(),
         zoneLst,
         faceMap
     );
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
index b50460a45d25a61f39cb9c00c5d3ed295e868dca..e038e927114816dbb7b35a0e572501c9f60aedb1 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
@@ -126,7 +126,7 @@ protected:
     // Protected Member functions
 
         //- Return non-const access to the zone Ids
-        List<label>& storedZoneIds()
+        labelList& storedZoneIds()
         {
             return zoneIds_;
         }
@@ -289,7 +289,7 @@ public:
             void setSize(const label);
 
             //- Return const access to the zone ids
-            const List<label>& zoneIds() const
+            virtual const labelList& zoneIds() const
             {
                 return zoneIds_;
             }
@@ -366,6 +366,9 @@ public:
             //- Transfer contents to the Xfer container
             Xfer<UnsortedMeshedSurface<Face>> xfer();
 
+            //- Transfer stored zoneIds to an Xfer container
+            Xfer<labelList> xferZoneIds();
+
 
         // Read
 
@@ -403,6 +406,7 @@ public:
     // IOstream Operators
 
         //- Read UnsortedMeshedSurface from Istream.
+        //  Avoid using to read/write file content (fragile).
         friend Istream& operator>> <Face>
         (
             Istream&,
@@ -411,6 +415,7 @@ public:
 
 
         //- Write UnsortedMeshedSurface to Ostream.
+        //  Avoid using to read/write file content (fragile).
         friend Ostream& operator<< <Face>
         (
             Ostream&,
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaces.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
index 400cafb1487272d1ed0f67c8d66ba74aa083c1cb..69c499174881f939d18e7e2d58f4f0f6ec3459db 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,6 +46,7 @@ namespace Foam
 
 makeSurface(UnsortedMeshedSurface, face)
 makeSurface(UnsortedMeshedSurface, triFace)
+makeSurface(UnsortedMeshedSurface, labelledTri)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/mergedSurf/mergedSurf.C b/src/surfMesh/mergedSurf/mergedSurf.C
new file mode 100644
index 0000000000000000000000000000000000000000..d5c5f3dc8e8ab835ae861c899e0da54ca7c8419a
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.C
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "mergedSurf.H"
+#include "PatchTools.H"
+#include "ListListOps.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::mergedSurf()
+:
+    points_(),
+    faces_(),
+    zones_(),
+    pointsMap_()
+{}
+
+
+Foam::mergedSurf::mergedSurf
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+:
+    mergedSurf()
+{
+    merge(surf, mergeDim);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::~mergedSurf()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::mergedSurf::use()
+{
+    return Pstream::parRun();
+}
+
+
+void Foam::mergedSurf::clear()
+{
+    points_.clear();
+    faces_.clear();
+    zones_.clear();
+    pointsMap_.clear();
+}
+
+
+bool Foam::mergedSurf::merge
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+{
+    // needed for extra safety?
+    // clear();
+
+    if (!use())
+    {
+        return false;
+    }
+
+    PatchTools::gatherAndMerge
+    (
+        mergeDim,
+        primitivePatch
+        (
+            SubList<face>(surf.faces(), surf.faces().size()),
+            surf.points()
+        ),
+        points_,
+        faces_,
+        pointsMap_
+    );
+
+    // Now handle zone/region information
+    List<labelList> allZones(Pstream::nProcs());
+    allZones[Pstream::myProcNo()] = surf.zoneIds();
+    Pstream::gatherList(allZones);
+
+    if (Pstream::master())
+    {
+        zones_ = ListListOps::combine<labelList>
+        (
+            allZones,
+            accessOp<labelList>()
+        );
+    }
+    allZones.clear();
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/mergedSurf/mergedSurf.H b/src/surfMesh/mergedSurf/mergedSurf.H
new file mode 100644
index 0000000000000000000000000000000000000000..dae03660ee95fcf6797b986d75a6e2f989d71387
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.H
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::mergedSurf
+
+Description
+    Simple class to manage surface merging information
+
+SourceFiles
+    mergedSurf.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef mergedSurf_H
+#define mergedSurf_H
+
+#include "meshedSurf.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class mergedSurf Declaration
+\*---------------------------------------------------------------------------*/
+
+class mergedSurf
+:
+    public meshedSurf
+{
+    pointField points_;
+    faceList   faces_;
+    labelList  zones_;
+    labelList  pointsMap_;
+
+    //- Disallow default bitwise copy construct
+    mergedSurf(const mergedSurf&) = delete;
+
+    // Assignment is needed for lists
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        mergedSurf();
+
+        //- Construct and merge meshed surfaces immediately (in parallel only).
+        mergedSurf(const meshedSurf&, const scalar mergeDim);
+
+
+    //- Destructor
+    virtual ~mergedSurf();
+
+
+    // Access Member Functions
+
+        //- Can use (parallel only)
+        static bool use();
+
+        //- Number of faces
+        label size() const
+        {
+            return faces_.size();
+        }
+
+        //- Const access to (global) points used for the surface
+        virtual const pointField& points() const
+        {
+            return points_;
+        }
+
+        //- Const access to the surface faces
+        virtual const faceList& faces() const
+        {
+            return faces_;
+        }
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return zones_;
+        }
+
+        //- Map for reordered points (old-to-new)
+        const labelList& pointsMap() const
+        {
+            return pointsMap_;
+        }
+
+
+    // Edit
+
+        //- Clear all storage
+        void clear();
+
+        //- Merge meshed surfaces (in parallel only).
+        bool merge(const meshedSurf&, const scalar mergeDim);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/faceSets.H b/src/surfMesh/meshedSurf/meshedSurf.H
similarity index 68%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/faceSets.H
rename to src/surfMesh/meshedSurf/meshedSurf.H
index 8b09bc7f39f789d0f2667b3e028699f2ed24f264..0d7281be04c55c37a83d5a1749bb9019f469c508 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/faceSets.H
+++ b/src/surfMesh/meshedSurf/meshedSurf.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,16 +22,19 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::faceSets
+    Foam::meshedSurf
 
 Description
+    Abstract definition of a meshed surface defined by faces and points.
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef faceSets_H
-#define faceSets_H
+#ifndef meshedSurf_H
+#define meshedSurf_H
 
-#include "labelList.H"
+#include "pointField.H"
+#include "faceList.H"
+#include "ListOps.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -39,34 +42,38 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class faceSets Declaration
+                         Class meshedSurf Declaration
 \*---------------------------------------------------------------------------*/
 
-class faceSets
+class meshedSurf
 {
 public:
 
-        label nTris;
-        label nQuads;
-        label nPolys;
-
-        labelList tris;
-        labelList quads;
-        labelList polys;
-
-
     // Constructors
 
         //- Construct null
-        faceSets()
-        :
-            nTris(0),
-            nQuads(0),
-            nPolys(0)
+        meshedSurf()
         {}
-};
 
 
+    //- Destructor
+    virtual ~meshedSurf()
+    {}
+
+
+    // Access Member Functions
+
+        //- Const access to (global) points used for the surface
+        virtual const pointField& points() const = 0;
+
+        //- Const access to the surface faces
+        virtual const faceList& faces() const = 0;
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const = 0;
+
+};
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/cellSets.H b/src/surfMesh/meshedSurf/meshedSurfRef.H
similarity index 53%
rename from applications/utilities/postProcessing/dataConversion/foamToEnsight/cellSets.H
rename to src/surfMesh/meshedSurf/meshedSurfRef.H
index 54887f662a2b560fdf8417bd8b8f1b33ac88cf55..8390795fb69b2cf86ecb85377a534210ff281cfc 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/cellSets.H
+++ b/src/surfMesh/meshedSurf/meshedSurfRef.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) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,15 +22,17 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::cellSets
+    Foam::meshedSurfRef
 
 Description
+    Implements a meshed surface by referencing existing faces and points.
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef cellSets_H
-#define cellSets_H
+#ifndef meshedSurfRef_H
+#define meshedSurfRef_H
 
+#include "meshedSurf.H"
 #include "labelList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -39,67 +41,72 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class cellSets Declaration
+                        Class meshedSurfRef Declaration
 \*---------------------------------------------------------------------------*/
 
-class cellSets
+class meshedSurfRef
+:
+    public meshedSurf
 {
-public:
+    const pointField& points_;
+    const faceList&   faces_;
+    const labelList&  zoneIds_;
+
 
-        label nTets;
-        label nPyrs;
-        label nPrisms;
-        label nHexesWedges;
-        label nPolys;
+    // Private Member Functions
 
-        labelList tets;
-        labelList pyrs;
-        labelList prisms;
-        labelList wedges;
-        labelList hexes;
-        labelList polys;
+        //- Disallow construct as copy
+        meshedSurfRef(const meshedSurfRef&) = delete;
 
+        //- Disallow default bitwise assignment
+        void operator=(const meshedSurfRef&) = delete;
+
+public:
+
+    // Public Member Functions
 
     // Constructors
 
-        //- Construct given the number ov cells
-        cellSets(const label nCells)
+        //- Construct from components
+        meshedSurfRef
+        (
+            const pointField& pts,
+            const faceList& faces,
+            const labelList& ids = Foam::emptyLabelList
+        )
         :
-            nTets(0),
-            nPyrs(0),
-            nPrisms(0),
-            nHexesWedges(0),
-            nPolys(0),
-
-            tets(nCells),
-            pyrs(nCells),
-            prisms(nCells),
-            wedges(nCells),
-            hexes(nCells),
-            polys(nCells)
+            points_(pts),
+            faces_(faces),
+            zoneIds_(ids)
         {}
 
 
-    // Member Functions
+    //- Destructor
+    virtual ~meshedSurfRef()
+    {}
+
+
+    // Access Member Functions
 
-        void setSize(const label nCells)
+        //- Const access to (global) points used for the surface
+        virtual const pointField& points() const
         {
-            nTets = 0;
-            nPyrs = 0;
-            nPrisms = 0;
-            nHexesWedges = 0;
-            nPolys = 0;
-
-            tets.setSize(nCells);
-            pyrs.setSize(nCells);
-            prisms.setSize(nCells);
-            wedges.setSize(nCells);
-            hexes.setSize(nCells);
-            polys.setSize(nCells);
+            return points_;
         }
 
-};
+        //- Const access to the surface faces
+        virtual const faceList& faces() const
+        {
+            return faces_;
+        }
 
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return zoneIds_;
+        }
+
+};
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfMesh/surfMesh.C b/src/surfMesh/surfMesh/surfMesh.C
index 1cc3ddcba46736391813c080c62cd8b78f5338ab..c7eef6b72b10f0eadc32c8a9ae1f9653fc570c9f 100644
--- a/src/surfMesh/surfMesh/surfMesh.C
+++ b/src/surfMesh/surfMesh/surfMesh.C
@@ -260,7 +260,28 @@ void Foam::surfMesh::resetPrimitives
 )
 {
     // Clear addressing.
-    MeshReference::clearGeom();
+    clearOut();
+
+    Allocator::reset(points, faces, zones);
+    this->updateRefs();
+
+    if (validate)
+    {
+        checkZones();
+    }
+}
+
+
+void Foam::surfMesh::resetPrimitives
+(
+    const Xfer<List<point>>& points,
+    const Xfer<faceList>& faces,
+    const Xfer<surfZoneList>& zones,
+    const bool validate
+)
+{
+    // Clear addressing.
+    clearOut();
 
     Allocator::reset(points, faces, zones);
     this->updateRefs();
@@ -278,7 +299,7 @@ void Foam::surfMesh::transfer
 )
 {
     // Clear addressing.
-    MeshReference::clearGeom();
+    clearOut();
 
     this->storedIOPoints().transfer(surf.storedPoints());
     this->storedIOFaces().transfer(surf.storedFaces());
@@ -288,7 +309,8 @@ void Foam::surfMesh::transfer
 }
 
 
-Foam::Xfer<Foam::MeshedSurface<Foam::face>> Foam::surfMesh::xfer()
+Foam::Xfer<Foam::MeshedSurface<Foam::face>>
+Foam::surfMesh::xfer()
 {
     Xfer<MeshedSurface<face>> xf;
 
@@ -300,7 +322,7 @@ Foam::Xfer<Foam::MeshedSurface<Foam::face>> Foam::surfMesh::xfer()
     this->updateRefs();
 
     // Clear addressing.
-    MeshReference::clearGeom();
+    clearOut();
 
     return xf;
 }
diff --git a/src/surfMesh/surfMesh/surfMesh.H b/src/surfMesh/surfMesh/surfMesh.H
index d8bbff5fe4f561822a2beaf420100a363209c392..64e7c0239a474e1603c0f00dd233116d21c92599 100644
--- a/src/surfMesh/surfMesh/surfMesh.H
+++ b/src/surfMesh/surfMesh/surfMesh.H
@@ -233,6 +233,25 @@ public:
             //- Check the surface zone definitions
             void checkZones();
 
+
+            //- Return face area vectors (normals)
+            inline const vectorField& Sf() const
+            {
+                return MeshReference::faceAreas();
+            }
+
+            //- Return face area magnitudes
+            inline const scalarField& magSf() const
+            {
+                return MeshReference::magFaceAreas();
+            }
+
+            //- Face centres
+            inline const vectorField& Cf() const
+            {
+                return MeshReference::faceCentres();
+            }
+
             //- Add surface zones
             void addZones
             (
@@ -258,6 +277,15 @@ public:
                 const bool validate = true
             );
 
+            //- Reset mesh primitive data.
+            void resetPrimitives
+            (
+                const Xfer<List<point>>& points,
+                const Xfer<faceList>& faces,
+                const Xfer<surfZoneList>& zones,
+                const bool validate = true
+            );
+
 
             //- Transfer the contents of the argument and annul the argument
             void transfer(MeshedSurface<face>&);
diff --git a/src/surfMesh/surfMesh/surfMeshClear.C b/src/surfMesh/surfMesh/surfMeshClear.C
index 179f202c2d5c589aa01718ef5d1147db45a08cf9..39bef03a02d153906b0a6b3ef64f507f34173b77 100644
--- a/src/surfMesh/surfMesh/surfMeshClear.C
+++ b/src/surfMesh/surfMesh/surfMeshClear.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -69,6 +69,8 @@ void Foam::surfMesh::clearAddressing()
 
 void Foam::surfMesh::clearOut()
 {
+    MeshReference::clearOut();
+
     clearGeom();
     clearAddressing();
 }
diff --git a/src/surfMesh/surfMesh/surfMeshIO.C b/src/surfMesh/surfMesh/surfMeshIO.C
index 5e7072e3a44480aa5a7f2d2a51c74331c3848eeb..f2a5c54245ab0bc8420b71db062b68bb3e497cad 100644
--- a/src/surfMesh/surfMesh/surfMeshIO.C
+++ b/src/surfMesh/surfMesh/surfMeshIO.C
@@ -168,7 +168,7 @@ Foam::surfMesh::readUpdateState Foam::surfMesh::readUpdate()
             Info<< "Point motion" << endl;
         }
 
-        clearGeom();
+        clearOut();
         storedIOPoints().instance() = pointsInst;
 
         storedIOPoints() = pointIOField
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
index d589c9a79e8164bfff5f7e6b3b5892c6a6a127ea..0c60b22ede22db7b1b71739a0b67cc76bcbd21fc 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,10 +24,8 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "AC3DsurfaceFormat.H"
-#include "clock.H"
 #include "IStringStream.H"
-#include "tensor.H"
-#include "primitivePatch.H"
+#include "PrimitivePatch.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -49,7 +47,6 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     IFstream is(filename);
@@ -199,7 +196,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
 
                     labelUList& f = static_cast<labelUList&>(verts);
 
-                    if (mustTriangulate && f.size() > 3)
+                    if (MeshedSurface<Face>::isTri() && f.size() > 3)
                     {
                         // simple face triangulation about f[0]
                         // points may be incomplete
@@ -248,11 +245,64 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
 
     // add zones, culling empty ones
     this->addZones(sizes, names, true);
+    this->addZonesToFaces(); // for labelledTri
     this->stitchFaces(SMALL);
+
     return true;
 }
 
 
+namespace Foam
+{
+// file-scope writing of a patch of faces
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+static void writeZone
+(
+    Ostream& os,
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& patch,
+    const word& name,
+    const label zoneI
+)
+{
+    // An isolated surface region (patch).
+    os  << "OBJECT poly" << nl
+        << "name \"" << name << "\"" << nl;
+
+    os << "numvert " << patch.nPoints() << nl;
+
+    forAll(patch.localPoints(), pti)
+    {
+        const point& pt = patch.localPoints()[pti];
+
+        os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
+    }
+
+    os << "numsurf " << patch.size() << nl;
+
+    forAll(patch.localFaces(), facei)
+    {
+        const Face& f = patch.localFaces()[facei];
+
+        os  << "SURF 0x20" << nl          // polygon
+            << "mat " << zoneI << nl
+            << "refs " << f.size() << nl;
+
+        forAll(f, fp)
+        {
+            os << f[fp] << " 0 0" << nl;
+        }
+    }
+
+    os << "kids 0" << endl;
+}
+}
+
 template<class Face>
 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 (
@@ -261,7 +311,7 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
 
     const List<surfZone>& zones =
     (
@@ -272,14 +322,6 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 
     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
 
-    if (useFaceMap)
-    {
-        FatalErrorInFunction
-            << "output with faceMap is not supported " << filename
-            << exit(FatalError);
-    }
-
-
     OFstream os(filename);
     if (!os.good())
     {
@@ -290,52 +332,42 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 
     writeHeader(os, zones);
 
-    forAll(zones, zoneI)
+    if (zones.size() == 1)
     {
-        const surfZone& zone = zones[zoneI];
-
-        os  << "OBJECT poly" << nl
-            << "name \"" << zone.name() << "\"\n";
-
-        // Temporary PrimitivePatch to calculate compact points & faces
-        // use 'UList' to avoid allocations!
         PrimitivePatch<Face, UList, const pointField&> patch
         (
-            SubList<Face>
-            (
-                faceLst,
-                zone.size(),
-                zone.start()
-            ),
-            pointLst
+            faceLst, pointLst
         );
 
-        os << "numvert " << patch.nPoints() << endl;
+        writeZone(os, patch, zones[0].name(), 0);
+        return;
+    }
+
+    forAll(zones, zoneI)
+    {
+        const surfZone& zone = zones[zoneI];
 
-        forAll(patch.localPoints(), ptI)
+        if (useFaceMap)
         {
-            const point& pt = patch.localPoints()[ptI];
+            SubList<label> zoneMap(surf.faceMap(), zone.size(), zone.start());
+            PrimitivePatch<Face, UIndirectList, const pointField&> patch
+            (
+                UIndirectList<Face>(faceLst, zoneMap),
+                pointLst
+            );
 
-            os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
+            writeZone(os, patch, zone.name(), zoneI);
         }
-
-        os << "numsurf " << patch.localFaces().size() << endl;
-
-        forAll(patch.localFaces(), localFacei)
+        else
         {
-            const Face& f = patch.localFaces()[localFacei];
-
-            os  << "SURF 0x20" << nl          // polygon
-                << "mat " << zoneI << nl
-                << "refs " << f.size() << nl;
+            PrimitivePatch<Face, UList, const pointField&> patch
+            (
+                SubList<Face>(faceLst, zone.size(), zone.start()),
+                pointLst
+            );
 
-            forAll(f, fp)
-            {
-                os << f[fp] << " 0 0" << nl;
-            }
+            writeZone(os, patch, zone.name(), zoneI);
         }
-
-        os << "kids 0" << endl;
     }
 }
 
@@ -347,81 +379,44 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
     const UnsortedMeshedSurface<Face>& surf
 )
 {
+    OFstream os(filename);
+    if (!os.good())
+    {
+        FatalErrorInFunction
+            << "Cannot open file for writing " << filename
+            << exit(FatalError);
+    }
+
     labelList faceMap;
     List<surfZone> zoneLst = surf.sortedZones(faceMap);
 
     if (zoneLst.size() <= 1)
     {
-        write
+        const List<surfZone>& zones =
         (
-            filename,
-            MeshedSurfaceProxy<Face>
-            (
-                surf.points(),
-                surf.faces(),
-                zoneLst
-            )
+            zoneLst.size()
+          ? zoneLst
+          : surfaceFormatsCore::oneZone(surf.surfFaces())
         );
-    }
-    else
-    {
-        OFstream os(filename);
-        if (!os.good())
-        {
-            FatalErrorInFunction
-                << "Cannot open file for writing " << filename
-                << exit(FatalError);
-        }
-
-        writeHeader(os, zoneLst);
-
-        label faceIndex = 0;
-        forAll(zoneLst, zoneI)
-        {
-            const surfZone& zone = zoneLst[zoneI];
-
-            os  << "OBJECT poly" << nl
-                << "name \"" << zone.name() << "\"\n";
 
-            // Create zone with only zone faces included for ease of addressing
-            labelHashSet include(surf.size());
-
-            forAll(zone, localFacei)
-            {
-                const label facei = faceMap[faceIndex++];
-                include.insert(facei);
-            }
-
-            UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
-
-            // Now we have isolated surface for this patch alone. Write it.
-            os << "numvert " << subm.nPoints() << endl;
-
-            forAll(subm.localPoints(), ptI)
-            {
-                const point& pt = subm.localPoints()[ptI];
-
-                os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
-            }
-
-            os << "numsurf " << subm.localFaces().size() << endl;
-
-            forAll(subm.localFaces(), localFacei)
-            {
-                const Face& f = subm.localFaces()[localFacei];
+        writeHeader(os, zones);
+        writeZone(os, surf, zones[0].name(), 0);
+        return;
+    }
 
-                os  << "SURF 0x20" << nl          // polygon
-                    << "mat " << zoneI << nl
-                    << "refs " << f.size() << nl;
+    writeHeader(os, zoneLst);
+    forAll(zoneLst, zoneI)
+    {
+        const surfZone& zone = zoneLst[zoneI];
 
-                forAll(f, fp)
-                {
-                    os << f[fp] << " 0 0" << nl;
-                }
-            }
+        SubList<label> zoneMap(faceMap, zone.size(), zone.start());
+        PrimitivePatch<Face, UIndirectList, const pointField&> patch
+        (
+            UIndirectList<Face>(surf.surfFaces(), zoneMap),
+            surf.points()
+        );
 
-            os << "kids 0" << endl;
-        }
+        writeZone(os, patch, zone.name(), zoneI);
     }
 }
 
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
index 8d626099c34ae456dcdd735b3c23fab6db8c7f2e..177c2deb41e81f05bf5fedaf51c1f1e3059f912e 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -67,10 +67,10 @@ class AC3DsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        AC3DsurfaceFormat(const AC3DsurfaceFormat<Face>&);
+        AC3DsurfaceFormat(const AC3DsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const AC3DsurfaceFormat<Face>&);
+        void operator=(const AC3DsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -101,10 +101,18 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Write UnsortedMeshedSurface, the output is always sorted by zones.
-        static void write(const fileName&, const UnsortedMeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C
index 89e4f5eb638cd5bd8f66b75d282b2310566e2f86..9c2846efee3b01d04b3d39ca6d7e4d07cd9cda4f 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     ac
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    AC3DsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    ac
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,6 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     ac
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    AC3DsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    ac
+);
 
 
 // write UnsortedMeshedSurface
@@ -93,6 +110,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     ac
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    AC3DsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    ac
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.C b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.C
new file mode 100644
index 0000000000000000000000000000000000000000..4cbfb60d561c486b225e6d90d819cc72451bb768
--- /dev/null
+++ b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.C
@@ -0,0 +1,390 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "FLMAsurfaceFormat.H"
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+//! \cond fileScope
+//- Output newline in ascii mode, no-op in binary mode
+inline static void newline(Foam::OSstream& os)
+{
+    if (os.format() == Foam::IOstream::ASCII)
+    {
+        os  << Foam::endl;
+    }
+}
+
+
+template<class Face>
+inline static int countFaces(const Face& f)
+{
+    int n = (f.size() - 2); // number triangles can be determined directly
+    return n == 2 ? 1 : n;  // quads don't need triangulation
+}
+
+//! \endcond
+
+
+template<class Face>
+inline void Foam::fileFormats::FLMAsurfaceFormat<Face>::writeShell
+(
+    OSstream& os,
+    const Face& f
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        if (f.size() == 3 || f.size() == 4)
+        {
+            putFireLabel(os, f.size());
+            forAll(f, fp)
+            {
+                putFireLabel(os, f[fp]);
+            }
+        }
+        else
+        {
+            // simple triangulation about f[0].
+            // better triangulation should have been done before
+            for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
+            {
+                label fp2 = f.fcIndex(fp1);
+
+                putFireLabel(os, 3);
+                putFireLabel(os, f[0]);
+                putFireLabel(os, f[fp1]);
+                putFireLabel(os, f[fp2]);
+            }
+        }
+    }
+    else
+    {
+        // ASCII
+        if (f.size() == 3 || f.size() == 4)
+        {
+            os  << ' ' << f.size();
+            forAll(f, fp)
+            {
+                os  << ' ' << f[fp];
+            }
+            os  << nl;
+        }
+        else
+        {
+            for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
+            {
+                label fp2 = f.fcIndex(fp1);
+                os  << ' ' << 3 << ' '
+                    << f[0] << ' ' << f[fp1] << ' ' << f[fp2]
+                    << nl;
+            }
+        }
+    }
+}
+
+
+template<class Face>
+inline void Foam::fileFormats::FLMAsurfaceFormat<Face>::writeType
+(
+    OSstream& os,
+    const Face& f
+)
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        if (f.size() == 4)
+        {
+            putFireLabel(os, fireQuad);
+        }
+        else
+        {
+            const label n = countFaces(f);
+            for (label i=0; i < n; ++i)
+            {
+                putFireLabel(os, fireTri);
+            }
+        }
+    }
+    else
+    {
+        // ASCII
+        if (f.size() == 4)
+        {
+            os  << ' ' << fireQuad;
+        }
+        else
+        {
+            const label n = countFaces(f);
+            for (label i=0; i < n; ++i)
+            {
+                os  << ' ' << fireTri;
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<class Face>
+void Foam::fileFormats::FLMAsurfaceFormat<Face>::write
+(
+    OSstream& os,
+    const MeshedSurfaceProxy<Face>& surf
+)
+{
+    if (!os.good())
+    {
+        FatalErrorIn
+        (
+            "fileFormats::FLMAsurfaceFormat::write"
+            "(OSstream&, const MeshedSurfaceProxy<Face>&)"
+        )
+            << "bad output state "
+            << exit(FatalError);
+    }
+
+    const pointField& pointLst = surf.points();
+    const List<Face>&  faceLst = surf.surfFaces();
+    const List<label>& faceMap = surf.faceMap();
+
+    // for no zones, suppress the group name
+    const List<surfZone>& zones =
+    (
+        surf.surfZones().empty()
+      ? surfaceFormatsCore::oneZone(faceLst, word::null)
+      : surf.surfZones()
+    );
+
+    const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
+
+
+    // determine the number of faces by counting the
+    // tri/quads/triangulated) faces in each zone
+    label nFaces = 0;
+    List<label> zoneCount(zones.size());
+
+    {
+        label faceIndex = 0;
+        forAll(zones, zoneI)
+        {
+            const surfZone& zone = zones[zoneI];
+
+            label selCount = 0;
+            if (useFaceMap)
+            {
+                forAll(zone, localFaceI)
+                {
+                    selCount += countFaces(faceLst[faceMap[faceIndex++]]);
+                }
+            }
+            else
+            {
+                forAll(zone, localFaceI)
+                {
+                    selCount += countFaces(faceLst[faceIndex++]);
+                }
+            }
+
+            zoneCount[zoneI] = selCount;
+            nFaces += selCount;
+        }
+    }
+
+
+    // Points
+    // ~~~~~~
+
+    // Set the precision of the points data to 10
+    os.precision(10);
+
+    Info<< "points: " << pointLst.size() << endl;
+    putFireLabel(os, pointLst.size());
+    newline(os);
+
+    forAll(pointLst, ptI)
+    {
+        // scaling is normally 1
+        putFirePoint(os, pointLst[ptI]);
+    }
+    newline(os); // readability
+
+    // Faces indices
+    {
+        Info<< "faces:  " << nFaces << endl;
+        putFireLabel(os, nFaces);
+        newline(os);
+
+        label faceIndex = 0;
+        forAll(zones, zoneI)
+        {
+            const surfZone& zone = zones[zoneI];
+
+            if (useFaceMap)
+            {
+                forAll(zone, localFaceI)
+                {
+                    writeShell(os, faceLst[faceMap[faceIndex++]]);
+                }
+            }
+            else
+            {
+                forAll(zone, localFaceI)
+                {
+                    writeShell(os, faceLst[faceIndex++]);
+                }
+            }
+        }
+        newline(os);
+        newline(os); // readability
+    }
+
+
+    // Face types
+    {
+        putFireLabel(os, nFaces);
+        newline(os);
+
+        label faceIndex = 0;
+        forAll(zones, zoneI)
+        {
+            const surfZone& zone = zones[zoneI];
+
+            if (useFaceMap)
+            {
+                forAll(zone, localFaceI)
+                {
+                    writeType(os, faceLst[faceMap[faceIndex++]]);
+                }
+            }
+            else
+            {
+                forAll(zone, localFaceI)
+                {
+                    writeType(os, faceLst[faceIndex++]);
+                }
+            }
+        }
+        newline(os);
+        newline(os); // readability
+    }
+
+    // Selections (cell)
+    {
+        putFireLabel(os, zones.size());
+        newline(os);
+
+        label faceIndex = 0;
+        forAll(zones, zoneI)
+        {
+            const surfZone& zone = zones[zoneI];
+            const label selCount = zoneCount[zoneI];
+
+            putFireString(os, zone.name());
+            putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
+            newline(os);
+
+            putFireLabels(os, selCount, faceIndex);
+            faceIndex += selCount;
+
+            newline(os); // readability
+        }
+    }
+}
+
+
+template<class Face>
+void Foam::fileFormats::FLMAsurfaceFormat<Face>::write
+(
+    const fileName& filename,
+    const MeshedSurfaceProxy<Face>& surf,
+    bool compress
+)
+{
+    autoPtr<OFstream> osPtr
+    (
+        compress
+      ? new OFstream
+        (
+            filename,
+            IOstream::ASCII,
+            IOstream::currentVersion,
+            IOstream::COMPRESSED
+        )
+      : new OFstream(filename)
+    );
+
+    if (osPtr->good())
+    {
+        FLMAsurfaceFormat<Face>::write(osPtr(), surf);
+        osPtr.clear();    // implicitly close the file
+
+        if (compress)
+        {
+            // rename .flmaz.gz -> .flmaz
+            // The '.gz' is automatically added by OFstream in compression mode
+            Foam::mv(filename + ".gz", filename);
+        }
+    }
+    else
+    {
+        FatalErrorIn
+        (
+            "fileFormats::FLMAsurfaceFormat::write"
+            "(const fileName&, const MeshedSurfaceProxy<Face>&)"
+        )
+            << "Cannot open file for writing " << filename
+            << exit(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Face>
+void Foam::fileFormats::FLMAsurfaceFormat<Face>::write
+(
+    const fileName& filename,
+    const MeshedSurfaceProxy<Face>& surf
+)
+{
+    write(filename, surf, false);
+}
+
+
+template<class Face>
+void Foam::fileFormats::FLMAZsurfaceFormat<Face>::write
+(
+    const fileName& filename,
+    const MeshedSurfaceProxy<Face>& surf
+)
+{
+    FLMAsurfaceFormat<Face>::write(filename, surf, true);
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.H b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.H
similarity index 50%
rename from src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.H
rename to src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.H
index 33ab7212a52a4de87002c452c129db0f74e6cb07..1af5a3f3972ac8aa1493013dde6dfb28829af47f 100644
--- a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormat.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,28 +22,22 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::fileFormats::OFSsurfaceFormat
+    Foam::fileFormats::FLMAsurfaceFormat
 
 Description
-    Provide a means of reading/writing the single-file OpenFOAM surface format.
-
-Note
-    This class provides more methods than the regular surface format interface.
+    Provide a means of writing AVL/FIRE FLMA format.
 
 SourceFiles
-    OFSsurfaceFormat.C
+    FLMAsurfaceFormat.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef OFSsurfaceFormat_H
-#define OFSsurfaceFormat_H
+#ifndef FLMAsurfaceFormat_H
+#define FLMAsurfaceFormat_H
 
-#include "Ostream.H"
-#include "OFstream.H"
 #include "MeshedSurface.H"
 #include "MeshedSurfaceProxy.H"
-#include "UnsortedMeshedSurface.H"
-#include "OFSsurfaceFormatCore.H"
+#include "FIRECore.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -53,87 +47,127 @@ namespace fileFormats
 {
 
 /*---------------------------------------------------------------------------*\
-                      Class OFSsurfaceFormat Declaration
+                      Class FLMAsurfaceFormat Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Face>
-class OFSsurfaceFormat
+class FLMAsurfaceFormat
 :
     public MeshedSurface<Face>,
-    public OFSsurfaceFormatCore
+    public FIRECore
 {
     // Private Member Functions
 
+        static inline void writeShell(OSstream&, const Face&);
+        static inline void writeType(OSstream&, const Face&);
+
         //- Disallow default bitwise copy construct
-        OFSsurfaceFormat(const OFSsurfaceFormat<Face>&);
+        FLMAsurfaceFormat(const FLMAsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const OFSsurfaceFormat<Face>&);
+        void operator=(const FLMAsurfaceFormat<Face>&) = delete;
 
 
-public:
+protected:
 
-    // Constructors
+    // Protected Member Functions
 
-        //- Construct from file name
-        OFSsurfaceFormat(const fileName&);
+        //- Write surface mesh components by proxy
+        static void write
+        (
+            OSstream&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
 
-    // Selectors
+        //- Write surface mesh components by proxy with/without compression
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&,
+            bool compress
+        );
 
-        //- Read file and return surface
-        static autoPtr<MeshedSurface<Face>> New(const fileName& name)
-        {
-            return autoPtr<MeshedSurface<Face>>
-            (
-                new OFSsurfaceFormat<Face>(name)
-            );
-        }
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        FLMAsurfaceFormat()
+        {}
 
 
     //- Destructor
-    virtual ~OFSsurfaceFormat()
+    virtual ~FLMAsurfaceFormat()
     {}
 
 
-
     // Member Functions
 
-        //- Read surface mesh components
-        static bool read
+        //- Write surface mesh components by proxy
+        static void write
         (
-            Istream&,
-            pointField&,
-            List<Face>&,
-            List<surfZone>&
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
         );
 
-        //- Read MeshedSurface
-        static bool read
-        (
-            Istream&,
-            MeshedSurface<Face>&
-        );
+        //- Write flma file
+        virtual void write(const fileName& name) const
+        {
+            write(name, MeshedSurfaceProxy<Face>(*this));
+        }
 
-        //- Read UnsortedMeshedSurface
-        //  The output is sorted by zones
-        static bool read
-        (
-            Istream&,
-            UnsortedMeshedSurface<Face>&
-        );
+};
 
-        //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
 
-        //- Read from file
-        virtual bool read(const fileName&);
+/*---------------------------------------------------------------------------*\
+                     Class FLMAZsurfaceFormat Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Face>
+class FLMAZsurfaceFormat
+:
+    public FLMAsurfaceFormat<Face>
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        FLMAZsurfaceFormat(const FLMAZsurfaceFormat<Face>&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const FLMAZsurfaceFormat<Face>&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        FLMAZsurfaceFormat()
+        {}
+
+
+    //- Destructor
+    virtual ~FLMAZsurfaceFormat()
+    {}
+
 
-        //- Write object
+    // Member Functions
+
+        //- Write surface mesh components by proxy
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
+
+        //- Write flmaz file
         virtual void write(const fileName& name) const
         {
             write(name, MeshedSurfaceProxy<Face>(*this));
         }
+
 };
 
 
@@ -145,7 +179,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-    #include "OFSsurfaceFormat.C"
+#   include "FLMAsurfaceFormat.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormatRunTime.C
similarity index 69%
rename from src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatRunTime.C
rename to src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormatRunTime.C
index 1f1069f0aba4893e6ddea66233221fb7fd6433fc..d4fd924b7b2eedf3fbb78122c2dbf89c524cf3cb 100644
--- a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/fire/FLMAsurfaceFormatRunTime.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,7 +23,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "OFSsurfaceFormat.H"
+#include "FLMAsurfaceFormat.H"
 
 #include "addToRunTimeSelectionTable.H"
 #include "addToMemberFunctionSelectionTable.H"
@@ -35,45 +35,64 @@ namespace Foam
 namespace fileFormats
 {
 
-// read MeshedSurface
-addNamedTemplatedToRunTimeSelectionTable
+// write MeshedSurfaceProxy
+addNamedTemplatedToMemberFunctionSelectionTable
 (
-    MeshedSurface,
-    OFSsurfaceFormat,
+    MeshedSurfaceProxy,
+    FLMAsurfaceFormat,
     face,
+    write,
     fileExtension,
-    ofs
+    flma
 );
-addNamedTemplatedToRunTimeSelectionTable
+addNamedTemplatedToMemberFunctionSelectionTable
 (
-    MeshedSurface,
-    OFSsurfaceFormat,
+    MeshedSurfaceProxy,
+    FLMAsurfaceFormat,
     triFace,
+    write,
     fileExtension,
-    ofs
+    flma
+);
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    FLMAsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    flma
 );
 
 
-// write MeshedSurfaceProxy
+// write MeshedSurfaceProxy (comnpressed versions of above)
 addNamedTemplatedToMemberFunctionSelectionTable
 (
     MeshedSurfaceProxy,
-    OFSsurfaceFormat,
+    FLMAZsurfaceFormat,
     face,
     write,
     fileExtension,
-    ofs
+    flmaz
 );
 addNamedTemplatedToMemberFunctionSelectionTable
 (
     MeshedSurfaceProxy,
-    OFSsurfaceFormat,
+    FLMAZsurfaceFormat,
     triFace,
     write,
     fileExtension,
-    ofs
+    flmaz
+);
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    FLMAZsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    flmaz
 );
-
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
index 9d9f3c5f0b60ec712a614255a704baba041b2c96..731b2e1b96aa397c06aeeecfb80073ea37721161 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -203,6 +203,7 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
     }
 
     this->storedZoneToc().transfer(newZones);
+    this->addZonesToFaces(); // for labelledTri
 
     return true;
 }
@@ -216,7 +217,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
+    const List<Face>& faceLst  = surf.surfFaces();
 
     const List<surfZone>& zones =
     (
@@ -323,7 +324,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst   = surf.points();
-    const List<Face>& faceLst    = surf.faces();
+    const List<Face>& faceLst    = surf.surfFaces();
     const List<label>& zoneIds   = surf.zoneIds();
     const List<surfZoneIdentifier>& zoneToc = surf.zoneToc();
 
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
index 7a0175d0d29992e27c8b4ab475b1a15bfd5759e5..c39c005af511fd384220acdb7485c7f2bf120a36 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,10 +60,10 @@ class GTSsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        GTSsurfaceFormat(const GTSsurfaceFormat<Face>&);
+        GTSsurfaceFormat(const GTSsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const GTSsurfaceFormat<Face>&);
+        void operator=(const GTSsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -94,10 +94,18 @@ public:
     // Member Functions
 
         //- Write MeshedSurface
-        static void write(const fileName&, const MeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurface<Face>&
+        );
 
         //- Write UnsortedMeshedSurface, the output remains unsorted
-        static void write(const fileName&, const UnsortedMeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormatRunTime.C
index 03fc0569ab2f48b15ed65b734a9a22eac2edcab2..35a6e95ba8a35521fc78ea500a947d1e0f122f8c 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     gts
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    UnsortedMeshedSurface,
+    GTSsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    gts
+);
 
 // write MeshedSurface
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,6 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     gts
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurface,
+    GTSsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    gts
+);
 
 // write UnsortedMeshedSurface
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -92,6 +109,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     gts
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    GTSsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    gts
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
index 2a7ea0ebc7953d8980f645a9fc731eadc45f35cd..d7b932ec485de4fba41ca5b3efbb1ae4996bc325 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
@@ -47,7 +47,6 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     IFstream is(filename);
@@ -253,7 +252,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             }
 
 
-            if (mustTriangulate)
+            if (MeshedSurface<Face>::isTri())
             {
                 dynFaces.append(triFace(f[0], f[1], f[2]));
                 dynFaces.append(triFace(f[0], f[2], f[3]));
@@ -374,9 +373,8 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
     }
 
     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
-
-    // add zones, culling empty ones
-    this->addZones(dynSizes, names, true);
+    this->addZones(dynSizes, names, true); // add zones, cull empty ones
+    this->addZonesToFaces(); // for labelledTri
 
     return true;
 }
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
index 65f22eecf7b4e5e3d6cefa4cbd66036558f871f4..d6b0ed0852bfefde27081808249b5335f7383d0a 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,10 +68,10 @@ class NASsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        NASsurfaceFormat(const NASsurfaceFormat<Face>&);
+        NASsurfaceFormat(const NASsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const NASsurfaceFormat<Face>&);
+        void operator=(const NASsurfaceFormat<Face>&) = delete;
 
 
 public:
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C
index 4fca5cc1b6882df9908068b03d335d897e8504d1..572a9aa9827c703a29851875d660b5b56a3d1dbd 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,7 +35,7 @@ namespace Foam
 namespace fileFormats
 {
 
-// read MeshedSurface - .bdf (Bulk Data Format)
+// read MeshedSurface - .bdf (Bulk Data Format) and nas (Nastran)
 addNamedTemplatedToRunTimeSelectionTable
 (
     MeshedSurface,
@@ -53,7 +53,6 @@ addNamedTemplatedToRunTimeSelectionTable
     nas
 );
 
-// read MeshedSurface - .nas (Nastran)
 addNamedTemplatedToRunTimeSelectionTable
 (
     MeshedSurface,
@@ -71,6 +70,23 @@ addNamedTemplatedToRunTimeSelectionTable
     nas
 );
 
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    NASsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    bdf
+);
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    NASsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    nas
+);
+
 }
 }
 
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
index 7a4eacde00b5ea6c7e7f399007aa68efe1fa8d25..04274c775a65bdf23581c7434914d0a3ebeb60f6 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -51,7 +51,6 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     IFstream is(filename);
@@ -173,7 +172,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 
             labelUList& f = static_cast<labelUList&>(dynVertices);
 
-            if (mustTriangulate && f.size() > 3)
+            if (MeshedSurface<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // points may be incomplete
@@ -200,9 +199,9 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
     this->storedPoints().transfer(dynPoints);
 
     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
+    this->addZones(dynSizes, dynNames, true); // add zones, cull empty ones
+    this->addZonesToFaces(); // for labelledTri
 
-    // add zones, culling empty ones
-    this->addZones(dynSizes, dynNames, true);
     return true;
 }
 
@@ -215,7 +214,7 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     // for no zones, suppress the group name
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
index 7162078175478fc366c91e7db9b33f6b255527af..dc472070371934b3ae70a4f259a8507607fb4fd9 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,10 +60,10 @@ class OBJsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        OBJsurfaceFormat(const OBJsurfaceFormat<Face>&);
+        OBJsurfaceFormat(const OBJsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const OBJsurfaceFormat<Face>&);
+        void operator=(const OBJsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -94,7 +94,11 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C
index a0d7ab518a16f1f39d15fca287bb047a02d85fe1..ff8b7ee1e51e98446518218c40cee2b001b0cddd 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     obj
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    OBJsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    obj
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,6 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     obj
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    OBJsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    obj
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
index 86e8220c6aa8ab1a684b61aa28971b5d0612b9cc..fd869a0c5086db67467529aa42bac8d9f282f080 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,7 +50,6 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     IFstream is(filename);
@@ -116,7 +115,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
 
             labelUList& f = static_cast<labelUList&>(verts);
 
-            if (mustTriangulate && f.size() > 3)
+            if (MeshedSurface<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // cannot use face::triangulation (points may be incomplete)
@@ -149,7 +148,7 @@ void Foam::fileFormats::OFFsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
     const List<surfZone>& zoneLst = surf.surfZones();
 
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
index 0fc6bdf6c67433d82b284fac2d3bcb97d48f94c3..654da0c93edc45a4d665cfb32bdd84fb87bb4b78 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,10 +68,10 @@ class OFFsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        OFFsurfaceFormat(const OFFsurfaceFormat&);
+        OFFsurfaceFormat(const OFFsurfaceFormat&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const OFFsurfaceFormat&);
+        void operator=(const OFFsurfaceFormat&) = delete;
 
 
 public:
@@ -102,7 +102,11 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatRunTime.C
index f3177520f87235beddb6d6970f5ba8234a9f75e5..6b355ecfe307ad6262564110b292d5630ec6141c 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     off
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    OFFsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    off
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,7 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     off
 );
-
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    OFFsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    off
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.C b/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.C
deleted file mode 100644
index 6f9d2595f7068bf8402c24c9c26b07aff59e30f4..0000000000000000000000000000000000000000
--- a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormat.C
+++ /dev/null
@@ -1,243 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "OFSsurfaceFormat.H"
-#include "IFstream.H"
-#include "IStringStream.H"
-#include "ListOps.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<class Face>
-Foam::fileFormats::OFSsurfaceFormat<Face>::OFSsurfaceFormat
-(
-    const fileName& filename
-)
-{
-    read(filename);
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Face>
-bool Foam::fileFormats::OFSsurfaceFormat<Face>::read
-(
-    const fileName& filename
-)
-{
-    this->clear();
-
-    IFstream is(filename);
-    if (!is.good())
-    {
-        FatalErrorInFunction
-            << "Cannot read file " << filename
-            << exit(FatalError);
-    }
-
-    // read surfZones:
-    is >> this->storedZones();
-
-    // read points:
-    is >> this->storedPoints();
-
-    // must triangulate?
-    if (MeshedSurface<Face>::isTri())
-    {
-        // read faces as 'face' and transcribe to 'triFace'
-        List<face> faceLst(is);
-
-        MeshedSurface<face> surf
-        (
-            xferMove(this->storedPoints()),
-            xferMove(faceLst),
-            xferMove(this->storedZones())
-        );
-
-        this->transcribe(surf);
-    }
-    else
-    {
-        // read faces directly
-        is >> this->storedFaces();
-    }
-
-    return true;
-}
-
-
-template<class Face>
-bool Foam::fileFormats::OFSsurfaceFormat<Face>::read
-(
-    Istream& is,
-    pointField& pointLst,
-    List<Face>& faceLst,
-    List<surfZone>& zoneLst
-)
-{
-    if (!is.good())
-    {
-        FatalErrorInFunction
-            << "read error "
-            << exit(FatalError);
-    }
-
-    // read surfZones:
-    is >> zoneLst;
-
-    // read points:
-    is >> pointLst;
-
-    // must triangulate?
-    if (MeshedSurface<Face>::isTri())
-    {
-        // read faces as 'face' and transcribe to 'triFace'
-        List<face> origFaces(is);
-
-        MeshedSurface<face> origSurf
-        (
-            xferMove(pointLst),
-            xferMove(origFaces),
-            xferMove(zoneLst)
-        );
-
-        MeshedSurface<Face> surf;
-        surf.transcribe(origSurf);
-    }
-    else
-    {
-        // read faces directly
-        is >> faceLst;
-    }
-
-    return true;
-}
-
-
-template<class Face>
-bool Foam::fileFormats::OFSsurfaceFormat<Face>::read
-(
-    Istream& is,
-    MeshedSurface<Face>& surf
-)
-{
-    surf.clear();
-
-    if (!is.good())
-    {
-        FatalErrorInFunction
-            << "read error "
-            << exit(FatalError);
-    }
-
-    pointField pointLst;
-    List<Face> faceLst;
-    List<surfZone> zoneLst;
-
-    read(is, pointLst, faceLst, zoneLst);
-
-    surf.reset
-    (
-        xferMove(pointLst),
-        xferMove(faceLst),
-        xferMove(zoneLst)
-    );
-
-    return true;
-}
-
-
-template<class Face>
-bool Foam::fileFormats::OFSsurfaceFormat<Face>::read
-(
-    Istream& is,
-    UnsortedMeshedSurface<Face>& surf
-)
-{
-    surf.clear();
-    MeshedSurface<Face> origSurf(is);
-    surf.transfer(origSurf);
-
-    return true;
-}
-
-
-
-template<class Face>
-void Foam::fileFormats::OFSsurfaceFormat<Face>::write
-(
-    const fileName& filename,
-    const MeshedSurfaceProxy<Face>& surf
-)
-{
-    const List<Face>&  faceLst = surf.faces();
-    const List<label>& faceMap = surf.faceMap();
-
-    OFstream os(filename);
-    if (!os.good())
-    {
-        FatalErrorInFunction
-            << "Cannot open file for writing " << filename
-            << exit(FatalError);
-    }
-
-
-    OFSsurfaceFormatCore::writeHeader(os, surf.points(), surf.surfZones());
-
-    const List<surfZone>& zones = surf.surfZones();
-    const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
-
-    if (useFaceMap)
-    {
-        os  << "\n// faces:"  << nl
-            << faceLst.size() << token::BEGIN_LIST << nl;
-
-        label facei = 0;
-        forAll(zones, zoneI)
-        {
-            // Print all faces belonging to this zone
-            const surfZone& zone = zones[zoneI];
-
-            forAll(zone, localFacei)
-            {
-                os << faceLst[faceMap[facei++]] << nl;
-            }
-        }
-        os << token::END_LIST << nl;
-    }
-    else
-    {
-        os  << "\n// faces:"  << nl << faceLst << nl;
-    }
-
-    IOobject::writeDivider(os);
-
-    // Check state of Ostream
-    os.check("OFSsurfaceFormat<Face>::write(Ostream&)");
-}
-
-
-// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.C
deleted file mode 100644
index 89ab4290956bf6d958a0a6d0814a3fdb5699691e..0000000000000000000000000000000000000000
--- a/src/surfMesh/surfaceFormats/ofs/OFSsurfaceFormatCore.C
+++ /dev/null
@@ -1,71 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "OFSsurfaceFormatCore.H"
-#include "clock.H"
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::fileFormats::OFSsurfaceFormatCore::writeHeader
-(
-    Ostream& os,
-    const pointField& pointLst,
-    const UList<surfZone>& zoneLst
-)
-{
-    // just emit some information until we get a nice IOobject
-    IOobject::writeBanner(os)
-        << "// OpenFOAM Surface Format - written "
-        << clock::dateTime().c_str() << nl
-        << "// ~~~~~~~~~~~~~~~~~~~~~~~" << nl << nl
-        << "// surfZones:" << nl;
-
-
-    // treat a single zone as being unzoned
-    if (zoneLst.size() <= 1)
-    {
-        os  << "0" << token::BEGIN_LIST << token::END_LIST << nl << nl;
-    }
-    else
-    {
-        os  << zoneLst.size() << nl << token::BEGIN_LIST << incrIndent << nl;
-
-        forAll(zoneLst, zoneI)
-        {
-            zoneLst[zoneI].writeDict(os);
-        }
-        os  << decrIndent << token::END_LIST << nl << nl;
-    }
-
-    // Note: write with global point numbering
-
-    IOobject::writeDivider(os)
-        << "\n// points:" << nl << pointLst << nl;
-
-    IOobject::writeDivider(os);
-}
-
-
-// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
index 2530cf8ed491c97ad66ee079d6a30f2e1c0a8730..01640aa5ec87665adb28c1b2dcfedada0ab91b1e 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,9 +25,7 @@ License
 
 #include "SMESHsurfaceFormat.H"
 #include "clock.H"
-#include "IFstream.H"
 #include "OFstream.H"
-#include "Ostream.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -46,7 +44,7 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -58,7 +56,6 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
 
     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
 
-
     OFstream os(filename);
     if (!os.good())
     {
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
index 94fd8e1df0db177bb8509d16d0c55177d0d44c85..0a4e315f3ebcdc09382b889e6f6db3d3a4ed9740 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -64,10 +64,10 @@ class SMESHsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        SMESHsurfaceFormat(const SMESHsurfaceFormat<Face>&);
+        SMESHsurfaceFormat(const SMESHsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const SMESHsurfaceFormat<Face>&);
+        void operator=(const SMESHsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -86,7 +86,11 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Write object
         virtual void write(const fileName& name) const
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormatRunTime.C
index 34db152c9f10071d0e2e371988f1a3e49b714a5b..2bb1dae786398270446687f68b35e69985b2d6bf 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -54,6 +54,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     smesh
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    SMESHsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    smesh
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
index 4ddd88c404d034fc420fece87c3a060aa0cb759a..7240ee78245a01aad1371e18d01ccdf1b7233dfe 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,10 +38,10 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
 )
 {
     os  << cellId                    // includes 1 offset
-        << ' ' << starcdShellShape_  // 3(shell) shape
+        << ' ' << starcdShell        // 3(shell) shape
         << ' ' << f.size()
         << ' ' << cellTableId
-        << ' ' << starcdShellType_;  // 4(shell)
+        << ' ' << starcdShellType;   // 4(shell)
 
     // primitives have <= 8 vertices, but prevent overrun anyhow
     // indent following lines for ease of reading
@@ -79,21 +79,15 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     fileName baseName = filename.lessExt();
 
     // read cellTable names (if possible)
-    Map<word> cellTableLookup;
-
-    {
-        IFstream is(baseName + ".inp");
-        if (is.good())
-        {
-            cellTableLookup = readInpCellTable(is);
-        }
-    }
+    Map<word> cellTableLookup = readInpCellTable
+    (
+        IFstream(starFileName(baseName, STARCDCore::INP_FILE))()
+    );
 
 
     // STAR-CD index of points
@@ -102,7 +96,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
     // read points from .vrt file
     readPoints
     (
-        IFstream(baseName + ".vrt")(),
+        IFstream(starFileName(baseName, STARCDCore::VRT_FILE))(),
         this->storedPoints(),
         pointId
     );
@@ -115,10 +109,10 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
     }
     pointId.clear();
 
-    //
+
     // read .cel file
     // ~~~~~~~~~~~~~~
-    IFstream is(baseName + ".cel");
+    IFstream is(starFileName(baseName, STARCDCore::CEL_FILE));
     if (!is.good())
     {
         FatalErrorInFunction
@@ -126,7 +120,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
             << exit(FatalError);
     }
 
-    readHeader(is, "PROSTAR_CELL");
+    readHeader(is, STARCDCore::HEADER_CEL);
 
     DynamicList<Face>  dynFaces;
     DynamicList<label> dynZones;
@@ -162,7 +156,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
             vertexLabels.append(mapPointId[vrtId]);
         }
 
-        if (typeId == starcdShellType_)
+        if (typeId == starcdShellType)
         {
             // Convert groupID into zoneID
             Map<label>::const_iterator fnd = lookup.find(cellTableId);
@@ -199,24 +193,19 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
             }
 
             SubList<label> vertices(vertexLabels, vertexLabels.size());
-            if (mustTriangulate && nLabels > 3)
+            if (MeshedSurface<Face>::isTri() && nLabels > 3)
             {
+                // face needs triangulation
                 face f(vertices);
 
-                faceList triFaces(f.nTriangles());
+                faceList trias(f.nTriangles());
                 label nTri = 0;
-                f.triangles(this->points(), nTri, triFaces);
+                f.triangles(this->points(), nTri, trias);
 
-                forAll(triFaces, facei)
+                forAll(trias, facei)
                 {
-                    // a triangular face, but not yet a triFace
-                    dynFaces.append
-                    (
-                        triFace
-                        (
-                            static_cast<labelUList&>(triFaces[facei])
-                        )
-                    );
+                    // a triangular 'face', convert to 'triFace' etc
+                    dynFaces.append(Face(trias[facei]));
                     dynZones.append(zoneI);
                     dynSizes[zoneI]++;
                 }
@@ -233,8 +222,9 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
 
     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
 
-    // add zones, culling empty ones
-    this->addZones(dynSizes, dynNames, true);
+    this->addZones(dynSizes, dynNames, true); // add zones, cull empty ones
+    this->addZonesToFaces(); // for labelledTri
+
     return true;
 }
 
@@ -247,7 +237,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -262,9 +252,13 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 
     fileName baseName = filename.lessExt();
 
-    writePoints(OFstream(baseName + ".vrt")(), pointLst);
-    OFstream os(baseName + ".cel");
-    writeHeader(os, "CELL");
+    writePoints
+    (
+        OFstream(starFileName(baseName, STARCDCore::VRT_FILE))(),
+        pointLst
+    );
+    OFstream os(starFileName(baseName, STARCDCore::CEL_FILE));
+    writeHeader(os, STARCDCore::HEADER_CEL);
 
     label faceIndex = 0;
     forAll(zones, zoneI)
@@ -292,7 +286,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
     // write simple .inp file
     writeCase
     (
-        OFstream(baseName + ".inp")(),
+        OFstream(starFileName(baseName, STARCDCore::INP_FILE))(),
         pointLst,
         faceLst.size(),
         zones
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
index 8e4c7e09413afe588229743af16744939d523f66..a0e3b39da3ac380ae069766132924b1cc2faeaae 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -63,15 +63,6 @@ class STARCDsurfaceFormat
     public MeshedSurface<Face>,
     public STARCDsurfaceFormatCore
 {
-    // Private Data
-
-        //- STAR-CD identifier for shell shapes (2d elements)
-        static const int starcdShellShape_ = 3;
-
-        //- STAR-CD identifier for shell type (shells vs. baffles)
-        static const int starcdShellType_  = 4;
-
-
     // Private Member Functions
 
         static inline void writeShell
@@ -83,10 +74,10 @@ class STARCDsurfaceFormat
         );
 
         //- Disallow default bitwise copy construct
-        STARCDsurfaceFormat(const STARCDsurfaceFormat<Face>&);
+        STARCDsurfaceFormat(const STARCDsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const STARCDsurfaceFormat<Face>&);
+        void operator=(const STARCDsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -117,7 +108,11 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
index c73db97ddb5c625a6a02b6843dd9d72f93ab823d..8200a5b58be44a9e66b7d1c07e0dcf00bbf1fac6 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -42,6 +42,11 @@ Foam::fileFormats::STARCDsurfaceFormatCore::readInpCellTable
 {
     Map<word> lookup;
 
+    if (!is.good())
+    {
+        return lookup;
+    }
+
     regExp ctnameRE
     (
         " *CTNA[^ ]*"        // keyword - min 4 chars
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C
index 50e395ff48e2de6cb1430a74b0a176070be7df9b..866a0d5d1621d297d17c6d53f98ee0e98c4ac7ca 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     inp
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    STARCDsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    inp
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,7 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     inp
 );
-
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    STARCDsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    inp
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index e3c53dabcc45fb255d60f7c257e7e24e651d5ff9..0529da9941d8fb954e21729541371be6d22187ac 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,7 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STLsurfaceFormat.H"
-#include "ListOps.H"
+#include "labelledTri.H"
 #include "triPointRef.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -51,20 +51,17 @@ inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
     const point& p0 = pointLst[f[0]];
     for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
     {
-        label fp2 = f.fcIndex(fp1);
-
-        const point& p1 = pointLst[f[fp1]];
-        const point& p2 = pointLst[f[fp2]];
-
-        // write STL triangle
-        os  << " facet normal "
-            << norm.x() << ' ' << norm.y() << ' ' << norm.z() << nl
-            << "  outer loop\n"
-            << "   vertex " << p0.x() << ' ' << p0.y() << ' ' << p0.z() << nl
-            << "   vertex " << p1.x() << ' ' << p1.y() << ' ' << p1.z() << nl
-            << "   vertex " << p2.x() << ' ' << p2.y() << ' ' << p2.z() << nl
-            << "  endloop\n"
-            << " endfacet" << endl;
+        const label fp2 = f.fcIndex(fp1);
+
+        // Write ASCII
+        STLtriangle::write
+        (
+            os,
+            norm,
+            p0,
+            pointLst[f[fp1]],
+            pointLst[f[fp2]]
+        );
     }
 }
 
@@ -92,18 +89,17 @@ inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
     const point& p0 = pointLst[f[0]];
     for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
     {
-        label fp2 = f.fcIndex(fp1);
+        const label fp2 = f.fcIndex(fp1);
 
-        STLtriangle stlTri
+        // Write BINARY
+        STLtriangle
         (
             norm,
             p0,
             pointLst[f[fp1]],
             pointLst[f[fp2]],
             zoneI
-        );
-
-        stlTri.write(os);
+        ).write(os);
     }
 }
 
@@ -131,7 +127,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
     this->clear();
 
     // read in the values
-    STLsurfaceFormatCore reader(filename);
+    STLReader reader(filename);
 
     // transfer points
     this->storedPoints().transfer(reader.points());
@@ -180,13 +176,13 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
     {
         this->addZones(sizes);
     }
-
+    this->addZonesToFaces(); // for labelledTri
     this->stitchFaces(SMALL);
+
     return true;
 }
 
 
-
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
 (
@@ -203,7 +199,7 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
     }
 
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -258,9 +254,8 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
             << exit(FatalError);
     }
 
-
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -272,23 +267,9 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
 
     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
 
-
-    unsigned int nTris = 0;
-    if (MeshedSurface<Face>::isTri())
-    {
-        nTris = faceLst.size();
-    }
-    else
-    {
-        // count triangles for on-the-fly triangulation
-        forAll(faceLst, facei)
-        {
-            nTris += faceLst[facei].size() - 2;
-        }
-    }
-
     // Write the STL header
-    STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
+    unsigned int nTris = surf.nTriangles();
+    STLCore::writeBinaryHeader(os, nTris);
 
     label faceIndex = 0;
     forAll(zones, zoneI)
@@ -340,13 +321,13 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
             << exit(FatalError);
     }
 
+    const pointField& pointLst = surf.points();
+    const List<Face>& faceLst  = surf.surfFaces();
+
     // a single zone - we can skip sorting
     if (surf.zoneToc().size() == 1)
     {
-        const pointField& pointLst = surf.points();
-        const List<Face>& faceLst  = surf.faces();
-
-        os << "solid " << surf.zoneToc()[0].name() << endl;
+        os << "solid " << surf.zoneToc()[0].name() << nl;
         forAll(faceLst, facei)
         {
             writeShell(os, pointLst, faceLst[facei]);
@@ -363,8 +344,8 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeAscii
            filename,
            MeshedSurfaceProxy<Face>
            (
-               surf.points(),
-               surf.faces(),
+               pointLst,
+               faceLst,
                zoneLst,
                faceMap
            )
@@ -389,25 +370,12 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBinary
     }
 
     const pointField&  pointLst = surf.points();
-    const List<Face>&  faceLst  = surf.faces();
+    const List<Face>&  faceLst  = surf.surfFaces();
     const List<label>& zoneIds  = surf.zoneIds();
 
-    unsigned int nTris = 0;
-    if (MeshedSurface<Face>::isTri())
-    {
-        nTris = faceLst.size();
-    }
-    else
-    {
-        // count triangles for on-the-fly triangulation
-        forAll(faceLst, facei)
-        {
-            nTris += faceLst[facei].size() - 2;
-        }
-    }
-
     // Write the STL header
-    STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
+    unsigned int nTris = surf.nTriangles();
+    STLCore::writeBinaryHeader(os, nTris);
 
     // always write unsorted
     forAll(faceLst, facei)
@@ -430,10 +398,20 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
     const MeshedSurfaceProxy<Face>& surf
 )
 {
-    const word ext = filename.ext();
+    // Auto-detect ASCII/BINARY extension
+    write(filename, surf, STLCore::DETECT);
+}
 
-    // handle 'stlb' as binary directly
-    if (ext == "stlb")
+
+template<class Face>
+void Foam::fileFormats::STLsurfaceFormat<Face>::write
+(
+    const fileName& filename,
+    const MeshedSurfaceProxy<Face>& surf,
+    const STLFormat& format
+)
+{
+    if (STLCore::isBinaryName(filename, format))
     {
         writeBinary(filename, surf);
     }
@@ -451,10 +429,20 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
     const UnsortedMeshedSurface<Face>& surf
 )
 {
-    word ext = filename.ext();
+    // Auto-detect ASCII/BINARY extension
+    write(filename, surf, STLCore::DETECT);
+}
+
 
-    // handle 'stlb' as binary directly
-    if (ext == "stlb")
+template<class Face>
+void Foam::fileFormats::STLsurfaceFormat<Face>::write
+(
+    const fileName& filename,
+    const UnsortedMeshedSurface<Face>& surf,
+    const STLFormat& format
+)
+{
+    if (STLCore::isBinaryName(filename, format))
     {
         writeBinary(filename, surf);
     }
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
index 02c12ae24b56dde6543bc2a22aa8062e85f14e5d..754ea005d92077276a7f84ef3a8526637db7621e 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,7 +25,7 @@ Class
     Foam::fileFormats::STLsurfaceFormat
 
 Description
-    Provide a means of reading/writing STL files (ASCII and binary).
+    Provide a means of reading/writing STL files (ASCII and BINARY).
 
 Note
     For efficiency, the zones are sorted before creating the faces.
@@ -40,7 +40,7 @@ SourceFiles
 #ifndef STLsurfaceFormat_H
 #define STLsurfaceFormat_H
 
-#include "STLsurfaceFormatCore.H"
+#include "STLReader.H"
 #include "MeshedSurface.H"
 #include "MeshedSurfaceProxy.H"
 #include "UnsortedMeshedSurface.H"
@@ -59,7 +59,8 @@ namespace fileFormats
 template<class Face>
 class STLsurfaceFormat
 :
-    public MeshedSurface<Face>
+    public MeshedSurface<Face>,
+    public STLCore
 {
     // Private Member Functions
 
@@ -80,11 +81,12 @@ class STLsurfaceFormat
             const label zoneI
         );
 
+
         //- Disallow default bitwise copy construct
-        STLsurfaceFormat(const STLsurfaceFormat<Face>&);
+        STLsurfaceFormat(const STLsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const STLsurfaceFormat<Face>&);
+        void operator=(const STLsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -130,7 +132,20 @@ public:
 
         //- Write surface mesh components by proxy
         //  as ASCII or BINARY, depending on the extension
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
+
+        //- Write surface mesh components by proxy
+        //  as ASCII or BINARY or dependent on the extension
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&,
+            const STLFormat&
+        );
 
         //- Write UnsortedMeshedSurface (as ASCII) sorted by zone
         static void writeAscii
@@ -148,7 +163,20 @@ public:
 
         //- Write UnsortedMeshedSurface
         //  as ASCII or BINARY, depending on the extension
-        static void write(const fileName&, const UnsortedMeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&
+        );
+
+        //- Write UnsortedMeshedSurface
+        //  as ASCII or BINARY or dependent on the extension
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&,
+            const STLFormat&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatRunTime.C
index f50cff99c2a44a827ad99c4ca1c80f12b2c3a3e1..298da7e8e1d071522bf891103a4c0a1d92c1493b 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STLsurfaceFormat.H"
+#include "labelledTri.H"
 
 #include "addToRunTimeSelectionTable.H"
 #include "addToMemberFunctionSelectionTable.H"
@@ -52,6 +53,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     stl
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    STLsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    stl
+);
 
 // read MeshedSurface (binary)
 addNamedTemplatedToRunTimeSelectionTable
@@ -70,6 +79,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     stlb
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    STLsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    stlb
+);
 
 
 // write MeshedSurfaceProxy (ascii)
@@ -91,6 +108,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     stl
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    STLsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    stl
+);
 
 // write MeshedSurfaceProxy (binary)
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -111,6 +137,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     stlb
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    STLsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    stlb
+);
 
 // write UnsortedMeshedSurface (ascii)
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -131,6 +166,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     stl
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    STLsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    stl
+);
 
 // write UnsortedMeshedSurface (binary)
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -151,6 +195,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     stlb
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    STLsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    stlb
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
index 39218b9bc936555807128902272f0c48565753fb..73ccc8eff3b14de66634ba17fdd28a2c035a79ba 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
@@ -99,15 +99,26 @@ public:
 
         //- Return the local file name (within time directory)
         //  NEEDS FIXING
-        static fileName localMeshFileName(const word& surfName="");
+        static fileName localMeshFileName
+        (
+            const word& surfName = word::null
+        );
 
         //- Find instance with surfName
         //  NEEDS FIXING
-        static fileName findMeshInstance(const Time&, const word& surfName="");
+        static fileName findMeshInstance
+        (
+            const Time&,
+            const word& surfName = word::null
+        );
 
         //- Find mesh file with surfName
         //  NEEDS FIXING
-        static fileName findMeshFile(const Time&, const word& surfName="");
+        static fileName findMeshFile
+        (
+            const Time&,
+            const word& surfName = word::null
+        );
 
 
     // Constructors
@@ -118,6 +129,7 @@ public:
 
     //- Destructor
     virtual ~surfaceFormatsCore();
+
 };
 
 
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index b95f2605be1d39b6126ce2891c560008667ab968..5b0aba1f8808a1a6885bd5925f2fe08ef9e42c7d 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,7 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "TRIsurfaceFormat.H"
-#include "ListOps.H"
+#include "OFstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -51,7 +51,7 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
             << p1.x() << ' ' << p1.y() << ' ' << p1.z() << ' '
             << p2.x() << ' ' << p2.y() << ' ' << p2.z() << ' '
             // zone as colour
-            << "0x" << hex << zoneI << dec << endl;
+            << "0x" << hex << zoneI << dec << nl;
     }
 }
 
@@ -120,6 +120,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
     this->storedFaces().transfer(faceLst);
 
     this->addZones(sizes);
+    this->addZonesToFaces(); // for labelledTri
     this->stitchFaces(SMALL);
     return true;
 }
@@ -133,7 +134,7 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -186,7 +187,7 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
+    const List<Face>& faceLst  = surf.surfFaces();
 
     OFstream os(filename);
     if (!os.good())
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
index 12834226f4f3ba20d12d5e8a43711105a265bba6..b4b914800a519c110b3b39e40655fd9ea2b0452f 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -71,10 +71,10 @@ class TRIsurfaceFormat
         );
 
         //- Disallow default bitwise copy construct
-        TRIsurfaceFormat(const TRIsurfaceFormat<Face>&);
+        TRIsurfaceFormat(const TRIsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const TRIsurfaceFormat<Face>&);
+        void operator=(const TRIsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -105,11 +105,19 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Write UnsortedMeshedSurface,
         //  by default the output is not sorted by zones
-        static void write(const fileName&, const UnsortedMeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
index 95fc0ffae59c50650d84357dc55ccdb82b5571ab..12ce08e3725fdc72d03e1f4b96313f7879baa186 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
@@ -38,10 +38,6 @@ SourceFiles
 #include "surfaceFormatsCore.H"
 #include "triFace.H"
 
-#include "IFstream.H"
-#include "Ostream.H"
-#include "OFstream.H"
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -74,10 +70,10 @@ class TRIsurfaceFormatCore
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        TRIsurfaceFormatCore(const TRIsurfaceFormatCore&);
+        TRIsurfaceFormatCore(const TRIsurfaceFormatCore&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const TRIsurfaceFormatCore&);
+        void operator=(const TRIsurfaceFormatCore&) = delete;
 
         bool read(const fileName&);
 
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C
index edceb53d08cf3f817b8f20fb9ffa34c276e49bd2..cd34f8311e9cfc7d155f548ea048fb4369321178 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     tri
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    TRIsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    tri
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,6 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     tri
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    TRIsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    tri
+);
 
 // write UnsortedMeshedSurface
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -92,6 +109,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     tri
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    TRIsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    tri
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
index f5e5a889204cb48ecd0c3082f9701c1690d6b22b..aedd18d6c853b42e048bfd75f514f62b4d8e85aa 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "VTKsurfaceFormat.H"
 #include "vtkUnstructuredReader.H"
 #include "scalarIOField.H"
+#include "OFstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -69,7 +70,6 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
     const fileName& filename
 )
 {
-    const bool mustTriangulate = this->isTri();
     this->clear();
 
     IFstream is(filename);
@@ -148,18 +148,21 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
     }
 
 
-    // See if needs triangulation
+    // Check if it needs triangulation
     label nTri = 0;
-    if (mustTriangulate)
+    if (MeshedSurface<Face>::isTri())
     {
         forAll(faces, facei)
         {
-            nTri += faces[facei].size()-2;
+            nTri += faces[facei].nTriangles();
         }
     }
 
-    if (nTri > 0)
+    if (nTri > faces.size())
     {
+        // We are here if the target surface needs triangles and
+        // the source surface has non-triangles
+
         DynamicList<Face> dynFaces(nTri);
         DynamicList<label> dynZones(nTri);
         forAll(faces, facei)
@@ -207,6 +210,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
         // add zones, culling empty ones
         this->addZones(zoneSizes, zoneNames, true);
     }
+    this->addZonesToFaces(); // for labelledTri
 
     // transfer to normal lists
     this->storedPoints().transfer(reader.points());
@@ -223,7 +227,7 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     const List<surfZone>& zones =
@@ -302,7 +306,7 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
     }
 
 
-    const List<Face>& faceLst = surf.faces();
+    const List<Face>& faceLst = surf.surfFaces();
 
     writeHeader(os, surf.points());
     writeHeaderPolygons(os, faceLst);
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
index 0691f404141664fa22ce037f44abb9638d98d6f1..437eb249212441ffc2c574e3259ad8bca6836652 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -64,10 +64,10 @@ class VTKsurfaceFormat
         static void writeHeaderPolygons(Ostream&, const UList<Face>&);
 
         //- Disallow default bitwise copy construct
-        VTKsurfaceFormat(const VTKsurfaceFormat<Face>&);
+        VTKsurfaceFormat(const VTKsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const VTKsurfaceFormat<Face>&);
+        void operator=(const VTKsurfaceFormat<Face>&) = delete;
 
 
 public:
@@ -89,6 +89,7 @@ public:
             );
         }
 
+
     //- Destructor
     virtual ~VTKsurfaceFormat()
     {}
@@ -99,10 +100,18 @@ public:
         // Write
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
         //- Write UnsortedMeshedSurface, the output remains unsorted
-        static void write(const fileName&, const UnsortedMeshedSurface<Face>&);
+        static void write
+        (
+            const fileName&,
+            const UnsortedMeshedSurface<Face>&
+        );
 
         //- Read from file
         virtual bool read(const fileName&);
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
index d9e7ebdbc42ff1d44ff4e608cf1f7d839f6c9c3e..946440ddb0cf3734cc1a2bf6e99d81d2b207c2ea 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
@@ -35,9 +35,8 @@ SourceFiles
 #ifndef VTKsurfaceFormatCore_H
 #define VTKsurfaceFormatCore_H
 
-#include "Ostream.H"
-#include "OFstream.H"
 #include "MeshedSurface.H"
+#include "Ostream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatRunTime.C
index 3636317223fba3fd8f045e3afb08ef1f50454411..5dc1aa2b67924030b56580baa58836cd7a8158ea 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatRunTime.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -52,6 +52,14 @@ addNamedTemplatedToRunTimeSelectionTable
     fileExtension,
     vtk
 );
+addNamedTemplatedToRunTimeSelectionTable
+(
+    MeshedSurface,
+    VTKsurfaceFormat,
+    labelledTri,
+    fileExtension,
+    vtk
+);
 
 // write MeshedSurfaceProxy
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -72,6 +80,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     vtk
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    VTKsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    vtk
+);
 
 // write UnsortedMeshedSurface
 addNamedTemplatedToMemberFunctionSelectionTable
@@ -92,7 +109,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     vtk
 );
-
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    UnsortedMeshedSurface,
+    VTKsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    vtk
+);
 
 }
 }
diff --git a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.C b/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.C
deleted file mode 100644
index e3d44d8281b1ee1de87eee3762cc22b17e8322f0..0000000000000000000000000000000000000000
--- a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormat.C
+++ /dev/null
@@ -1,139 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "WRLsurfaceFormat.H"
-
-#include "Ostream.H"
-#include "OFstream.H"
-#include "ListOps.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<class Face>
-Foam::fileFormats::WRLsurfaceFormat<Face>::WRLsurfaceFormat()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Face>
-void Foam::fileFormats::WRLsurfaceFormat<Face>::write
-(
-    const fileName& filename,
-    const MeshedSurfaceProxy<Face>& surf
-)
-{
-    const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
-    const List<label>& faceMap = surf.faceMap();
-
-    // for no zones, suppress the group name
-    const List<surfZone>& zones =
-    (
-        surf.surfZones().empty()
-      ? surfaceFormatsCore::oneZone(faceLst, "")
-      : surf.surfZones()
-    );
-
-    const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
-
-    OFstream os(filename);
-    if (!os.good())
-    {
-        FatalErrorInFunction
-            << "Cannot open file for writing " << filename
-            << exit(FatalError);
-    }
-
-    writeHeader(os, pointLst, faceLst.size(), zones);
-
-    os  << "\n"
-        "Group {\n"
-        " children [\n"
-        "  Shape {\n";
-
-   writeAppearance(os);
-
-   os  <<
-        "   geometry IndexedFaceSet {\n"
-        "    coord Coordinate {\n"
-        "     point [\n";
-
-    // Write vertex coords
-    forAll(pointLst, ptI)
-    {
-        const point& pt = pointLst[ptI];
-
-        os  << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
-    }
-
-    os  <<
-        "     ]\n"                     // end point
-        "    }\n"                      // end coord Coordinate
-        "    coordIndex [\n";
-
-    label faceIndex = 0;
-    forAll(zones, zoneI)
-    {
-        const surfZone& zone = zones[zoneI];
-
-        if (useFaceMap)
-        {
-            forAll(zone, localFacei)
-            {
-                const Face& f = faceLst[faceMap[faceIndex++]];
-
-                forAll(f, fp)
-                {
-                    os << f[fp] << ' ';
-                }
-                os << "-1,\n";
-            }
-        }
-        else
-        {
-            forAll(zone, localFacei)
-            {
-                const Face& f = faceLst[faceIndex++];
-
-                forAll(f, fp)
-                {
-                    os << ' ' << f[fp];
-                }
-                os << " -1,\n";
-            }
-        }
-    }
-
-    os  <<
-        "    ]\n"                      // end coordIndex
-        "   }\n"                       // end geometry IndexedFaceSet
-        "  }\n"                        // end Shape
-        " ]\n"                         // end children
-        "}\n";                         // end Group
-}
-
-
-// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.C
deleted file mode 100644
index b7c33c9e9a76f50889c4d574b1a77de456de76d6..0000000000000000000000000000000000000000
--- a/src/surfMesh/surfaceFormats/wrl/WRLsurfaceFormatCore.C
+++ /dev/null
@@ -1,73 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "WRLsurfaceFormatCore.H"
-#include "clock.H"
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-void Foam::fileFormats::WRLsurfaceFormatCore::writeHeader
-(
-    Ostream& os,
-    const pointField& pointLst,
-    const label nFaces,
-    const UList<surfZone>& zoneLst
-)
-{
-    os  << "#VRML V2.0 utf8" << nl
-        << nl
-        << "# written " << clock::dateTime().c_str() << nl
-        << "# points : " << pointLst.size() << nl
-        << "# faces  : " << nFaces << nl
-        << "# zones  : " << zoneLst.size() << nl;
-
-    // Print zone names as comment
-    forAll(zoneLst, zoneI)
-    {
-        os  << "#   " << zoneI << "  " << zoneLst[zoneI].name()
-            << "  (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
-    }
-}
-
-
-void Foam::fileFormats::WRLsurfaceFormatCore::writeAppearance
-(
-    Ostream& os
-)
-{
-    os  <<
-        "   appearance Appearance {\n"
-        "    material Material {\n"
-        "     diffuseColor   0.8 0.8 0.8\n"
-        "     specularColor  1.0 1.0 1.0\n"
-        "     shininess      0.5\n"
-        "     transparency   0.0\n"
-        "    }\n"                      // end material
-        "   }\n";                      // end appearance
-
-}
-
-
-// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.C
index 2c296d6ab7ca51b8cc6c30e51b745c283c128d6c..a9c63ccf4114f26f2019e1c27e6c2469a28765a1 100644
--- a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,12 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "X3DsurfaceFormat.H"
-#include "clock.H"
-#include "IFstream.H"
-#include "IStringStream.H"
-#include "Ostream.H"
 #include "OFstream.H"
-#include "ListOps.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -48,14 +43,14 @@ void Foam::fileFormats::X3DsurfaceFormat<Face>::write
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
+    const List<Face>&  faceLst = surf.surfFaces();
     const List<label>& faceMap = surf.faceMap();
 
     // for no zones, suppress the group name
     const List<surfZone>& zones =
     (
         surf.surfZones().empty()
-      ? surfaceFormatsCore::oneZone(faceLst, "")
+      ? surfaceFormatsCore::oneZone(faceLst, word::null)
       : surf.surfZones()
     );
 
diff --git a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.H b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.H
index 1dce035069ad8b0a83110b75826cd6198b33fc14..20caa634202d114ad3d5403c5e7238f365c5b74c 100644
--- a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormat.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -60,10 +60,10 @@ class X3DsurfaceFormat
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        X3DsurfaceFormat(const X3DsurfaceFormat<Face>&);
+        X3DsurfaceFormat(const X3DsurfaceFormat<Face>&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const X3DsurfaceFormat<Face>&);
+        void operator=(const X3DsurfaceFormat<Face>&) = delete;
 
 public:
 
@@ -81,9 +81,14 @@ public:
     // Member Functions
 
         //- Write surface mesh components by proxy
-        static void write(const fileName&, const MeshedSurfaceProxy<Face>&);
+        static void write
+        (
+            const fileName&,
+            const MeshedSurfaceProxy<Face>&
+        );
 
-        //- Write object file
+
+        //- Write object
         virtual void write(const fileName& name) const
         {
             write(name, MeshedSurfaceProxy<Face>(*this));
diff --git a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatCore.H
index 309fdd2380eedf1083d3360f029fed547d5d8910..751d91e2b25d5c3549f08a68c4aec8c55bf347a8 100644
--- a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatCore.H
@@ -35,9 +35,8 @@ SourceFiles
 #ifndef X3DsurfaceFormatCore_H
 #define X3DsurfaceFormatCore_H
 
-#include "Ostream.H"
-#include "OFstream.H"
 #include "MeshedSurface.H"
+#include "Ostream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatRunTime.C
index aff02bfcc446a0883b2119161beee02b8d69fa22..5a15901df3844bb10066f21299cb2408d9bfacbc 100644
--- a/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/x3d/X3DsurfaceFormatRunTime.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) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,6 +53,15 @@ addNamedTemplatedToMemberFunctionSelectionTable
     fileExtension,
     x3d
 );
+addNamedTemplatedToMemberFunctionSelectionTable
+(
+    MeshedSurfaceProxy,
+    X3DsurfaceFormat,
+    labelledTri,
+    write,
+    fileExtension,
+    x3d
+);
 
 }
 }
diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.C b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.C
index 54ae1eb7da26768a59ff023e88f4e5f9d5efea10..c8f0e9376d0b1d331e394b60a7e2430208aa852f 100644
--- a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.C
+++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -113,6 +113,32 @@ greyDiffusiveViewFactorFixedValueFvPatchScalarField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::radiation::greyDiffusiveViewFactorFixedValueFvPatchScalarField::
+autoMap
+(
+    const fvPatchFieldMapper& m
+)
+{
+    fixedValueFvPatchScalarField::autoMap(m);
+    Qro_.autoMap(m);
+}
+
+
+void Foam::radiation::greyDiffusiveViewFactorFixedValueFvPatchScalarField::rmap
+(
+    const fvPatchScalarField& ptf,
+    const labelList& addr
+)
+{
+    fixedValueFvPatchScalarField::rmap(ptf, addr);
+
+    const greyDiffusiveViewFactorFixedValueFvPatchScalarField& mrptf =
+        refCast<const greyDiffusiveViewFactorFixedValueFvPatchScalarField>(ptf);
+
+    Qro_.rmap(mrptf.Qro_, addr);
+}
+
+
 void Foam::radiation::greyDiffusiveViewFactorFixedValueFvPatchScalarField::
 updateCoeffs()
 {
diff --git a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.H b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.H
index 051b560ca450d74409583e90a784d9e35e4010e0..88cd34ccd9573a2eea44f87b9dc6e226930c6326 100644
--- a/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.H
+++ b/src/thermophysicalModels/radiation/derivedFvPatchFields/greyDiffusiveViewFactor/greyDiffusiveViewFactorFixedValueFvPatchScalarField.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -172,6 +172,22 @@ public:
             virtual void updateCoeffs();
 
 
+        // Mapping functions
+
+            //- Map (and resize as needed) from self given a mapping object
+            virtual void autoMap
+            (
+                const fvPatchFieldMapper&
+            );
+
+            //- Reverse map the given fvPatchField onto this fvPatchField
+            virtual void rmap
+            (
+                const fvPatchScalarField&,
+                const labelList&
+            );
+
+
         // I-O
 
             //- Write
diff --git a/src/triSurface/Make/files b/src/triSurface/Make/files
index d2384b311342feea9544a63392afa8ea0f7dc196..fab067d63e40e6fe889943c33a08fbd8ae9c8a80 100644
--- a/src/triSurface/Make/files
+++ b/src/triSurface/Make/files
@@ -1,9 +1,3 @@
-triSurfaceTools                       = triSurface/triSurfaceTools
-geometricSurfacePatch                 = triSurface/geometricSurfacePatch
-
-faceTriangulation/faceTriangulation.C
-meshTriangulation/meshTriangulation.C
-
 triSurface/triSurface.C
 triSurface/triSurfaceAddressing.C
 triSurface/stitchTriangles.C
@@ -31,9 +25,6 @@ $(interfaces)/NAS/readNAS.C
 
 triSurface/geometricSurfacePatch/geometricSurfacePatch.C
 triSurface/surfacePatch/surfacePatch.C
-triSurface/surfacePatch/surfacePatchIOList.C
-
-tools/labelledTri/sortLabelledTri.C
 
 triSurfaceFields/triSurfaceFields.C
 
diff --git a/src/triSurface/Make/options b/src/triSurface/Make/options
index 9ee5884e5908ccdb6b1ba3acf323b8c524ec996a..210c65589602fc5911b063e86e95879380069bc9 100644
--- a/src/triSurface/Make/options
+++ b/src/triSurface/Make/options
@@ -3,5 +3,4 @@ EXE_INC = \
     -I$(LIB_SRC)/surfMesh/lnInclude
 
 LIB_LIBS = \
-    -lfileFormats \
     -lsurfMesh
diff --git a/src/triSurface/meshTriangulation/meshTriangulation.C b/src/triSurface/meshTriangulation/meshTriangulation.C
deleted file mode 100644
index e0d8a753d0e340ce71c548df24d803d1d8d4ddc2..0000000000000000000000000000000000000000
--- a/src/triSurface/meshTriangulation/meshTriangulation.C
+++ /dev/null
@@ -1,511 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "meshTriangulation.H"
-#include "polyMesh.H"
-#include "faceTriangulation.H"
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-bool Foam::meshTriangulation::isInternalFace
-(
-    const primitiveMesh& mesh,
-    const boolList& includedCell,
-    const label facei
-)
-{
-    if (mesh.isInternalFace(facei))
-    {
-        label own = mesh.faceOwner()[facei];
-        label nei = mesh.faceNeighbour()[facei];
-
-        if (includedCell[own] && includedCell[nei])
-        {
-            // Neighbouring cell will get included in subset
-            // as well so face is internal.
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-    else
-    {
-        return false;
-    }
-}
-
-
-void Foam::meshTriangulation::getFaces
-(
-    const primitiveMesh& mesh,
-    const boolList& includedCell,
-    boolList& faceIsCut,
-    label& nFaces,
-    label& nInternalFaces
-)
-{
-    // All faces to be triangulated.
-    faceIsCut.setSize(mesh.nFaces());
-    faceIsCut = false;
-
-    nFaces = 0;
-    nInternalFaces = 0;
-
-    forAll(includedCell, celli)
-    {
-        // Include faces of cut cells only.
-        if (includedCell[celli])
-        {
-            const labelList& cFaces = mesh.cells()[celli];
-
-            forAll(cFaces, i)
-            {
-                label facei = cFaces[i];
-
-                if (!faceIsCut[facei])
-                {
-                    // First visit of face.
-                    nFaces++;
-                    faceIsCut[facei] = true;
-
-                    // See if would become internal or external face
-                    if (isInternalFace(mesh, includedCell, facei))
-                    {
-                        nInternalFaces++;
-                    }
-                }
-            }
-        }
-    }
-
-    Pout<< "Subset consists of " << nFaces << " faces out of " << mesh.nFaces()
-        << " of which " << nInternalFaces << " are internal" << endl;
-}
-
-
-void Foam::meshTriangulation::insertTriangles
-(
-    const triFaceList& faceTris,
-    const label facei,
-    const label regionI,
-    const bool reverse,
-
-    List<labelledTri>& triangles,
-    label& triI
-)
-{
-    // Copy triangles. Optionally reverse them
-    forAll(faceTris, i)
-    {
-        const triFace& f = faceTris[i];
-
-        labelledTri& tri = triangles[triI];
-
-        if (reverse)
-        {
-            tri[0] = f[0];
-            tri[2] = f[1];
-            tri[1] = f[2];
-        }
-        else
-        {
-            tri[0] = f[0];
-            tri[1] = f[1];
-            tri[2] = f[2];
-        }
-
-        tri.region() = regionI;
-
-        faceMap_[triI] = facei;
-
-        triI++;
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-// Null constructor
-Foam::meshTriangulation::meshTriangulation()
-:
-    triSurface(),
-    nInternalFaces_(0),
-    faceMap_()
-{}
-
-
-// Construct from faces of cells
-Foam::meshTriangulation::meshTriangulation
-(
-    const polyMesh& mesh,
-    const label internalFacesPatch,
-    const boolList& includedCell,
-    const bool faceCentreDecomposition
-)
-:
-    triSurface(),
-    nInternalFaces_(0),
-    faceMap_()
-{
-    const faceList& faces = mesh.faces();
-    const pointField& points = mesh.points();
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
-
-    // All faces to be triangulated.
-    boolList faceIsCut;
-    label nFaces, nInternalFaces;
-
-    getFaces
-    (
-        mesh,
-        includedCell,
-        faceIsCut,
-        nFaces,
-        nInternalFaces
-    );
-
-
-    // Find upper limit for number of triangles
-    // (can be less if triangulation fails)
-    label nTotTri = 0;
-
-    if (faceCentreDecomposition)
-    {
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei])
-            {
-                nTotTri += faces[facei].size();
-            }
-        }
-    }
-    else
-    {
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei])
-            {
-                nTotTri += faces[facei].nTriangles(points);
-            }
-        }
-    }
-    Pout<< "nTotTri : " << nTotTri << endl;
-
-
-    // Storage for new and old points (only for faceCentre decomposition;
-    // for triangulation uses only existing points)
-    pointField newPoints;
-
-    if (faceCentreDecomposition)
-    {
-        newPoints.setSize(mesh.nPoints() + faces.size());
-        forAll(mesh.points(), pointi)
-        {
-            newPoints[pointi] = mesh.points()[pointi];
-        }
-        // Face centres
-        forAll(faces, facei)
-        {
-            newPoints[mesh.nPoints() + facei] = mesh.faceCentres()[facei];
-        }
-    }
-
-    // Storage for all triangles
-    List<labelledTri> triangles(nTotTri);
-    faceMap_.setSize(nTotTri);
-    label triI = 0;
-
-
-    if (faceCentreDecomposition)
-    {
-        // Decomposition around face centre
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        // Triangulate internal faces
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei] && isInternalFace(mesh, includedCell, facei))
-            {
-                // Face was internal to the mesh and will be 'internal' to
-                // the surface.
-
-                // Triangulate face
-                const face& f = faces[facei];
-
-                forAll(f, fp)
-                {
-                    faceMap_[triI] = facei;
-
-                    triangles[triI++] =
-                        labelledTri
-                        (
-                            f[fp],
-                            f.nextLabel(fp),
-                            mesh.nPoints() + facei,     // face centre
-                            internalFacesPatch
-                        );
-                }
-            }
-        }
-        nInternalFaces_ = triI;
-
-
-        // Triangulate external faces
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei] && !isInternalFace(mesh, includedCell, facei))
-            {
-                // Face will become outside of the surface.
-
-                label patchi = -1;
-                bool reverse = false;
-
-                if (mesh.isInternalFace(facei))
-                {
-                    patchi = internalFacesPatch;
-
-                    // Check orientation. Check which side of the face gets
-                    // included (note: only one side is).
-                    if (includedCell[mesh.faceOwner()[facei]])
-                    {
-                        reverse = false;
-                    }
-                    else
-                    {
-                        reverse = true;
-                    }
-                }
-                else
-                {
-                    // Face was already outside so orientation ok.
-
-                    patchi = patches.whichPatch(facei);
-
-                    reverse = false;
-                }
-
-
-                // Triangulate face
-                const face& f = faces[facei];
-
-                if (reverse)
-                {
-                    forAll(f, fp)
-                    {
-                        faceMap_[triI] = facei;
-
-                        triangles[triI++] =
-                            labelledTri
-                            (
-                                f.nextLabel(fp),
-                                f[fp],
-                                mesh.nPoints() + facei,     // face centre
-                                patchi
-                            );
-                    }
-                }
-                else
-                {
-                    forAll(f, fp)
-                    {
-                        faceMap_[triI] = facei;
-
-                        triangles[triI++] =
-                            labelledTri
-                            (
-                                f[fp],
-                                f.nextLabel(fp),
-                                mesh.nPoints() + facei,     // face centre
-                                patchi
-                            );
-                    }
-                }
-            }
-        }
-    }
-    else
-    {
-        // Triangulation using existing vertices
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        // Triangulate internal faces
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei] && isInternalFace(mesh, includedCell, facei))
-            {
-                // Face was internal to the mesh and will be 'internal' to
-                // the surface.
-
-                // Triangulate face. Fall back to naive triangulation if failed.
-                faceTriangulation faceTris(points, faces[facei], true);
-
-                if (faceTris.empty())
-                {
-                    WarningInFunction
-                        << "Could not find triangulation for face " << facei
-                        << " vertices " << faces[facei] << " coords "
-                        << IndirectList<point>(points, faces[facei])() << endl;
-                }
-                else
-                {
-                    // Copy triangles. Make them internalFacesPatch
-                    insertTriangles
-                    (
-                        faceTris,
-                        facei,
-                        internalFacesPatch,
-                        false,                  // no reverse
-
-                        triangles,
-                        triI
-                    );
-                }
-            }
-        }
-        nInternalFaces_ = triI;
-
-
-        // Triangulate external faces
-        forAll(faceIsCut, facei)
-        {
-            if (faceIsCut[facei] && !isInternalFace(mesh, includedCell, facei))
-            {
-                // Face will become outside of the surface.
-
-                label patchi = -1;
-                bool reverse = false;
-
-                if (mesh.isInternalFace(facei))
-                {
-                    patchi = internalFacesPatch;
-
-                    // Check orientation. Check which side of the face gets
-                    // included (note: only one side is).
-                    if (includedCell[mesh.faceOwner()[facei]])
-                    {
-                        reverse = false;
-                    }
-                    else
-                    {
-                        reverse = true;
-                    }
-                }
-                else
-                {
-                    // Face was already outside so orientation ok.
-
-                    patchi = patches.whichPatch(facei);
-
-                    reverse = false;
-                }
-
-                // Triangulate face
-                faceTriangulation faceTris(points, faces[facei], true);
-
-                if (faceTris.empty())
-                {
-                    WarningInFunction
-                        << "Could not find triangulation for face " << facei
-                        << " vertices " << faces[facei] << " coords "
-                        << IndirectList<point>(points, faces[facei])() << endl;
-                }
-                else
-                {
-                    // Copy triangles. Optionally reverse them
-                    insertTriangles
-                    (
-                        faceTris,
-                        facei,
-                        patchi,
-                        reverse,    // whether to reverse
-
-                        triangles,
-                        triI
-                    );
-                }
-            }
-        }
-    }
-
-    // Shrink if necessary (because of invalid triangulations)
-    triangles.setSize(triI);
-    faceMap_.setSize(triI);
-
-    Pout<< "nInternalFaces_:" << nInternalFaces_ << endl;
-    Pout<< "triangles:" << triangles.size() << endl;
-
-
-    geometricSurfacePatchList surfPatches(patches.size());
-
-    forAll(patches, patchi)
-    {
-        surfPatches[patchi] =
-            geometricSurfacePatch
-            (
-                patches[patchi].physicalType(),
-                patches[patchi].name(),
-                patchi
-            );
-    }
-
-    // Create globally numbered tri surface
-    if (faceCentreDecomposition)
-    {
-        // Use newPoints (mesh points + face centres)
-        triSurface globalSurf(triangles, surfPatches, newPoints);
-
-        // Create locally numbered tri surface
-        triSurface::operator=
-        (
-            triSurface
-            (
-                globalSurf.localFaces(),
-                surfPatches,
-                globalSurf.localPoints()
-            )
-        );
-    }
-    else
-    {
-        // Use mesh points
-        triSurface globalSurf(triangles, surfPatches, mesh.points());
-
-        // Create locally numbered tri surface
-        triSurface::operator=
-        (
-            triSurface
-            (
-                globalSurf.localFaces(),
-                surfPatches,
-                globalSurf.localPoints()
-            )
-        );
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/src/triSurface/meshTriangulation/meshTriangulation.H b/src/triSurface/meshTriangulation/meshTriangulation.H
deleted file mode 100644
index c1f87bc0eb71099776af0d9f02ffcae897a3e4d6..0000000000000000000000000000000000000000
--- a/src/triSurface/meshTriangulation/meshTriangulation.H
+++ /dev/null
@@ -1,152 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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::meshTriangulation
-
-Description
-    Triangulation of mesh faces. Generates (multiply connected) trisurface.
-
-    All patch faces keep their patchID as triangle region.
-    Internal faces get the supplied region number.
-
-SourceFiles
-    meshTriangulation.C
-
-\*---------------------------------------------------------------------------*/
-
-
-#ifndef meshTriangulation_H
-#define meshTriangulation_H
-
-#include "triSurface.H"
-#include "typeInfo.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// Forward declaration of classes
-class polyMesh;
-class primitiveMesh;
-
-/*---------------------------------------------------------------------------*\
-                           Class meshTriangulation Declaration
-\*---------------------------------------------------------------------------*/
-
-class meshTriangulation
-:
-    public triSurface
-{
-    // Private data
-
-        //- Number of triangles in this that are internal to the surface.
-        label nInternalFaces_;
-
-        //- From triangle to mesh face
-        labelList faceMap_;
-
-    // Private Member Functions
-
-        //- Is face internal to the subset.
-        static bool isInternalFace
-        (
-            const primitiveMesh&,
-            const boolList& includedCell,
-            const label facei
-        );
-
-        //- Find boundary faces of subset.
-        static void getFaces
-        (
-            const primitiveMesh&,
-            const boolList& includedCell,
-            boolList& faceIsCut,
-            label& nFaces,
-            label& nInternalFaces
-        );
-
-        //- Add triangulation of face to triangles. Optionally reverse.
-        void insertTriangles
-        (
-            const triFaceList&,
-            const label facei,
-            const label regionI,
-            const bool reverse,
-
-            List<labelledTri>& triangles,
-            label& triI
-        );
-
-
-public:
-
-    ClassName("meshTriangulation");
-
-
-    // Constructors
-
-        //- Construct null
-        meshTriangulation();
-
-        //- Construct from selected mesh cell and region number to be used
-        //  for triangles resulting from internal faces. (all boundary triangles
-        //  get polyMesh patch id).
-        //  faceCentreDecomposition = true  : decomposition around face centre
-        //                            false : decomposition using
-        //                                    existing vertices
-        meshTriangulation
-        (
-            const polyMesh&,
-            const label internalFacesPatch,
-            const boolList& includedCell,
-            const bool faceCentreDecomposition = false
-        );
-
-
-    // Member Functions
-
-        //- Number of triangles in *this which are internal to the surface
-        label nInternalFaces() const
-        {
-            return nInternalFaces_;
-        }
-
-        //- From triangle to mesh face
-        const labelList& faceMap() const
-        {
-            return faceMap_;
-        }
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/triSurface/tools/labelledTri/sortLabelledTri.H b/src/triSurface/tools/labelledTri/sortLabelledTri.H
deleted file mode 100644
index 593ebe1eaf95b374c78617fbea6513483822535a..0000000000000000000000000000000000000000
--- a/src/triSurface/tools/labelledTri/sortLabelledTri.H
+++ /dev/null
@@ -1,135 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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::sortLabelledTri
-
-Description
-    Helper class which when constructed with a triSurface
-    sorts the faces according to region number (or rather constructs a
-    mapping).
-
-SourceFiles
-    sortLabelledTri.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef sortLabelledTri_H
-#define sortLabelledTri_H
-
-#include "labelList.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-class sortLabelledTri;
-class triSurface;
-
-/*---------------------------------------------------------------------------*\
-                         Class surfAndLabel Declaration
-\*---------------------------------------------------------------------------*/
-
-//- Hold surface and label
-class surfAndLabel
-{
-    const triSurface* surfPtr_;
-
-    label index_;
-
-    // Private Classes
-
-        //- Scalar comparison function used for sorting
-        class less
-        {
-        public:
-
-            inline bool operator()
-            (
-                const surfAndLabel& one,
-                const surfAndLabel& two
-            ) const;
-        };
-
-
-public:
-
-    friend class sortLabelledTri;
-
-    // Constructors
-
-        //- Construct null
-        surfAndLabel()
-        :
-            surfPtr_(nullptr),
-            index_(-1)
-        {}
-
-        //- Construct from surface and index
-        surfAndLabel(const triSurface& surf, const label index)
-        :
-            surfPtr_(&surf),
-            index_(index)
-        {}
-};
-
-
-/*---------------------------------------------------------------------------*\
-                           Class sortLabelledTri Declaration
-\*---------------------------------------------------------------------------*/
-
-class sortLabelledTri
-:
-    public List<surfAndLabel>
-{
-
-public:
-
-    // Constructors
-
-        //- Construct from surface, sorting the faces according to patch
-        sortLabelledTri(const triSurface&);
-
-
-    // Member Functions
-
-        // Access
-
-            //- Set the labelList to those of sorted point indices
-            void indices(labelList&) const;
-
-            //- Return the list of sorted point indices
-            labelList indices() const;
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/triSurface/triSurface/interfaces/STL/writeSTL.C b/src/triSurface/triSurface/interfaces/STL/writeSTL.C
index ffa4eb826ad3c6128d286387c4a4243c8291148a..3532b006ab972688d37868b7d5d03fb7c0e5c4d0 100644
--- a/src/triSurface/triSurface/interfaces/STL/writeSTL.C
+++ b/src/triSurface/triSurface/interfaces/STL/writeSTL.C
@@ -26,8 +26,6 @@ License
 #include "triSurface.H"
 #include "STLtriangle.H"
 #include "primitivePatch.H"
-#include "HashTable.H"
-#include "hashSignedLabel.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
diff --git a/src/triSurface/triSurface/interfaces/VTK/readVTK.C b/src/triSurface/triSurface/interfaces/VTK/readVTK.C
index f4f026979c4e5d7dd5f603be05bbc5ba8a54e3ba..b413641102d4754d23cda88562680cecce0221cb 100644
--- a/src/triSurface/triSurface/interfaces/VTK/readVTK.C
+++ b/src/triSurface/triSurface/interfaces/VTK/readVTK.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,7 +38,7 @@ bool Foam::triSurface::readVTK(const fileName& fName)
     // Read (and triangulate) point, faces, zone info
     fileFormats::VTKsurfaceFormat<triFace> surf(fName);
 
-    List<labelledTri> tris(surf.faces().size());
+    List<labelledTri> tris(surf.size());
     forAll(tris, i)
     {
         const triFace& f = surf[i];
@@ -67,11 +67,7 @@ bool Foam::triSurface::readVTK(const fileName& fName)
 
             patches[zoneI] = geometricSurfacePatch
             (
-                (
-                    zone.geometricType() != word::null
-                  ? zone.geometricType()
-                  : "empty"
-                ),
+                zone.geometricType().size() ? zone.geometricType() : "empty",
                 regionName,
                 zoneI
             );
@@ -86,6 +82,7 @@ bool Foam::triSurface::readVTK(const fileName& fName)
     else
     {
         // Add single patch
+        patches.setSize(1);
         patches[0] = geometricSurfacePatch("empty", "patch0", 0);
 
         // Triangle regions already set to 0
@@ -97,7 +94,7 @@ bool Foam::triSurface::readVTK(const fileName& fName)
     (
         tris.xfer(),
         patches,
-        xferCopy<List<point>>(surf.points())
+        surf.xferPoints()
     );
 
     return true;
diff --git a/src/triSurface/triSurface/surfacePatch/surfacePatchIOList.C b/src/triSurface/triSurface/surfacePatch/surfacePatchIOList.C
deleted file mode 100644
index be055638f6c5be9e825928160c6f4f2b6767dce6..0000000000000000000000000000000000000000
--- a/src/triSurface/triSurface/surfacePatch/surfacePatchIOList.C
+++ /dev/null
@@ -1,160 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 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 "surfacePatchIOList.H"
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-namespace Foam
-{
-defineTypeNameAndDebug(surfacePatchIOList, 0);
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-// Construct from IOObject
-Foam::surfacePatchIOList::surfacePatchIOList
-(
-    const IOobject& io
-)
-:
-    surfacePatchList(),
-    regIOobject(io)
-{
-    Foam::string functionName =
-        "surfacePatchIOList::surfacePatchIOList"
-        "(const IOobject& io)";
-
-
-    if
-    (
-        readOpt() == IOobject::MUST_READ
-     || readOpt() == IOobject::MUST_READ_IF_MODIFIED
-    )
-    {
-        // Warn for MUST_READ_IF_MODIFIED
-        warnNoRereading<surfacePatchIOList>();
-
-        surfacePatchList& patches = *this;
-
-        // read polyPatchList
-        Istream& is = readStream(typeName);
-
-        PtrList<entry> patchEntries(is);
-        patches.setSize(patchEntries.size());
-
-        label facei = 0;
-
-        forAll(patches, patchi)
-        {
-            const dictionary& dict = patchEntries[patchi].dict();
-
-            label patchSize = readLabel(dict.lookup("nFaces"));
-            label startFacei = readLabel(dict.lookup("startFace"));
-
-            patches[patchi] =
-                surfacePatch
-                (
-                    word(dict.lookup("geometricType")),
-                    patchEntries[patchi].keyword(),
-                    patchSize,
-                    startFacei,
-                    patchi
-                );
-
-
-            if (startFacei != facei)
-            {
-                FatalErrorInFunction
-                    << "Patches are not ordered. Start of patch " << patchi
-                    << " does not correspond to sum of preceding patches."
-                    << endl
-                    << "while reading " << io.objectPath()
-                    << exit(FatalError);
-            }
-
-            facei += patchSize;
-        }
-
-        // Check state of IOstream
-        is.check(functionName.c_str());
-
-        close();
-    }
-}
-
-// Construct from IOObject
-Foam::surfacePatchIOList::surfacePatchIOList
-(
-    const IOobject& io,
-    const surfacePatchList& patches
-)
-:
-    surfacePatchList(patches),
-    regIOobject(io)
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::surfacePatchIOList::~surfacePatchIOList()
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-
-// writeData member function required by regIOobject
-bool Foam::surfacePatchIOList::writeData(Ostream& os) const
-{
-    os  << *this;
-    return os.good();
-}
-
-
-// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
-
-Foam::Ostream& Foam::operator<<(Ostream& os, const surfacePatchIOList& patches)
-{
-    os  << patches.size() << nl << token::BEGIN_LIST;
-
-    forAll(patches, patchi)
-    {
-        patches[patchi].writeDict(os);
-    }
-
-    os  << token::END_LIST;
-
-    return os;
-}
-
-
-// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
-
-
-// * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
-
-// ************************************************************************* //
diff --git a/src/triSurface/triSurface/triSurface.H b/src/triSurface/triSurface/triSurface.H
index c892fb22c0e19d6fa55e4f02cc5774dc8bc2ca67..cfa253fbb3c9939273d123b5a58b69124ce4a2b7 100644
--- a/src/triSurface/triSurface/triSurface.H
+++ b/src/triSurface/triSurface/triSurface.H
@@ -270,7 +270,7 @@ public:
             const bool reuse
         );
 
-        //- Construct from triangles, patches, points.
+        //- Construct by transferring (triangles, points) components.
         triSurface
         (
             const Xfer<List<labelledTri>>&,
@@ -278,7 +278,7 @@ public:
             const Xfer<List<point>>&
         );
 
-        //- Construct from triangles, points. Set patchnames to default.
+        //- Construct from triangles, points. Set patch names to default.
         triSurface(const List<labelledTri>&, const pointField&);
 
         //- Construct from triangles, points. Set region to 0 and default
@@ -299,7 +299,7 @@ public:
 
 
     //- Destructor
-    ~triSurface();
+    virtual ~triSurface();
 
         void clearOut();
 
@@ -335,6 +335,25 @@ public:
             const labelList& edgeOwner() const;
 
 
+            //- Face area vectors (normals)
+            inline const vectorField& Sf() const
+            {
+                return ParentType::faceAreas();
+            }
+
+            //- Face area magnitudes
+            inline const scalarField& magSf() const
+            {
+                return ParentType::magFaceAreas();
+            }
+
+            //- Face centres
+            inline const vectorField& Cf() const
+            {
+                return ParentType::faceCentres();
+            }
+
+
         // Edit
 
             //- Move points
diff --git a/tutorials/combustion/fireFoam/LES/compartmentFire/system/controlDict b/tutorials/combustion/fireFoam/LES/compartmentFire/system/controlDict
index 192aa0c9f566c926f63a69c990d27346d55ecbcf..bc6ad0d11e1cb9ef8845f98fb89805c1d2b36a0e 100644
--- a/tutorials/combustion/fireFoam/LES/compartmentFire/system/controlDict
+++ b/tutorials/combustion/fireFoam/LES/compartmentFire/system/controlDict
@@ -59,8 +59,7 @@ functions
     patchInlet_phi
     {
         type                surfaceFieldValue;
-        functionObjectLibs  ("libfieldFunctionObjects.so");
-        enabled             true;
+        libs                ("libfieldFunctionObjects.so");
         writeControl        timeStep;
         writeInterval       20;
         log                 true;
@@ -74,17 +73,16 @@ functions
     wallPanel_Qin
     {
         type                patchProbes;
-        functionObjectLibs  ("libsampling.so");
-        enabled             true;
-        writeControl        outputTime;
+        libs                ("libsampling.so");
+        writeControl        writeTime;
         writeInterval       20;
         log                 true;
         patchName           region0_to_panelRegion_wallPanel;
         probeLocations
         (
-            ( 0.15 0.0 0.01 ) //HF2
-            ( 0.2 0.2 0.01 )  //HF3
-            ( 0.0 0.4 0.01 )  //HF4
+            (0.15 0.0 0.01)  // HF2
+            (0.2  0.2 0.01)  // HF3
+            (0.0  0.4 0.01)  // HF4
         );
         fields              (Qin);
     }
@@ -92,19 +90,18 @@ functions
     inletQr_Qin
     {
         type                patchProbes;
-        functionObjectLibs ("libsampling.so");
-        enabled            true;
-        writeControl       outputTime;
-        writeInterval      20;
-        log                true;
-        patchName          inlet;
+        libs                ("libsampling.so");
+        writeControl        writeTime;
+        writeInterval       20;
+        log                 true;
+        patchName           inlet;
         probeLocations
         (
-            ( 0.0 0.0 0.0 )     //HF1
-            ( 0.02 0.0 0.02 )   //HF2
-            ( 0.02 0.0 -0.02 )  //HF3
-            ( -0.02 0.0 0.02 )  //HF4
-            ( -0.02 0.0 -0.02 ) //HF5
+            ( 0.0  0.0  0.0 ) // HF1
+            ( 0.02 0.0  0.02) // HF2
+            ( 0.02 0.0 -0.02) // HF3
+            (-0.02 0.0  0.02) // HF4
+            (-0.02 0.0 -0.02) // HF5
         );
         fields    (Qr Qin);
     }
@@ -112,10 +109,9 @@ functions
     thermoCouple
     {
         type            thermoCoupleProbes;
-
-        functionObjectLibs      ("libutilityFunctionObjects.so");
-        writeControl           timeStep;
-        writeInterval          100;
+        libs            ("libutilityFunctionObjects.so");
+        writeControl    timeStep;
+        writeInterval   100;
 
         solver          Euler;
         absTol          1e-4;
@@ -123,13 +119,13 @@ functions
 
         interpolationScheme cell;
 
-        // thermocouple properties
+        // Thermocouple properties
         rho             8908;
         Cp              440;
         d               1e-3;
         epsilon         0.9;
 
-        radName         G;
+        radiationField  G;
 
         probeLocations
         (
@@ -157,17 +153,17 @@ functions
     probes_O2
     {
         type                probes;
-        functionObjectLibs ("libsampling.so");
-        writeControl       outputTime;
-        writeInterval      30;
+        libs                ("libsampling.so");
+        writeControl        writeTime;
+        writeInterval       30;
         probeLocations
         (
-            (-0.1 0.02 0.0)    //lower Gas
-            (-0.1 0.38 0.0)    //Upper Gas
+            (-0.1 0.02 0.0)    // Lower Gas
+            (-0.1 0.38 0.0)    // Upper Gas
         );
         fields  (O2);
-
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/runtimePostProcessing b/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/runtimePostProcessing
index b331e95ac0a63fa786de9c697ca06ff730dfcaa2..8ba9bf34dae55b76848e2029516cc3ccc4d4ea47 100644
--- a/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/runtimePostProcessing
+++ b/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/runtimePostProcessing
@@ -1,8 +1,8 @@
 postPro1
 {
     type            runTimePostProcessing;
-    functionObjectLibs ("librunTimePostProcessing.so");
-    outputControl   outputTime;
+    libs            ("librunTimePostProcessing.so");
+    writeControl    writeTime;
     output
     {
         name            image;
@@ -51,7 +51,7 @@ postPro1
     {
         streamline
         {
-            type            line;
+            type            functionObjectLine;
             functionObject  streamLines;
             representation  tube;
             visible         yes;
@@ -89,7 +89,7 @@ postPro1
         }
         cuttingPlane1
         {
-            type            functionObject;
+            type            functionObjectSurface;
             functionObject  cuttingPlane;
             colourMap       blueWhiteRed;
             representation  glyph;
diff --git a/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/streamLines b/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/streamLines
index 95a07f82e26e87504589b308d8e3e371027eb0ea..83ec2e4018a95f2cfe10187654278a0170a84ba9 100644
--- a/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/streamLines
+++ b/tutorials/incompressible/pisoFoam/LES/motorBike/motorBike/system/streamLines
@@ -23,13 +23,13 @@ streamLines
     trackForward    true;
 
     // Names of fields to sample. Should contain above velocity field!
-    fields (p U);
+    fields          (p U);
 
     // Steps particles can travel before being removed
     lifeTime        10000;
 
     // Number of steps per cell (estimate). Set to 1 to disable subcycling.
-    nSubCycle 5;
+    nSubCycle       5;
 
     // Cloud name to use
     cloudName       particleTracks;
diff --git a/tutorials/incompressible/pisoFoam/les/motorBike/motorBike/system/runtimePostProcessing b/tutorials/incompressible/pisoFoam/les/motorBike/motorBike/system/runtimePostProcessing
deleted file mode 100644
index ebdeafbdc095d9a9e830a82e81a9047163afb9f3..0000000000000000000000000000000000000000
--- a/tutorials/incompressible/pisoFoam/les/motorBike/motorBike/system/runtimePostProcessing
+++ /dev/null
@@ -1,122 +0,0 @@
-postPro1
-{
-    type            runTimePostProcessing;
-    libs            ("librunTimePostProcessing.so");
-    writeControl    writeTime;
-    output
-    {
-        name            image;
-        width           2000;
-        height          1200;
-    }
-    camera
-    {
-        // If camera is moving, optionally provide start and end times
-        // startPosition    0.2;
-        // endPosition      0.75;
-
-        // Total number of frames to generate
-        nFrameTotal         1;
-
-        // Parallel projection flag
-        parallelProjection  no;
-
-        // Camera mode:
-        // - flightPath: define flight path
-        // - static: fixed position
-        mode                static;
-        staticCoeffs
-        {
-            clipBox         (-0.2 -0.2 0)(1.65 0.2 1.25); // optional
-            focalPoint      (1.2 1.1 0.2);
-            up              (0 0 1);
-            lookDir         (2.4 4.0 -1.5);
-        }
-    }
-
-    // Default colours
-    // - If select to colourBy colour, these values are used unless
-    // they are locally overriden
-    colours
-    {
-        background      (1 1 1);
-        background2     (0 0 1);
-        text            (0 0 0);
-        edge            (1 0 0);
-        surface         (0.5 0.5 0.5);
-        line            (1 0 0);
-    }
-    // Line data
-    lines
-    {
-        streamline
-        {
-            type            line;
-            functionObject  streamLines;
-            representation  tube;
-            visible         yes;
-            tubeRadius      0.01;
-            colourBy        field;
-            fieldName       U;
-            range           (0 20);
-            opacity         1;
-            scalarBar
-            {
-                visible         yes;
-                position        (0.8 0.1);
-                vertical        yes;
-                fontSize        16;
-                title           "velocity / [m/s]";
-                labelFormat     "%6.2f";
-                numberOfLabels  5;
-            }
-        }
-    }
-
-    // Surface data
-    surfaces
-    {
-        surface1
-        {
-            type            geometry;
-            files           ("$FOAM_CASE/constant/triSurface/motorBike.obj.gz");
-            renderMode      phong;
-            representation  surface;
-            edgeColour      (0 0 0);
-            visible         yes;
-            featureEdges    yes;
-            opacity         1;
-        }
-        cuttingPlane1
-        {
-            type            functionObject;
-            functionObject  cuttingPlane;
-            colourMap       blueWhiteRed;
-            representation  glyph;
-            maxGlyphLength  0.1;
-            visible         yes;
-            featureEdges    no;
-            colourBy        field;
-            fieldName       U;
-            range           (0 30);
-            opacity         1;
-            scalarBar
-            {
-                visible         no;
-            }
-        }
-    }
-
-    // Text data
-    text
-    {
-        text1
-        {
-            string          "Motorbike";
-            position        (0.1 0.05);
-            size            72;
-            bold            yes;
-            visible         yes;
-        }
-    }
-}
diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/controlDict b/tutorials/incompressible/simpleFoam/motorBike/system/controlDict
index 5678be2ee3f8aed358a484f2c612885235cd0972..d728f0be9c3d7a85c8ae660c9530b9b9a66386b6 100644
--- a/tutorials/incompressible/simpleFoam/motorBike/system/controlDict
+++ b/tutorials/incompressible/simpleFoam/motorBike/system/controlDict
@@ -50,6 +50,7 @@ functions
     #include "wallBoundedStreamLines"
     #include "cuttingPlane"
     #include "forceCoeffs"
+    #include "ensightWrite"
 }
 
 
diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite b/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite
new file mode 100644
index 0000000000000000000000000000000000000000..34e7b14d71b4f1e12eea04845ba07454a9f3264b
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/motorBike/system/ensightWrite
@@ -0,0 +1,17 @@
+// -*- C++ -*-
+// Minimal example of using the ensight write function object.
+// Many more options possible
+ensightWrite
+{
+    type    ensightWrite;
+    libs    ("libutilityFunctionObjects.so");
+    log     true;
+
+    // Fields to output (words or regex)
+    fields  (U p "(k|epsilon|omega)");
+
+    writeControl writeTime;
+    writeIterval 1;
+}
+
+// ************************************************************************* //
diff --git a/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/0/alpha.water.org b/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/0/alpha.water.orig
similarity index 100%
rename from tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/0/alpha.water.org
rename to tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/0/alpha.water.orig
diff --git a/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/Allclean b/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/Allclean
index 1029c96a711f94273fed8e08806babd7d1c2200e..9cbb0c1a827e7b2818c31d1b389e118c11e55922 100755
--- a/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/Allclean
+++ b/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/Allclean
@@ -6,7 +6,7 @@ cd ${0%/*} || exit 1    # Run from this directory
 
 cleanCase
 
-rm system/blockMeshDict
-rm 0/alpha.water
+rm -f system/blockMeshDict
+rm -f 0/alpha.water
 
 # ----------------------------------------------------------------- end-of-file
diff --git a/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/system/pachuka.m4 b/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/system/pachuka.m4
old mode 100755
new mode 100644
index baa1f4a96ae17b095ebab0977719c307a11100a7..b817fb48d749305f436d1ea92b0613e646e3433f
--- a/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/system/pachuka.m4
+++ b/tutorials/multiphase/MPPICInterFoam/twoPhasePachuka/system/pachuka.m4
@@ -851,36 +851,34 @@ edges
     arc 73 75 (0.0 Rd3 Hl3)
     arc 69 71 (0.0 qRt Hl3)
 
-    arc 68 69 (qRt 0.0 Hl3)
     arc 76 77 (Rt 0.0 Hl3)
-
     arc 78 79 (-Rt 0.0 Hl3)
-    arc 76 78 (0.0 -Rt Hl3)
 
+    arc 76 78 (0.0 -Rt Hl3)
     arc 77 79 (0.0 Rt Hl3)
-    arc 84 85 (Rd 0.0 Ht)
 
+    arc 84 85 (Rd 0.0 Ht)
     arc 86 87 (-Rd 0.0 Ht)
-    arc 84 86 (0.0 -Rd Ht)
 
+    arc 84 86 (0.0 -Rd Ht)
     arc 85 87 (0.0 Rd Ht)
-    arc 92 93 (Rd3 0.0 Ht)
 
+    arc 92 93 (Rd3 0.0 Ht)
     arc 94 95 (-Rd3 0.0 Ht)
-    arc 94 92 (0.0 -Rd3 Ht)
 
+    arc 94 92 (0.0 -Rd3 Ht)
     arc 93 95 (0.0 Rd3 Ht)
-    arc 88 89 (qRt 0.0 Ht)
 
+    arc 88 89 (qRt 0.0 Ht)
     arc 90 91 (-qRt 0.0 Ht)
-    arc 88 90 (0.0 -qRt Ht)
 
+    arc 88 90 (0.0 -qRt Ht)
     arc 89 91 (0.0 qRt Ht)
-    arc 96 97 (Rt 0.0 Ht)
 
+    arc 96 97 (Rt 0.0 Ht)
     arc 98 99 (-Rt 0.0 Ht)
-    arc 98 96 (0.0 -Rt Ht)
 
+    arc 98 96 (0.0 -Rt Ht)
     arc 97 99 (0.0 Rt Ht)
 );
 
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/g b/tutorials/multiphase/interDyMFoam/RAS/damBreakWithObstacle/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/g
rename to tutorials/multiphase/interDyMFoam/RAS/damBreakWithObstacle/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/U b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/U
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/U
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/alpha.water b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/alpha.water
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/alpha.water
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/alpha.water
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/k b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/k
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/k
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/k
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/nut b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/nut
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/nut
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/nut
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/omega b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/omega
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/omega
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/omega
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/p_rgh b/tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/0.orig/p_rgh
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/0.orig/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/Allclean b/tutorials/multiphase/interDyMFoam/RAS/motorBike/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/Allclean
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/Allrun b/tutorials/multiphase/interDyMFoam/RAS/motorBike/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/Allrun
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/Allrun.pre b/tutorials/multiphase/interDyMFoam/RAS/motorBike/Allrun.pre
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/Allrun.pre
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/Allrun.pre
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/constant/g b/tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/constant/g
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/constant/transportProperties b/tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/constant/triSurface/README b/tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/triSurface/README
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/constant/triSurface/README
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/triSurface/README
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/turbulenceProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/constant/turbulenceProperties
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/constant/turbulenceProperties
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/blockMeshDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/blockMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/blockMeshDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/blockMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict_nextWrite b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict_nextWrite
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict_nextWrite
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict_nextWrite
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict_run b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict_run
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/controlDict_run
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/controlDict_run
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/decomposeParDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/decomposeParDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/decomposeParDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/fvSchemes b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/fvSchemes
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/fvSchemes
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/fvSchemes
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/fvSolution b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/meshQualityDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/meshQualityDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/meshQualityDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/meshQualityDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/minMax b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/minMax
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/minMax
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/minMax
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/snappyHexMeshDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/snappyHexMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/snappyHexMeshDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/snappyHexMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/ras/motorBike/system/surfaceFeatureExtractDict b/tutorials/multiphase/interDyMFoam/RAS/motorBike/system/surfaceFeatureExtractDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/ras/motorBike/system/surfaceFeatureExtractDict
rename to tutorials/multiphase/interDyMFoam/RAS/motorBike/system/surfaceFeatureExtractDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/alpha.water.orig
deleted file mode 100644
index 0a30f6e7e0765778415db83c9943c5350310ecad..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/alpha.water.orig
+++ /dev/null
@@ -1,37 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    front
-    {
-        type            empty;
-    }
-    back
-    {
-        type            empty;
-    }
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/alpha.water.orig
deleted file mode 100644
index 0a30f6e7e0765778415db83c9943c5350310ecad..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/alpha.water.orig
+++ /dev/null
@@ -1,37 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    front
-    {
-        type            empty;
-    }
-    back
-    {
-        type            empty;
-    }
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/alpha.water.orig
deleted file mode 100644
index a33fee45053ed867220c07ed75450bd8c0770117..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/alpha.water.orig
+++ /dev/null
@@ -1,29 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/turbulenceProperties
deleted file mode 100644
index c2c3b28a1b4e8f4a2cae55f58bd61f9b1a67b488..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/turbulenceProperties
+++ /dev/null
@@ -1,21 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "constant";
-    object      turbulenceProperties;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-simulationType  laminar;
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/alpha.water.orig
deleted file mode 100644
index a33fee45053ed867220c07ed75450bd8c0770117..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/alpha.water.orig
+++ /dev/null
@@ -1,29 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/turbulenceProperties
deleted file mode 100644
index c2c3b28a1b4e8f4a2cae55f58bd61f9b1a67b488..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/turbulenceProperties
+++ /dev/null
@@ -1,21 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "constant";
-    object      turbulenceProperties;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-simulationType  laminar;
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/alpha.water.orig
deleted file mode 100644
index a33fee45053ed867220c07ed75450bd8c0770117..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/alpha.water.orig
+++ /dev/null
@@ -1,29 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/Allrun b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/Allrun
deleted file mode 100755
index c1f08e0d5a1992512f06dfb64a4de45e49cd36d0..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/Allrun
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-cd ${0%/*} || exit 1    # Run from this directory
-
-# Source tutorial run functions
-. $WM_PROJECT_DIR/bin/tools/RunFunctions
-
-m4 system/blockMeshDict.m4 > system/blockMeshDict
-runApplication blockMesh
-\cp 0/alpha.water.orig 0/alpha.water
-runApplication setFields
-runApplication $(getApplication)
-
-#------------------------------------------------------------------------------
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/turbulenceProperties
deleted file mode 100644
index 5eec04267266e7fd15e7701a875d683d5e658cd9..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/turbulenceProperties
+++ /dev/null
@@ -1,21 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "constant";
-    object      turbulenceProperties;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-simulationType  laminar;
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/decomposeParDict
deleted file mode 100644
index 62f61b7350604b918cd56af06b2b2267ad3da746..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/decomposeParDict
+++ /dev/null
@@ -1,45 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      decomposeParDict;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-numberOfSubdomains 16;
-
-method          hierarchical;
-
-simpleCoeffs
-{
-    n               (2 2 1);
-    delta           0.001;
-}
-
-hierarchicalCoeffs
-{
-    n               (4 2 2);
-    delta           0.001;
-    order           xyz;
-}
-
-manualCoeffs
-{
-    dataFile        "";
-}
-
-distributed     no;
-
-roots           ( );
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSchemes b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSchemes
deleted file mode 100644
index 2d0ecbd0e1b722f6b1f0e60a87e12a449d4db283..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSchemes
+++ /dev/null
@@ -1,51 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      fvSchemes;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-ddtSchemes
-{
-    default         Euler;
-}
-
-gradSchemes
-{
-    default         Gauss linear;
-}
-
-divSchemes
-{
-    div(rhoPhi,U)  Gauss vanLeerV;
-    div(phi,alpha)  Gauss vanLeer;
-    div(phirb,alpha) Gauss vanLeer;
-    div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
-}
-
-laplacianSchemes
-{
-    default         Gauss linear corrected;
-}
-
-interpolationSchemes
-{
-    default         linear;
-}
-
-snGradSchemes
-{
-    default         corrected;
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSolution b/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSolution
deleted file mode 100644
index 97f5144002828f54554f334ab6cdb9a0bc8ba7f4..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/fvSolution
+++ /dev/null
@@ -1,100 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      fvSolution;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-solvers
-{
-    alpha.water
-    {
-        nAlphaCorr      1;
-        nAlphaSubCycles 3;
-        cAlpha          1.5;
-    }
-
-    pcorr
-    {
-        solver          PCG;
-        preconditioner
-        {
-            preconditioner  GAMG;
-            tolerance       1e-05;
-            relTol          0;
-            smoother        DICGaussSeidel;
-            cacheAgglomeration no;
-        }
-
-        tolerance       1e-05;
-        relTol          0;
-        maxIter         100;
-    }
-
-    p_rgh
-    {
-        solver          GAMG;
-        tolerance       1e-08;
-        relTol          0.01;
-        smoother        DIC;
-    }
-
-    p_rghFinal
-    {
-        solver          PCG;
-        preconditioner
-        {
-            preconditioner  GAMG;
-            tolerance       2e-09;
-            relTol          0;
-            nVcycles        2;
-            smoother        DICGaussSeidel;
-            nPreSweeps      2;
-        }
-
-        tolerance       2e-09;
-        relTol          0;
-        maxIter         20;
-    }
-
-    U
-    {
-        solver          smoothSolver;
-        smoother        GaussSeidel;
-        tolerance       1e-06;
-        relTol          0;
-        nSweeps         1;
-    }
-}
-
-PIMPLE
-{
-    momentumPredictor no;
-    nCorrectors     2;
-    nNonOrthogonalCorrectors 0;
-    correctPhi      no;
-
-    pRefPoint       (0 0 0.15);
-    pRefValue       1e5;
-}
-
-relaxationFactors
-{
-    equations
-    {
-        "U.*"           1;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/alpha.water.orig
deleted file mode 100644
index a33fee45053ed867220c07ed75450bd8c0770117..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/alpha.water.orig
+++ /dev/null
@@ -1,29 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    object      alpha.water;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 0 0 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    walls
-    {
-        type            zeroGradient;
-    }
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/g b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/g
deleted file mode 100644
index abc208807166736c3e6e79b6af09a77709e4c8b2..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/g
+++ /dev/null
@@ -1,22 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       uniformDimensionedVectorField;
-    location    "constant";
-    object      g;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [0 1 -2 0 0 0 0];
-value           (0 0 -9.81);
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/turbulenceProperties
deleted file mode 100644
index 5eec04267266e7fd15e7701a875d683d5e658cd9..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/turbulenceProperties
+++ /dev/null
@@ -1,21 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "constant";
-    object      turbulenceProperties;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-simulationType  laminar;
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/controlDict b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/controlDict
deleted file mode 100644
index 9d279a2f7e9134e6343625d8ac3e1620ffead03a..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/controlDict
+++ /dev/null
@@ -1,56 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      controlDict;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-application     interDyMFoam;
-
-startFrom       startTime;
-
-startTime       0;
-
-stopAt          endTime;
-
-endTime         1;
-
-deltaT          0.0001;
-
-writeControl    adjustableRunTime;
-
-writeInterval   0.01;
-
-purgeWrite      0;
-
-writeFormat     ascii;
-
-writePrecision  6;
-
-writeCompression off;
-
-timeFormat      general;
-
-timePrecision   6;
-
-runTimeModifiable true;
-
-adjustTimeStep  yes;
-
-maxCo           0.5;
-maxAlphaCo      0.5;
-
-maxDeltaT       1;
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/decomposeParDict
deleted file mode 100644
index 4b8c326537f15ea0b64d16cdabaea4e65302fae4..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/decomposeParDict
+++ /dev/null
@@ -1,45 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      decomposeParDict;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-numberOfSubdomains 16;
-
-method          hierarchical;
-
-simpleCoeffs
-{
-    n               (2 2 1);
-    delta           0.001;
-}
-
-hierarchicalCoeffs
-{
-    n               (4 2 2);
-    delta           0.001;
-    order           xyz;
-}
-
-manualCoeffs
-{
-    dataFile        "";
-}
-
-distributed     no;
-
-roots           ( );
-
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/fvSchemes b/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/fvSchemes
deleted file mode 100644
index 2d0ecbd0e1b722f6b1f0e60a87e12a449d4db283..0000000000000000000000000000000000000000
--- a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/fvSchemes
+++ /dev/null
@@ -1,51 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       dictionary;
-    location    "system";
-    object      fvSchemes;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-ddtSchemes
-{
-    default         Euler;
-}
-
-gradSchemes
-{
-    default         Gauss linear;
-}
-
-divSchemes
-{
-    div(rhoPhi,U)  Gauss vanLeerV;
-    div(phi,alpha)  Gauss vanLeer;
-    div(phirb,alpha) Gauss vanLeer;
-    div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
-}
-
-laplacianSchemes
-{
-    default         Gauss linear corrected;
-}
-
-interpolationSchemes
-{
-    default         linear;
-}
-
-snGradSchemes
-{
-    default         corrected;
-}
-
-// ************************************************************************* //
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/U b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/alpha.water.orig
index 1a4430bade5d5db39524136a26112633745e70a2..0a30f6e7e0765778415db83c9943c5350310ecad 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/Allclean b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/Allrun b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/Allrun
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/g b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/g
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/turbulenceProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/constant/turbulenceProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/constant/turbulenceProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/blockMeshDict.m4 b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/blockMeshDict.m4
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/blockMeshDict.m4
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/blockMeshDict.m4
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/controlDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/decomposeParDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/decomposeParDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/decomposeParDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/fvSchemes
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/fvSchemes
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/fvSchemes
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/U b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/alpha.water.orig
index 1a4430bade5d5db39524136a26112633745e70a2..0a30f6e7e0765778415db83c9943c5350310ecad 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/Allclean b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/Allrun b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/Allrun
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/g b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/g
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/turbulenceProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/constant/turbulenceProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/constant/turbulenceProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/blockMeshDict.m4 b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/blockMeshDict.m4
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/blockMeshDict.m4
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/blockMeshDict.m4
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/controlDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/decomposeParDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/decomposeParDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/decomposeParDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/fvSchemes
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/fvSchemes
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/fvSchemes
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank2D3DoF/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank2D3DoF/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/U b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/alpha.water.orig
index dcac9db1da134e9baba9e4a0c02e5b6ab625f4d3..a33fee45053ed867220c07ed75450bd8c0770117 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/Allclean b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/Allrun b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/Allrun
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/g b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/g
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/turbulenceProperties
index 5eec04267266e7fd15e7701a875d683d5e658cd9..c2c3b28a1b4e8f4a2cae55f58bd61f9b1a67b488 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/turbulenceProperties
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/constant/turbulenceProperties
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/blockMeshDict.m4 b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/blockMeshDict.m4
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/blockMeshDict.m4
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/blockMeshDict.m4
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/controlDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/decomposeParDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/decomposeParDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/decomposeParDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/fvSchemes
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/fvSchemes
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/fvSchemes
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/U b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/alpha.water.orig
index dcac9db1da134e9baba9e4a0c02e5b6ab625f4d3..a33fee45053ed867220c07ed75450bd8c0770117 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/Allclean b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/Allrun b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/Allrun
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/g b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/g
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/g
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/g
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/turbulenceProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/turbulenceProperties
index 5eec04267266e7fd15e7701a875d683d5e658cd9..c2c3b28a1b4e8f4a2cae55f58bd61f9b1a67b488 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/turbulenceProperties
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/constant/turbulenceProperties
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/blockMeshDict.m4 b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/blockMeshDict.m4
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/blockMeshDict.m4
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/blockMeshDict.m4
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/controlDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/decomposeParDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/decomposeParDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/decomposeParDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/fvSchemes
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/fvSchemes
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/fvSchemes
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D3DoF/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D3DoF/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/U b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/alpha.water.orig
index dcac9db1da134e9baba9e4a0c02e5b6ab625f4d3..a33fee45053ed867220c07ed75450bd8c0770117 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/Allclean b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/6DoF.dat b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/6DoF.dat
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/6DoF.dat
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/6DoF.dat
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/Make/files b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/Make/files
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/Make/files
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/Make/files
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/Make/options b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/Make/options
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/Make/options
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/Make/options
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/gen6DoF.C b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/gen6DoF.C
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/gen6DoF/gen6DoF.C
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/gen6DoF/gen6DoF.C
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/blockMeshDict.m4 b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/blockMeshDict.m4
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/blockMeshDict.m4
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/blockMeshDict.m4
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/controlDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/controlDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/controlDict
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/decomposeParDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/decomposeParDict
index 4b8c326537f15ea0b64d16cdabaea4e65302fae4..62f61b7350604b918cd56af06b2b2267ad3da746 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/decomposeParDict
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/decomposeParDict
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSchemes
index 33f70de79d6c022c65e0336b478ae245640e6642..2d0ecbd0e1b722f6b1f0e60a87e12a449d4db283 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSchemes
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSchemes
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSolution
index a9ed09910a4ff2f0653200fcc93036b6d5680472..97f5144002828f54554f334ab6cdb9a0bc8ba7f4 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSolution
+++ b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/fvSolution
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -33,13 +33,7 @@ solvers
             tolerance       1e-05;
             relTol          0;
             smoother        DICGaussSeidel;
-            nPreSweeps      0;
-            nPostSweeps     2;
-            nFinestSweeps   2;
-            cacheAgglomeration false;
-            nCellsInCoarsestLevel 10;
-            agglomerator    faceAreaPair;
-            mergeLevels     1;
+            cacheAgglomeration no;
         }
 
         tolerance       1e-05;
@@ -53,13 +47,6 @@ solvers
         tolerance       1e-08;
         relTol          0.01;
         smoother        DIC;
-        nPreSweeps      0;
-        nPostSweeps     2;
-        nFinestSweeps   2;
-        cacheAgglomeration true;
-        nCellsInCoarsestLevel 10;
-        agglomerator    faceAreaPair;
-        mergeLevels     1;
     }
 
     p_rghFinal
@@ -73,12 +60,6 @@ solvers
             nVcycles        2;
             smoother        DICGaussSeidel;
             nPreSweeps      2;
-            nPostSweeps     2;
-            nFinestSweeps   2;
-            cacheAgglomeration true;
-            nCellsInCoarsestLevel 10;
-            agglomerator    faceAreaPair;
-            mergeLevels     1;
         }
 
         tolerance       2e-09;
diff --git a/tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/sloshingTank3D6DoF/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/sloshingTank3D6DoF/system/setFieldsDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/U b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/U
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/U
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/U
diff --git a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/alpha.water.orig b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/alpha.water.orig
index dcac9db1da134e9baba9e4a0c02e5b6ab625f4d3..a33fee45053ed867220c07ed75450bd8c0770117 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/alpha.water.orig
+++ b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/alpha.water.orig
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
+|  \\    /   O peration     | Version:  dev                                   |
 |   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/p_rgh b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/p_rgh
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/0/p_rgh
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/0/p_rgh
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/Allclean b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/Allclean
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/Allclean
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/Allclean
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/Allrun b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/Allrun
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/Allrun
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/Allrun
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/constant/dynamicMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/dynamicMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/constant/dynamicMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/transportProperties b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/constant/transportProperties
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/constant/transportProperties
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/constant/transportProperties
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/blockMeshDict b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/blockMeshDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/blockMeshDict
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/blockMeshDict
diff --git a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/controlDict b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/controlDict
index 075affc441dbf8d5bd4dbd772897bb531754ef4d..9d279a2f7e9134e6343625d8ac3e1620ffead03a 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/controlDict
+++ b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/controlDict
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSchemes b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSchemes
index 33f70de79d6c022c65e0336b478ae245640e6642..2d0ecbd0e1b722f6b1f0e60a87e12a449d4db283 100644
--- a/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSchemes
+++ b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSchemes
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  plus                                  |
-|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/fvSolution b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSolution
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/fvSolution
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/fvSolution
diff --git a/tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/setFieldsDict b/tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/setFieldsDict
similarity index 100%
rename from tutorials/multiphase/interDyMFoam/RAS/testTubeMixer/system/setFieldsDict
rename to tutorials/multiphase/interDyMFoam/laminar/testTubeMixer/system/setFieldsDict
diff --git a/wmake/rules/General/CGAL b/wmake/rules/General/CGAL
index fd1965e656e351412c3d1b34cb53e89cce56e08b..83e8b1df1e9edcf44233b08cc898d79da5ff6797 100644
--- a/wmake/rules/General/CGAL
+++ b/wmake/rules/General/CGAL
@@ -8,6 +8,6 @@ CGAL_INC = \
 CGAL_LIBS = \
     -L$(MPFR_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
     -L$(GMP_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
-    -L$(BOOST_ARCH_PATH)/lib \
-    -L$(CGAL_ARCH_PATH)/lib \
+    -L$(BOOST_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+    -L$(CGAL_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
     -lCGAL