diff --git a/src/OpenFOAM/meshes/meshShapes/cell/cell.C b/src/OpenFOAM/meshes/meshShapes/cell/cell.C
index 33f6f71cf5023d807c3090e8a3915b4588146520..293537c85e1de6bf0702be5146fa310ff8a6606c 100644
--- a/src/OpenFOAM/meshes/meshShapes/cell/cell.C
+++ b/src/OpenFOAM/meshes/meshShapes/cell/cell.C
@@ -36,130 +36,116 @@ const char* const Foam::cell::typeName = "cell";
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::labelList Foam::cell::labels(const faceUList& f) const
+Foam::labelList Foam::cell::labels(const faceUList& meshFaces) const
 {
-    const labelList& faces = *this;
+    const labelList& cFaces = *this;
 
-    // Count the maximum size of all vertices
-    label maxVert = 0;
-    forAll(faces, facei)
+    label nVerts = 0;
+    for (const label facei : cFaces)
     {
-        maxVert += f[faces[facei]].size();
+        nVerts += meshFaces[facei].size();
     }
 
-    // set the fill-in list
-    labelList p(maxVert);
+    labelList pointLabels(nVerts);
 
-    // in the first face there is no duplicates
-    const labelList& first = f[faces[0]];
+    // The first face has no duplicates, can copy in values
+    const labelList& firstFace = meshFaces[cFaces[0]];
 
-    forAll(first, pointi)
-    {
-        p[pointi] = first[pointi];
-    }
+    std::copy(firstFace.cbegin(), firstFace.cend(), pointLabels.begin());
 
-    // re-use maxVert to count the real vertices
-    maxVert = first.size();
+    // Now already contains some vertices
+    nVerts = firstFace.size();
 
-    // go through the rest of the faces. For each vertex, check if the point is
-    // already inserted (up to maxVert, which now carries the number of real
+    // For the rest of the faces. For each vertex, check if the point is
+    // already inserted (up to nVerts, which now carries the number of real
     // points. If not, add it at the end of the list.
 
-    for (label facei = 1; facei < faces.size(); facei++)
+    for (label facei = 1; facei < cFaces.size(); ++facei)
     {
-        const labelList& curFace = f[faces[facei]];
-
-        forAll(curFace, pointi)
+        for (const label curPoint : meshFaces[cFaces[facei]])
         {
-            const label curPoint = curFace[pointi];
-
-            bool found = false;
+            bool pointFound = false;
 
-            for (label checkI = 0; checkI < maxVert; checkI++)
+            for (label checki = 0; checki < nVerts; ++checki)
             {
-                if (curPoint == p[checkI])
+                if (curPoint == pointLabels[checki])
                 {
-                    found = true;
+                    pointFound = true;
                     break;
                 }
             }
 
-            if (!found)
+            if (!pointFound)
             {
-                p[maxVert] = curPoint;
-                ++maxVert;
+                pointLabels[nVerts] = curPoint;
+                ++nVerts;
             }
         }
     }
 
-    // reset the size of the list
-    p.setSize(maxVert);
+    pointLabels.resize(nVerts);
 
-    return p;
+    return pointLabels;
 }
 
 
 Foam::pointField Foam::cell::points
 (
-    const faceUList& f,
+    const faceUList& meshFaces,
     const UList<point>& meshPoints
 ) const
 {
-    const labelList pointLabels = labels(f);
+    const labelList pointLabels = labels(meshFaces);
 
-    pointField p(pointLabels.size());
+    pointField allPoints(pointLabels.size());
 
-    forAll(p, i)
+    forAll(allPoints, i)
     {
-        p[i] = meshPoints[pointLabels[i]];
+        allPoints[i] = meshPoints[pointLabels[i]];
     }
 
-    return p;
+    return allPoints;
 }
 
 
-Foam::edgeList Foam::cell::edges(const faceUList& f) const
+Foam::edgeList Foam::cell::edges(const faceUList& meshFaces) const
 {
-    const labelList& curFaces = *this;
+    const labelList& cFaces = *this;
 
-    label maxNoEdges = 0;
-
-    forAll(curFaces, facei)
+    label nEdges = 0;
+    for (const label facei : cFaces)
     {
-        maxNoEdges += f[curFaces[facei]].nEdges();
+        nEdges += meshFaces[facei].nEdges();
     }
 
-    edgeList allEdges(maxNoEdges);
-    label nEdges = 0;
+    edgeList allEdges(nEdges);
 
-    forAll(curFaces, facei)
-    {
-        const edgeList curFaceEdges = f[curFaces[facei]].edges();
+    nEdges = 0;
 
-        for (const edge& curEdge : curFaceEdges)
+    forAll(cFaces, facei)
+    {
+        for (const edge& curEdge : meshFaces[cFaces[facei]].edges())
         {
             bool edgeFound = false;
 
-            for (label addedEdgeI = 0; addedEdgeI < nEdges; addedEdgeI++)
+            for (label checki = 0; checki < nEdges; ++checki)
             {
-                if (allEdges[addedEdgeI] == curEdge)
+                if (curEdge == allEdges[checki])
                 {
                     edgeFound = true;
-
                     break;
                 }
             }
 
             if (!edgeFound)
             {
-                // Add the new edge onto the list
                 allEdges[nEdges] = curEdge;
                 ++nEdges;
             }
         }
     }
 
-    allEdges.setSize(nEdges);
+    allEdges.resize(nEdges);
 
     return allEdges;
 }
@@ -167,8 +153,8 @@ Foam::edgeList Foam::cell::edges(const faceUList& f) const
 
 Foam::point Foam::cell::centre
 (
-    const UList<point>& p,
-    const faceUList& f
+    const UList<point>& meshPoints,
+    const faceUList& meshFaces
 ) const
 {
     // When one wants to access the cell centre and magnitude, the
@@ -186,36 +172,33 @@ Foam::point Foam::cell::centre
     // relationship, which is not available on this level. Thus, all the
     // pyramids are believed to be positive with no checking.
 
-    // first calculate the approximate cell centre as the average of all
-    // face centres
+    // Approximate cell centre as the area average of all face centres
 
-    vector cEst = Zero;
+    vector ctr = Zero;
     scalar sumArea = 0;
 
-    const labelList& faces = *this;
+    const labelList& cFaces = *this;
 
-    forAll(faces, facei)
+    for (const label facei : cFaces)
     {
-        scalar a = f[faces[facei]].mag(p);
-        cEst += f[faces[facei]].centre(p)*a;
-        sumArea += a;
+        const scalar magArea = meshFaces[facei].mag(meshPoints);
+        ctr += meshFaces[facei].centre(meshPoints)*magArea;
+        sumArea += magArea;
     }
 
-    cEst /= sumArea + VSMALL;
+    ctr /= sumArea + VSMALL;
 
     // Calculate the centre by breaking the cell into pyramids and
     // volume-weighted averaging their centres
-    vector sumVc = Zero;
 
     scalar sumV = 0;
+    vector sumVc = Zero;
 
-    forAll(faces, facei)
+    for (const label facei : cFaces)
     {
-        // calculate pyramid volume. If it is greater than zero, OK.
-        // If not, the pyramid is inside-out. Create a face with the opposite
-        // order and recalculate pyramid centre!
-        scalar pyrVol = pyramidPointFaceRef(f[faces[facei]], cEst).mag(p);
-        vector pyrCentre = pyramidPointFaceRef(f[faces[facei]], cEst).centre(p);
+        const face& f = meshFaces[facei];
+
+        scalar pyrVol = pyramidPointFaceRef(f, ctr).mag(meshPoints);
 
         // if pyramid inside-out because face points inwards invert
         // N.B. pyramid remains unchanged
@@ -224,8 +207,8 @@ Foam::point Foam::cell::centre
             pyrVol = -pyrVol;
         }
 
-        sumVc += pyrVol*pyrCentre;
         sumV += pyrVol;
+        sumVc += pyrVol * pyramidPointFaceRef(f, ctr).centre(meshPoints);
     }
 
     return sumVc/(sumV + VSMALL);
@@ -234,8 +217,8 @@ Foam::point Foam::cell::centre
 
 Foam::scalar Foam::cell::mag
 (
-    const UList<point>& p,
-    const faceUList& f
+    const UList<point>& meshPoints,
+    const faceUList& meshFaces
 ) const
 {
     // When one wants to access the cell centre and magnitude, the
@@ -246,30 +229,28 @@ Foam::scalar Foam::cell::mag
 
     // WARNING! See cell::centre
 
-    // first calculate the approximate cell centre as the average of all
-    // face centres
-    vector cEst = Zero;
-    scalar nCellFaces = 0;
+    const labelList& cFaces = *this;
 
-    const labelList& faces = *this;
+    // Approximate cell centre as the average of all face centres
 
-    forAll(faces, facei)
+    vector ctr = Zero;
+    for (const label facei : cFaces)
     {
-        cEst += f[faces[facei]].centre(p);
-        nCellFaces += 1;
+        ctr += meshFaces[facei].centre(meshPoints);
     }
-
-    cEst /= nCellFaces;
+    ctr /= cFaces.size();
 
     // Calculate the magnitude by summing the mags of the pyramids
-    scalar v = 0;
+    scalar sumV = 0;
 
-    forAll(faces, facei)
+    for (const label facei : cFaces)
     {
-        v += ::Foam::mag(pyramidPointFaceRef(f[faces[facei]], cEst).mag(p));
+        const face& f = meshFaces[facei];
+
+        sumV += ::Foam::mag(pyramidPointFaceRef(f, ctr).mag(meshPoints));
     }
 
-    return v;
+    return sumV;
 }
 
 
diff --git a/src/OpenFOAM/meshes/meshShapes/cell/cell.H b/src/OpenFOAM/meshes/meshShapes/cell/cell.H
index afedec85433b4e5d07acf766fe9ba3c06aeb1257..d9656d66edd7852588be427bd9de1c6129caff90 100644
--- a/src/OpenFOAM/meshes/meshShapes/cell/cell.H
+++ b/src/OpenFOAM/meshes/meshShapes/cell/cell.H
@@ -89,13 +89,13 @@ public:
         inline cell(const labelUList& list, const FixedList<label, N>& indices);
 
         //- Construct from Istream
-        inline cell(Istream& is);
+        inline explicit cell(Istream& is);
 
 
     // Member Functions
 
         //- Return number of faces
-        inline label nFaces() const;
+        inline label nFaces() const noexcept;
 
         //- Return unordered list of cell vertices given the list of faces
         labelList labels(const faceUList& meshFaces) const;
diff --git a/src/OpenFOAM/meshes/meshShapes/cell/cellI.H b/src/OpenFOAM/meshes/meshShapes/cell/cellI.H
index 56fe8947a613669d894ec9bb70bec8bd9c96654e..daf5cfd1e4b95f0636e83d8a8677cc6454806372 100644
--- a/src/OpenFOAM/meshes/meshShapes/cell/cellI.H
+++ b/src/OpenFOAM/meshes/meshShapes/cell/cellI.H
@@ -78,7 +78,7 @@ inline Foam::cell::cell(Istream& is)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-inline Foam::label Foam::cell::nFaces() const
+inline Foam::label Foam::cell::nFaces() const noexcept
 {
     return size();
 }
diff --git a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModel.H b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModel.H
index 747ae7dd276e8923b7ce939521b7ae3dd8510957..bfe223cdb292d8d3180b33c5fd9954391e920696 100644
--- a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModel.H
+++ b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModel.H
@@ -173,25 +173,25 @@ public:
     // Member Functions
 
         //- Return model name
-        inline const word& name() const;
+        inline const word& name() const noexcept;
 
         //- Return index of model in the model list
-        inline label index() const;
+        inline label index() const noexcept;
 
         //- Return number of points
-        inline label nPoints() const;
+        inline label nPoints() const noexcept;
 
         //- Return number of edges
-        inline label nEdges() const;
+        inline label nEdges() const noexcept;
 
         //- Return number of faces
-        inline label nFaces() const;
+        inline label nFaces() const noexcept;
 
         //- Return a raw list of model edges
-        inline const edgeList& modelEdges() const;
+        inline const edgeList& modelEdges() const noexcept;
 
         //- Return a raw list of model faces
-        inline const faceList& modelFaces() const;
+        inline const faceList& modelFaces() const noexcept;
 
         //- Return list of cell edges
         inline edgeList edges(const labelUList& pointLabels) const;
@@ -199,6 +199,13 @@ public:
         //- Return list of cell faces
         inline faceList faces(const labelUList& pointLabels) const;
 
+        //- Return the cell edge for specified model edge
+        inline Foam::edge edge
+        (
+            const label modelEdgei,
+            const labelUList& pointLabels
+        ) const;
+
         //- Return the cell face for specified model face
         inline Foam::face face
         (
@@ -251,10 +258,10 @@ Ostream& operator<<(Ostream& os, const InfoProxy<cellModel>& ip);
 // Global Operators
 
 //- Equality: true when model pointers are identical
-inline bool operator==(const cellModel& lhs, const cellModel& rhs);
+inline bool operator==(const cellModel& lhs, const cellModel& rhs) noexcept;
 
 //- Inequality: true when model pointers are not identical
-inline bool operator!=(const cellModel& lhs, const cellModel& rhs);
+inline bool operator!=(const cellModel& lhs, const cellModel& rhs) noexcept;
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModelI.H b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModelI.H
index cc5ba490721ee2b8239a185e361121e7ce1625a8..5c3b0fd810ad42c0e2026419ffce028e8704a6d4 100644
--- a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModelI.H
+++ b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModelI.H
@@ -28,43 +28,43 @@ License
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-inline const Foam::word& Foam::cellModel::name() const
+inline const Foam::word& Foam::cellModel::name() const noexcept
 {
     return name_;
 }
 
 
-inline Foam::label Foam::cellModel::index() const
+inline Foam::label Foam::cellModel::index() const noexcept
 {
     return index_;
 }
 
 
-inline Foam::label Foam::cellModel::nPoints() const
+inline Foam::label Foam::cellModel::nPoints() const noexcept
 {
     return nPoints_;
 }
 
 
-inline Foam::label Foam::cellModel::nEdges() const
+inline Foam::label Foam::cellModel::nEdges() const noexcept
 {
     return edges_.size();
 }
 
 
-inline Foam::label Foam::cellModel::nFaces() const
+inline Foam::label Foam::cellModel::nFaces() const noexcept
 {
     return faces_.size();
 }
 
 
-inline const Foam::edgeList& Foam::cellModel::modelEdges() const
+inline const Foam::edgeList& Foam::cellModel::modelEdges() const noexcept
 {
     return edges_;
 }
 
 
-inline const Foam::faceList& Foam::cellModel::modelFaces() const
+inline const Foam::faceList& Foam::cellModel::modelFaces() const noexcept
 {
     return faces_;
 }
@@ -80,18 +80,24 @@ inline Foam::edgeList Foam::cellModel::edges
     forAll(edges_, edgei)
     {
         // From model labels to global labels
-        theEdges[edgei] =
-            edge
-            (
-                pointLabels[edges_[edgei].first()],
-                pointLabels[edges_[edgei].second()]
-            );
+        theEdges[edgei] = Foam::edge(pointLabels, edges_[edgei]);
     }
 
     return theEdges;
 }
 
 
+inline Foam::edge Foam::cellModel::edge
+(
+    const label modelEdgei,
+    const labelUList& pointLabels
+) const
+{
+    // From model labels to global labels
+    return Foam::edge(pointLabels, edges_[modelEdgei]);
+}
+
+
 inline Foam::faceList Foam::cellModel::faces
 (
     const labelUList& pointLabels
@@ -122,13 +128,21 @@ inline Foam::face Foam::cellModel::face
 
 // * * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * //
 
-inline bool Foam::operator==(const cellModel& lhs, const cellModel& rhs)
+inline bool Foam::operator==
+(
+    const cellModel& lhs,
+    const cellModel& rhs
+) noexcept
 {
     return (&lhs == &rhs);
 }
 
 
-inline bool Foam::operator!=(const cellModel& lhs, const cellModel& rhs)
+inline bool Foam::operator!=
+(
+    const cellModel& lhs,
+    const cellModel& rhs
+) noexcept
 {
     return (&lhs != &rhs);
 }
diff --git a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModeller.H b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModeller.H
index b5eb5c84c80e658922b4d93dbbb5fde349561ebc..32976c6f077b71f74c54850e9b074432cb31a0e2 100644
--- a/src/OpenFOAM/meshes/meshShapes/cellModel/cellModeller.H
+++ b/src/OpenFOAM/meshes/meshShapes/cellModel/cellModeller.H
@@ -10,7 +10,7 @@
 License
     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 
-Namespace
+Class
     Foam::cellModeller
 
 Description
@@ -18,6 +18,9 @@ Description
 
     Superseded (NOV-2017) by cellModel methods.
 
+See Also
+    Foam::cellModel
+
 \*---------------------------------------------------------------------------*/
 
 #ifndef cellModeller_H
@@ -28,10 +31,10 @@ Description
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
-{
-namespace cellModeller
 {
 
+struct cellModeller
+{
     //- Deprecated(2017-11) equivalent to cellModel::ptr static method.
     //  \deprecated(2017-11) use cellModel::ptr instead
     FOAM_DEPRECATED_FOR(2017-11, "cellModel::ptr() static method")
@@ -47,8 +50,8 @@ namespace cellModeller
     {
         return cellModel::ptr(modelIndex);
     }
+};
 
-} // End namespace cellModeller
 } // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/meshShapes/cellShape/cellShape.H b/src/OpenFOAM/meshes/meshShapes/cellShape/cellShape.H
index 29c59981f72563e53f307bcc55748d83e7314d26..250fcbe655504f97fae785a583d0521e55aeba3d 100644
--- a/src/OpenFOAM/meshes/meshShapes/cellShape/cellShape.H
+++ b/src/OpenFOAM/meshes/meshShapes/cellShape/cellShape.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -91,6 +92,15 @@ public:
             const bool doCollapse = false
         );
 
+        //- Copy construct from components
+        template<unsigned N>
+        inline cellShape
+        (
+            const cellModel& model,
+            const FixedList<label, N>& labels,
+            const bool doCollapse = false
+        );
+
         //- Move construct from components
         inline cellShape
         (
@@ -99,7 +109,7 @@ public:
             const bool doCollapse = false
         );
 
-        //- Copy construct from components
+        //- Copy construct from components, using lookup cellModel by name
         inline cellShape
         (
             const word& modelName,
@@ -108,7 +118,7 @@ public:
         );
 
         //- Construct from Istream
-        inline cellShape(Istream& is);
+        inline explicit cellShape(Istream& is);
 
         //- Clone
         inline autoPtr<cellShape> clone() const;
diff --git a/src/OpenFOAM/meshes/meshShapes/cellShape/cellShapeI.H b/src/OpenFOAM/meshes/meshShapes/cellShape/cellShapeI.H
index 3f8273c6a243fb664ca2ceb764bd0334127a475f..b66d8c78b77ce35f07eac7342c6a84cf35a5d970 100644
--- a/src/OpenFOAM/meshes/meshShapes/cellShape/cellShapeI.H
+++ b/src/OpenFOAM/meshes/meshShapes/cellShape/cellShapeI.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -55,6 +56,24 @@ inline Foam::cellShape::cellShape
 }
 
 
+template<unsigned N>
+inline Foam::cellShape::cellShape
+(
+    const cellModel& model,
+    const FixedList<label, N>& labels,
+    const bool doCollapse
+)
+:
+    labelList(labels),
+    m(&model)
+{
+    if (doCollapse)
+    {
+        collapse();
+    }
+}
+
+
 inline Foam::cellShape::cellShape
 (
     const cellModel& model,