diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 95c39598de35f36053d2dc9b6e101f00fd1189f1..82ef462ebe9d049aeb7963b97f2ca1f259650cf5 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -186,6 +186,59 @@ void MElement::scaledJacRange(double &jmin, double &jmax, GEntity *ge) const
 #endif
 }
 
+void MElement::idealJacRange(double &jmin, double &jmax, GEntity *ge)
+{
+  jmin = jmax = 1.0;
+#if defined(HAVE_MESH)
+  const JacobianBasis *jac = getJacobianFuncSpace();
+  const int numJacNodes = jac->getNumJacNodes();
+  fullMatrix<double> nodesXYZ(jac->getNumMapNodes(),3);
+  getNodesCoord(nodesXYZ);
+  fullVector<double> iJi(numJacNodes), Bi(numJacNodes);
+  jac->getSignedIdealJacobian(nodesXYZ,iJi);
+  const int nEd = getNumEdges(), dim = getDim();
+  double sumEdLength = 0.;
+  for(int iEd = 0; iEd < nEd; iEd++)
+    sumEdLength += getEdge(iEd).length();
+  const double invMeanEdLength = double(nEd)/sumEdLength;
+  if (sumEdLength == 0.) {
+    jmin = 0.; jmax = 0.;
+    return;
+  }
+  double scale = (dim == 1.) ? invMeanEdLength :
+                 (dim == 2.) ? invMeanEdLength*invMeanEdLength :
+                 invMeanEdLength*invMeanEdLength*invMeanEdLength;
+  if (ge && (ge->dim() == 2) && ge->haveParametrization()) {
+    // If parametrized surface entity provided...
+    SVector3 geoNorm(0.,0.,0.);
+    // ... correct Jacobian sign with geometrical normal
+    for (int i=0; i<jac->getNumPrimMapNodes(); i++) {
+      const MVertex *vert = getVertex(i);
+      if (vert->onWhat() == ge) {
+        double u, v;
+        vert->getParameter(0,u);
+        vert->getParameter(1,v);
+        geoNorm += ((GFace*)ge)->normal(SPoint2(u,v));
+      }
+    }
+    if (geoNorm.normSq() == 0.) {
+      // If no vertex on surface or average is zero, take normal at barycenter
+      SPoint2 param = ((GFace*)ge)->parFromPoint(barycenter(true),false);
+      geoNorm = ((GFace*)ge)->normal(param);
+    }
+    fullMatrix<double> elNorm(1,3);
+    jac->getPrimNormal2D(nodesXYZ, elNorm, true);
+    const double dp = geoNorm(0) * elNorm(0,0) + geoNorm(1) * elNorm(0,1) +
+      geoNorm(2) * elNorm(0,2);
+    if (dp < 0.) scale = -scale;
+  }
+  iJi.scale(scale);
+  jac->lag2Bez(iJi,Bi);
+  jmin = *std::min_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size());
+  jmax = *std::max_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size());
+#endif
+}
+
 void MElement::getNode(int num, double &u, double &v, double &w) const
 {
   // only for MElements that don't have a lookup table for this
diff --git a/Geo/MElement.h b/Geo/MElement.h
index 831d307af7b09306d878986e7340f72790818621..26852d821b56d062f9d25e8201e2554d4ad92715 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -191,6 +191,7 @@ class MElement
   }
   virtual double angleShapeMeasure() { return 1.0; }
   virtual void scaledJacRange(double &jmin, double &jmax, GEntity *ge = 0) const;
+  virtual void idealJacRange(double &jmin, double &jmax, GEntity *ge = 0);
   virtual double metricShapeMeasure();
   virtual double metricShapeMeasure2();
 
diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp
index 828b8973c9971f2f5b48ae4bfece05966475cb75..cbfdc0ca27ebe241b5693bffcb79b862b0da630c 100644
--- a/Numeric/JacobianBasis.cpp
+++ b/Numeric/JacobianBasis.cpp
@@ -134,8 +134,9 @@ inline void calcJDJ3D(double dxdX, double dxdY, double dxdZ,
                                     dzdX, dzdY, dzdZ);
 }
 
-// Compute inverse condition number and its gradients
+// Compute condition number and its gradients
 // w.r.t. node positions, at one location in a 1D element
+// FIXME: TO BE UPDATED
 inline void calcIDI1D(double dxdX, double dxdY, double dxdZ,
                       double dydX, double dydY, double dydZ,
                       double dzdX, double dzdY, double dzdZ,
@@ -179,9 +180,9 @@ inline void calcIDI1D(double dxdX, double dxdY, double dxdZ,
   }
 }
 
-// Compute inverse condition number and its gradients
+// Compute condition number and its gradients
 // w.r.t. node positions, at one location in a 2D element
-// FIXME: Precision issues?
+// FIXME: TO BE UPDATED
 inline void calcIDI2D(double dxdX, double dxdY, double dxdZ,
                       double dydX, double dydY, double dydZ,
                       double dzdX, double dzdY, double dzdZ,
@@ -230,8 +231,9 @@ inline void calcIDI2D(double dxdX, double dxdY, double dxdZ,
   }
 }
 
-// Compute inverse condition number and its gradients
+// Compute condition number and its gradients
 // w.r.t. node positions, at one location in a 3D element
+// FIXME: TO BE UPDATED
 inline void calcIDI3D(double dxdX, double dxdY, double dxdZ,
                       double dydX, double dydY, double dydZ,
                       double dzdX, double dzdY, double dzdZ,
@@ -285,9 +287,7 @@ inline void calcIDI3D(double dxdX, double dxdY, double dxdZ,
 }
 
 GradientBasis::GradientBasis(int tag, int order) :
-    _type(ElementType::ParentTypeFromTag(tag)),
-    _idealDifferent(_type == TYPE_TRI || _type == TYPE_PRI ||
-                    _type == TYPE_TET || _type == TYPE_PYR)
+    _type(ElementType::ParentTypeFromTag(tag))
 {
   const int type = ElementType::ParentTypeFromTag(tag);
 
@@ -356,25 +356,36 @@ void GradientBasis::mapFromIdealElement(fullMatrix<double> *dxyzdX,
                                         fullMatrix<double> *dxyzdY,
                                         fullMatrix<double> *dxyzdZ) const
 {
-  if (_idealDifferent) {
-    if (_type == TYPE_PYR) {
-      dxyzdZ->scale(.5);
-      return;
+  // 2D scaling
+  switch(_type) {
+    case TYPE_QUA:                                             // Quad, hex, pyramid -> square with side of length 1
+    case TYPE_HEX:
+    case TYPE_PYR: {
+      dxyzdX->scale(2.);
+      dxyzdY->scale(2.);
+      break;
     }
+    default: {                                                // Tri, tet, prism: equilateral tri with side of length 1
+      static const double cTri[2] = {-1./std::sqrt(3), 2./std::sqrt(3)};
+      dxyzdY->scale(cTri[1]);
+      dxyzdY->axpy(*dxyzdX, cTri[0]);
+      break;
+    }
+  }
 
-    static const double cTri[2] = {-1./std::sqrt(3), 2./std::sqrt(3)};
-    dxyzdY->scale(cTri[1]);
-    dxyzdY->axpy(*dxyzdX, cTri[0]);
-
-    switch(_type) {
-    case TYPE_TRI:
-      return;
-
-    case TYPE_PRI:
-      dxyzdZ->scale(2);
-      return;
-
-    case TYPE_TET:
+  // 3D scaling
+  switch(_type) {
+    case TYPE_HEX:                                            // Hex, prism -> side of length 1 in z
+    case TYPE_PRI: {
+      dxyzdZ->scale(2.);
+      break;
+    }
+    case TYPE_PYR: {                                          // Pyramid -> height sqrt(2)/2
+      static const double cPyr = sqrt(2.);
+      dxyzdZ->scale(cPyr);
+      break;
+    }
+    case TYPE_TET:                                            // Tet: take into account (x, y) scaling to obtain regular tet
     {
       static const double cTet[3] = {-3./2/std::sqrt(6),
                                      -1./2/std::sqrt(2),
@@ -383,21 +394,6 @@ void GradientBasis::mapFromIdealElement(fullMatrix<double> *dxyzdX,
       dxyzdZ->axpy(*dxyzdX, cTet[0]);
       dxyzdZ->axpy(*dxyzdY, cTet[1]);
     }
-    }
-  }
-}
-
-// Given Jac. det. from reference element, compute Jac. det. from ideal element
-void GradientBasis::detJacFromIdealElement(double &dJ) const
-{
-  static const double TriFact = 2./sqrt(3.), TetFact = sqrt(2.);
-  if (_idealDifferent) {
-    switch(_type) {
-    case TYPE_TRI: dJ *= TriFact; return;
-    case TYPE_PRI: dJ *= 0.5; return;
-    case TYPE_TET: dJ *= TetFact; return;
-    case TYPE_PYR: dJ *= 2.; return;
-    }
   }
 }
 
@@ -551,47 +547,47 @@ double JacobianBasis::getPrimNormals1D(const fullMatrix<double> &nodesXYZ, fullM
 // Computes (unit) normal to straight surface element at barycenter (with norm as return value)
 double JacobianBasis::getPrimNormal2D(const fullMatrix<double> &nodesXYZ, fullMatrix<double> &result, bool ideal) const
 {
-  fullVector<double> dxyzdXbar(3), dxyzdYbar(3);
+  fullMatrix<double> dxyzdX(1, 3), dxyzdY(1, 3);
   for (int j=0; j<numPrimMapNodes; j++) {
-    dxyzdXbar(0) += primGradShapeBarycenterX(j)*nodesXYZ(j,0);
-    dxyzdXbar(1) += primGradShapeBarycenterX(j)*nodesXYZ(j,1);
-    dxyzdXbar(2) += primGradShapeBarycenterX(j)*nodesXYZ(j,2);
-    dxyzdYbar(0) += primGradShapeBarycenterY(j)*nodesXYZ(j,0);
-    dxyzdYbar(1) += primGradShapeBarycenterY(j)*nodesXYZ(j,1);
-    dxyzdYbar(2) += primGradShapeBarycenterY(j)*nodesXYZ(j,2);
+    dxyzdX(0, 0) += primGradShapeBarycenterX(j)*nodesXYZ(j,0);
+    dxyzdX(0, 1) += primGradShapeBarycenterX(j)*nodesXYZ(j,1);
+    dxyzdX(0, 2) += primGradShapeBarycenterX(j)*nodesXYZ(j,2);
+    dxyzdY(0, 0) += primGradShapeBarycenterY(j)*nodesXYZ(j,0);
+    dxyzdY(0, 1) += primGradShapeBarycenterY(j)*nodesXYZ(j,1);
+    dxyzdY(0, 2) += primGradShapeBarycenterY(j)*nodesXYZ(j,2);
   }
 
-  result(0,2) = dxyzdXbar(0) * dxyzdYbar(1) - dxyzdXbar(1) * dxyzdYbar(0);
-  result(0,1) = -dxyzdXbar(0) * dxyzdYbar(2) + dxyzdXbar(2) * dxyzdYbar(0);
-  result(0,0) = dxyzdXbar(1) * dxyzdYbar(2) - dxyzdXbar(2) * dxyzdYbar(1);
-  double norm0 = sqrt(result(0,0)*result(0,0)+result(0,1)*result(0,1)+result(0,2)*result(0,2));
+  if (ideal) _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, 0);
+  result(0, 2) = dxyzdX(0, 0) * dxyzdY(0, 1) - dxyzdX(0, 1) * dxyzdY(0, 0);
+  result(0, 1) = -dxyzdX(0, 0) * dxyzdY(0, 2) + dxyzdX(0, 2) * dxyzdY(0, 0);
+  result(0, 0) = dxyzdX(0, 1) * dxyzdY(0, 2) - dxyzdX(0, 2) * dxyzdY(0, 1);
+  double norm0 = sqrt(result(0, 0)*result(0, 0)+result(0, 1)*result(0, 1)+result(0, 2)*result(0, 2));
   const double invNorm0 = 1./norm0;
-  result(0,0) *= invNorm0; result(0,1) *= invNorm0; result(0,2) *= invNorm0;
+  result(0, 0) *= invNorm0; result(0, 1) *= invNorm0; result(0, 2) *= invNorm0;
 
-  if (ideal) _gradBasis->detJacFromIdealElement(norm0);
   return norm0;
 }
 
 // Returns absolute value of Jacobian of straight volume element at barycenter
 double JacobianBasis::getPrimJac3D(const fullMatrix<double> &nodesXYZ, bool ideal) const
 {
-  double dxdX = 0, dydX = 0, dzdX = 0, dxdY = 0, dydY = 0, dzdY = 0, dxdZ = 0, dydZ = 0, dzdZ = 0;
+  fullMatrix<double> dxyzdX(1, 3), dxyzdY(1, 3), dxyzdZ(1, 3);
   for (int j=0; j<numPrimMapNodes; j++) {
-    dxdX += primGradShapeBarycenterX(j)*nodesXYZ(j,0);
-    dydX += primGradShapeBarycenterX(j)*nodesXYZ(j,1);
-    dzdX += primGradShapeBarycenterX(j)*nodesXYZ(j,2);
-    dxdY += primGradShapeBarycenterY(j)*nodesXYZ(j,0);
-    dydY += primGradShapeBarycenterY(j)*nodesXYZ(j,1);
-    dzdY += primGradShapeBarycenterY(j)*nodesXYZ(j,2);
-    dxdZ += primGradShapeBarycenterZ(j)*nodesXYZ(j,0);
-    dydZ += primGradShapeBarycenterZ(j)*nodesXYZ(j,1);
-    dzdZ += primGradShapeBarycenterZ(j)*nodesXYZ(j,2);
+    dxyzdX(0, 0) += primGradShapeBarycenterX(j)*nodesXYZ(j,0);
+    dxyzdX(0, 1) += primGradShapeBarycenterX(j)*nodesXYZ(j,1);
+    dxyzdX(0, 2) += primGradShapeBarycenterX(j)*nodesXYZ(j,2);
+    dxyzdY(0, 0) += primGradShapeBarycenterY(j)*nodesXYZ(j,0);
+    dxyzdY(0, 1) += primGradShapeBarycenterY(j)*nodesXYZ(j,1);
+    dxyzdY(0, 2) += primGradShapeBarycenterY(j)*nodesXYZ(j,2);
+    dxyzdZ(0, 0) += primGradShapeBarycenterZ(j)*nodesXYZ(j,0);
+    dxyzdZ(0, 1) += primGradShapeBarycenterZ(j)*nodesXYZ(j,1);
+    dxyzdZ(0, 2) += primGradShapeBarycenterZ(j)*nodesXYZ(j,2);
   }
 
-  double dJ = fabs(calcDet3D(dxdX, dxdY, dxdZ,
-                             dydX, dydY, dydZ,
-                             dzdX, dzdY, dzdZ));
-  if (ideal) _gradBasis->detJacFromIdealElement(dJ);
+  if (ideal) _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, &dxyzdZ);
+  double dJ = fabs(calcDet3D(dxyzdX(0, 0), dxyzdY(0, 0), dxyzdZ(0, 0),
+                             dxyzdX(0, 1), dxyzdY(0, 1), dxyzdZ(0, 1),
+                             dxyzdX(0, 2), dxyzdY(0, 2), dxyzdZ(0, 2)));
   return dJ;
 }
 
@@ -686,6 +682,15 @@ void JacobianBasis::getSignedJacobianGeneral(int nJacNodes, const fullMatrix<dou
   getJacobianGeneral<false, false>(nJacNodes, gSMatX,  gSMatY, gSMatZ, nodesXYZ, jacobian);
 }
 
+// Calculate signed Jacobian (from ideal) for one element, with normal vectors to straight element for
+// regularization. Evaluation points depend on the given matrices for shape function gradients.
+void JacobianBasis::getSignedIdealJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                                 const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                                 const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const
+{
+  getJacobianGeneral<false, true>(nJacNodes, gSMatX,  gSMatY, gSMatZ, nodesXYZ, jacobian);
+}
+
 // Calculate (signed) scaled Jacobian for one element, with normal vectors to straight element
 // for regularization. Evaluation points depend on the given matrices for shape function gradients.
 void JacobianBasis::getScaledJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
@@ -819,6 +824,16 @@ void JacobianBasis::getSignedJacobianGeneral(int nJacNodes, const fullMatrix<dou
   getJacobianGeneral<false, false>(nJacNodes, gSMatX,  gSMatY, gSMatZ, nodesX, nodesY, nodesZ, jacobian);
 }
 
+// Calculate signed Jacobian (from ideal) for several elements, with normal vectors to straight elements
+// for regularization. Evaluation points depend on the given matrices for shape function gradients.
+void JacobianBasis::getSignedIdealJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                                  const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                                  const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
+                                                  const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const
+{
+  getJacobianGeneral<false, true>(nJacNodes, gSMatX,  gSMatY, gSMatZ, nodesX, nodesY, nodesZ, jacobian);
+}
+
 // Calculate (signed) scaled Jacobian for several elements, with normal vectors to straight elements
 // for regularization. Evaluation points depend on the given matrices for shape function gradients.
 void JacobianBasis::getScaledJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
@@ -914,7 +929,7 @@ inline void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes,
 // Calculate the inverse condition number in Frobenius norm for one element, with normal vectors to straight
 // element for regularization. Evaluation points depend on the given matrices for shape function gradients.
 template<bool ideal>
-inline void JacobianBasis::getInvCondGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+inline void JacobianBasis::getCondNumGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                                             const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                             const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const
 {
@@ -992,18 +1007,18 @@ inline void JacobianBasis::getInvCondGeneral(int nJacNodes, const fullMatrix<dou
   }
 }
 
-void JacobianBasis::getInvCondGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+void JacobianBasis::getCondNumGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                                       const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                       const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const
 {
-  getInvCondGeneral<true>(nJacNodes, gSMatX,  gSMatY,  gSMatZ, nodesXYZ, invCond);
+  getCondNumGeneral<true>(nJacNodes, gSMatX,  gSMatY,  gSMatZ, nodesXYZ, invCond);
 }
 
 // Calculate the inverse condition number in Frobenius norm and its gradients w.r.t. node position,
 // with normal vectors to straight element  for regularization. Evaluation points depend on the
 // given matrices for shape function gradients.
 template<bool ideal>
-inline void JacobianBasis::getInvCondAndGradientsGeneral(int nJacNodes,
+inline void JacobianBasis::getCondNumAndGradientsGeneral(int nJacNodes,
                                                          const fullMatrix<double> &gSMatX,
                                                          const fullMatrix<double> &gSMatY,
                                                          const fullMatrix<double> &gSMatZ,
@@ -1091,13 +1106,21 @@ inline void JacobianBasis::getInvCondAndGradientsGeneral(int nJacNodes,
                   dzdX, dzdY, dzdZ,
                   i, numMapNodes,
                   gSMatX, gSMatY, gSMatZ, JDJ, IDI);
+//        std::cout << "DBGTT: Jac. node " << i << ":\n";
+//        std::cout << "DBGTT:     -> g = " << IDI(i, 3*getNumMapNodes()) << ":\n";
+//        for (int j=0; j<getNumMapNodes(); j++)
+//          std::cout << "DBGTT:     -> djd{x,y,z}" << j << " = (" << JDJ(i, j)
+//                    << ", " << JDJ(i, j+getNumMapNodes()) << ", " << JDJ(i, j+2*getNumMapNodes()) << ")\n";
+//        for (int j=0; j<getNumMapNodes(); j++)
+//          std::cout << "DBGTT:     -> dgd{x,y,z}" << j << " = (" << IDI(i, j)
+//                    << ", " << IDI(i, j+getNumMapNodes()) << ", " << IDI(i, j+2*getNumMapNodes()) << ")\n";
       }
       break;
     }
   }
 }
 
-void JacobianBasis::getInvCondAndGradientsGeneral(int nJacNodes,
+void JacobianBasis::getCondNumAndGradientsGeneral(int nJacNodes,
                                                   const fullMatrix<double> &gSMatX,
                                                   const fullMatrix<double> &gSMatY,
                                                   const fullMatrix<double> &gSMatZ,
@@ -1105,20 +1128,31 @@ void JacobianBasis::getInvCondAndGradientsGeneral(int nJacNodes,
                                                   const fullMatrix<double> &normals,
                                                   fullMatrix<double> &IDI) const
 {
-  getInvCondAndGradientsGeneral<true>(nJacNodes, gSMatX, gSMatY, gSMatZ, nodesXYZ, normals, IDI);
+  getCondNumAndGradientsGeneral<true>(nJacNodes, gSMatX, gSMatY, gSMatZ, nodesXYZ, normals, IDI);
 }
 
 void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes,
-                                                           const fullMatrix<double> &gSMatX,
-                                                           const fullMatrix<double> &gSMatY,
-                                                           const fullMatrix<double> &gSMatZ,
-                                                           const fullMatrix<double> &nodesXYZ,
-                                                           const fullMatrix<double> &normals,
-                                                           fullMatrix<double> &JDJ) const
+                                                    const fullMatrix<double> &gSMatX,
+                                                    const fullMatrix<double> &gSMatY,
+                                                    const fullMatrix<double> &gSMatZ,
+                                                    const fullMatrix<double> &nodesXYZ,
+                                                    const fullMatrix<double> &normals,
+                                                    fullMatrix<double> &JDJ) const
 {
   getSignedJacAndGradientsGeneral<false>(nJacNodes, gSMatX, gSMatY, gSMatZ, nodesXYZ, normals, JDJ);
 }
 
+void JacobianBasis::getSignedIdealJacAndGradientsGeneral(int nJacNodes,
+                                                         const fullMatrix<double> &gSMatX,
+                                                         const fullMatrix<double> &gSMatY,
+                                                         const fullMatrix<double> &gSMatZ,
+                                                         const fullMatrix<double> &nodesXYZ,
+                                                         const fullMatrix<double> &normals,
+                                                         fullMatrix<double> &JDJ) const
+{
+  getSignedJacAndGradientsGeneral<true>(nJacNodes, gSMatX, gSMatY, gSMatZ, nodesXYZ, normals, JDJ);
+}
+
 
 void JacobianBasis::getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ,
                                              const fullMatrix<double> &nodesXYZStraight,
diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h
index cae31165f0289cbe182b17920b9101fe576ab79f..d45ce88ab87b0fc2a6af01fa821496111b9e37b3 100644
--- a/Numeric/JacobianBasis.h
+++ b/Numeric/JacobianBasis.h
@@ -18,7 +18,6 @@ class GradientBasis {
 
  private:
   const int _type;
-  const bool _idealDifferent;
 
  public:
   GradientBasis(int tag, int order);
@@ -33,7 +32,6 @@ class GradientBasis {
   void mapFromIdealElement(fullMatrix<double> *dxyzdX,
                            fullMatrix<double> *dxyzdY,
                            fullMatrix<double> *dxyzdZ) const;
-  void detJacFromIdealElement(double &dJ) const;
 };
 
 
@@ -78,14 +76,24 @@ class JacobianBasis {
     getSignedJacAndGradientsGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
                                     gradShapeMatZFast,nodesXYZ,normals,JDJ);
   }
-  inline void getInvCondAndGradients(const fullMatrix<double> &nodesXYZ,
+  inline void getSignedIdealJacAndGradients(const fullMatrix<double> &nodesXYZ,
+                                            const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const {
+    getSignedIdealJacAndGradientsGeneral(numJacNodes, _gradBasis->gradShapeMatX,
+        _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ, nodesXYZ, normals, JDJ);
+  }
+  inline void getSignedIdealJacAndGradientsFast(const fullMatrix<double> &nodesXYZ,
+                                                const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const {
+    getSignedIdealJacAndGradientsGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
+                                         gradShapeMatZFast,nodesXYZ,normals,JDJ);
+  }
+  inline void getCondNumAndGradients(const fullMatrix<double> &nodesXYZ,
                                      const fullMatrix<double> &normals, fullMatrix<double> &IDI) const {
-    getInvCondAndGradientsGeneral(numJacNodes, _gradBasis->gradShapeMatX,
+    getCondNumAndGradientsGeneral(numJacNodes, _gradBasis->gradShapeMatX,
         _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ, nodesXYZ, normals, IDI);
   }
-  inline void getInvCondAndGradientsFast(const fullMatrix<double> &nodesXYZ,
+  inline void getCondNumAndGradientsFast(const fullMatrix<double> &nodesXYZ,
                                          const fullMatrix<double> &normals, fullMatrix<double> &IDI) const {
-    getInvCondAndGradientsGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
+    getCondNumAndGradientsGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
                                     gradShapeMatZFast,nodesXYZ,normals,IDI);
   }
   void getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ,
@@ -100,6 +108,15 @@ class JacobianBasis {
     getSignedJacobianGeneral(numJacNodes, _gradBasis->gradShapeMatX,
         _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ,nodesX,nodesY,nodesZ,jacobian);
   }
+  inline void getSignedIdealJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getSignedIdealJacobianGeneral(numJacNodes, _gradBasis->gradShapeMatX,
+        _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ,nodesXYZ,jacobian);
+  }
+  inline void getSignedIdealJacobian(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
+                                     const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const {
+    getSignedIdealJacobianGeneral(numJacNodes, _gradBasis->gradShapeMatX,
+        _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ,nodesX,nodesY,nodesZ,jacobian);
+  }
   inline void getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
     getScaledJacobianGeneral(numJacNodes, _gradBasis->gradShapeMatX,
         _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ,nodesXYZ,jacobian);
@@ -112,15 +129,18 @@ class JacobianBasis {
   inline void getSignedJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
     getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian);
   }
+  inline void getSignedIdealJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getSignedIdealJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian);
+  }
   inline void getScaledJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
     getScaledJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian);
   }
-  inline void getInvCond(const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const {
-    getInvCondGeneral(numJacNodes, _gradBasis->gradShapeMatX,
+  inline void getCondNum(const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const {
+    getCondNumGeneral(numJacNodes, _gradBasis->gradShapeMatX,
         _gradBasis->gradShapeMatY, _gradBasis->gradShapeMatZ, nodesXYZ, invCond);
   }
-  inline void getInvCondFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const {
-    getInvCondGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,invCond);
+  inline void getCondNumFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const {
+    getCondNumGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,invCond);
   }
   //
   inline void lag2Bez(const fullVector<double> &jac, fullVector<double> &bez) const {
@@ -159,6 +179,13 @@ class JacobianBasis {
                                 const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                 const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
                                 const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const;
+  void getSignedIdealJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                     const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                      const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const;
+  void getSignedIdealJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                     const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                     const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
+                                     const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const;
   void getScaledJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                                 const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                 const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const;
@@ -176,21 +203,25 @@ class JacobianBasis {
                                        const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                        const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals,
                                        fullMatrix<double> &JDJ) const;
+  void getSignedIdealJacAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                            const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                            const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals,
+                                            fullMatrix<double> &JDJ) const;
 
   template<bool ideal>
-  void getInvCondGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+  void getCondNumGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                          const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                          const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const;
-  void getInvCondGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+  void getCondNumGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                          const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                          const fullMatrix<double> &nodesXYZ, fullVector<double> &invCond) const;
 
   template<bool ideal>
-  void getInvCondAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+  void getCondNumAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                                      const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                      const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals,
                                      fullMatrix<double> &IDI) const;
-  void getInvCondAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+  void getCondNumAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
                                      const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
                                      const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals,
                                      fullMatrix<double> &IDI) const;