diff --git a/contrib/HighOrderMeshOptimizer/OptHomFastCurving.cpp b/contrib/HighOrderMeshOptimizer/OptHomFastCurving.cpp
index 89df1ceca659d220a48decd288146f866dda6ed3..e517b77d97196fe4f07b1d2d943ea054db6c8376 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomFastCurving.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHomFastCurving.cpp
@@ -88,26 +88,6 @@ void calcFace2Elements(GEntity *entity, MFaceVecMEltMap &face2el)
 
 
 
-// Get the face index of an element given a MFace
-inline int getElementFace(const MFace &face, MElement *el)
-{
-  for (int iFace = 0; iFace < el->getNumFaces(); iFace++)
-    if (el->getFace(iFace) == face) return iFace;
-  return -1;
-}
-
-
-
-// Get the edge index of an element given a MEdge
-inline int getElementEdge(const MEdge &edge, MElement *el)
-{
-  for (int iEdge = 0; iEdge < el->getNumEdges(); iEdge++)
-    if (el->getEdge(iEdge) == edge) return iEdge;
-  return -1;
-}
-
-
-
 void makeStraight(MElement *el, const std::set<MVertex*> &movedVert)
 {
   const nodalBasis *nb = el->getFunctionSpace();
@@ -115,7 +95,8 @@ void makeStraight(MElement *el, const std::set<MVertex*> &movedVert)
 
   SPoint3 p;
 
-  for(int iPt = el->getNumPrimaryVertices(); iPt < el->getNumVertices(); ++iPt) {
+  for (int iPt = el->getNumPrimaryVertices();
+       iPt < el->getNumVertices(); iPt++) {
     MVertex *vert = el->getVertex(iPt);
     if (movedVert.find(vert) == movedVert.end()) {
       el->primaryPnt(pts(iPt,0),pts(iPt,1),pts(iPt,2),p);
@@ -128,9 +109,9 @@ void makeStraight(MElement *el, const std::set<MVertex*> &movedVert)
 
 inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl)
 {
-  static const double curvedTol = 1.e-3;                                              // Tolerance to consider element as curved
+  static const double curvedTol = 1.e-3;                                        // Tolerance to consider element as curved
 
-  const double normalDispCurved = curvedTol*el->getInnerRadius();                     // Threshold in normal displacement to consider element as curved
+  const double normalDispCurved = curvedTol*el->getInnerRadius();               // Threshold in normal displacement to consider element as curved
   const int dim = el->getDim();
 
   // Compute unit normal to straight edge/face
@@ -149,13 +130,13 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl)
   for (int iV = 0; iV < nV1; ++iV) xyz1[iV] = el->getVertex(iV)->point();
 
   // Check normal displacement at each HO vertex
-  for (int iV = nV1; iV < nV; ++iV) {                                                 // Loop over HO nodes
+  for (int iV = nV1; iV < nV; ++iV) {                                           // Loop over HO nodes
     double f[256];
     lagBasis1->f(uvw(iV, 0), (dim > 1) ? uvw(iV, 1) : 0., 0., f);
     SPoint3 xyzS(0.,0.,0.);
-    for (int iSF = 0; iSF < nV1; ++iSF) xyzS += xyz1[iSF]*f[iSF];                     // Compute location of node in straight element
+    for (int iSF = 0; iSF < nV1; ++iSF) xyzS += xyz1[iSF]*f[iSF];               // Compute location of node in straight element
     const SVector3 vec(xyzS, el->getVertex(iV)->point());
-    const double normalDisp = fabs(dot(vec, normal));                                 // Normal component of displacement
+    const double normalDisp = fabs(dot(vec, normal));                           // Normal component of displacement
     if (normalDisp > normalDispCurved) {
       bndEl.push_back(el);
       break;
@@ -165,13 +146,43 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl)
 
 
 
-void getOppositeEdge(MElement *el, const MEdge &elBaseEd, MEdge &elTopEd,
-                     double &edLenMin, double &edLenMax)
+void getOppositeEdgeQuad(MElement *el, const MEdge &elBaseEd, MEdge &elTopEd,
+                         double &edLenMin, double &edLenMax)
+{
+  // Find base face
+  int iElBaseEd, elBaseEdOrient;
+  el->getEdgeInfo(elBaseEd, iElBaseEd, elBaseEdOrient);
+
+  // Determine opposite and side edges
+  int iOppEd, iSideEd0, iSideEd1;
+  if (iElBaseEd == 0) { iOppEd = 2; iSideEd0 = 1; iSideEd1 = 3;}
+  else if (iElBaseEd == 1) { iOppEd = 3; iSideEd0 = 0; iSideEd1 = 2;}
+  else if (iElBaseEd == 2) { iOppEd = 0; iSideEd0 = 1; iSideEd1 = 3;}
+  else { iOppEd = 1; iSideEd0 = 0; iSideEd1 = 2;}
+  const MEdge elOppEd = el->getEdge(iOppEd);
+
+  // Create top edge
+  if (elBaseEdOrient > 0)
+    elTopEd = MEdge(elOppEd.getVertex(1), elOppEd.getVertex(0));
+  else
+    elTopEd = elOppEd;
+
+  // Compute max. and min. edge lengths
+  edLenMax = elTopEd.length();
+  edLenMin = std::min(el->getEdge(iSideEd0).length(),
+                      el->getEdge(iSideEd1).length());
+}
+
+
+
+void getOppositeEdgeTri(MElement *el, const MEdge &elBaseEd, MEdge &elTopEd,
+                        double &edLenMin, double &edLenMax)
 {
   static const double BIG = 1e300;
 
   // Find base face
-  const int iElBaseEd = getElementEdge(elBaseEd, el);
+  int iElBaseEd, iDum;
+  el->getEdgeInfo(elBaseEd, iElBaseEd, iDum);
   edLenMin = BIG;
   edLenMax = -BIG;
   MEdge elMaxEd;
@@ -190,19 +201,7 @@ void getOppositeEdge(MElement *el, const MEdge &elBaseEd, MEdge &elTopEd,
   }
 
   // Build top edge from max edge (with right orientation)
-  bool sameOrient = false;
-  if (el->getType() == TYPE_TRI) {                                    // Triangle: look for common vertex
-    sameOrient = (elBaseEd.getVertex(0) == elMaxEd.getVertex(0));
-  }
-  else {                                                              // Quad: look for edge between base and top vert.
-    MEdge sideEdTest(elBaseEd.getVertex(0), elMaxEd.getVertex(0));
-    for (int iElEd = 0; iElEd < el->getNumEdges(); iElEd++)
-      if (el->getEdge(iElEd) == sideEdTest) {
-        sameOrient = true;
-        break;
-      }
-  }
-  if (sameOrient) elTopEd = elMaxEd;
+  if (elBaseEd.getVertex(0) == elMaxEd.getVertex(0)) elTopEd = elMaxEd;
   else elTopEd = MEdge(elMaxEd.getVertex(1), elMaxEd.getVertex(0));
 }
 
@@ -221,7 +220,7 @@ void getColumnQuad(MEdgeVecMEltMap &ed2el, const FastCurvingParameters &p,
     if (el->getType() != TYPE_QUA) break;
     MEdge elTopEd;
     double edLenMin, edLenMax;
-    getOppositeEdge(el, elBaseEd, elTopEd, edLenMin, edLenMax);
+    getOppositeEdgeQuad(el, elBaseEd, elTopEd, edLenMin, edLenMax);
 
     if (edLenMin > edLenMax*p.maxRho) break;
     const double dp = dot(elBaseEd.normal(), elTopEd.normal());
@@ -249,7 +248,7 @@ void getColumnTri(MEdgeVecMEltMap &ed2el, const FastCurvingParameters &p,
     if (el0->getType() != TYPE_TRI) break;
     MEdge elTopEd0;
     double edLenMin0, edLenMax0;
-    getOppositeEdge(el0, elBaseEd, elTopEd0, edLenMin0, edLenMax0);
+    getOppositeEdgeTri(el0, elBaseEd, elTopEd0, edLenMin0, edLenMax0);
     const SVector3 normBase = elBaseEd.normal();
     const SVector3 normTop0 = elTopEd0.normal();
     if (std::abs(dot(normBase, normTop0)) < maxDPIn) break;
@@ -260,7 +259,7 @@ void getColumnTri(MEdgeVecMEltMap &ed2el, const FastCurvingParameters &p,
     if (el1->getType() != TYPE_TRI) break;
     MEdge elTopEd1;
     double edLenMin1, edLenMax1;
-    getOppositeEdge(el1, elTopEd0, elTopEd1, edLenMin1, edLenMax1);
+    getOppositeEdgeTri(el1, elTopEd0, elTopEd1, edLenMin1, edLenMax1);
     const SVector3 normTop1 = elTopEd1.normal();
     if (std::abs(dot(normTop0, normTop1)) < maxDPIn) break;
 
@@ -287,7 +286,8 @@ bool getColumn2D(MEdgeVecMEltMap &ed2el, const FastCurvingParameters &p,
   // Get first element and base vertices
   std::vector<MElement*> firstElts = ed2el[baseEd];
   MElement *el = firstElts[0];
-  const int iFirstElEd = getElementEdge(baseEd, el);
+  int iFirstElEd, iDum;
+  el->getEdgeInfo(baseEd, iFirstElEd, iDum);
   el->getEdgeVertices(iFirstElEd, baseVert);
   MEdge elBaseEd(baseVert[0], baseVert[1]);
 
@@ -414,13 +414,13 @@ void getOppositeFaceTet(MElement *el, const MFace &elBaseFace, MFace &elTopFace,
   MVertex *maxVert[3] = {elMaxFace.getVertex(0),
                          elMaxFace.getVertex(1), elMaxFace.getVertex(2)};
   std::vector<MVertex*> topVert(3, static_cast<MVertex*>(0));
-  for (int iBaseV = 0; iBaseV < 3; iBaseV++)                                // Two vertices of elTopFace are those of elMaxFace coinciding with elBaseFace
+  for (int iBaseV = 0; iBaseV < 3; iBaseV++)                                    // Two vertices of elTopFace are those of elMaxFace coinciding with elBaseFace
     for (int iMaxV = 0; iMaxV < 3; iMaxV++)
       if (elBaseFace.getVertex(iBaseV) == maxVert[iMaxV]) {
         topVert[iBaseV] = maxVert[iMaxV];
         maxVert[iMaxV] = 0;
       }
-  MVertex *thirdMaxVert = (maxVert[0] != 0) ? maxVert[0] :                  // Set last vertex of elTopFace as remaining vertex in elMaxFace
+  MVertex *thirdMaxVert = (maxVert[0] != 0) ? maxVert[0] :                      // Set last vertex of elTopFace as remaining vertex in elMaxFace
                           (maxVert[1] != 0) ? maxVert[1] : maxVert[2];
   if (topVert[0] == 0) topVert[0] = thirdMaxVert;
   else if (topVert[1] == 0) topVert[1] = thirdMaxVert;
@@ -430,20 +430,6 @@ void getOppositeFaceTet(MElement *el, const MFace &elBaseFace, MFace &elTopFace,
 
 
 
-//bool getTetInLayer(MFaceVecMEltMap &face2el, const MElement *lowerEl,
-//                   MElement *&el, const MFace &bottomFace, MFace &topFace,
-//                   double &faceSurfMin, double &faceSurfMax)
-//{
-//  std::vector<MElement*> newElts = face2el[bottomFace];
-//  el = (newElts[0] == lowerEl) ? newElts[1] : newElts[0];
-//  if (el->getType() != TYPE_TET) return false;
-//  MFace elMidFace0;
-//  getOppositeFaceTet(el, bottomFace, topFace, faceSurfMin, faceSurfMax);
-//  return true;
-//}
-
-
-
 // Column of tets: assume tets obtained from subdivision of prism
 void getColumnTet(MFaceVecMEltMap &face2el,
                   const FastCurvingParameters &p, MFace &elBaseFace,
@@ -544,7 +530,8 @@ bool getColumn3D(MFaceVecMEltMap &face2el, const FastCurvingParameters &p,
   const int nbBaseFaceVert = baseFace.getNumVertices();
   std::vector<MElement*> firstElts = face2el[baseFace];
   MElement *el = firstElts[0];
-  const int iFirstElFace = getElementFace(baseFace, el);
+  int iFirstElFace = -1, iDum;
+  el->getFaceInfo(baseFace, iFirstElFace, iDum, iDum);
   el->getFaceVertices(iFirstElFace, baseVert);
   MFace elBaseFace(baseVert[0], baseVert[1], baseVert[2],
                    (nbBaseFaceVert == 3) ? 0 : baseVert[3]);
@@ -553,7 +540,7 @@ bool getColumn3D(MFaceVecMEltMap &face2el, const FastCurvingParameters &p,
   if (nbBaseFaceVert == 3) {
     if (el->getType() == TYPE_PRI)                                              // Get BL column of prisms
       getColumnPrismHex(TYPE_PRI, face2el, p, elBaseFace, blob);
-    else if (el->getType() == TYPE_TET)                                       // TODO: finish implementing BL with tets
+    else if (el->getType() == TYPE_TET)
       getColumnTet(face2el, p, elBaseFace, blob);
   }
   else if ((nbBaseFaceVert == 4) && (el->getType() == TYPE_HEX))                // Get BL column of hexas
@@ -643,7 +630,8 @@ public:
     fprintf(fp, "%d\n", elt_.size());
     int iV = 0;
     for (int iEl = 0; iEl < elt_.size(); iEl++) {
-      fprintf(fp, "%i %i 2 0 0 ", elt_[iEl]->getNum(), elt_[iEl]->getTypeForMSH());
+      fprintf(fp, "%i %i 2 0 0 ", elt_[iEl]->getNum(),
+                                  elt_[iEl]->getTypeForMSH());
       for (int iVEl = 0; iVEl < elt_[iEl]->getNumVertices(); iVEl++)
         fprintf(fp, " %i", elt_[iEl]->getVertex(iVEl)->getNum());
       fprintf(fp, "\n");
@@ -690,7 +678,7 @@ void curveMeshFromBnd(MEdgeVecMEltMap &ed2el, MFaceVecMEltMap &face2el,
     bool foundCol;
     std::vector<MVertex*> baseVert, topPrimVert;
     std::vector<MElement*> blob;
-    if (bndType == TYPE_LIN) {                                                               // 1D boundary?
+    if (bndType == TYPE_LIN) {                                                  // 1D boundary
       MVertex *vb0 = (*itBE)->getVertex(0);
       MVertex *vb1 = (*itBE)->getVertex(1);
       metaElType = TYPE_QUA;