diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H
index 46989a4e648d9cb5cf4a19ef66efaac956a0f1ea..7f94597067f41bc47e63fee58dc5a7ec367ae3d0 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H
@@ -56,7 +56,7 @@ if (doLagrangian)
         {
             autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
 
-            ensightCloud::writePositions
+            ensightOutput::writeCloudPositions
             (
                 mesh,
                 cloudName,
@@ -104,7 +104,7 @@ if (doLagrangian)
                 autoPtr<ensightFile> os =
                     ensCase.newCloudData<scalar>(cloudName, fieldName);
 
-                wrote = ensightCloud::writeCloudField<scalar>
+                wrote = ensightOutput::writeCloudField<scalar>
                 (
                     fieldObject, fieldExists, os
                 );
@@ -114,7 +114,7 @@ if (doLagrangian)
                 autoPtr<ensightFile> os =
                     ensCase.newCloudData<vector>(cloudName, fieldName);
 
-                wrote = ensightCloud::writeCloudField<vector>
+                wrote = ensightOutput::writeCloudField<vector>
                 (
                     fieldObject, fieldExists, os
                 );
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
index 68815b8bfe0c0c7f132f88c635bf0c4abc1bdba8..e90b8462403bb1c1379a4d1d6d19d173ae971983 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C
@@ -99,8 +99,8 @@ Note
 #include "ensightCase.H"
 #include "ensightGeoFile.H"
 #include "ensightMesh.H"
-#include "ensightOutput.H"
 #include "ensightOutputCloud.H"
+#include "ensightOutputVolField.H"
 #include "fvMeshSubsetProxy.H"
 
 // local files
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H
index 98f388d9ecc242d0e9f39996cd7258ffb415089b..f72c74db590ab6e9d7816449895c403463056999 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H
@@ -62,11 +62,11 @@ bool writeVolField
 
     autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
 
-    bool wrote = ensightOutput::writeField<Type>
+    bool wrote = ensightOutput::writeVolField<Type>
     (
         field,
         ensMesh,
-        os,
+        os.ref(),
         nodeValues
     );
 
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H
index 827500474b206a389b29d6bb817906394026c1ef..ce1f9b4d64c46f0a05c29654c99ce0fa95abc921 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H
@@ -55,7 +55,7 @@ if (doLagrangian)
         {
             autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
 
-            ensightCloud::writePositions
+            ensightOutput::writeCloudPositions
             (
                 mesh,
                 cloudName,
@@ -103,7 +103,7 @@ if (doLagrangian)
                 autoPtr<ensightFile> os =
                     ensCase.newCloudData<scalar>(cloudName, fieldName);
 
-                wrote = ensightCloud::writeCloudField<scalar>
+                wrote = ensightOutput::writeCloudField<scalar>
                 (
                     fieldObject, fieldExists, os
                 );
@@ -113,7 +113,7 @@ if (doLagrangian)
                 autoPtr<ensightFile> os =
                     ensCase.newCloudData<vector>(cloudName, fieldName);
 
-                wrote = ensightCloud::writeCloudField<vector>
+                wrote = ensightOutput::writeCloudField<vector>
                 (
                     fieldObject, fieldExists, os
                 );
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
index 4aa572c43646006d4f0c9f6c099aec7bfb027076..c3460ea729a0298964e58f3ae986f7afe87cc0db 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
@@ -94,8 +94,8 @@ Note
 #include "ensightCase.H"
 #include "ensightGeoFile.H"
 #include "ensightParts.H"
-#include "ensightSerialOutput.H"
 #include "ensightOutputCloud.H"
+#include "ensightOutputVolField.H"
 #include "fvMeshSubsetProxy.H"
 
 // local files
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H
index 303f97ad532daf72f82e17c38e683cf6c9a28bf8..017ef31bf00f38b2c65aa8e5df72a6bde0d2b5d2 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H
@@ -61,11 +61,12 @@ bool writeVolField
 
     autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
 
-    bool wrote = ensightSerialOutput::writeField<Type>
+    // Currently serial only
+    bool wrote = ensightOutput::Serial::writeVolField<Type>
     (
         field,
         ensParts,
-        os
+        os.ref()
     );
 
     tfield.clear();
diff --git a/src/conversion/ensight/output/ensightOutput.H b/src/conversion/ensight/output/ensightOutput.H
deleted file mode 100644
index 2649fd5b769b83665cefc77f91d57795b259290f..0000000000000000000000000000000000000000
--- a/src/conversion/ensight/output/ensightOutput.H
+++ /dev/null
@@ -1,164 +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::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
-
-    //- Write field content (component-wise) for the given ensight element type
-    template<template<typename> class FieldContainer, class Type>
-    static void writeFieldContent
-    (
-        const char* key,
-        const FieldContainer<Type>& fld,
-        ensightFile& os
-    );
-
-    //- Write a field of faces values as an indirect list,
-    //  using the face ids from ensightFaces
-    template<class Type>
-    static bool writeFaceField
-    (
-        const Field<Type>& fld,
-        const ensightFaces&,
-        ensightFile& os
-    );
-
-    //- Write a field of faces values as a sublist,
-    //  using the sublist sizes ensightFaces
-    template<class Type>
-    static bool writeFaceSubField
-    (
-        const Field<Type>& fld,
-        const ensightFaces&,
-        ensightFile& os
-    );
-
-    //- Write a field of cell values as an indirect list,
-    //  using the cell ids from ensightCells
-    template<class Type>
-    static bool writeCellField
-    (
-        const Field<Type>& fld,
-        const ensightCells&,
-        ensightFile& os
-    );
-
-
-    //- 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
-    );
-
-    //- No 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.ref(), nodeValues);
-    }
-
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-    #include "ensightOutputTemplates.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightOutputVolField.H b/src/conversion/ensight/output/ensightOutputVolField.H
new file mode 100644
index 0000000000000000000000000000000000000000..fd3bf9506ad2421c9ea0111535d70f10945b4525
--- /dev/null
+++ b/src/conversion/ensight/output/ensightOutputVolField.H
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 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/>.
+
+InNamespace
+    Foam::ensightOutput
+
+Description
+    A collection of functions for writing volField content in ensight format.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightOutputVolField_H
+#define ensightOutputVolField_H
+
+#include "ensightOutput.H"
+#include "ensightPart.H"
+#include "ensightParts.H"
+#include "ensightPartFaces.H"
+#include "ensightPartCells.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class ensightMesh;
+
+namespace ensightOutput
+{
+
+/*---------------------------------------------------------------------------*\
+                        Namespace ensightOutput::Detail
+\*---------------------------------------------------------------------------*/
+
+namespace Detail
+{
+
+//- Write volume field component-wise
+template<class Type>
+bool writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightMesh& ensMesh,
+    ensightFile& os
+);
+
+//- Write point field component-wise
+template<class Type>
+bool writePointField
+(
+    const GeometricField<Type, pointPatchField, pointMesh>& pf,
+    const ensightMesh& ensMesh,
+    ensightFile& os
+);
+
+} // End namespace Detail
+
+
+/*---------------------------------------------------------------------------*\
+                            Namespace ensightOutput
+\*---------------------------------------------------------------------------*/
+
+//- Write volume field component-wise
+template<class Type>
+bool writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>&,
+    const ensightMesh& ensMesh,
+    ensightFile& os,
+    const bool nodeValues = false
+);
+
+
+/*---------------------------------------------------------------------------*\
+                        Namespace ensightOutput::Serial
+\*---------------------------------------------------------------------------*/
+
+namespace Serial
+{
+
+//- Write volume field component-wise for specified faces
+template<class Type>
+bool writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightPartFaces& part,
+    ensightFile& os
+);
+
+
+//- Write volume field component-wise for specified cells
+template<class Type>
+bool writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightPartCells& part,
+    ensightFile& os
+);
+
+
+//- Write volume field component-wise
+template<class Type>
+bool writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightParts& list,
+    ensightFile& os
+);
+
+} // End namespace Serial
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ensightOutput
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ensightOutputVolFieldTemplates.C"
+#endif
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/output/ensightOutputTemplates.C b/src/conversion/ensight/output/ensightOutputVolFieldTemplates.C
similarity index 62%
rename from src/conversion/ensight/output/ensightOutputTemplates.C
rename to src/conversion/ensight/output/ensightOutputVolFieldTemplates.C
index 5176845e6f1de45b5a35d4d7b41afd4f6db22bed..4a22d74d8a67b7a1509ccf025c3ee9e2478bb22b 100644
--- a/src/conversion/ensight/output/ensightOutputTemplates.C
+++ b/src/conversion/ensight/output/ensightOutputVolFieldTemplates.C
@@ -23,191 +23,29 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "ensightFile.H"
-#include "ensightOutput.H"
-#include "ensightPTraits.H"
+#include "ensightOutputVolField.H"
+#include "ensightMesh.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 "volPointInterpolation.H"
 #include "interpolation.H"
 #include "linear.H"
 #include "processorFvPatch.H"
+#include "uindirectPrimitivePatch.H"
 
-// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
-
-template<template<typename> class FieldContainer, class Type>
-void Foam::ensightOutput::writeFieldContent
-(
-    const char* key,
-    const FieldContainer<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::commsTypes::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::commsTypes::scheduled,
-                    Pstream::masterNo()
-                );
-
-                toMaster
-                    << fld.component(cmpt);
-            }
-        }
-    }
-}
-
-
-template<class Type>
-bool Foam::ensightOutput::writeFaceField
-(
-    const Field<Type>& pf,
-    const ensightFaces& ensFaces,
-    Foam::ensightFile& os
-)
-{
-    if (ensFaces.total())
-    {
-        if (Pstream::master())
-        {
-            os.beginPart(ensFaces.index());
-        }
-
-        for (label typei=0; typei < ensightFaces::nTypes; ++typei)
-        {
-            const ensightFaces::elemType what =
-                ensightFaces::elemType(typei);
-
-            writeFieldContent
-            (
-                ensightFaces::key(what),
-                Field<Type>(pf, ensFaces.faceIds(what)),
-                os
-            );
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-
-template<class Type>
-bool Foam::ensightOutput::writeFaceSubField
-(
-    const Field<Type>& pf,
-    const ensightFaces& ensFaces,
-    Foam::ensightFile& os
-)
-{
-    if (ensFaces.total())
-    {
-        if (Pstream::master())
-        {
-            os.beginPart(ensFaces.index());
-        }
-
-        label start = 0; // start of sublist
-        for (label typei=0; typei < ensightFaces::nTypes; ++typei)
-        {
-            const ensightFaces::elemType what =
-                ensightFaces::elemType(typei);
-
-            const label size = ensFaces.faceIds(what).size();
-
-            writeFieldContent
-            (
-                ensightFaces::key(what),
-                SubField<Type>(pf, size, start),
-                os
-            );
-
-            start += size; // start of next sublist
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-
-template<class Type>
-bool Foam::ensightOutput::writeCellField
-(
-    const Field<Type>& vf,
-    const ensightCells& ensCells,
-    ensightFile& os
-)
-{
-    if (ensCells.total())
-    {
-        if (Pstream::master())
-        {
-            os.beginPart(ensCells.index());
-        }
-
-        for (label typei=0; typei < ensightCells::nTypes; ++typei)
-        {
-            const ensightCells::elemType what =
-                ensightCells::elemType(typei);
-
-            writeFieldContent
-            (
-                ensightCells::key(what),
-                Field<Type>(vf, ensCells.cellIds(what)),
-                os
-            );
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
+// * * * * * * * * * * * * * * * *  Detail * * * * * * * * * * * * * * * * * //
 
 template<class Type>
-bool Foam::ensightOutput::writeField
+bool Foam::ensightOutput::Detail::writeVolField
 (
     const GeometricField<Type, fvPatchField, volMesh>& vf,
     const ensightMesh& ensMesh,
     ensightFile& os
 )
 {
+    constexpr bool parallel = true;
+
     const fvMesh& mesh = ensMesh.mesh();
     const ensightCells& meshCells = ensMesh.meshCells();
     const Map<word>&  patchLookup = ensMesh.patches();
@@ -219,7 +57,7 @@ bool Foam::ensightOutput::writeField
     //
     if (ensMesh.useInternalMesh())
     {
-        writeCellField(vf, meshCells, os);
+        Detail::writeCellField(vf, meshCells, os, parallel);
     }
 
     //
@@ -230,13 +68,14 @@ bool Foam::ensightOutput::writeField
     for (const label patchId : patchIds)
     {
         const word& patchName = patchLookup[patchId];
-        const ensightFaces& ensFaces = patchFaces[patchName];
+        const ensightFaces& part = patchFaces[patchName];
 
         writeFaceField
         (
             vf.boundaryField()[patchId],
-            ensFaces,
-            os
+            part,
+            os,
+            parallel
         );
     }
 
@@ -291,17 +130,17 @@ bool Foam::ensightOutput::writeField
 
         for (const word& zoneName : zoneNames)
         {
-            const ensightFaces& ensFaces = zoneFaces[zoneName];
+            const ensightFaces& part = zoneFaces[zoneName];
 
             // Field (local size)
-            Field<Type> values(ensFaces.size());
+            Field<Type> values(part.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)
+            forAll(part, i)
             {
-                const label faceId = ensFaces[i];
+                const label faceId = part[i];
                 values[i] =
                 (
                     mesh.isInternalFace(faceId)
@@ -312,7 +151,7 @@ bool Foam::ensightOutput::writeField
 
             // The field is already copied in the proper order
             // - just need its corresponding sub-fields
-            writeFaceSubField(values, ensFaces, os);
+            Detail::writeFaceSubField(values, part, os, parallel);
         }
     }
 
@@ -321,13 +160,15 @@ bool Foam::ensightOutput::writeField
 
 
 template<class Type>
-bool Foam::ensightOutput::ensightPointField
+bool Foam::ensightOutput::Detail::writePointField
 (
     const GeometricField<Type, pointPatchField, pointMesh>& pf,
     const ensightMesh& ensMesh,
     ensightFile& os
 )
 {
+    constexpr bool parallel = true;
+
     const fvMesh& mesh = ensMesh.mesh();
     const Map<word>& patchLookup  = ensMesh.patches();
 
@@ -344,11 +185,12 @@ bool Foam::ensightOutput::ensightPointField
             os.beginPart(0); // 0 = internalMesh
         }
 
-        writeFieldContent
+        Detail::writeFieldComponents
         (
             "coordinates",
             Field<Type>(pf.internalField(), ensMesh.uniquePointMap()),
-            os
+            os,
+            parallel
         );
     }
 
@@ -360,7 +202,7 @@ bool Foam::ensightOutput::ensightPointField
     for (const label patchId : patchIds)
     {
         const word& patchName = patchLookup[patchId];
-        const ensightFaces& ensFaces = patchFaces[patchName];
+        const ensightFaces& part = patchFaces[patchName];
 
         const fvPatch& p = mesh.boundary()[patchId];
 
@@ -378,14 +220,15 @@ bool Foam::ensightOutput::ensightPointField
 
         if (Pstream::master())
         {
-            os.beginPart(ensFaces.index());
+            os.beginPart(part.index());
         }
 
-        writeFieldContent
+        Detail::writeFieldComponents
         (
             "coordinates",
             Field<Type>(pf.internalField(), uniqueMeshPointLabels),
-            os
+            os,
+            parallel
         );
     }
 
@@ -395,14 +238,14 @@ bool Foam::ensightOutput::ensightPointField
     const wordList zoneNames = zoneFaces.sortedToc();
     for (const word& zoneName : zoneNames)
     {
-        const ensightFaces& ensFaces = zoneFaces[zoneName];
+        const ensightFaces& part = zoneFaces[zoneName];
 
         uindirectPrimitivePatch p
         (
             UIndirectList<face>
             (
                 mesh.faces(),
-                ensFaces.faceIds()
+                part.faceIds()
             ),
             mesh.points()
         );
@@ -421,14 +264,15 @@ bool Foam::ensightOutput::ensightPointField
 
         if (Pstream::master())
         {
-            os.beginPart(ensFaces.index());
+            os.beginPart(part.index());
         }
 
-        writeFieldContent
+        Detail::writeFieldComponents
         (
             "coordinates",
             Field<Type>(pf.internalField(), uniqueMeshPointLabels),
-            os
+            os,
+            parallel
         );
     }
 
@@ -436,10 +280,10 @@ bool Foam::ensightOutput::ensightPointField
 }
 
 
-// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 template<class Type>
-bool Foam::ensightOutput::writeField
+bool Foam::ensightOutput::writeVolField
 (
     const GeometricField<Type, fvPatchField, volMesh>& vf,
     const ensightMesh& ensMesh,
@@ -456,12 +300,86 @@ bool Foam::ensightOutput::writeField
         pfld.ref().checkOut();
         pfld.ref().rename(vf.name());
 
-        return ensightPointField<Type>(pfld, ensMesh, os);
+        return Detail::writePointField<Type>(pfld, ensMesh, os);
     }
-    else
+
+    return Detail::writeVolField<Type>(vf, ensMesh, os);
+}
+
+
+// * * * * * * * * * * * * * * * *  Serial * * * * * * * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::ensightOutput::Serial::writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightPartFaces& part,
+    ensightFile& os
+)
+{
+    const label patchi = part.patchIndex();
+
+    if (patchi >= 0 && patchi < vf.boundaryField().size())
     {
-        return writeField<Type>(vf, ensMesh, os);
+        return ensightOutput::Detail::writeFaceField
+        (
+            vf.boundaryField()[patchi],
+            part,
+            os,
+            false // serial
+        );
     }
+
+    return false;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Serial::writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightPartCells& part,
+    ensightFile& os
+)
+{
+    return ensightOutput::Detail::writeCellField
+    (
+        vf.internalField(),
+        part,
+        os,
+        false // serial
+    );
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Serial::writeVolField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vf,
+    const ensightParts& list,
+    ensightFile& os
+)
+{
+    for (const ensightPart& part : list)
+    {
+        const ensightPartFaces* fptr = isA<ensightPartFaces>(part);
+
+        if (fptr)
+        {
+            Serial::writeVolField(vf, *fptr, os);
+            continue;
+        }
+
+        const ensightPartCells* cptr = isA<ensightPartCells>(part);
+
+        if (cptr)
+        {
+            Serial::writeVolField(vf, *cptr, os);
+            continue;
+        }
+    }
+
+    return true;
 }
 
 
diff --git a/src/conversion/ensight/output/ensightSerialOutput.H b/src/conversion/ensight/output/ensightSerialOutput.H
deleted file mode 100644
index 5fa1c359d3688b2c7d74d83ad41dd9f9d1636c84..0000000000000000000000000000000000000000
--- a/src/conversion/ensight/output/ensightSerialOutput.H
+++ /dev/null
@@ -1,146 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  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 content (component-wise) for the given ensight element type
-    template<template<typename> class FieldContainer, class Type>
-    static void writeFieldContent
-    (
-        const word& key,
-        const FieldContainer<Type>& fld,
-        ensightFile& os
-    );
-
-    //- No 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.ref());
-    }
-
-
-    //- 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.ref());
-    }
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // 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
deleted file mode 100644
index 3a027ab6dddf1699e2ffa41cc5ccb8de8fd1ac3a..0000000000000000000000000000000000000000
--- a/src/conversion/ensight/output/ensightSerialOutputTemplates.C
+++ /dev/null
@@ -1,174 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  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<template<typename> class FieldContainer, class Type>
-void Foam::ensightSerialOutput::writeFieldContent
-(
-    const word& key,
-    const FieldContainer<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());
-
-            for (label typei=0; typei < ensightFaces::nTypes; ++typei)
-            {
-                const ensightFaces::elemType what =
-                    ensightFaces::elemType(typei);
-
-                writeFieldContent
-                (
-                    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());
-
-        for (label typei=0; typei < ensightCells::nTypes; ++typei)
-        {
-            const ensightCells::elemType what =
-                ensightCells::elemType(typei);
-
-            writeFieldContent
-            (
-                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/fileFormats/ensight/output/ensightOutput.H b/src/fileFormats/ensight/output/ensightOutput.H
new file mode 100644
index 0000000000000000000000000000000000000000..326580a421f365be002126bd3108e897abf85421
--- /dev/null
+++ b/src/fileFormats/ensight/output/ensightOutput.H
@@ -0,0 +1,146 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2019 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::ensightOutput
+
+Description
+    A collection of functions for writing ensight file content.
+
+SourceFiles
+    ensightOutputTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightOutput_H
+#define ensightOutput_H
+
+#include "ensightFile.H"
+#include "ensightCells.H"
+#include "ensightFaces.H"
+#include "ensightPTraits.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+namespace Foam
+{
+namespace ensightOutput
+{
+
+/*---------------------------------------------------------------------------*\
+                        Namespace ensightOutput::Detail
+\*---------------------------------------------------------------------------*/
+
+//- \brief Implementation details and output backends that would not normally
+//- be called directly by a user.
+
+namespace Detail
+{
+
+//- Write field content (component-wise) for the given ensight element type
+template<template<typename> class FieldContainer, class Type>
+bool writeFieldComponents
+(
+    const char* key,
+    const FieldContainer<Type>& fld,
+    ensightFile& os,
+    bool parallel         //!< Collective write?
+);
+
+
+//- Write a field of faces values as an indirect list,
+//- using the face ids from ensightFaces
+template<class Type>
+bool writeFaceField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os,
+    bool parallel         //!< Collective write?
+);
+
+
+//- Write a sub-field of faces values as an indirect list,
+//- using the sublist sizing information from ensightFaces
+template<class Type>
+bool writeFaceSubField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os,
+    bool parallel         //!< Collective write?
+);
+
+
+
+//- Write a field of cell values as an indirect list,
+//- using the cell ids from ensightCells
+template<class Type>
+bool writeCellField
+(
+    const Field<Type>& fld,
+    const ensightCells& part,
+    ensightFile& os,
+    bool parallel         //!< Collective write?
+);
+
+} // End namespace Detail
+
+
+/*---------------------------------------------------------------------------*\
+                        Namespace ensightOutput::Serial
+\*---------------------------------------------------------------------------*/
+
+//- \brief Output routines that are either designed for serial-only,
+//- or for which parallelization is pending.
+namespace Serial
+{
+
+//- Write a field of point (node) values (already compacted?)
+template<class Type>
+bool writePointField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os
+);
+
+} // End namespace Serial
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ensightOutput
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "ensightOutputTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/output/ensightOutputTemplates.C b/src/fileFormats/ensight/output/ensightOutputTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..1ddaaf4c614e526202695bc1271ea6d9284bb5f4
--- /dev/null
+++ b/src/fileFormats/ensight/output/ensightOutputTemplates.C
@@ -0,0 +1,323 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 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 "ensightOutput.H"
+#include "ensightPTraits.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<template<typename> class FieldContainer, class Type>
+bool Foam::ensightOutput::Detail::writeFieldComponents
+(
+    const char* key,
+    const FieldContainer<Type>& fld,
+    ensightFile& os,
+    bool parallel
+)
+{
+    // Preliminary checks
+    // ~~~~~~~~~~~~~~~~~~
+
+    parallel = parallel && Pstream::parRun();
+
+    bool hasField = !fld.empty();
+
+    if (parallel)
+    {
+        reduce(hasField, orOp<bool>());
+    }
+
+    // Nothing to write
+    if (!hasField) return false;
+
+    // End preliminary checks
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
+
+    if (Pstream::master())
+    {
+        os.writeKeyword(key);
+
+        if (!parallel)
+        {
+            // Serial output
+            for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+            {
+                const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+                os.writeList(fld.component(cmpt));
+            }
+        }
+        else
+        {
+            // Parallel (master)
+
+            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::commsTypes::scheduled, slave);
+                    scalarField received(fromSlave);
+                    os.writeList(received);
+                }
+            }
+        }
+    }
+    else if (parallel)
+    {
+        // Parallel (slaves)
+
+        for (direction d=0; d < pTraits<Type>::nComponents; ++d)
+        {
+            const label cmpt = ensightPTraits<Type>::componentOrder[d];
+
+            OPstream toMaster
+            (
+                Pstream::commsTypes::scheduled,
+                Pstream::masterNo()
+            );
+
+            toMaster
+                << fld.component(cmpt);
+        }
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Detail::writeFaceField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os,
+    bool parallel
+)
+{
+    // Preliminary checks
+    // ~~~~~~~~~~~~~~~~~~
+
+    parallel = parallel && Pstream::parRun();
+
+    bool hasGeom = (parallel ? part.total() : part.size());
+    bool hasField = !fld.empty();
+
+    if (parallel)
+    {
+        // Used 'pre-reduced' information for hasGeom
+        reduce(hasField, orOp<bool>());
+    }
+
+    // Nothing to write
+    if (!hasGeom || !hasField) return false;
+
+    // End preliminary checks
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
+
+    if (Pstream::master())
+    {
+        os.beginPart(part.index());
+    }
+
+    for (int typei=0; typei < ensightFaces::nTypes; ++typei)
+    {
+        const ensightFaces::elemType what = ensightFaces::elemType(typei);
+
+        writeFieldComponents
+        (
+            ensightFaces::key(what),
+            Field<Type>(fld, part.faceIds(what)),
+            os,
+            parallel
+        );
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Detail::writeFaceSubField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os,
+    bool parallel
+)
+{
+    // Preliminary checks
+    // ~~~~~~~~~~~~~~~~~~
+
+    parallel = parallel && Pstream::parRun();
+
+    bool hasGeom = (parallel ? part.total() : part.size());
+    bool hasField = !fld.empty();
+
+    if (parallel)
+    {
+        // Used 'pre-reduced' information for hasGeom
+        reduce(hasField, orOp<bool>());
+    }
+
+    // Nothing to write
+    if (!hasGeom || !hasField) return false;
+
+    // End preliminary checks
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
+
+    if (Pstream::master())
+    {
+        os.beginPart(part.index());
+    }
+
+
+    label start = 0; // The start of the sub-list
+    for (int typei=0; typei < ensightFaces::nTypes; ++typei)
+    {
+        const ensightFaces::elemType what = ensightFaces::elemType(typei);
+
+        const label size = part.faceIds(what).size();
+
+        writeFieldComponents
+        (
+            ensightFaces::key(what),
+            SubField<Type>(fld, size, start),
+            os,
+            parallel
+        );
+
+        start += size;  // Advance the start for next sub-list
+    }
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Serial::writePointField
+(
+    const Field<Type>& fld,
+    const ensightFaces& part,
+    ensightFile& os
+)
+{
+    // Preliminary checks
+    // ~~~~~~~~~~~~~~~~~~
+
+    bool parallel = false && Pstream::parRun();
+
+    bool hasGeom = (parallel ? part.total() : part.size());
+    bool hasField = !fld.empty();
+
+    if (parallel)
+    {
+        // Used 'pre-reduced' information for hasGeom
+        reduce(hasField, orOp<bool>());
+    }
+
+    // Nothing to write
+    if (!hasGeom || !hasField) return false;
+
+    // End preliminary checks
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
+
+    if (Pstream::master())
+    {
+        os.beginPart(part.index());
+    }
+
+    ensightOutput::Detail::writeFieldComponents
+    (
+        "coordinates",
+        fld,
+        os,
+        parallel
+    );
+
+    return true;
+}
+
+
+template<class Type>
+bool Foam::ensightOutput::Detail::writeCellField
+(
+    const Field<Type>& fld,
+    const ensightCells& part,
+    ensightFile& os,
+    bool parallel
+)
+{
+    // Preliminary checks
+    // ~~~~~~~~~~~~~~~~~~
+
+    parallel = parallel && Pstream::parRun();
+
+    bool hasGeom = (parallel ? part.total() : part.size());
+    bool hasField = !fld.empty();
+
+    if (parallel)
+    {
+        // Used 'pre-reduced' information for hasGeom
+        reduce(hasField, orOp<bool>());
+    }
+
+    // Nothing to write
+    if (!hasGeom || !hasField) return false;
+
+    // End preliminary checks
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
+
+    if (Pstream::master())
+    {
+        os.beginPart(part.index());
+    }
+
+    for (int typei=0; typei < ensightCells::nTypes; ++typei)
+    {
+        const ensightCells::elemType what = ensightCells::elemType(typei);
+
+        Detail::writeFieldComponents
+        (
+            ensightCells::key(what),
+            Field<Type>(fld, part.cellIds(what)),
+            os,
+            parallel
+        );
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightCells.H b/src/fileFormats/ensight/part/ensightCells.H
index 00cd99b438b8c5b169e932fa6c486e9d57236ed6..83c5200d81b8b15cc2786804d02a154f150d493d 100644
--- a/src/fileFormats/ensight/part/ensightCells.H
+++ b/src/fileFormats/ensight/part/ensightCells.H
@@ -66,7 +66,7 @@ public:
         };
 
         //- Number of element types (5)
-        static constexpr label nTypes = 5;
+        static constexpr int nTypes = 5;
 
         //- The ensight element type names
         static const char* elemNames[5];
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
index 4022076f6929012262f6483a28075fdb5d33cf76..c079f39744816f6393ff53963393b9eb522b25c0 100644
--- a/src/fileFormats/ensight/part/ensightFaces.H
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -62,7 +62,7 @@ public:
         };
 
         //- Number of element types (3)
-        static constexpr label nTypes = 3;
+        static constexpr int nTypes = 3;
 
         //- The ensight element type names
         static const char* elemNames[3];
diff --git a/src/fileFormats/ensight/part/ensightPartCells.C b/src/fileFormats/ensight/part/ensightPartCells.C
index 16238060506b9bf956820461e2a2d4af265d86a3..afb8b8deed188c7e04465891bfb4d220cdd93d19 100644
--- a/src/fileFormats/ensight/part/ensightPartCells.C
+++ b/src/fileFormats/ensight/part/ensightPartCells.C
@@ -269,8 +269,8 @@ void Foam::ensightPartCells::write
             }
         }
 
-        // write each element type
-        for (label typei=0; typei < ensightCells::nTypes; ++typei)
+        // Write each element type
+        for (int typei=0; typei < ensightCells::nTypes; ++typei)
         {
             const ensightCells::elemType what = ensightCells::elemType(typei);
 
@@ -312,7 +312,7 @@ void Foam::ensightPartCells::dumpInfo(Ostream& os) const
     os.writeEntry("name",   name());
     os.writeEntry("size",   size());
 
-    for (label typei=0; typei < ensightCells::nTypes; ++typei)
+    for (int typei=0; typei < ensightCells::nTypes; ++typei)
     {
         const ensightCells::elemType what = ensightCells::elemType(typei);
         const labelUList& addr = this->cellIds(what);
diff --git a/src/fileFormats/ensight/part/ensightPartFaces.C b/src/fileFormats/ensight/part/ensightPartFaces.C
index f3fdc68e7c4654b4154a3d21e3a819e3265c4e2f..f81789fdcad4b7ee3d72f6a35d1f163c5634c7e5 100644
--- a/src/fileFormats/ensight/part/ensightPartFaces.C
+++ b/src/fileFormats/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  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -219,8 +219,8 @@ void Foam::ensightPartFaces::write
             }
         }
 
-        // write part
-        for (label typei=0; typei < ensightFaces::nTypes; ++typei)
+        // Write part
+        for (int typei=0; typei < ensightFaces::nTypes; ++typei)
         {
             const ensightFaces::elemType what = ensightFaces::elemType(typei);
 
@@ -264,7 +264,7 @@ void Foam::ensightPartFaces::dumpInfo(Ostream& os) const
     os.writeEntry("start",  start_);
     os.writeEntry("size",   size());
 
-    for (label typei=0; typei < ensightFaces::nTypes; ++typei)
+    for (int typei=0; typei < ensightFaces::nTypes; ++typei)
     {
         const ensightFaces::elemType what = ensightFaces::elemType(typei);
         const labelUList& addr = this->faceIds(what);
diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C
index 9649a26bac84fde9cfdb7033f65ba02df48c4f38..7747f0277ea92faae62241908c81738447b7a110 100644
--- a/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C
+++ b/src/functionObjects/utilities/ensightWrite/ensightWriteTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,7 +23,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "ensightOutput.H"
+#include "ensightOutputVolField.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -54,11 +54,11 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFields
 
         autoPtr<ensightFile> os = ensCase().newData<Type>(fieldName);
 
-        ensightOutput::writeField<Type>
+        ensightOutput::writeVolField<Type>
         (
             field,
             ensMesh(),
-            os,
+            os.ref(),
             caseOpts_.nodeValues()
         );
 
diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C
index 7fef643f0df33a1f5c75bddd096d72820b37380d..e00086fec74813747ebbd5eaa60b5709796da4b0 100644
--- a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C
+++ b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -73,7 +73,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
-bool Foam::ensightCloud::writePositions
+bool Foam::ensightOutput::writeCloudPositions
 (
     const fvMesh& mesh,
     const word& cloudName,
@@ -92,9 +92,9 @@ bool Foam::ensightCloud::writePositions
 
         auto outIter = positions.begin();
 
-        forAllConstIters(parcels, iter)
+        for (const passiveParticle& p : parcels)
         {
-            *outIter = iter().position();
+            *outIter = p.position();
             ++outIter;
         }
     }
diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H
index 4707f4235024e37716c441fae9075b2a6ad9f739..0607e4a087743e5357d119d4a8399526427390d9 100644
--- a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H
+++ b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloud.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,12 +21,11 @@ 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
-    Foam::ensightCloud
+InNamespace
+    Foam::ensightOutput
 
 Description
-    A collection of global functions for writing clouds as
-    ensight file content.
+    A collection of functions for writing clouds as ensight file content.
 
 SourceFiles
     ensightOutputCloud.C
@@ -45,14 +44,18 @@ SourceFiles
 
 namespace Foam
 {
+
 // Forward declarations
 class fvMesh;
 
-namespace ensightCloud
+namespace ensightOutput
 {
 
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
 //- Write cloud positions
-bool writePositions
+bool writeCloudPositions
 (
     const fvMesh& mesh,
     const word& cloudName,
@@ -84,7 +87,7 @@ bool writeCloudField
 );
 
 
-} // End namespace ensightCloud
+} // End namespace ensightOutput
 } // End namespace Foam
 
 
diff --git a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C
index aa0ead7b4ffad0ac5fee60167789a48f55f50c43..0ff836ab9879d2093a0a12ca2070f57fea20d3fc 100644
--- a/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C
+++ b/src/lagrangian/intermediate/conversion/ensight/ensightOutputCloudTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -29,7 +29,7 @@ License
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-bool Foam::ensightCloud::writeCloudField
+bool Foam::ensightOutput::writeCloudField
 (
     const IOField<Type>& field,
     ensightFile& os,
@@ -113,7 +113,7 @@ bool Foam::ensightCloud::writeCloudField
 
 
 template<class Type>
-bool Foam::ensightCloud::writeCloudField
+bool Foam::ensightOutput::writeCloudField
 (
     const IOobject& io,
     const bool exists,
diff --git a/src/sampling/Make/options b/src/sampling/Make/options
index 2a3f63979533704b36eefcb23596fbd07cca2671..85fc47f4325ffcfe195b1aa534c7d6cc7ed30100 100644
--- a/src/sampling/Make/options
+++ b/src/sampling/Make/options
@@ -3,13 +3,11 @@ EXE_INC = \
     -I$(LIB_SRC)/fileFormats/lnInclude \
     -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
-    -I$(LIB_SRC)/conversion/lnInclude \
     -I$(LIB_SRC)/dynamicMesh/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
     -lmeshTools \
-    -lconversion \
     -ldynamicMesh \
     -llagrangian
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C
index cb040ff965fbb65ed9024d229d570ed124191403..c4435c54b9abdee0db3fece57bbb6f23f2809f3e 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.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-2018 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,9 +26,10 @@ License
 #include "IOmanip.H"
 #include "Fstream.H"
 #include "OSspecific.H"
+
 #include "ensightCase.H"
 #include "ensightPartFaces.H"
-#include "ensightSerialOutput.H"
+#include "ensightOutput.H"
 #include "ensightPTraits.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -140,13 +141,27 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
 
     // Write field
     osField.writeKeyword(ensightPTraits<Type>::typeName);
-    ensightSerialOutput::writeField
-    (
-        values,
-        ensPart,
-        osField,
-        isNodeValues
-    );
+
+    if (isNodeValues)
+    {
+        ensightOutput::Serial::writePointField
+        (
+            values,
+            ensPart,
+            osField
+            // false // serial
+        );
+    }
+    else
+    {
+        ensightOutput::Detail::writeFaceField
+        (
+            values,
+            ensPart,
+            osField,
+            false // serial
+        );
+    }
 
     return osCase.name();
 }
@@ -436,13 +451,27 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
 
     // Write field
     osField.writeKeyword(ensightPTraits<Type>::typeName);
-    ensightSerialOutput::writeField
-    (
-        values,
-        ensPart,
-        osField,
-        isNodeValues
-    );
+
+    if (isNodeValues)
+    {
+        ensightOutput::Serial::writePointField
+        (
+            values,
+            ensPart,
+            osField
+            // serial
+        );
+    }
+    else
+    {
+        ensightOutput::Detail::writeFaceField
+        (
+            values,
+            ensPart,
+            osField,
+            false // serial
+        );
+    }
 
     // Place a timestamp in the directory for future reference
     {