diff --git a/src/OpenFOAM/containers/Lists/UList/UList.C b/src/OpenFOAM/containers/Lists/UList/UList.C
index f3feb5b83526355c5a80105435866d10fad2c02e..f47969874420dee885258c2eaab74473ebc9d146 100644
--- a/src/OpenFOAM/containers/Lists/UList/UList.C
+++ b/src/OpenFOAM/containers/Lists/UList/UList.C
@@ -112,6 +112,7 @@ Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range)
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range) const
 {
@@ -132,6 +133,7 @@ Foam::UList<T> Foam::UList<T>::operator[]
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[]
 (
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edge.H b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
index 52bf97cb7cf65cfebbe2e30ca0a26881b808d3d7..aecb9a9c2e416c1acc4b055fcf1c4ff12e162b17 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edge.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
@@ -149,7 +149,11 @@ public:
 
         //- Return true if point label is found in edge.
         //  Always false for a negative label.
-        inline bool found(const label index) const;
+        inline bool found(const label pointLabel) const;
+
+        //- Return local index (0,1) of point label in edge -1 on failure
+        //  Always return -1 for a negative label.
+        inline label which(const label pointLabel) const;
 
         //- Do the edges share a common vertex index?
         //  Negative point labels never connect.
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
index 75a5ba23655c5dd5fbe1d82cbf5a0ddb06a98bf9..e4ca81e9386f6abb51f0abc14ba2035222656268 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
@@ -206,10 +206,28 @@ inline Foam::label Foam::edge::maxVertex() const
 }
 
 
-inline bool Foam::edge::found(const label index) const
+inline bool Foam::edge::found(const label pointLabel) const
 {
     // -1: always false
-    return (index >= 0 && (index == start() || index == end()));
+    return (pointLabel >= 0 && (pointLabel == start() || pointLabel == end()));
+}
+
+
+inline Foam::label Foam::edge::which(const label pointLabel) const
+{
+    // -1: always false
+    if (pointLabel >= 0)
+    {
+        if (pointLabel == start())
+        {
+            return 0;
+        }
+        if (pointLabel == end())
+        {
+            return 1;
+        }
+    }
+    return -1;
 }
 
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 2d83def92090a598a8b38213dc82f79a0c2b301e..822e3c4f9a6fc3f146480ee1ada390afb311497f 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.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.
@@ -202,7 +202,10 @@ public:
 
         //- Navigation through face vertices
 
-            //- Which vertex on face (face index given a global index)
+            //- Return true if the global point label is found in face.
+            inline bool found(const label globalIndex) const;
+
+            //- Which local vertex on face given a global index.
             //  returns -1 if not found
             label which(const label globalIndex) const;
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
index b45193f0e730b3d59ede32f0f443bf62b252046a..ce807528c6598dbbeae7b5489f3f187d6adbeafe 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.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.
@@ -116,20 +116,24 @@ inline Foam::edge Foam::face::faceEdge(const label n) const
 }
 
 
-// Next vertex on face
+inline bool Foam::face::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
 inline Foam::label Foam::face::nextLabel(const label i) const
 {
     return operator[](fcIndex(i));
 }
 
 
-// Previous vertex on face
 inline Foam::label Foam::face::prevLabel(const label i) const
 {
     return operator[](rcIndex(i));
 }
 
-// Number of triangles directly known from number of vertices
+
 inline Foam::label Foam::face::nTriangles() const
 {
     return size() - 2;
diff --git a/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
new file mode 100644
index 0000000000000000000000000000000000000000..523233a569957ab20c5e1c78cf35f5e4723646a6
--- /dev/null
+++ b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::faceTraits
+
+Description
+    Traits class for faces
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef faceTraits_H
+#define faceTraits_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class triFace;
+class labelledTri;
+
+/*---------------------------------------------------------------------------*\
+                         Class faceTraits Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class FaceType>
+class faceTraits
+{
+public:
+
+    //- Face-type only handles triangles. Not true in general.
+    inline static bool isTri()  { return false; }
+};
+
+
+template<>
+inline bool faceTraits<triFace>::isTri()        { return true; }
+
+template<>
+inline bool faceTraits<labelledTri>::isTri()    { return true; }
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
index e0e586673acd317ba968050ae2d270137d6f2dfd..301b845d112a82499420b4de2eeddd3daf6f4477 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.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.
@@ -137,6 +137,13 @@ public:
         //  The starting points of the original and reverse face are identical.
         inline triFace reverseFace() const;
 
+        //- Return true if the global point label is found in face.
+        bool found(const label globalIndex) const;
+
+        //- Which local index (0,1,2) on face given a global index.
+        //  returns -1 if not found
+        label which(const label globalIndex) const;
+
         //- Return swept-volume from old-points to new-points
         inline scalar sweptVol
         (
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
index 69d2a4033b8607c32d13a876b3670a9effb0763c..ae2545a7aa233e8542a9e4e644e1f098bd6b3c09 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -209,6 +209,21 @@ inline Foam::triFace Foam::triFace::reverseFace() const
 }
 
 
+inline bool Foam::triFace::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
+inline Foam::label Foam::triFace::which(const label globalIndex) const
+{
+    if (operator[](0) == globalIndex) return 0;
+    if (operator[](1) == globalIndex) return 1;
+    if (operator[](2) == globalIndex) return 2;
+    return -1;
+}
+
+
 inline Foam::scalar Foam::triFace::sweptVol
 (
     const UList<point>& opts,
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/line.H b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
index 74bc680134eb0b4c2873ac4a9c14c0e81924634e..778a843ba75740616ef5922d017b94747f6a839a 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/line.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
@@ -98,10 +98,10 @@ public:
 
         // Access
 
-            //- Return first vertex
+            //- Return first point
             inline PointRef start() const;
 
-            //- Return second vertex
+            //- Return second point
             inline PointRef end() const;
 
 
@@ -113,9 +113,12 @@ public:
             //- Return scalar magnitude
             inline scalar mag() const;
 
-            //- Return start-end vector
+            //- Return start-to-end vector
             inline Point vec() const;
 
+            //- Return the unit vector (start-to-end)
+            inline Point unitVec() const;
+
             //- Return nearest distance to line from a given point
             //  If the nearest point is on the line, return a hit
             PointHit<Point> nearestDist(const Point& p) const;
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
index 2dfca1e1c2c01c52405a410d9a6636a568016dd6..c4757716cfc9ad71d0fd17e3eaac235a55ee8cbe 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
@@ -90,6 +90,16 @@ inline Point Foam::line<Point, PointRef>::vec() const
 }
 
 
+template<class Point, class PointRef>
+inline Point Foam::line<Point, PointRef>::unitVec() const
+{
+    Point v = b_ - a_;
+    v /= ::Foam::mag(v) + VSMALL;
+
+    return v;
+}
+
+
 template<class Point, class PointRef>
 Foam::PointHit<Point> Foam::line<Point, PointRef>::nearestDist
 (