diff --git a/src/fileFormats/ensight/file/ensightFile.C b/src/fileFormats/ensight/file/ensightFile.C
index 69a24d5b4c61d24e40640dc52547557c061dd960..a81d4e06fe2543b1f6c7e51a040962207d3eb8a6 100644
--- a/src/fileFormats/ensight/file/ensightFile.C
+++ b/src/fileFormats/ensight/file/ensightFile.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016-2018 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -348,29 +348,21 @@ void Foam::ensightFile::writeList
 void Foam::ensightFile::writeList
 (
     const UList<scalar>& field,
-    const labelUList& idList
+    const labelUList& addr
 )
 {
-    if (notNull(idList))
+    for (const label id : addr)
     {
-        for (const label idx : idList)
+        if (idx >= field.size() || std::isnan(field[id]))
         {
-            if (idx >= field.size() || std::isnan(field[idx]))
-            {
-                writeUndef();
-            }
-            else
-            {
-                write(field[idx]);
-            }
-
-            newline();
+            writeUndef();
         }
-    }
-    else
-    {
-        // No idList => perNode
-        writeList(field);
+        else
+        {
+            write(field[id]);
+        }
+
+        newline();
     }
 }
 
diff --git a/src/fileFormats/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H
index 2ee73905345f88190ec5cd247d9583efe08ff359..2940d86b57438eba63bd557a62a1b32367ce77dd 100644
--- a/src/fileFormats/ensight/file/ensightFile.H
+++ b/src/fileFormats/ensight/file/ensightFile.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  | Copyright (C) 2016-2018 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -195,11 +195,7 @@ public:
 
         //- 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
-        );
+        void writeList(const UList<scalar>& field, const labelUList& addr);
 
 };
 
diff --git a/src/fileFormats/ensight/part/ensightCells.C b/src/fileFormats/ensight/part/ensightCells.C
index 8d734bf7f4699b285c24c363c58ae8b86d394231..d032b2bf60d490300cccf3658499d1a9c29b2f9d 100644
--- a/src/fileFormats/ensight/part/ensightCells.C
+++ b/src/fileFormats/ensight/part/ensightCells.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
@@ -25,6 +25,7 @@ License
 
 #include "ensightCells.H"
 #include "error.H"
+#include "bitSet.H"
 #include "polyMesh.H"
 #include "cellModel.H"
 
@@ -90,7 +91,7 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
     // Need local sizes for the resize operation
     this->sizes_ = obj.sizes();
 
-    resizeAll(); // adjust allocation/sizing
+    resizeAll(); // Adjust allocation/sizing
 
     // Restore total (reduced) sizes
     this->sizes_ = totSizes;
@@ -153,10 +154,11 @@ void Foam::ensightCells::sort()
 }
 
 
-void Foam::ensightCells::classify
+template<class Addressing>
+void Foam::ensightCells::classifyImpl
 (
     const polyMesh& mesh,
-    const labelUList& addressing
+    const Addressing& cellIds
 )
 {
     // References to cell shape models
@@ -167,16 +169,11 @@ void Foam::ensightCells::classify
 
     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
+    // Pass 1: Count the shapes
 
     sizes_ = Zero;  // reset sizes
-    for (label listi = 0; listi < sz; ++listi)
+    for (const label id : cellIds)
     {
-        const label id = indirect ? addressing[listi] : listi;
         const cellModel& model = shapes[id].model();
 
         enum elemType what = NFACED;
@@ -203,10 +200,10 @@ void Foam::ensightCells::classify
     resizeAll();    // adjust allocation
     sizes_ = Zero;  // reset sizes - use for local indexing here
 
-    // Assign cell-id per shape type
-    for (label listi = 0; listi < sz; ++listi)
+    // Pass 2: Assign cell-id per shape type
+
+    for (const label id : cellIds)
     {
-        const label id = indirect ? addressing[listi] : listi;
         const cellModel& model = shapes[id].model();
 
         enum elemType what = NFACED;
@@ -236,4 +233,31 @@ void Foam::ensightCells::classify
 }
 
 
+void Foam::ensightCells::classify(const polyMesh& mesh)
+{
+    // All mesh cells
+    classifyImpl(mesh, labelRange::identity(mesh.nCells()));
+}
+
+
+void Foam::ensightCells::classify
+(
+    const polyMesh& mesh,
+    const labelUList& cellIds
+)
+{
+    classifyImpl(mesh, cellIds);
+}
+
+
+void Foam::ensightCells::classify
+(
+    const polyMesh& mesh,
+    const bitSet& selection
+)
+{
+    classifyImpl(mesh, selection);
+}
+
+
 // ************************************************************************* //
diff --git a/src/fileFormats/ensight/part/ensightCells.H b/src/fileFormats/ensight/part/ensightCells.H
index 4a5885fedd4f5f83b65b6eae2ef338d211916a7e..00cd99b438b8c5b169e932fa6c486e9d57236ed6 100644
--- a/src/fileFormats/ensight/part/ensightCells.H
+++ b/src/fileFormats/ensight/part/ensightCells.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
@@ -42,6 +42,7 @@ namespace Foam
 {
 
 // Forward declarations
+class bitSet;
 class polyMesh;
 
 /*---------------------------------------------------------------------------*\
@@ -79,7 +80,7 @@ public:
 
 private:
 
-    // Private data
+    // Private Data
 
         //- Location within a list.
         //  The ensight part number is typically this value +1.
@@ -101,6 +102,10 @@ private:
         //- Use temporarily stored sizes to redimension the element lists
         void resizeAll();
 
+        //- Classify cell types, set element lists for selection (implemention)
+        template<class Addressing>
+        void classifyImpl(const polyMesh& mesh, const Addressing& cellIds);
+
         //- No copy assignment
         void operator=(const ensightCells&) = delete;
 
@@ -167,14 +172,15 @@ public:
     // 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& mesh,
-            const labelUList& addressing = labelUList::null()
-        );
+        void classify(const polyMesh& mesh);
+
+        //- Classify cell types and set element lists,
+        //- using a subgroup of cells (eg, from a cellZone etc).
+        void classify(const polyMesh& mesh, const labelUList& cellIds);
 
+        //- Classify cell types and set element lists,
+        //- using a subgroup of cells
+        void classify(const polyMesh& mesh, const bitSet& selection);
 
         //- Set addressable sizes to zero, free up addressing memory.
         void clear();
diff --git a/src/fileFormats/ensight/part/ensightFaces.C b/src/fileFormats/ensight/part/ensightFaces.C
index 8eda22616e506ffd3fdafb71f5dbb56272ad3235..5a2761b9e6ef29848f224397ef6d3b58a07a9e55 100644
--- a/src/fileFormats/ensight/part/ensightFaces.C
+++ b/src/fileFormats/ensight/part/ensightFaces.C
@@ -26,7 +26,6 @@ License
 #include "ensightFaces.H"
 #include "error.H"
 #include "polyMesh.H"
-#include "ListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -34,11 +33,13 @@ const char* Foam::ensightFaces::elemNames[3] =
     { "tria3", "quad4", "nsided" };
 
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+namespace
+{
 
-// only used in this file-scope
-inline Foam::ensightFaces::elemType
-Foam::ensightFaces::whatType(const face& f)
+// Simple shape classifier
+static inline Foam::ensightFaces::elemType whatType(const Foam::face& f)
 {
     return
     (
@@ -50,8 +51,12 @@ Foam::ensightFaces::whatType(const face& f)
     );
 }
 
+} // End anonymous namespace
 
-// only used in this file-scope
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// Only used in this file-scope
 inline void Foam::ensightFaces::add
 (
     const face& f,
@@ -223,8 +228,7 @@ 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
+    // Pass 1: Count the shapes
 
     sizes_ = Zero;  // reset sizes
     for (label listi = 0; listi < sz; ++listi)
@@ -236,7 +240,8 @@ void Foam::ensightFaces::classify(const faceList& faces)
     resizeAll();    // adjust allocation
     sizes_ = Zero;  // reset sizes - use for local indexing here
 
-    // Assign face-id per shape type
+    // Pass 2: Assign face-id per shape type
+
     for (label listi = 0; listi < sz; ++listi)
     {
         add(faces[listi], listi);
@@ -252,14 +257,10 @@ void Foam::ensightFaces::classify
     const bitSet& 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
+    // Pass 1: Count the shapes
 
     sizes_ = Zero;  // reset sizes
     for (label listi = 0; listi < sz; ++listi)
@@ -282,7 +283,8 @@ void Foam::ensightFaces::classify
         flipMap_ = false;
     }
 
-    // Assign face-id per shape type
+    // Pass 2: Assign face-id per shape type
+
     for (label listi = 0; listi < sz; ++listi)
     {
         const label faceId = addressing[listi];
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
index 5e2af71c4e7ce7b9c8e11701085fa6d951fc1f3c..4022076f6929012262f6483a28075fdb5d33cf76 100644
--- a/src/fileFormats/ensight/part/ensightFaces.H
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -51,7 +51,7 @@ class ensightFaces
 {
 public:
 
-    // Public data
+    // Public Data
 
         //- Addressable ensight element types
         enum elemType
@@ -98,9 +98,6 @@ private:
 
     // Private Member Functions
 
-        //- Simple classifier
-        inline static elemType whatType(const face& f);
-
         //- Low-level internal addition routine
         inline void add(const face& f, const label id, const bool flip = false);
 
diff --git a/src/fileFormats/ensight/part/ensightPart.C b/src/fileFormats/ensight/part/ensightPart.C
index 2e7fc02c233ebc38e215fe03a246fb56a8c8f139..52dec08e5ad2b26f0ce5c9fc6bab47f72a71c7da 100644
--- a/src/fileFormats/ensight/part/ensightPart.C
+++ b/src/fileFormats/ensight/part/ensightPart.C
@@ -65,12 +65,6 @@ Foam::ensightPart::ensightPart(const string& description)
 {}
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::ensightPart::~ensightPart()
-{}
-
-
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 Foam::ensightGeoFile& Foam::operator<<
diff --git a/src/fileFormats/ensight/part/ensightPart.H b/src/fileFormats/ensight/part/ensightPart.H
index 57ddcf5efca113b7b0491421fe0fdb2166c1dea0..61c102860ed519a51d738c7097e75ddae62dc20d 100644
--- a/src/fileFormats/ensight/part/ensightPart.H
+++ b/src/fileFormats/ensight/part/ensightPart.H
@@ -47,9 +47,9 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of friend functions and operators
-
+// Forward declarations
 class ensightPart;
+
 ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
 
 
@@ -79,9 +79,8 @@ protected:
     // Protected Classes
 
         //- Track the points used by the part and map global to local indices
-        class localPoints
+        struct localPoints
         {
-        public:
             //- Number of points used
             label nPoints;
 
@@ -92,7 +91,7 @@ protected:
             localPoints()
             :
                 nPoints(0),
-                list(0)
+                list()
             {}
 
             //- Construct for mesh points
@@ -116,7 +115,7 @@ public:
 
 
     //- Destructor
-    virtual ~ensightPart();
+    virtual ~ensightPart() = default;
 
 
     // Access
@@ -130,16 +129,16 @@ public:
             return 0;
         }
 
-        //- Part name or description
+        //- Return the part name or description
         const string& name() const
         {
             return name_;
         }
 
-        //- non-const access to part name or description
-        void name(const string& value)
+        //- Change the part name or description
+        void name(string value)
         {
-            name_ = value;
+            name_ = std::move(value);
         }
 
 
diff --git a/src/fileFormats/ensight/part/ensightPartCells.C b/src/fileFormats/ensight/part/ensightPartCells.C
index 25ef3bf3a95f472e5af10577a3789a6c8a8b8705..16238060506b9bf956820461e2a2d4af265d86a3 100644
--- a/src/fileFormats/ensight/part/ensightPartCells.C
+++ b/src/fileFormats/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  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -41,12 +41,11 @@ Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
     labelList& usedPoints = ptList.list;
     label nPoints = 0;
 
-    // add all points from cells
+    // Add all points from cells
     const labelUList& idList = this->cellIds();
 
-    forAll(idList, i)
+    for (const label id : idList)
     {
-        const label id = idList[i];
         const labelUList& cFaces = mesh_.cells()[id];
 
         forAll(cFaces, cFacei)
@@ -98,14 +97,14 @@ Foam::ensightPartCells::ensightPartCells
 (
     label partIndex,
     const polyMesh& mesh,
-    const labelUList& idList
+    const labelUList& cellIds
 )
 :
     ensightCells(partIndex),
     ensightPart("cells"),
     mesh_(mesh)
 {
-    classify(mesh, idList);
+    classify(mesh, cellIds);
 }
 
 
@@ -113,21 +112,29 @@ Foam::ensightPartCells::ensightPartCells
 (
     label partIndex,
     const polyMesh& mesh,
-    const cellZone& cZone
+    const cellZone& zn
 )
 :
-    ensightCells(partIndex),
-    ensightPart(cZone.name()),
-    mesh_(mesh)
+    ensightPartCells(partIndex, mesh, static_cast<const labelList&>(zn))
 {
-    classify(mesh, cZone);
+    // Rename according to the zone name
+    name(zn.name());
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::ensightPartCells::~ensightPartCells()
-{}
+Foam::ensightPartCells::ensightPartCells
+(
+    label partIndex,
+    const polyMesh& mesh,
+    const bitSet& selection
+)
+:
+    ensightCells(partIndex),
+    ensightPart("cells"),
+    mesh_(mesh)
+{
+    classify(mesh, selection);
+}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
diff --git a/src/fileFormats/ensight/part/ensightPartCells.H b/src/fileFormats/ensight/part/ensightPartCells.H
index 0936f90ca6c36d87ee3a7a503be9268903f46eea..7162b2cdbce586464ac6b07c3ec7d1c38b95b1b1 100644
--- a/src/fileFormats/ensight/part/ensightPartCells.H
+++ b/src/fileFormats/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  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,7 +53,7 @@ class ensightPartCells
     public ensightCells,
     public ensightPart
 {
-    // Private data
+    // Private Data
 
         //- Mesh referenced
         const polyMesh& mesh_;
@@ -92,28 +92,36 @@ public:
         ensightPartCells
         (
             label partIndex,
-            const polyMesh&
+            const polyMesh& mesh
         );
 
-        //- Construct from polyMesh and list of (non-zoned) cells
+        //- Construct a "cells" part from polyMesh and list of cells
         ensightPartCells
         (
             label partIndex,
-            const polyMesh&,
-            const labelUList&
+            const polyMesh& mesh,
+            const labelUList& cellIds
         );
 
-        //- Construct from polyMesh and cellZone
+        //- Construct from polyMesh and cellZone with name of the zone.
         ensightPartCells
         (
             label partIndex,
-            const polyMesh&,
-            const cellZone&
+            const polyMesh& mesh,
+            const cellZone& zn
+        );
+
+        //- Construct a "cells" part from polyMesh and selection of cells
+        ensightPartCells
+        (
+            label partIndex,
+            const polyMesh& mesh,
+            const bitSet& selection
         );
 
 
     //- Destructor
-    virtual ~ensightPartCells();
+    virtual ~ensightPartCells() = default;
 
 
     // Member Functions
@@ -136,17 +144,17 @@ public:
     // Output
 
         //- Write geometry
-        virtual void write(ensightGeoFile&) const;
+        virtual void write(ensightGeoFile& os) const;
 
         //- Helper: write geometry given the pointField
-        virtual void write(ensightGeoFile&, const pointField&) const;
+        virtual void write(ensightGeoFile& os, const pointField& points) const;
 
 
         //- Write summary information about the object
-        virtual void writeSummary(Ostream&) const;
+        virtual void writeSummary(Ostream& os) const;
 
         //- Print various types of debugging information
-        virtual void dumpInfo(Ostream&) const;
+        virtual void dumpInfo(Ostream& os) const;
 
 };
 
diff --git a/src/fileFormats/ensight/part/ensightPartFaces.C b/src/fileFormats/ensight/part/ensightPartFaces.C
index 8358f713718533088b057d696a53cd4c31703ed0..f3fdc68e7c4654b4154a3d21e3a819e3265c4e2f 100644
--- a/src/fileFormats/ensight/part/ensightPartFaces.C
+++ b/src/fileFormats/ensight/part/ensightPartFaces.C
@@ -126,12 +126,6 @@ Foam::ensightPartFaces::ensightPartFaces
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::ensightPartFaces::~ensightPartFaces()
-{}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::ensightPartFaces::writeConnectivity
diff --git a/src/fileFormats/ensight/part/ensightPartFaces.H b/src/fileFormats/ensight/part/ensightPartFaces.H
index 71572d3183c76f278e57435c3945cc4ce9c3f6a3..da6ee09df948175db5d39a4de2670ea62fbfc37f 100644
--- a/src/fileFormats/ensight/part/ensightPartFaces.H
+++ b/src/fileFormats/ensight/part/ensightPartFaces.H
@@ -118,8 +118,8 @@ public:
         (
             label partIndex,
             const string& description,
-            const pointField&,
-            const faceList&,
+            const pointField& points,
+            const faceList& faces,
             const bool contiguousPoints = false
         );
 
@@ -127,54 +127,54 @@ public:
         ensightPartFaces
         (
             label partIndex,
-            const polyMesh&,
-            const polyPatch&
+            const polyMesh& mesh,
+            const polyPatch& patch
         );
 
 
     //- Destructor
-    virtual ~ensightPartFaces();
+    virtual ~ensightPartFaces() = default;
 
 
     // Member Functions
 
-        // Access
+    // Access
 
-            //- Part index (0-based)
-            virtual label index() const
-            {
-                return ensightFaces::index();
-            }
+        //- Part index (0-based)
+        virtual label index() const
+        {
+            return ensightFaces::index();
+        }
 
 
-            //- Number of elements in this part
-            virtual label size() const
-            {
-                return ensightFaces::size();
-            }
+        //- Number of elements in this part
+        virtual label size() const
+        {
+            return ensightFaces::size();
+        }
 
 
-            //- Return the patch index, -1 when not in use.
-            inline label patchIndex() const
-            {
-                return patchIndex_;
-            }
+        //- Return the patch index, -1 when not in use.
+        inline label patchIndex() const
+        {
+            return patchIndex_;
+        }
 
 
-        // Output
+    // Output
 
-            //- Write summary information about the object
-            virtual void writeSummary(Ostream&) const;
+        //- Write summary information about the object
+        virtual void writeSummary(Ostream& os) const;
 
-            //- Write geometry
-            virtual void write(ensightGeoFile&) const;
+        //- Write geometry
+        virtual void write(ensightGeoFile& os) const;
 
-            //- Helper: write geometry given the pointField
-            virtual void write(ensightGeoFile&, const pointField&) const;
+        //- Helper: write geometry given the pointField
+        virtual void write(ensightGeoFile& os, const pointField& points) const;
 
 
-            //- Print various types of debugging information
-            virtual void dumpInfo(Ostream&) const;
+        //- Print various types of debugging information
+        virtual void dumpInfo(Ostream& os) const;
 };
 
 
diff --git a/src/fileFormats/ensight/part/ensightParts.C b/src/fileFormats/ensight/part/ensightParts.C
index 2bcf5b96854c7ffaa8c2ed3fbf3edded80a56c03..43d0701ec185a69fca2cfb86432cfd333d2e458a 100644
--- a/src/fileFormats/ensight/part/ensightParts.C
+++ b/src/fileFormats/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  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,8 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ensightParts.H"
+#include "bitSet.H"
+#include "processorPolyPatch.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -35,12 +37,6 @@ Foam::ensightParts::ensightParts(const polyMesh& mesh)
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::ensightParts::~ensightParts()
-{}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::ensightParts::recalculate(const polyMesh& mesh)
@@ -48,65 +44,46 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
     StorageType::clear();
 
     label nPart = 0;
-    label nZoneCells = 0;
 
-    // do cell zones
-    forAll(mesh.cellZones(), zoneI)
-    {
-        const cellZone& cZone = mesh.cellZones()[zoneI];
-        nZoneCells += cZone.size();
+    // Track which cells are in a zone or not
+    bitSet selection(mesh.nCells());
 
-        if (cZone.size())
+    // Do cell zones
+    for (const cellZone& zn : mesh.cellZones())
+    {
+        if (zn.size())
         {
-            this->append(new ensightPartCells(nPart++, mesh, cZone));
+            selection.set(zn);
+            this->append(new ensightPartCells(nPart++, mesh, zn));
         }
     }
 
-    // collect unzoned cells
-
-    // special case: no zones at all - do entire mesh
-    if (nZoneCells == 0)
+    if (selection.none())
     {
+        // No zones at all? - do entire mesh
         this->append(new ensightPartCells(nPart++, mesh));
     }
-    else if (mesh.nCells() > nZoneCells)
+    else
     {
-        // determine which cells are not in a cellZone
-        labelList unzoned(mesh.nCells(), -1);
+        // Flip from zoned to unzoned
+        selection.flip();
 
-        forAll(mesh.cellZones(), zoneI)
+        if (selection.any())
         {
-            const labelUList& idList = mesh.cellZones()[zoneI];
-
-            forAll(idList, i)
-            {
-                unzoned[idList[i]] = idList[i];
-            }
-        }
-
-        label nUnzoned = 0;
-        forAll(unzoned, i)
-        {
-            if (unzoned[i] < 0)
-            {
-                unzoned[nUnzoned] = i;
-                nUnzoned++;
-            }
-        }
-        unzoned.setSize(nUnzoned);
-
-        if (unzoned.size())
-        {
-            this->append(new ensightPartCells(nPart++, mesh, unzoned));
+            this->append(new ensightPartCells(nPart++, mesh, selection));
         }
     }
 
 
-    // do boundaries, skipping empty and processor patches
-    forAll(mesh.boundaryMesh(), patchi)
+    // Do boundaries, skipping empty and processor patches
+    for (const polyPatch& patch : mesh.boundaryMesh())
     {
-        const polyPatch& patch = mesh.boundaryMesh()[patchi];
-        if (patch.size() && !isA<processorPolyPatch>(patch))
+        if (isA<processorPolyPatch>(patch))
+        {
+            // No processor patches
+            break;
+        }
+        if (patch.size())
         {
             this->append(new ensightPartFaces(nPart++, mesh, patch));
         }
@@ -119,10 +96,10 @@ void Foam::ensightParts::write(ensightGeoFile& os) const
     // Some feedback
     Info<< "Write geometry part (" << flush;
 
-    forAllConstIter(StorageType, *this, iter)
+    for (const ensightPart& part : *this)
     {
-        Info<< ' ' << (*iter).index() << flush;
-        (*iter).write(os);
+        Info<< ' ' << part.index() << flush;
+        part.write(os);
     }
     Info<< " )" << endl;
 }
@@ -130,18 +107,18 @@ void Foam::ensightParts::write(ensightGeoFile& os) const
 
 void Foam::ensightParts::writeSummary(Ostream& os) const
 {
-    forAllConstIter(StorageType, *this, iter)
+    for (const ensightPart& part : *this)
     {
-        (*iter).writeSummary(os);
+        part.writeSummary(os);
     }
 }
 
 
 void Foam::ensightParts::dumpInfo(Ostream& os) const
 {
-    forAllConstIter(StorageType, *this, iter)
+    for (const ensightPart& part : *this)
     {
-        (*iter).dumpInfo(os);
+        part.dumpInfo(os);
     }
 }
 
diff --git a/src/fileFormats/ensight/part/ensightParts.H b/src/fileFormats/ensight/part/ensightParts.H
index d68b21e8a3c47fa4f5e185225d5f5eb71b0ec498..fb9528f80202cb17fe8112282433b12b9b936376 100644
--- a/src/fileFormats/ensight/part/ensightParts.H
+++ b/src/fileFormats/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  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,7 +39,6 @@ SourceFiles
 #include "ensightPart.H"
 #include "ensightPartFaces.H"
 #include "ensightPartCells.H"
-#include "volFields.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -72,30 +71,30 @@ public:
     // Constructors
 
         //- Construct from polyMesh
-        ensightParts(const polyMesh&);
+        explicit ensightParts(const polyMesh& mesh);
 
 
     //- Destructor
-    ~ensightParts();
+    ~ensightParts() = default;
 
 
-    // Member functions
+    // Member Functions
 
         //- Clear old information and construct anew from polyMesh
-        void recalculate(const polyMesh&);
+        void recalculate(const polyMesh& mesh);
 
         //- Number of parts
         using StorageType::size;
 
 
         //- Write the geometry
-        void write(ensightGeoFile&) const;
+        void write(ensightGeoFile& os) const;
 
         //- Write summary information about the objects
-        void writeSummary(Ostream&) const;
+        void writeSummary(Ostream& os) const;
 
         //- Print various types of debugging information
-        void dumpInfo(Ostream&) const;
+        void dumpInfo(Ostream& os) const;
 
 };