From a59c87d5ac2e063d36ad21ae8a60bfe0163376fd Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 10 Nov 2017 02:09:37 +0100
Subject: [PATCH] ENH: improved zone constructors

- constructor for empty cell/face/point Zones, with contents to be
  transferred in later.

- ZoneMesh::operator(const word&) to return existing zone or a new empty one.
---
 .../mesh/conversion/ansysToFoam/ansysToFoam.L |   2 +-
 .../fluent3DMeshToFoam/fluent3DMeshToFoam.L   |   3 -
 .../fluentMeshToFoam/fluentMeshToFoam.L       |   3 +-
 .../mesh/conversion/gmshToFoam/gmshToFoam.C   |   2 +-
 .../ideasUnvToFoam/ideasUnvToFoam.C           |   2 +-
 .../generation/blockMesh/mergePatchPairs.H    |  10 +-
 .../extrude/extrudeMesh/extrudeMesh.C         |   2 +-
 .../manipulation/mergeMeshes/mergePolyMesh.C  |  60 +++-----
 .../manipulation/setsToZones/setsToZones.C    | 127 ++++++---------
 .../mesh/manipulation/stitchMesh/stitchMesh.C | 145 ++++--------------
 .../redistributePar/loadOrCreateMesh.C        |   8 -
 .../meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C |  71 +++++++--
 .../meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H |  30 +++-
 .../meshes/polyMesh/zones/cellZone/cellZone.C |  49 +++++-
 .../meshes/polyMesh/zones/cellZone/cellZone.H |  47 ++++--
 .../meshes/polyMesh/zones/faceZone/faceZone.C |  90 +++++++++--
 .../meshes/polyMesh/zones/faceZone/faceZone.H |  66 +++++---
 .../polyMesh/zones/pointZone/pointZone.C      |  54 ++++++-
 .../polyMesh/zones/pointZone/pointZone.H      |  38 ++++-
 .../meshes/polyMesh/zones/zone/zone.C         |  50 +++++-
 .../meshes/polyMesh/zones/zone/zone.H         |  41 +++--
 src/conversion/ccm/reader/ccmReaderMesh.C     |   2 +-
 src/conversion/common/reader/meshReader.C     |   2 +-
 src/dynamicMesh/fvMeshSubset/fvMeshSubset.C   |  14 +-
 src/dynamicMesh/fvMeshTools/fvMeshTools.C     |   4 -
 .../polyTopoChange/polyTopoChange.C           |   4 -
 .../linearValveFvMesh/linearValveFvMesh.C     |  26 +---
 .../linearValveLayersFvMesh.C                 |  28 +---
 .../mixerFvMesh/mixerFvMesh.C                 |  28 +---
 29 files changed, 579 insertions(+), 429 deletions(-)

diff --git a/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L b/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
index 61b89c279c3..e1202c70043 100644
--- a/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
+++ b/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
@@ -642,7 +642,7 @@ int main(int argc, char *argv[])
                     (
                         patchNames[patchi],
                         bFaceLabels,
-                        boolList(bFaceLabels.size(), false),
+                        false, // none are flipped
                         fz.size(),
                         pShapeMesh.faceZones()
                     )
diff --git a/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L b/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
index 8898cded2c6..7f06475c504 100644
--- a/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
+++ b/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
@@ -1156,7 +1156,6 @@ int main(int argc, char *argv[])
             new cellZone
             (
                 name,
-                labelList(0),
                 cellZonei,
                 mesh.cellZones()
             )
@@ -1186,8 +1185,6 @@ int main(int argc, char *argv[])
             new faceZone
             (
                 name,
-                labelList(0),
-                boolList(0),
                 faceZonei,
                 mesh.faceZones()
             )
diff --git a/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L b/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
index 527d7e368c4..e00bbcf9075 100644
--- a/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
+++ b/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
@@ -1077,7 +1077,6 @@ int main(int argc, char *argv[])
         // Create new faces
         forAll(faces, facei)
         {
-
             if (faces[facei].size() != 2)
             {
                 FatalErrorInFunction
@@ -1660,7 +1659,7 @@ int main(int argc, char *argv[])
             (
                 name,
                 zoneFaces,
-                boolList(zoneFaces.size(), false),
+                false, // none are flipped
                 cnt,
                 pShapeMesh.faceZones()
             );
diff --git a/applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C b/applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C
index 398563d9cbc..c107f03e384 100644
--- a/applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C
+++ b/applications/utilities/mesh/conversion/gmshToFoam/gmshToFoam.C
@@ -1102,7 +1102,7 @@ int main(int argc, char *argv[])
                 (
                     zoneName,
                     zoneFaces[zoneI],
-                    boolList(zoneFaces[zoneI].size(), true),
+                    true, // all are flipped
                     nValidFaceZones,
                     mesh.faceZones()
                 );
diff --git a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
index ea44a998a6b..ccb2e5e42fd 100644
--- a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
+++ b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
@@ -1282,7 +1282,7 @@ int main(int argc, char *argv[])
                 (
                     faceZones.toc()[cnt],
                     indizes,
-                    boolList(indizes.size(),false),
+                    false, // none are flipped
                     cnt,
                     mesh.faceZones()
                 );
diff --git a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
index fa25d815eab..c4e472363c9 100644
--- a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
+++ b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
@@ -16,10 +16,10 @@
                   + name(pairI)
                 );
 
+                // An empty zone for cut points
                 pz[pairI] = new pointZone
                 (
                     mergeName + "CutPointZone",
-                    labelList(0),
                     0,
                     mesh.pointZones()
                 );
@@ -40,7 +40,7 @@
                 (
                     mergeName + "MasterZone",
                     isf,
-                    boolList(masterPatch.size(), false),
+                    false, // none are flipped
                     0,
                     mesh.faceZones()
                 );
@@ -61,17 +61,15 @@
                 (
                     mergeName + "SlaveZone",
                     osf,
-                    boolList(slavePatch.size(), false),
+                    false, // none are flipped
                     1,
                     mesh.faceZones()
                 );
 
-                // Add empty zone for cut faces
+                // An empty zone for cut faces
                 fz[3*pairI + 2] = new faceZone
                 (
                     mergeName + "CutFaceZone",
-                    labelList(0),
-                    boolList(0, false),
                     2,
                     mesh.faceZones()
                 );
diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
index a08f245e14d..731e38f67bd 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
@@ -1026,7 +1026,7 @@ int main(int argc, char *argv[])
             (
                 cutZoneName,
                 frontPatchFaces,
-                boolList(frontPatchFaces.size(), false),
+                false, // none are flipped
                 0,
                 mesh.faceZones()
             )
diff --git a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
index 72f0a675d54..7a114c3e221 100644
--- a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
+++ b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
@@ -502,70 +502,58 @@ void Foam::mergePolyMesh::merge()
     // Add the zones if necessary
     if (pointZoneNames_.size() > pointZones().size())
     {
-        Info<< "Adding new pointZones. " << endl;
-        label nZones = pointZones().size();
+        Info<< "Adding new pointZones." << endl;
 
-        pointZones().setSize(pointZoneNames_.size());
+        label zonei = pointZones().size(); // continue from here
 
-        for (label zoneI = nZones; zoneI < pointZoneNames_.size(); zoneI++)
+        const label nZones = pointZoneNames_.size();
+
+        pointZones().setSize(nZones);
+
+        for (/*nil*/; zonei < nZones; ++zonei)
         {
             pointZones().set
             (
-                zoneI,
-                new pointZone
-                (
-                    pointZoneNames_[zoneI],
-                    labelList(),
-                    zoneI,
-                    pointZones()
-                )
+                zonei,
+                new pointZone(pointZoneNames_[zonei], zonei, pointZones())
             );
         }
     }
     if (cellZoneNames_.size() > cellZones().size())
     {
-        Info<< "Adding new cellZones. " << endl;
+        Info<< "Adding new cellZones." << endl;
+
+        label zonei = cellZones().size(); // continue from here
 
-        label nZones = cellZones().size();
+        const label nZones = cellZoneNames_.size();
 
         cellZones().setSize(cellZoneNames_.size());
 
-        for (label zoneI = nZones; zoneI < cellZoneNames_.size(); zoneI++)
+        for (/*nil*/; zonei < nZones; ++zonei)
         {
             cellZones().set
             (
-                zoneI,
-                new cellZone
-                (
-                    cellZoneNames_[zoneI],
-                    labelList(),
-                    zoneI,
-                    cellZones()
-                )
+                zonei,
+                new cellZone(cellZoneNames_[zonei], zonei, cellZones())
             );
         }
     }
     if (faceZoneNames_.size() > faceZones().size())
     {
-        Info<< "Adding new faceZones. " << endl;
+        Info<< "Adding new faceZones." << endl;
+
+        label zonei = faceZones().size(); // continue from here
 
-        label nZones = faceZones().size();
+        const label nZones = faceZoneNames_.size();
 
-        faceZones().setSize(faceZoneNames_.size());
+        faceZones().setSize(nZones);
 
-        for (label zoneI = nZones; zoneI < faceZoneNames_.size(); zoneI++)
+        for (/*nil*/; zonei < nZones; ++zonei)
         {
             faceZones().set
             (
-                zoneI,
-                new faceZone
-                (
-                    faceZoneNames_[zoneI],
-                    labelList(),
-                    boolList(),
-                    zoneI,
-                    faceZones()
-                )
+                zonei,
+                new faceZone(faceZoneNames_[zonei], zonei, faceZones())
             );
         }
     }
diff --git a/applications/utilities/mesh/manipulation/setsToZones/setsToZones.C b/applications/utilities/mesh/manipulation/setsToZones/setsToZones.C
index 2b30a5d7fa2..f6b2dccc503 100644
--- a/applications/utilities/mesh/manipulation/setsToZones/setsToZones.C
+++ b/applications/utilities/mesh/manipulation/setsToZones/setsToZones.C
@@ -113,36 +113,28 @@ int main(int argc, char *argv[])
         pointSet set(*iter());
         SortableList<label> pointLabels(set.toc());
 
-        label zoneID = mesh.pointZones().findZoneID(set.name());
-        if (zoneID == -1)
+        // The original number of zones
+        const label nOrigZones = mesh.pointZones().size();
+
+        // Get existing or create new empty zone
+        pointZone& zn = mesh.pointZones()(set.name());
+
+        if (nOrigZones == mesh.pointZones().size())
         {
-            Info<< "Adding set " << set.name() << " as a pointZone." << endl;
-            label sz = mesh.pointZones().size();
-            mesh.pointZones().setSize(sz+1);
-            mesh.pointZones().set
-            (
-                sz,
-                new pointZone
-                (
-                    set.name(),             //name
-                    pointLabels,            //addressing
-                    sz,                     //index
-                    mesh.pointZones()       //pointZoneMesh
-                )
-            );
-            mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
-            mesh.pointZones().instance() = mesh.facesInstance();
+            Info<< "Overwriting contents of existing pointZone "
+                << zn.index()
+                << " with that of set " << set.name() << "." << endl;
         }
         else
         {
-            Info<< "Overwriting contents of existing pointZone " << zoneID
-                << " with that of set " << set.name() << "." << endl;
-            mesh.pointZones()[zoneID] = pointLabels;
-            mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
-            mesh.pointZones().instance() = mesh.facesInstance();
+            Info<< "Adding set " << set.name() << " as a pointZone." << endl;
         }
-    }
 
+        zn = pointLabels;
+
+        mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
+        mesh.pointZones().instance() = mesh.facesInstance();
+    }
 
 
     IOobjectList faceObjects(objects.lookupClass(faceSet::typeName));
@@ -244,39 +236,31 @@ int main(int argc, char *argv[])
             }
         }
 
-        label zoneID = mesh.faceZones().findZoneID(set.name());
-        if (zoneID == -1)
+        // The original number of zones
+        const label nOrigZones = mesh.faceZones().size();
+
+        // Get existing or create new empty zone
+        faceZone& zn = mesh.faceZones()(set.name());
+
+        if (nOrigZones == mesh.faceZones().size())
         {
-            Info<< "Adding set " << set.name() << " as a faceZone." << endl;
-            label sz = mesh.faceZones().size();
-            mesh.faceZones().setSize(sz+1);
-            mesh.faceZones().set
-            (
-                sz,
-                new faceZone
-                (
-                    set.name(),             //name
-                    addressing.shrink(),    //addressing
-                    flipMap.shrink(),       //flipmap
-                    sz,                     //index
-                    mesh.faceZones()        //pointZoneMesh
-                )
-            );
-            mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
-            mesh.faceZones().instance() = mesh.facesInstance();
+            Info<< "Overwriting contents of existing faceZone "
+                << zn.index()
+                << " with that of set " << set.name() << "." << endl;
         }
         else
         {
-            Info<< "Overwriting contents of existing faceZone " << zoneID
-                << " with that of set " << set.name() << "." << endl;
-            mesh.faceZones()[zoneID].resetAddressing
-            (
-                addressing.shrink(),
-                flipMap.shrink()
-            );
-            mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
-            mesh.faceZones().instance() = mesh.facesInstance();
+            Info<< "Adding set " << set.name() << " as a faceZone." << endl;
         }
+
+        zn.resetAddressing
+        (
+            addressing.shrink(),
+            flipMap.shrink()
+        );
+
+        mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
+        mesh.faceZones().instance() = mesh.facesInstance();
     }
 
 
@@ -293,39 +277,30 @@ int main(int argc, char *argv[])
             cellSet set(*iter());
             SortableList<label> cellLabels(set.toc());
 
-            label zoneID = mesh.cellZones().findZoneID(set.name());
-            if (zoneID == -1)
+            // The original number of zones
+            const label nOrigZones = mesh.cellZones().size();
+
+            cellZone& zn = mesh.cellZones()(set.name());
+
+            if (nOrigZones == mesh.cellZones().size())
             {
-                Info<< "Adding set " << set.name() << " as a cellZone." << endl;
-                label sz = mesh.cellZones().size();
-                mesh.cellZones().setSize(sz+1);
-                mesh.cellZones().set
-                (
-                    sz,
-                    new cellZone
-                    (
-                        set.name(),             //name
-                        cellLabels,             //addressing
-                        sz,                     //index
-                        mesh.cellZones()        //pointZoneMesh
-                    )
-                );
-                mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
-                mesh.cellZones().instance() = mesh.facesInstance();
+                Info<< "Overwriting contents of existing cellZone "
+                    << zn.index()
+                    << " with that of set " << set.name() << "." << endl;
             }
             else
             {
-                Info<< "Overwriting contents of existing cellZone " << zoneID
-                    << " with that of set " << set.name() << "." << endl;
-                mesh.cellZones()[zoneID] = cellLabels;
-                mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
-                mesh.cellZones().instance() = mesh.facesInstance();
+                Info<< "Adding set " << set.name() << " as a cellZone." << endl;
             }
+
+            zn = cellLabels;
+
+            mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
+            mesh.cellZones().instance() = mesh.facesInstance();
         }
     }
 
 
-
     Info<< "Writing mesh." << endl;
 
     if (!mesh.write())
diff --git a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
index ca0289a10e5..4b524880cef 100644
--- a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
+++ b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
@@ -72,109 +72,8 @@ Description
 #include "IOobjectList.H"
 #include "ReadFields.H"
 
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-label addPointZone(polyMesh& mesh, const word& name)
-{
-    pointZoneMesh& zones = mesh.pointZones();
-    label zoneID = zones.findZoneID(name);
-
-    if (zoneID != -1)
-    {
-        Info<< "Reusing existing pointZone " << zones[zoneID].name()
-            << " at index " << zoneID << endl;
-
-        return zoneID;
-    }
-
-    zoneID = zones.size();
-    Info<< "Adding pointZone " << name << " at index " << zoneID << endl;
-
-    zones.setSize(zoneID+1);
-    zones.set
-    (
-        zoneID,
-        new pointZone
-        (
-            name,
-            labelList(0),
-            zoneID,
-            zones
-        )
-    );
-
-    return zoneID;
-}
-
-
-label addFaceZone(polyMesh& mesh, const word& name)
-{
-    faceZoneMesh& zones = mesh.faceZones();
-    label zoneID = zones.findZoneID(name);
-
-    if (zoneID != -1)
-    {
-        Info<< "Reusing existing faceZone " << zones[zoneID].name()
-            << " at index " << zoneID << endl;
-
-        return zoneID;
-    }
-
-    zoneID = zones.size();
-    Info<< "Adding faceZone " << name << " at index " << zoneID << endl;
-
-    zones.setSize(zoneID+1);
-    zones.set
-    (
-        zoneID,
-        new faceZone
-        (
-            name,
-            labelList(0),
-            boolList(),
-            zoneID,
-            zones
-        )
-    );
-
-    return zoneID;
-}
-
-
-label addCellZone(polyMesh& mesh, const word& name)
-{
-    cellZoneMesh& zones = mesh.cellZones();
-    label zoneID = zones.findZoneID(name);
-
-    if (zoneID != -1)
-    {
-        Info<< "Reusing existing cellZone " << zones[zoneID].name()
-            << " at index " << zoneID << endl;
-
-        return zoneID;
-    }
-
-    zoneID = zones.size();
-    Info<< "Adding cellZone " << name << " at index " << zoneID << endl;
-
-    zones.setSize(zoneID+1);
-    zones.set
-    (
-        zoneID,
-        new cellZone
-        (
-            name,
-            labelList(0),
-            zoneID,
-            zones
-        )
-    );
-
-    return zoneID;
-}
-
-
 // Checks whether patch present
 void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
 {
@@ -198,7 +97,6 @@ void checkPatch(const polyBoundaryMesh& bMesh, const word& name)
 }
 
 
-
 int main(int argc, char *argv[])
 {
     argList::addNote
@@ -341,10 +239,12 @@ int main(int argc, char *argv[])
 
     if (perfectCover)
     {
-        // Add empty zone for resulting internal faces
-        const label cutZoneID = addFaceZone(mesh, cutZoneName);
-
-        mesh.faceZones()[cutZoneID].resetAddressing(isf.xfer(), false);
+        // Starts as master zone, but receives the resulting internal faces
+        mesh.faceZones()
+        (
+            cutZoneName,
+            true // verbose
+        ).resetAddressing(isf.xfer(), false);
 
         // Add the perfect interface mesh modifier
         stitcher.set
@@ -363,12 +263,19 @@ int main(int argc, char *argv[])
     }
     else
     {
-        label pointZoneID = addPointZone(mesh, mergePatchName + "CutPointZone");
-        mesh.pointZones()[pointZoneID] = labelList(0);
-
-        label masterZoneID = addFaceZone(mesh, mergePatchName + "MasterZone");
+        // An empty point zone
+        mesh.pointZones()
+        (
+            mergePatchName + "CutPointZone",
+            true // verbose
+        ) = labelList();
 
-        mesh.faceZones()[masterZoneID].resetAddressing(isf.xfer(), false);
+        // The master zone
+        mesh.faceZones()
+        (
+            mergePatchName + "MasterZone",
+            true // verbose
+        ).resetAddressing(isf.xfer(), false);
 
         // Slave patch
         const polyPatch& slavePatch = mesh.boundaryMesh()[slavePatchName];
@@ -380,12 +287,18 @@ int main(int argc, char *argv[])
             osf[i] = slavePatch.start() + i;
         }
 
-        label slaveZoneID = addFaceZone(mesh, mergePatchName + "SlaveZone");
-        mesh.faceZones()[slaveZoneID].resetAddressing(osf.xfer(), false);
+        mesh.faceZones()
+        (
+            mergePatchName + "SlaveZone",
+            true // verbose
+        ).resetAddressing(osf.xfer(), false);
 
-        // Add empty zone for cut faces
-        const label cutZoneID = addFaceZone(mesh, cutZoneName);
-        mesh.faceZones()[cutZoneID].resetAddressing(labelList(0), false);
+        // An empty zone for cut faces
+        mesh.faceZones()
+        (
+            cutZoneName,
+            true // verbose
+        ).resetAddressing(labelList(), false);
 
 
         // Add the sliding interface mesh modifier
diff --git a/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C b/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C
index b9f55ec82df..db4582034b2 100644
--- a/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C
+++ b/applications/utilities/parallelProcessing/redistributePar/loadOrCreateMesh.C
@@ -218,7 +218,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             new pointZone
             (
                 "dummyPointZone",
-                labelList(0),
                 0,
                 dummyMesh.pointZones()
             )
@@ -229,8 +228,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             new faceZone
             (
                 "dummyFaceZone",
-                labelList(0),
-                boolList(0),
                 0,
                 dummyMesh.faceZones()
             )
@@ -241,7 +238,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             new cellZone
             (
                 "dummyCellZone",
-                labelList(0),
                 0,
                 dummyMesh.cellZones()
             )
@@ -347,7 +343,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             pz[i] = new pointZone
             (
                 pointZoneNames[i],
-                labelList(0),
                 i,
                 mesh.pointZones()
             );
@@ -358,8 +353,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             fz[i] = new faceZone
             (
                 faceZoneNames[i],
-                labelList(0),
-                boolList(0),
                 i,
                 mesh.faceZones()
             );
@@ -370,7 +363,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
             cz[i] = new cellZone
             (
                 cellZoneNames[i],
-                labelList(0),
                 i,
                 mesh.cellZones()
             );
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
index 9c67afde9b4..11a94d7c887 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
@@ -61,9 +61,9 @@ void Foam::ZoneMesh<ZoneType, MeshType>::calcZoneMap() const
         {
             const labelList& zoneObjects = this->operator[](zonei);
 
-            forAll(zoneObjects, objI)
+            for (const label idx : zoneObjects)
             {
-                zm.insert(zoneObjects[objI], zonei);
+                zm.insert(idx, zonei);
             }
         }
     }
@@ -113,11 +113,9 @@ bool Foam::ZoneMesh<ZoneType, MeshType>::read()
 
         return true;
     }
-    else
-    {
-        // Nothing read
-        return false;
-    }
+
+    // Nothing read
+    return false;
 }
 
 
@@ -209,6 +207,7 @@ Foam::ZoneMesh<ZoneType, MeshType>::ZoneMesh
         // Nothing read. Use supplied zones
         PtrList<ZoneType>& zones = *this;
         zones.setSize(pzm.size());
+
         forAll(zones, zonei)
         {
             zones.set(zonei, pzm[zonei].clone(*this).ptr());
@@ -630,6 +629,45 @@ ZoneType& Foam::ZoneMesh<ZoneType, MeshType>::operator[]
 }
 
 
+template<class ZoneType, class MeshType>
+ZoneType& Foam::ZoneMesh<ZoneType, MeshType>::operator()
+(
+    const word& zoneName,
+    const bool verbose
+)
+{
+    PtrList<ZoneType>& zones = *this;
+
+    label zoneId = findZoneID(zoneName);
+
+    if (zoneId < 0)
+    {
+        zoneId = zones.size();
+
+        zones.setSize(zoneId+1);
+        zones.set(zoneId, new ZoneType(zoneName, zoneId, *this));
+
+        if (verbose)
+        {
+            Info<< ZoneType::typeName << " " << zoneName
+                << " (new at index " << zoneId << ")"
+                << endl;
+        }
+    }
+    else
+    {
+        if (verbose)
+        {
+            Info<< ZoneType::typeName << " " << zoneName
+                << " (existing at index " << zoneId << ")"
+                << endl;
+        }
+    }
+
+    return zones[zoneId];
+}
+
+
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
 template<class ZoneType, class MeshType>
@@ -639,14 +677,23 @@ Foam::Ostream& Foam::operator<<
     const ZoneMesh<ZoneType, MeshType>& zones
 )
 {
-    os  << zones.size() << nl << token::BEGIN_LIST;
+    const label sz = zones.size();
 
-    forAll(zones, zonei)
+    if (sz)
     {
-        zones[zonei].writeDict(os);
-    }
+        os  << sz << nl << token::BEGIN_LIST;
+
+        for (label i=0; i<sz; ++i)
+        {
+            zones[i].writeDict(os);
+        }
 
-    os  << token::END_LIST;
+        os  << token::END_LIST;
+    }
+    else
+    {
+        os  << sz << token::BEGIN_LIST << token::END_LIST;
+    }
 
     return os;
 }
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
index 9c83890d767..232e87ce593 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
@@ -145,7 +145,7 @@ public:
         const Map<label>& zoneMap() const;
 
         //- Given a global object index, return the zone it is in.
-        // If object does not belong to any zones, return -1
+        //  If object does not belong to any zones, return -1
         label whichZone(const label objectIndex) const;
 
         //- Return a list of zone types
@@ -179,7 +179,7 @@ public:
         //- Find zone index given a name, return -1 if not found
         label findZoneID(const word& zoneName) const;
 
-        //- Mark cells that match the zone specification
+        //- Mark items (cells, faces, points) that match the zone specification
         PackedBoolList findMatching(const keyType& key) const;
 
         //- Clear addressing
@@ -203,15 +203,35 @@ public:
 
     // Member Operators
 
-        //- Return const and non-const reference to ZoneType by index.
+        //- Return const and non-const reference to zone by index.
         using PtrList<ZoneType>::operator[];
 
-        //- Return const reference to ZoneType by name.
+        //- Return const reference to zone by name.
+        //  Fatal if the zone does not exist.
         const ZoneType& operator[](const word& zoneName) const;
 
-        //- Return reference to ZoneType by name.
+        //- Return reference to an existing zone by name
+        //  Fatal if the zone does not exist.
         ZoneType& operator[](const word& zoneName);
 
+        //- Find an existing zone by name or create a new empty one
+        //- if required.
+        //
+        //  To determine if the zone already existed or was newly created,
+        //  it will be necessary to add additional logic in the caller.
+        //  For example,
+        //  \code
+        //      const label nOrig = zones.size();
+        //
+        //      ZoneType& zn = zones("zoneName");
+        //
+        //      if (nOrig == zones.size()) { existing... } else { new... }
+        //  \endcode
+        //  \param verbose report if an existing zone was selected or
+        //      a new zone was created.
+        //  \return non-const reference to the existing or new zone
+        ZoneType& operator()(const word& zoneName, const bool verbose=false);
+
 
     // Ostream operator
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
index 4940529e115..4790bf176b0 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,18 @@ const char * const Foam::cellZone::labelsName = "cellLabels";
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::cellZone::cellZone
+(
+    const word& name,
+    const label index,
+    const cellZoneMesh& zm
+)
+:
+    zone(name, index),
+    zoneMesh_(zm)
+{}
+
+
 Foam::cellZone::cellZone
 (
     const word& name,
@@ -58,6 +70,19 @@ Foam::cellZone::cellZone
 {}
 
 
+Foam::cellZone::cellZone
+(
+    const word& name,
+    labelList&& addr,
+    const label index,
+    const cellZoneMesh& zm
+)
+:
+    zone(name, std::move(addr), index),
+    zoneMesh_(zm)
+{}
+
+
 Foam::cellZone::cellZone
 (
     const word& name,
@@ -86,25 +111,39 @@ Foam::cellZone::cellZone
 
 Foam::cellZone::cellZone
 (
-    const cellZone& cz,
+    const cellZone& origZone,
     const labelUList& addr,
     const label index,
     const cellZoneMesh& zm
 )
 :
-    zone(cz, addr, index),
+    zone(origZone, addr, index),
+    zoneMesh_(zm)
+{}
+
+
+Foam::cellZone::cellZone
+(
+    const cellZone& origZone,
+    labelList&& addr,
+    const label index,
+    const cellZoneMesh& zm
+)
+:
+    zone(origZone, std::move(addr), index),
     zoneMesh_(zm)
 {}
 
+
 Foam::cellZone::cellZone
 (
-    const cellZone& cz,
+    const cellZone& origZone,
     const Xfer<labelList>& addr,
     const label index,
     const cellZoneMesh& zm
 )
 :
-    zone(cz, addr, index),
+    zone(origZone, addr, index),
     zoneMesh_(zm)
 {}
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
index 3d3658b207e..fe39d79d24c 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -109,6 +109,9 @@ public:
 
     // Constructors
 
+        //- Construct an empty zone
+        cellZone(const word& name, const label index, const cellZoneMesh& zm);
+
         //- Construct from components
         cellZone
         (
@@ -118,7 +121,16 @@ public:
             const cellZoneMesh& zm
         );
 
-        //- Construct from components, transferring contents
+        //- Construct from components, transferring addressing
+        cellZone
+        (
+            const word& name,
+            labelList&& addr,
+            const label index,
+            const cellZoneMesh& zm
+        );
+
+        //- Construct from components, transferring addressing
         cellZone
         (
             const word& name,
@@ -136,26 +148,37 @@ public:
             const cellZoneMesh& zm
         );
 
-        //- Construct given the original zone,
-        //  resetting the cell list and zone mesh information
+        //- Construct given the original zone (name is used),
+        //- and resetting the cell list and zone mesh information
         cellZone
         (
-            const cellZone& cz,
+            const cellZone& origZone,
             const labelUList& addr,
             const label index,
             const cellZoneMesh& zm
         );
 
-        //- Construct given the original zone,
-        //  resetting the cell list and zone mesh information
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, resetting the cell addressing.
         cellZone
         (
-            const cellZone& cz,
+            const cellZone& origZone,
+            labelList&& addr,
+            const label index,
+            const cellZoneMesh& zm
+        );
+
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, (move) resetting the cell addressing.
+        cellZone
+        (
+            const cellZone& origZone,
             const Xfer<labelList>& addr,
             const label index,
             const cellZoneMesh& zm
         );
 
+
         //- Construct and return a clone, resetting the zone mesh
         virtual autoPtr<cellZone> clone(const cellZoneMesh& zm) const
         {
@@ -165,8 +188,8 @@ public:
             );
         }
 
-        //- Construct and return a clone, resetting the cell list
-        //  and zone mesh
+        //- Construct and return a clone,
+        //- resetting the cell list and zone mesh
         virtual autoPtr<cellZone> clone
         (
             const labelUList& addr,
@@ -184,7 +207,7 @@ public:
     // Selectors
 
         //- Return a pointer to a new cell zone
-        //  created on freestore from dictionary
+        //- created on freestore from dictionary
         static autoPtr<cellZone> New
         (
             const word& name,
@@ -228,7 +251,7 @@ public:
         //- Assign addressing, clearing demand-driven data
         void operator=(const labelUList& addr);
 
-        //- Assign addressing, clearing demand-driven data
+        //- Move assign addressing, clearing demand-driven data
         void operator=(const Xfer<labelList>& addr);
 
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
index f91a48b9e33..895ff740c4b 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -43,20 +43,21 @@ namespace Foam
 
 const char* const Foam::faceZone::labelsName = "faceLabels";
 
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::faceZone::setFlipMap(const bool flipValue)
+void Foam::faceZone::setFlipMap(const bool val)
 {
     // Match size for flipMap
     if (flipMap_.size() == this->size())
     {
-        flipMap_ = flipValue;
+        flipMap_ = val;
     }
     else
     {
         // Avoid copying old values on resize
         flipMap_.clear();
-        flipMap_.setSize(this->size(), flipValue);
+        flipMap_.setSize(this->size(), val);
     }
 }
 
@@ -200,6 +201,67 @@ void Foam::faceZone::checkAddressing() const
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::faceZone::faceZone
+(
+    const word& name,
+    const label index,
+    const faceZoneMesh& zm
+)
+:
+    zone(name, index),
+    flipMap_(),
+    zoneMesh_(zm),
+    patchPtr_(nullptr),
+    masterCellsPtr_(nullptr),
+    slaveCellsPtr_(nullptr),
+    mePtr_(nullptr)
+{}
+
+
+Foam::faceZone::faceZone
+(
+    const word& name,
+    const labelUList& addr,
+    const bool flipMapValue,
+    const label index,
+    const faceZoneMesh& zm
+)
+:
+    zone(name, addr, index),
+    flipMap_(),
+    zoneMesh_(zm),
+    patchPtr_(nullptr),
+    masterCellsPtr_(nullptr),
+    slaveCellsPtr_(nullptr),
+    mePtr_(nullptr)
+{
+    flipMap_.setSize(size(), flipMapValue);
+    checkAddressing();
+}
+
+
+Foam::faceZone::faceZone
+(
+    const word& name,
+    labelList&& addr,
+    const bool flipMapValue,
+    const label index,
+    const faceZoneMesh& zm
+)
+:
+    zone(name, std::move(addr), index),
+    flipMap_(),
+    zoneMesh_(zm),
+    patchPtr_(nullptr),
+    masterCellsPtr_(nullptr),
+    slaveCellsPtr_(nullptr),
+    mePtr_(nullptr)
+{
+    flipMap_.setSize(size(), flipMapValue);
+    checkAddressing();
+}
+
+
 Foam::faceZone::faceZone
 (
     const word& name,
@@ -264,14 +326,14 @@ Foam::faceZone::faceZone
 
 Foam::faceZone::faceZone
 (
-    const faceZone& fz,
+    const faceZone& origZone,
     const labelUList& addr,
     const boolList& fm,
     const label index,
     const faceZoneMesh& zm
 )
 :
-    zone(fz, addr, index),
+    zone(origZone, addr, index),
     flipMap_(fm),
     zoneMesh_(zm),
     patchPtr_(nullptr),
@@ -285,14 +347,14 @@ Foam::faceZone::faceZone
 
 Foam::faceZone::faceZone
 (
-    const faceZone& fz,
+    const faceZone& origZone,
     const Xfer<labelList>& addr,
     const Xfer<boolList>& fm,
     const label index,
     const faceZoneMesh& zm
 )
 :
-    zone(fz, addr, index),
+    zone(origZone, addr, index),
     flipMap_(fm),
     zoneMesh_(zm),
     patchPtr_(nullptr),
@@ -394,36 +456,36 @@ void Foam::faceZone::clearAddressing()
 void Foam::faceZone::resetAddressing
 (
     const labelUList& addr,
-    const boolList& flipMap
+    const bool flipMapValue
 )
 {
     clearAddressing();
     labelList::operator=(addr);
-    flipMap_ = flipMap;
+    setFlipMap(flipMapValue);
 }
 
 
 void Foam::faceZone::resetAddressing
 (
     const labelUList& addr,
-    const bool flipValue
+    const boolList& flipMap
 )
 {
     clearAddressing();
     labelList::operator=(addr);
-    setFlipMap(flipValue);
+    flipMap_ = flipMap;
 }
 
 
 void Foam::faceZone::resetAddressing
 (
     const Xfer<labelList>& addr,
-    const bool flipValue
+    const bool flipMapValue
 )
 {
     clearAddressing();
     labelList::operator=(addr);
-    setFlipMap(flipValue);
+    setFlipMap(flipMapValue);
 }
 
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
index 5a6896db7c1..0d1d6607eb2 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,8 +68,8 @@ class faceZone
 {
     // Private Member Functions
 
-        //- Set flip-map to constant value
-        void setFlipMap(const bool flipValue);
+        //- Set flip-map to uniform value
+        void setFlipMap(const bool val);
 
         //- Disallow default bitwise copy construct
         faceZone(const faceZone&) = delete;
@@ -148,6 +148,30 @@ public:
 
     // Constructors
 
+        //- Construct an empty zone
+        faceZone(const word& name, const label index, const faceZoneMesh& zm);
+
+        //- Construct from components with uniform flip map value
+        faceZone
+        (
+            const word& name,
+            const labelUList& addr,
+            const bool flipMapValue,
+            const label index,
+            const faceZoneMesh& zm
+        );
+
+        //- Construct from components with uniform flip map value,
+        //- transferring addressing.
+        faceZone
+        (
+            const word& name,
+            labelList&& addr,
+            const bool flipMapValue,
+            const label index,
+            const faceZoneMesh& zm
+        );
+
         //- Construct from components
         faceZone
         (
@@ -158,7 +182,7 @@ public:
             const faceZoneMesh& zm
         );
 
-        //- Construct from components, transferring contents
+        //- Construct from components, transferring addressing
         faceZone
         (
             const word& name,
@@ -177,22 +201,24 @@ public:
             const faceZoneMesh& zm
         );
 
-        //- Construct given the original zone and resetting the
-        //  face list and zone mesh information
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, resetting the face addressing
+        //- and flip-map.
         faceZone
         (
-            const faceZone& fz,
+            const faceZone& origZone,
             const labelUList& addr,
             const boolList& fm,
             const label index,
             const faceZoneMesh& zm
         );
 
-        //- Construct given the original zone,
-        //  resetting the face list and zone mesh information
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, (move) resetting the face addressing
+        //- and flip-map.
         faceZone
         (
-            const faceZone& fz,
+            const faceZone& origZone,
             const Xfer<labelList>& addr,
             const Xfer<boolList>& fm,
             const label index,
@@ -208,8 +234,8 @@ public:
             );
         }
 
-        //- Construct and return a clone, resetting the face list
-        //  and zone mesh
+        //- Construct and return a clone,
+        //- resetting the face list and zone mesh
         virtual autoPtr<faceZone> clone
         (
             const labelUList& addr,
@@ -228,7 +254,7 @@ public:
     // Selectors
 
         //- Return a pointer to a new face zone
-        //  created on freestore from dictionary
+        //- created on freestore from dictionary
         static autoPtr<faceZone> New
         (
             const word& name,
@@ -263,7 +289,7 @@ public:
       // Addressing into mesh
 
         //- Return labels of master cells (cells next to the master face
-        //  zone in the prescribed direction)
+        //- zone in the prescribed direction)
         const labelList& masterCells() const;
 
         //- Return labels of slave cells
@@ -276,28 +302,28 @@ public:
         //- Clear addressing
         virtual void clearAddressing();
 
-        //- Reset addressing and flip map.
+        //- Reset addressing - use uniform flip map value
         //  Clears demand-driven data.
         virtual void resetAddressing
         (
             const labelUList& addr,
-            const boolList& flipMap
+            const bool flipMapValue
         );
 
-        //- Reset addressing - use constant flip map
+        //- Reset addressing and flip map.
         //  Clears demand-driven data.
         virtual void resetAddressing
         (
             const labelUList& addr,
-            const bool flipValue
+            const boolList& flipMap
         );
 
-        //- Reset addressing - use constant flip map
+        //- Move reset addressing - use uniform flip map value
         //  Clears demand-driven data.
         virtual void resetAddressing
         (
             const Xfer<labelList>& addr,
-            const bool flipValue
+            const bool flipMapValue
         );
 
         //- Check zone definition. Return true if in error.
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
index 7a197bef349..de3917f1725 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,18 @@ const char* const Foam::pointZone::labelsName = "pointLabels";
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::pointZone::pointZone
+(
+    const word& name,
+    const label index,
+    const pointZoneMesh& zm
+)
+:
+    zone(name, index),
+    zoneMesh_(zm)
+{}
+
+
 Foam::pointZone::pointZone
 (
     const word& name,
@@ -58,6 +70,19 @@ Foam::pointZone::pointZone
 {}
 
 
+Foam::pointZone::pointZone
+(
+    const word& name,
+    labelList&& addr,
+    const label index,
+    const pointZoneMesh& zm
+)
+:
+    zone(name, std::move(addr), index),
+    zoneMesh_(zm)
+{}
+
+
 Foam::pointZone::pointZone
 (
     const word& name,
@@ -86,26 +111,39 @@ Foam::pointZone::pointZone
 
 Foam::pointZone::pointZone
 (
-    const pointZone& pz,
+    const pointZone& origZone,
     const labelUList& addr,
     const label index,
     const pointZoneMesh& zm
 )
 :
-    zone(pz, addr, index),
+    zone(origZone, addr, index),
     zoneMesh_(zm)
 {}
 
 
 Foam::pointZone::pointZone
 (
-    const pointZone& pz,
+    const pointZone& origZone,
+    labelList&& addr,
+    const label index,
+    const pointZoneMesh& zm
+)
+:
+    zone(origZone, std::move(addr), index),
+    zoneMesh_(zm)
+{}
+
+
+Foam::pointZone::pointZone
+(
+    const pointZone& origZone,
     const Xfer<labelList>& addr,
     const label index,
     const pointZoneMesh& zm
 )
 :
-    zone(pz, addr, index),
+    zone(origZone, addr, index),
     zoneMesh_(zm)
 {}
 
@@ -142,9 +180,11 @@ bool Foam::pointZone::checkParallelSync(const bool report) const
 
     labelList maxZone(mesh.nPoints(), -1);
     labelList minZone(mesh.nPoints(), labelMax);
-    forAll(*this, i)
+
+    const labelList& addr = *this;
+
+    for (const label pointi : addr)
     {
-        label pointi = operator[](i);
         maxZone[pointi] = index();
         minZone[pointi] = index();
     }
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
index d8e71270b0c..a42d49e1c98 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ Class
 
 Description
     A subset of mesh points.
+
     The labels of points in the zone can be obtained from the addressing()
     list.
 
@@ -109,6 +110,9 @@ public:
 
     // Constructors
 
+        //- Construct an empty zone
+        pointZone(const word& name, const label index, const pointZoneMesh& zm);
+
         //- Construct from components
         pointZone
         (
@@ -118,6 +122,15 @@ public:
             const pointZoneMesh& zm
         );
 
+        //- Construct from components, transferring addressing
+        pointZone
+        (
+            const word& name,
+            labelList&& addr,
+            const label index,
+            const pointZoneMesh& zm
+        );
+
         //- Construct from components, transferring contents
         pointZone
         (
@@ -136,26 +149,37 @@ public:
             const pointZoneMesh& zm
         );
 
-        //- Construct given the original zone and resetting the
-        //  point list and zone mesh information
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, resetting the point addressing.
         pointZone
         (
-            const pointZone& pz,
+            const pointZone& origZone,
             const labelUList& addr,
             const label index,
             const pointZoneMesh& zm
         );
 
-        //- Construct given the original zone,
-        //  resetting the point list and zone mesh information
+        //- Construct with a new index and zone mesh information, the name
+        //- of the original zone, (move) resetting the point addressing.
+        pointZone
+        (
+            const pointZone& origZone,
+            labelList&& addr,
+            const label index,
+            const pointZoneMesh& zm
+        );
+
+        //- Construct with a new index and zone mesh information from
+        //- an original zone, (move) resetting the point list.
         pointZone
         (
-            const pointZone& pz,
+            const pointZone& origZone,
             const Xfer<labelList>& addr,
             const label index,
             const pointZoneMesh& zm
         );
 
+
         //- Construct and return a clone, resetting the zone mesh
         virtual autoPtr<pointZone> clone(const pointZoneMesh& zm) const
         {
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
index 8e11bc24a71..bb489498101 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -82,6 +82,15 @@ void Foam::zone::calcLookupMap() const
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::zone::zone(const word& name, const label index)
+:
+    labelList(),
+    name_(name),
+    index_(index),
+    lookupMapPtr_(nullptr)
+{}
+
+
 Foam::zone::zone
 (
     const word& name,
@@ -96,6 +105,20 @@ Foam::zone::zone
 {}
 
 
+Foam::zone::zone
+(
+    const word& name,
+    labelList&& addr,
+    const label index
+)
+:
+    labelList(std::move(addr)),
+    name_(name),
+    index_(index),
+    lookupMapPtr_(nullptr)
+{}
+
+
 Foam::zone::zone
 (
     const word& name,
@@ -127,13 +150,13 @@ Foam::zone::zone
 
 Foam::zone::zone
 (
-    const zone& zn,
+    const zone& origZone,
     const labelUList& addr,
     const label index
 )
 :
     labelList(addr),
-    name_(zn.name()),
+    name_(origZone.name()),
     index_(index),
     lookupMapPtr_(nullptr)
 {}
@@ -141,13 +164,27 @@ Foam::zone::zone
 
 Foam::zone::zone
 (
-    const zone& zn,
+    const zone& origZone,
+    labelList&& addr,
+    const label index
+)
+:
+    labelList(std::move(addr)),
+    name_(origZone.name()),
+    index_(index),
+    lookupMapPtr_(nullptr)
+{}
+
+
+Foam::zone::zone
+(
+    const zone& origZone,
     const Xfer<labelList>& addr,
     const label index
 )
 :
     labelList(addr),
-    name_(zn.name()),
+    name_(origZone.name()),
     index_(index),
     lookupMapPtr_(nullptr)
 {}
@@ -184,9 +221,8 @@ bool Foam::zone::checkDefinition(const label maxSize, const bool report) const
     // To check for duplicate entries
     labelHashSet elems(size());
 
-    forAll(addr, i)
+    for (const label idx : addr)
     {
-        const label idx = addr[i];
         if (idx < 0 || idx >= maxSize)
         {
             hasError = true;
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
index db769812957..7083f72e818 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,7 +25,10 @@ Class
     Foam::zone
 
 Description
-    Base class for zones
+    Base class for mesh zones.
+
+    A zone is a list of labels (eg, cells, faces, points) with
+    a name and associated with an index within another list.
 
 SourceFiles
     zone.C
@@ -96,7 +99,10 @@ public:
 
     // Constructors
 
-        //- Construct from components
+        //- Construct an empty zone
+        zone(const word& name, const label index);
+
+        //- Copy construct from components
         zone
         (
             const word& name,
@@ -104,7 +110,15 @@ public:
             const label index
         );
 
-        //- Construct from components, transferring contents
+        //- Move construct from components
+        zone
+        (
+            const word& name,
+            labelList&& addr,
+            const label index
+        );
+
+        //- Move construct from components
         zone
         (
             const word& name,
@@ -121,17 +135,26 @@ public:
             const label index
         );
 
-        //- Construct given the original zone and resetting the
-        //  cell list and zone mesh information
+        //- Construct given the name of the original zone (name is used)
+        //- and resetting addressing and index.
         zone
         (
-            const zone& zn,
+            const zone& origZone,
             const labelUList& addr,
             const label index
         );
 
-        //- Construct given the original zone, resetting the
-        //  cell list and zone mesh information
+        //- Construct given the name of the original zone (name is used)
+        //- and (move) resetting addressing and index.
+        zone
+        (
+            const zone& origZone,
+            labelList&& addr,
+            const label index
+        );
+
+        //- Construct given the name of the original zone (name is used)
+        //- and (move) resetting addressing and index.
         zone
         (
             const zone& zn,
diff --git a/src/conversion/ccm/reader/ccmReaderMesh.C b/src/conversion/ccm/reader/ccmReaderMesh.C
index d58016f768b..b8fa67b8031 100644
--- a/src/conversion/ccm/reader/ccmReaderMesh.C
+++ b/src/conversion/ccm/reader/ccmReaderMesh.C
@@ -2546,7 +2546,7 @@ void Foam::ccm::reader::addFaceZones
             (
                 iter.key(),
                 iter(),
-                boolList(iter().size(), false),
+                false, // none are flipped
                 nZone,
                 mesh.faceZones()
             )
diff --git a/src/conversion/common/reader/meshReader.C b/src/conversion/common/reader/meshReader.C
index d78ed75f6dd..dd3650db67a 100644
--- a/src/conversion/common/reader/meshReader.C
+++ b/src/conversion/common/reader/meshReader.C
@@ -63,7 +63,7 @@ void Foam::meshReader::addFaceZones(polyMesh& mesh) const
             (
                 iter.key(),
                 iter(),
-                boolList(iter().size(), false),
+                false, // none are flipped
                 nZone,
                 mesh.faceZones()
             )
diff --git a/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C b/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C
index f7a105ae081..3af15d40af5 100644
--- a/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C
+++ b/src/dynamicMesh/fvMeshSubset/fvMeshSubset.C
@@ -56,10 +56,8 @@ bool Foam::fvMeshSubset::checkCellSubset() const
 
         return false;
     }
-    else
-    {
-        return true;
-    }
+
+    return true;
 }
 
 
@@ -69,10 +67,10 @@ void Foam::fvMeshSubset::markPoints
     Map<label>& pointMap
 )
 {
-    forAll(curPoints, pointi)
+    for (const label pointi : curPoints)
     {
         // Note: insert will only insert if not yet there.
-        pointMap.insert(curPoints[pointi], 0);
+        pointMap.insert(pointi, 0);
     }
 }
 
@@ -83,9 +81,9 @@ void Foam::fvMeshSubset::markPoints
     labelList& pointMap
 )
 {
-    forAll(curPoints, pointi)
+    for (const label pointi : curPoints)
     {
-        pointMap[curPoints[pointi]] = 0;
+        pointMap[pointi] = 0;
     }
 }
 
diff --git a/src/dynamicMesh/fvMeshTools/fvMeshTools.C b/src/dynamicMesh/fvMeshTools/fvMeshTools.C
index 117ddca4e52..285674ec110 100644
--- a/src/dynamicMesh/fvMeshTools/fvMeshTools.C
+++ b/src/dynamicMesh/fvMeshTools/fvMeshTools.C
@@ -642,7 +642,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshTools::newMesh
             pz[i] = new pointZone
             (
                 pointZoneNames[i],
-                labelList(0),
                 i,
                 mesh.pointZones()
             );
@@ -653,8 +652,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshTools::newMesh
             fz[i] = new faceZone
             (
                 faceZoneNames[i],
-                labelList(0),
-                boolList(0),
                 i,
                 mesh.faceZones()
             );
@@ -665,7 +662,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshTools::newMesh
             cz[i] = new cellZone
             (
                 cellZoneNames[i],
-                labelList(0),
                 i,
                 mesh.cellZones()
             );
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
index 90c3c635201..8414ab51cf9 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
@@ -3422,7 +3422,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
             pZonePtrs[i] = new pointZone
             (
                 oldPointZones[i].name(),
-                labelList(0),
                 i,
                 newMesh.pointZones()
             );
@@ -3437,8 +3436,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
             fZonePtrs[i] = new faceZone
             (
                 oldFaceZones[i].name(),
-                labelList(0),
-                boolList(0),
                 i,
                 newMesh.faceZones()
             );
@@ -3453,7 +3450,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
             cZonePtrs[i] = new cellZone
             (
                 oldCellZones[i].name(),
-                labelList(0),
                 i,
                 newMesh.cellZones()
             );
diff --git a/src/topoChangerFvMesh/linearValveFvMesh/linearValveFvMesh.C b/src/topoChangerFvMesh/linearValveFvMesh/linearValveFvMesh.C
index c9fbb148195..fa59d955a2a 100644
--- a/src/topoChangerFvMesh/linearValveFvMesh/linearValveFvMesh.C
+++ b/src/topoChangerFvMesh/linearValveFvMesh/linearValveFvMesh.C
@@ -67,15 +67,8 @@ void Foam::linearValveFvMesh::addZonesAndModifiers()
     // Add zones
     List<pointZone*> pz(1);
 
-    // Add an empty zone for cut points
-
-    pz[0] = new pointZone
-    (
-        "cutPointZone",
-        labelList(0),
-        0,
-        pointZones()
-    );
+    // An empty zone for cut points
+    pz[0] = new pointZone("cutPointZone", 0, pointZones());
 
 
     // Do face zones for slider
@@ -97,7 +90,7 @@ void Foam::linearValveFvMesh::addZonesAndModifiers()
     (
         "insideSliderZone",
         isf,
-        boolList(innerSlider.size(), false),
+        false, // none are flipped
         0,
         faceZones()
     );
@@ -117,20 +110,13 @@ void Foam::linearValveFvMesh::addZonesAndModifiers()
     (
         "outsideSliderZone",
         osf,
-        boolList(outerSlider.size(), false),
+        false, // none are flipped
         1,
         faceZones()
     );
 
-    // Add empty zone for cut faces
-    fz[2] = new faceZone
-    (
-        "cutFaceZone",
-        labelList(0),
-        boolList(0, false),
-        2,
-        faceZones()
-    );
+    // An empty zone for cut faces
+    fz[2] = new faceZone("cutFaceZone", 2, faceZones());
 
     List<cellZone*> cz(0);
 
diff --git a/src/topoChangerFvMesh/linearValveLayersFvMesh/linearValveLayersFvMesh.C b/src/topoChangerFvMesh/linearValveLayersFvMesh/linearValveLayersFvMesh.C
index 7bf5592af78..7728b146fc6 100644
--- a/src/topoChangerFvMesh/linearValveLayersFvMesh/linearValveLayersFvMesh.C
+++ b/src/topoChangerFvMesh/linearValveLayersFvMesh/linearValveLayersFvMesh.C
@@ -76,15 +76,8 @@ void Foam::linearValveLayersFvMesh::addZonesAndModifiers()
     List<cellZone*> cz(0);
 
 
-    // Add an empty zone for cut points
-
-    pz[0] = new pointZone
-    (
-        "cutPointZone",
-        labelList(0),
-        0,
-        pointZones()
-    );
+    // An empty zone for cut points
+    pz[0] = new pointZone("cutPointZone", 0, pointZones());
 
 
     // Do face zones for slider
@@ -104,7 +97,7 @@ void Foam::linearValveLayersFvMesh::addZonesAndModifiers()
     (
         "insideSliderZone",
         isf,
-        boolList(innerSlider.size(), false),
+        false, // none are flipped
         0,
         faceZones()
     );
@@ -124,20 +117,13 @@ void Foam::linearValveLayersFvMesh::addZonesAndModifiers()
     (
         "outsideSliderZone",
         osf,
-        boolList(outerSlider.size(), false),
+        false, // none are flipped
         1,
         faceZones()
     );
 
-    // Add empty zone for cut faces
-    fz[2] = new faceZone
-    (
-        "cutFaceZone",
-        labelList(0),
-        boolList(0, false),
-        2,
-        faceZones()
-    );
+    // An empty zone for cut faces
+    fz[2] = new faceZone("cutFaceZone", 2, faceZones());
 
     // Add face zone for layer addition
     const word layerPatchName
@@ -158,7 +144,7 @@ void Foam::linearValveLayersFvMesh::addZonesAndModifiers()
     (
         "valveLayerZone",
         lpf,
-        boolList(layerPatch.size(), true),
+        true, // all are flipped
         0,
         faceZones()
     );
diff --git a/src/topoChangerFvMesh/mixerFvMesh/mixerFvMesh.C b/src/topoChangerFvMesh/mixerFvMesh/mixerFvMesh.C
index ff9ad4f17a4..3d09c7d967d 100644
--- a/src/topoChangerFvMesh/mixerFvMesh/mixerFvMesh.C
+++ b/src/topoChangerFvMesh/mixerFvMesh/mixerFvMesh.C
@@ -67,15 +67,8 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
     // Add zones
     List<pointZone*> pz(1);
 
-    // Add an empty zone for cut points
-
-    pz[0] = new pointZone
-    (
-        "cutPointZone",
-        labelList(0),
-        0,
-        pointZones()
-    );
+    // An empty zone for cut points
+    pz[0] = new pointZone("cutPointZone", 0, pointZones());
 
 
     // Do face zones for slider
@@ -97,7 +90,7 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
     (
         "insideSliderZone",
         isf,
-        boolList(innerSlider.size(), false),
+        false, // none are flipped
         0,
         faceZones()
     );
@@ -117,20 +110,13 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
     (
         "outsideSliderZone",
         osf,
-        boolList(outerSlider.size(), false),
+        false, // none are flipped
         1,
         faceZones()
     );
 
-    // Add empty zone for cut faces
-    fz[2] = new faceZone
-    (
-        "cutFaceZone",
-        labelList(0),
-        boolList(0, false),
-        2,
-        faceZones()
-    );
+    // An empty zone for cut faces
+    fz[2] = new faceZone("cutFaceZone", 2, faceZones());
 
     List<cellZone*> cz(1);
 
@@ -338,7 +324,7 @@ const Foam::scalarField& Foam::mixerFvMesh::movingPointsMask() const
 
 bool Foam::mixerFvMesh::update()
 {
-     // Rotational speed needs to be converted from rpm
+    // Rotational speed needs to be converted from rpm
     movePoints
     (
         csPtr_->globalPosition
-- 
GitLab