diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp
index 9f956eb87c6488dcb2685e0137fd032726c5fa4d..922b312d3003eddb4ae99524a32fe46c71f5e77c 100644
--- a/Numeric/JacobianBasis.cpp
+++ b/Numeric/JacobianBasis.cpp
@@ -30,6 +30,8 @@ JacobianBasis::JacobianBasis(int tag)
   const int jacobianOrder =  JacobianBasis::jacobianOrder(parentType, order);
   const int primJacobianOrder =  JacobianBasis::jacobianOrder(parentType, 1);
 
+  fullMatrix<double> lagPoints;                                  // Sampling points
+
   switch (parentType) {
     case TYPE_PNT :
       lagPoints = gmshGeneratePointsLine(0);
@@ -38,19 +40,19 @@ JacobianBasis::JacobianBasis(int tag)
       lagPoints = gmshGeneratePointsLine(jacobianOrder);
       break;
     case TYPE_TRI :
-      lagPoints = gmshGeneratePointsTriangle(jacobianOrder);
+      lagPoints = gmshGeneratePointsTriangle(jacobianOrder,false);
       break;
     case TYPE_QUA :
-      lagPoints = gmshGeneratePointsQuadrangle(jacobianOrder);
+      lagPoints = gmshGeneratePointsQuadrangle(jacobianOrder,false);
       break;
     case TYPE_TET :
-      lagPoints = gmshGeneratePointsTetrahedron(jacobianOrder);
+      lagPoints = gmshGeneratePointsTetrahedron(jacobianOrder,false);
       break;
     case TYPE_PRI :
-      lagPoints = gmshGeneratePointsPrism(jacobianOrder);
+      lagPoints = gmshGeneratePointsPrism(jacobianOrder,false);
       break;
     case TYPE_HEX :
-      lagPoints = gmshGeneratePointsHexahedron(jacobianOrder);
+      lagPoints = gmshGeneratePointsHexahedron(jacobianOrder,false);
       break;
     case TYPE_PYR :
       lagPoints = generateJacPointsPyramid(jacobianOrder);
@@ -118,7 +120,35 @@ JacobianBasis::JacobianBasis(int tag)
     primGradShapeBarycenterY(j) = barDPsi[j][1];
     primGradShapeBarycenterZ(j) = barDPsi[j][2];
   }
+
   delete[] barDPsi;
+
+  // Compute "fast" Jacobian evaluation matrices (at 1st order nodes + barycenter)
+//  numJacNodesFast = numPrimMapNodes+1;
+//  fullMatrix<double> lagPointsFast(numJacNodesFast,3);                                  // Sampling points
+//  lagPointsFast.copy(primMapBasis->points,0,numPrimMapNodes,0,3,0,0);                   // 1st order nodes
+//  lagPointsFast(numPrimMapNodes,0) = barycenter[0];                                     // Last point = barycenter
+//  lagPointsFast(numPrimMapNodes,1) = barycenter[1];
+//  lagPointsFast(numPrimMapNodes,2) = barycenter[2];
+  fullMatrix<double> lagPointsFast(numJacNodesFast,3);                                  // Sampling points
+  lagPointsFast(0,0) = barycenter[0];                                     // Last point = barycenter
+  lagPointsFast(0,1) = barycenter[1];
+  lagPointsFast(0,2) = barycenter[2];
+
+  fullMatrix<double> allDPsiFast;
+  mapBasis->df(lagPointsFast, allDPsiFast);
+
+  gradShapeMatXFast.resize(numJacNodesFast, numMapNodes);
+  gradShapeMatYFast.resize(numJacNodesFast, numMapNodes);
+  gradShapeMatZFast.resize(numJacNodesFast, numMapNodes);
+  for (int i=0; i<numJacNodesFast; i++) {
+    for (int j=0; j<numMapNodes; j++) {
+      gradShapeMatXFast(i, j) = allDPsiFast(j, 3*i);
+      gradShapeMatYFast(i, j) = allDPsiFast(j, 3*i+1);
+      gradShapeMatZFast(i, j) = allDPsiFast(j, 3*i+2);
+    }
+  }
+
 }
 
 // Computes (unit) normals to straight line element at barycenter (with norm of gradient as return value)
@@ -197,31 +227,97 @@ double JacobianBasis::getPrimJac3D(const fullMatrix<double> &nodesXYZ) const
 
 }
 
-// Calculate (signed) Jacobian at mapping's nodes for one element, with normal vectors to
-// straight element for regularization
-void JacobianBasis::getSignedJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const
+namespace {
+
+// Calculate (signed) Jacobian for one element, given the gradients of the shape functions
+// and vectors for regularization of line and surface Jacobians in 3D.
+inline void computeSignedJacobian(int dim, int numJacNodes, const fullMatrix<double> &gradShapeMatX,
+                                  const fullMatrix<double> &gradShapeMatY, const fullMatrix<double> &gradShapeMatZ,
+                                  const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals,
+                                  fullVector<double> &jacobian)
 {
 
-  switch (bezier->getDim()) {
+  switch (dim) {
+
+    case 0 : {
+      for (int i = 0; i < numJacNodes; i++) jacobian(i) = 1.;
+      break;
+    }
+
+    case 1 : {
+      fullMatrix<double> dxyzdX(numJacNodes,3);
+      gradShapeMatX.mult(nodesXYZ, dxyzdX);
+      for (int i = 0; i < numJacNodes; i++) {
+        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
+        const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2);
+        const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2);
+        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
+      }
+      break;
+    }
+
+    case 2 : {
+      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3);
+      gradShapeMatX.mult(nodesXYZ, dxyzdX);
+      gradShapeMatY.mult(nodesXYZ, dxyzdY);
+      for (int i = 0; i < numJacNodes; i++) {
+        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
+        const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
+        const double &dxdZ = normals(0,0), &dydZ = normals(0,1), &dzdZ = normals(0,2);
+        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
+      }
+      break;
+    }
+
+    case 3 : {
+      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3), dxyzdZ(numJacNodes,3);
+      gradShapeMatX.mult(nodesXYZ, dxyzdX);
+      gradShapeMatY.mult(nodesXYZ, dxyzdY);
+      gradShapeMatZ.mult(nodesXYZ, dxyzdZ);
+      for (int i = 0; i < numJacNodes; i++) {
+        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
+        const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
+        const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2);
+        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
+      }
+      break;
+    }
+
+  }
+
+}
+
+} // namespace
+
+// Calculate (signed) 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::getSignedJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                             const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                             const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const
+{
+
+  const int dim = bezier->getDim();
+
+  switch (dim) {
 
     case 1 : {
       fullMatrix<double> normals(2,3);
       getPrimNormals1D(nodesXYZ,normals);
-      getSignedJacobian(nodesXYZ,normals,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,normals,jacobian);
       break;
     }
 
     case 2 : {
       fullMatrix<double> normal(1,3);
       getPrimNormal2D(nodesXYZ,normal);
-      getSignedJacobian(nodesXYZ,normal,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,normal,jacobian);
       break;
     }
 
     case 0 :
     case 3 : {
       fullMatrix<double> dum;
-      getSignedJacobian(nodesXYZ,dum,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,dum,jacobian);
       break;
     }
 
@@ -229,18 +325,22 @@ void JacobianBasis::getSignedJacobian(const fullMatrix<double> &nodesXYZ, fullVe
 
 }
 
-// Calculate scaled (signed) Jacobian at mapping's nodes for one element, with normal vectors to
-// straight element for regularization and scaling
-void JacobianBasis::getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const
+// Calculate scaled (signed) Jacobian for one element, with normal vectors to straight element for regularization
+// and scaling. Evaluation points depend on the given matrices for shape function gradients.
+void JacobianBasis::getScaledJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                             const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                             const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const
 {
 
-  switch (bezier->getDim()) {
+  const int dim = bezier->getDim();
+
+  switch (dim) {
 
     case 1 : {
       fullMatrix<double> normals(2,3);
       const double scale = 1./getPrimNormals1D(nodesXYZ,normals);
       normals(0,0) *= scale; normals(0,1) *= scale; normals(0,2) *= scale;  // Faster to scale 1 normal than afterwards
-      getSignedJacobian(nodesXYZ,normals,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,normals,jacobian);
       break;
     }
 
@@ -248,7 +348,7 @@ void JacobianBasis::getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVe
       fullMatrix<double> normal(1,3);
       const double scale = 1./getPrimNormal2D(nodesXYZ,normal);
       normal(0,0) *= scale; normal(0,1) *= scale; normal(0,2) *= scale;     // Faster to scale normal than afterwards
-      getSignedJacobian(nodesXYZ,normal,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,normal,jacobian);
       break;
     }
 
@@ -256,7 +356,7 @@ void JacobianBasis::getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVe
     case 3 : {
       fullMatrix<double> dum;
       const double scale = 1./getPrimJac3D(nodesXYZ);
-      getSignedJacobian(nodesXYZ,dum,jacobian);
+      computeSignedJacobian(dim,nJacNodes,gSMatX,gSMatY,gSMatZ,nodesXYZ,dum,jacobian);
       jacobian.scale(scale);
       break;
     }
@@ -265,55 +365,84 @@ void JacobianBasis::getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVe
 
 }
 
-// Calculate (signed) Jacobian at mapping's nodes for one element, given vectors for regularization
-// of line and surface Jacobians in 3D
-void JacobianBasis::getSignedJacobian(const fullMatrix<double> &nodesXYZ,
-                                      const fullMatrix<double> &normals, fullVector<double> &jacobian) const
+// Calculate (signed) Jacobian for several elements.
+// Evaluation points depend on the given matrices for shape function gradients.
+// TODO: Optimize and test 1D & 2D
+void JacobianBasis::getSignedJacobianGeneral(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
 {
 
   switch (bezier->getDim()) {
 
     case 0 : {
-      for (int i = 0; i < numJacNodes; i++) jacobian(i) = 1.;
+      const int numEl = nodesX.size2();
+      for (int iEl = 0; iEl < numEl; iEl++)
+        for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = 1.;
       break;
     }
 
     case 1 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      for (int i = 0; i < numJacNodes; i++) {
-        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
+      const int numEl = nodesX.size2();
+      fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl);
+      gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX);
+      for (int iEl = 0; iEl < numEl; iEl++) {
+        fullMatrix<double> nodesXYZ(numPrimJacNodes,3);
+        for (int i = 0; i < numPrimJacNodes; i++) {
+          nodesXYZ(i,0) = nodesX(i,iEl);
+          nodesXYZ(i,1) = nodesY(i,iEl);
+          nodesXYZ(i,2) = nodesZ(i,iEl);
+        }
+        fullMatrix<double> normals(2,3);
+        getPrimNormals1D(nodesXYZ,normals);
         const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2);
         const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2);
-        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
+        for (int i = 0; i < nJacNodes; i++)
+          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
+                                      dxdY,dydY,dzdY,
+                                      dxdZ,dydZ,dzdZ);
       }
       break;
     }
 
     case 2 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      gradShapeMatY.mult(nodesXYZ, dxyzdY);
-      for (int i = 0; i < numJacNodes; i++) {
-        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
-        const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
-        const double &dxdZ = normals(0,0), &dydZ = normals(0,1), &dzdZ = normals(0,2);
-        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
+      const int numEl = nodesX.size2();
+      fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl);
+      fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl);
+      gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX);
+      gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY);
+      for (int iEl = 0; iEl < numEl; iEl++) {
+        fullMatrix<double> nodesXYZ(numPrimJacNodes,3);
+        for (int i = 0; i < numPrimJacNodes; i++) {
+          nodesXYZ(i,0) = nodesX(i,iEl);
+          nodesXYZ(i,1) = nodesY(i,iEl);
+          nodesXYZ(i,2) = nodesZ(i,iEl);
+        }
+        fullMatrix<double> normal(1,3);
+        getPrimNormal2D(nodesXYZ,normal);
+        const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2);
+        for (int i = 0; i < nJacNodes; i++)
+          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
+                                      dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl),
+                                      dxdZ,dydZ,dzdZ);
       }
       break;
     }
 
     case 3 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3), dxyzdZ(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      gradShapeMatY.mult(nodesXYZ, dxyzdY);
-      gradShapeMatZ.mult(nodesXYZ, dxyzdZ);
-      for (int i = 0; i < numJacNodes; i++) {
-        const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
-        const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
-        const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2);
-        jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ);
-      }
+      const int numEl = nodesX.size2();
+      fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl);
+      fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl);
+      fullMatrix<double> dxdZ(nJacNodes,numEl), dydZ(nJacNodes,numEl), dzdZ(nJacNodes,numEl);
+      gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX);
+      gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY);
+      gSMatZ.mult(nodesX, dxdZ); gSMatZ.mult(nodesY, dydZ); gSMatZ.mult(nodesZ, dzdZ);
+      for (int iEl = 0; iEl < numEl; iEl++)
+        for (int i = 0; i < nJacNodes; i++)
+          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
+                                      dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl),
+                                      dxdZ(i,iEl),dydZ(i,iEl),dzdZ(i,iEl));
       break;
     }
 
@@ -321,17 +450,20 @@ void JacobianBasis::getSignedJacobian(const fullMatrix<double> &nodesXYZ,
 
 }
 
-// Calculate (signed) Jacobian at mapping's nodes for one element, given vectors for regularization
-// of line and surface Jacobians in 3D
-void JacobianBasis::getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
-                                             const fullMatrix<double> &normals,
-                                             fullMatrix<double> &JDJ) const
+// Calculate (signed) Jacobian and its gradients for one element, with normal vectors to straight element
+// for regularization. Evaluation points depend on the given matrices for shape function gradients.
+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
 {
 
   switch (bezier->getDim()) {
 
     case 0 : {
-      for (int i = 0; i < numJacNodes; i++) {
+      for (int i = 0; i < nJacNodes; i++) {
         for (int j = 0; j < numMapNodes; j++) {
           JDJ (i,j) = 0.;
           JDJ (i,j+1*numMapNodes) = 0.;
@@ -343,14 +475,14 @@ void JacobianBasis::getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
     }
 
     case 1 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      for (int i = 0; i < numJacNodes; i++) {
+      fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3);
+      gSMatX.mult(nodesXYZ, dxyzdX);
+      for (int i = 0; i < nJacNodes; i++) {
         const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
         const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2);
         const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2);
         for (int j = 0; j < numMapNodes; j++) {
-          const double &dPhidX = gradShapeMatX(i,j);
+          const double &dPhidX = gSMatX(i,j);
           JDJ (i,j) = dPhidX * dydY * dzdZ + dPhidX * dzdY * dydZ;
           JDJ (i,j+1*numMapNodes) = dPhidX * dzdY * dxdZ - dPhidX * dxdY * dzdZ;
           JDJ (i,j+2*numMapNodes) = dPhidX * dxdY * dydZ - dPhidX * dydY * dxdZ;
@@ -361,16 +493,16 @@ void JacobianBasis::getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
     }
 
     case 2 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      gradShapeMatY.mult(nodesXYZ, dxyzdY);
-      for (int i = 0; i < numJacNodes; i++) {
+      fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3);
+      gSMatX.mult(nodesXYZ, dxyzdX);
+      gSMatY.mult(nodesXYZ, dxyzdY);
+      for (int i = 0; i < nJacNodes; i++) {
         const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
         const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
         const double &dxdZ = normals(0,0), &dydZ = normals(0,1), &dzdZ = normals(0,2);
         for (int j = 0; j < numMapNodes; j++) {
-          const double &dPhidX = gradShapeMatX(i,j);
-          const double &dPhidY = gradShapeMatY(i,j);
+          const double &dPhidX = gSMatX(i,j);
+          const double &dPhidY = gSMatY(i,j);
           JDJ (i,j) =
             dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ +
             dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ;
@@ -389,18 +521,18 @@ void JacobianBasis::getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
     }
 
     case 3 : {
-      fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3), dxyzdZ(numJacNodes,3);
-      gradShapeMatX.mult(nodesXYZ, dxyzdX);
-      gradShapeMatY.mult(nodesXYZ, dxyzdY);
-      gradShapeMatZ.mult(nodesXYZ, dxyzdZ);
-      for (int i = 0; i < numJacNodes; i++) {
+      fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3), dxyzdZ(nJacNodes,3);
+      gSMatX.mult(nodesXYZ, dxyzdX);
+      gSMatY.mult(nodesXYZ, dxyzdY);
+      gSMatZ.mult(nodesXYZ, dxyzdZ);
+      for (int i = 0; i < nJacNodes; i++) {
         const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2);
         const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2);
         const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2);
         for (int j = 0; j < numMapNodes; j++) {
-          const double &dPhidX = gradShapeMatX(i,j);
-          const double &dPhidY = gradShapeMatY(i,j);
-          const double &dPhidZ = gradShapeMatZ(i,j);
+          const double &dPhidX = gSMatX(i,j);
+          const double &dPhidY = gSMatY(i,j);
+          const double &dPhidZ = gSMatZ(i,j);
           JDJ (i,j) =
             dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ +
             dydX * dzdY * dPhidZ - dzdX * dydY * dPhidZ -
@@ -425,7 +557,7 @@ void JacobianBasis::getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
 
 void JacobianBasis::getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ,
                                              const fullMatrix<double> &nodesXYZStraight,
-                                             fullVector<double> &lambdaJ , fullMatrix<double> &gradLambdaJ) const
+                                             fullVector<double> &lambdaJ, fullMatrix<double> &gradLambdaJ) const
 {
 
   // jacobian of the straight elements (only triangles for now)
@@ -476,88 +608,6 @@ void JacobianBasis::getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ,
 
 }
 
-// Calculate (signed) Jacobian at mapping's nodes for several elements
-// TODO: Optimize and test 1D & 2D
-void JacobianBasis::getSignedJacobian(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
-                                      const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const
-{
-
-  switch (bezier->getDim()) {
-
-    case 0 : {
-      const int numEl = nodesX.size2();
-      for (int iEl = 0; iEl < numEl; iEl++)
-        for (int i = 0; i < numJacNodes; i++) jacobian(i,iEl) = 1.;
-      break;
-    }
-
-    case 1 : {
-      const int numEl = nodesX.size2();
-      fullMatrix<double> dxdX(numJacNodes,numEl), dydX(numJacNodes,numEl), dzdX(numJacNodes,numEl);
-      gradShapeMatX.mult(nodesX, dxdX); gradShapeMatX.mult(nodesY, dydX); gradShapeMatX.mult(nodesZ, dzdX);
-      for (int iEl = 0; iEl < numEl; iEl++) {
-        fullMatrix<double> nodesXYZ(numPrimJacNodes,3);
-        for (int i = 0; i < numPrimJacNodes; i++) {
-          nodesXYZ(i,0) = nodesX(i,iEl);
-          nodesXYZ(i,1) = nodesY(i,iEl);
-          nodesXYZ(i,2) = nodesZ(i,iEl);
-        }
-        fullMatrix<double> normals(2,3);
-        getPrimNormals1D(nodesXYZ,normals);
-        const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2);
-        const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2);
-        for (int i = 0; i < numJacNodes; i++)
-          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
-                                      dxdY,dydY,dzdY,
-                                      dxdZ,dydZ,dzdZ);
-      }
-      break;
-    }
-
-    case 2 : {
-      const int numEl = nodesX.size2();
-      fullMatrix<double> dxdX(numJacNodes,numEl), dydX(numJacNodes,numEl), dzdX(numJacNodes,numEl);
-      fullMatrix<double> dxdY(numJacNodes,numEl), dydY(numJacNodes,numEl), dzdY(numJacNodes,numEl);
-      gradShapeMatX.mult(nodesX, dxdX); gradShapeMatX.mult(nodesY, dydX); gradShapeMatX.mult(nodesZ, dzdX);
-      gradShapeMatY.mult(nodesX, dxdY); gradShapeMatY.mult(nodesY, dydY); gradShapeMatY.mult(nodesZ, dzdY);
-      for (int iEl = 0; iEl < numEl; iEl++) {
-        fullMatrix<double> nodesXYZ(numPrimJacNodes,3);
-        for (int i = 0; i < numPrimJacNodes; i++) {
-          nodesXYZ(i,0) = nodesX(i,iEl);
-          nodesXYZ(i,1) = nodesY(i,iEl);
-          nodesXYZ(i,2) = nodesZ(i,iEl);
-        }
-        fullMatrix<double> normal(1,3);
-        getPrimNormal2D(nodesXYZ,normal);
-        const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2);
-        for (int i = 0; i < numJacNodes; i++)
-          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
-                                      dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl),
-                                      dxdZ,dydZ,dzdZ);
-      }
-      break;
-    }
-
-    case 3 : {
-      const int numEl = nodesX.size2();
-      fullMatrix<double> dxdX(numJacNodes,numEl), dydX(numJacNodes,numEl), dzdX(numJacNodes,numEl);
-      fullMatrix<double> dxdY(numJacNodes,numEl), dydY(numJacNodes,numEl), dzdY(numJacNodes,numEl);
-      fullMatrix<double> dxdZ(numJacNodes,numEl), dydZ(numJacNodes,numEl), dzdZ(numJacNodes,numEl);
-      gradShapeMatX.mult(nodesX, dxdX); gradShapeMatX.mult(nodesY, dydX); gradShapeMatX.mult(nodesZ, dzdX);
-      gradShapeMatY.mult(nodesX, dxdY); gradShapeMatY.mult(nodesY, dydY); gradShapeMatY.mult(nodesZ, dzdY);
-      gradShapeMatZ.mult(nodesX, dxdZ); gradShapeMatZ.mult(nodesY, dydZ); gradShapeMatZ.mult(nodesZ, dzdZ);
-      for (int iEl = 0; iEl < numEl; iEl++)
-        for (int i = 0; i < numJacNodes; i++)
-          jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl),
-                                      dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl),
-                                      dxdZ(i,iEl),dydZ(i,iEl),dzdZ(i,iEl));
-      break;
-    }
-
-  }
-
-}
-
 fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order)
 {
   int nbMonomials = (order+3)*((order+3)+1)*(2*(order+3)+1)/6 - 5;
diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h
index 31890fc5f0d69c636b706aea668b744ffb0d6f9a..e28f949958da0d1c787c447da6088be186f17645 100644
--- a/Numeric/JacobianBasis.h
+++ b/Numeric/JacobianBasis.h
@@ -16,19 +16,36 @@ class JacobianBasis {
  private:
   const bezierBasis *bezier;
 
-  fullMatrix<double> lagPoints; // sampling point
   fullMatrix<double> gradShapeMatX, gradShapeMatY, gradShapeMatZ;
+  fullMatrix<double> gradShapeMatXFast, gradShapeMatYFast, gradShapeMatZFast;
   fullVector<double> primGradShapeBarycenterX, primGradShapeBarycenterY, primGradShapeBarycenterZ;
   fullMatrix<double> matrixPrimJac2Jac;                                   // Lifts Lagrange basis of primary Jac. to Lagrange basis of Jac.
 
   int numJacNodes, numPrimJacNodes;
   int numMapNodes, numPrimMapNodes;
+  static const int numJacNodesFast = 1;
+
+  void getSignedJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX,
+                                const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ,
+                                const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const;
+  void getSignedJacobianGeneral(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;
+  void 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;
 
  public :
   JacobianBasis(int tag);
 
-  // get methods
+  // Get methods
   inline int getNumJacNodes() const { return numJacNodes; }
+  inline int getNumJacNodesFast() const { return numJacNodesFast; }
   inline int getNumMapNodes() const { return numMapNodes; }
   inline int getNumPrimJacNodes() const { return numPrimJacNodes; }
   inline int getNumPrimMapNodes() const { return numPrimMapNodes; }
@@ -36,22 +53,44 @@ class JacobianBasis {
   inline int getNumSubNodes() const { return bezier->subDivisor.size1(); }
   inline int getNumLagCoeff() const { return bezier->getNumLagCoeff(); }
 
-  //
+  // Jacobian evaluation methods
   double getPrimNormals1D(const fullMatrix<double> &nodesXYZ, fullMatrix<double> &result) const;
   double getPrimNormal2D(const fullMatrix<double> &nodesXYZ, fullMatrix<double> &result) const;
   double getPrimJac3D(const fullMatrix<double> &nodesXYZ) const;
-  void getSignedJacobian(const fullMatrix<double> &nodesXYZ,
-                         const fullMatrix<double> &normals, fullVector<double> &jacobian) const;
-  void getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
-                                const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const;
+  inline void getSignedJacAndGradients(const fullMatrix<double> &nodesXYZ,
+                                       const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const {
+    getSignedJacAndGradientsGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,normals,JDJ);
+  }
+  inline void getSignedJacAndGradientsFast(const fullMatrix<double> &nodesXYZ,
+                                           const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const {
+    getSignedJacAndGradientsGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
+                                    gradShapeMatZFast,nodesXYZ,normals,JDJ);
+  }
   void getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ,
                                 const fullMatrix<double> &nodesXYZStraight,
                                 fullVector<double> &lambdaJ , fullMatrix<double> &gradLambdaJ) const;
-  void getSignedJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const;
-  void getSignedJacobian(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
-                         const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const;
-  void getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const;
-
+  inline void getSignedJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getSignedJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,jacobian);
+  }
+  inline void getSignedJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian);
+  }
+  inline void getSignedJacobian(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
+                                const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const {
+    getSignedJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,
+                             gradShapeMatZ,nodesX,nodesY,nodesZ,jacobian);
+  }
+  inline void getSignedJacobianFast(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY,
+                                    const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const {
+    getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,
+                             gradShapeMatZFast,nodesX,nodesY,nodesZ,jacobian);
+  }
+  inline void getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getScaledJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,jacobian);
+  }
+  inline void getScaledJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const {
+    getScaledJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian);
+  }
   //
   inline void lag2Bez(const fullVector<double> &jac, fullVector<double> &bez) const {
     bezier->matrixLag2Bez.mult(jac,bez);
@@ -66,7 +105,7 @@ class JacobianBasis {
     bezier->subDivisor.mult(bez,result);
   }
 
-  //
+  // Jacobian basis order and pyramidal basis
   static int jacobianOrder(int parentType, int order);
   static fullMatrix<double> generateJacMonomialsPyramid(int order);
   static fullMatrix<double> generateJacPointsPyramid(int order);
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.cpp b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
index 64b2cc200b18ebf14299f20e473e1c782887502d..45db5d249c0fd6edf679a25c0a13ff8665a3d92f 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
@@ -68,8 +68,8 @@ static inline double compute_f1(double v, double barrier)
 }
 
 OptHOM::OptHOM(const std::set<MElement*> &els, std::set<MVertex*> & toFix,
-               bool fixBndNodes) :
-  mesh(els, toFix, fixBndNodes)
+               bool fixBndNodes, bool fastJacEval) :
+  mesh(els, toFix, fixBndNodes, fastJacEval)
 {
   _optimizeMetricMin = false;
 }
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.h b/contrib/HighOrderMeshOptimizer/OptHOM.h
index 19e5c42931a0645873c370afdc61f511f38cec45..debbc6a856c7858f4ad78d3419d136fdc834ae0c 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.h
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.h
@@ -44,7 +44,7 @@ class OptHOM
 public:
   Mesh mesh;
   OptHOM(const std::set<MElement*> &els, std::set<MVertex*> & toFix,
-         bool fixBndNodes);
+         bool fixBndNodes, bool fastJacEval = false);
   // returns 1 if the mesh has been optimized with success i.e. all jacobians
   // are in the range; returns 0 if the mesh is valid (all jacobians positive,
   // JMIN > 0) but JMIN < barrier_min || JMAX > barrier_max; returns -1 if the
diff --git a/contrib/HighOrderMeshOptimizer/OptHomMesh.cpp b/contrib/HighOrderMeshOptimizer/OptHomMesh.cpp
index 85efcef199e98bcb9afb543e877c4a17500cea15..4ed1a1a119ad8f8780b280324a31b6d6d62dbb55 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomMesh.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHomMesh.cpp
@@ -35,7 +35,8 @@
 #include "ParamCoord.h"
 #include "OptHomMesh.h"
 
-Mesh::Mesh(const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBndNodes)
+Mesh::Mesh(const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBndNodes, bool fastJacEval) :
+ _fastJacEval(fastJacEval)
 {
 
   _dim = (*els.begin())->getDim();
@@ -65,7 +66,7 @@ Mesh::Mesh(const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBn
       it != els.end(); ++it, ++iEl) {
     _el[iEl] = *it;
     const JacobianBasis *jac = _el[iEl]->getJacobianFuncSpace();
-    _nBezEl[iEl] = jac->getNumJacNodes();
+    _nBezEl[iEl] = _fastJacEval ? jac->getNumJacNodesFast() : jac->getNumJacNodes();
     _nNodEl[iEl] = jac->getNumMapNodes();
     for (int iVEl = 0; iVEl < jac->getNumMapNodes(); iVEl++) {
       MVertex *vert = _el[iEl]->getVertex(iVEl);
@@ -73,10 +74,12 @@ Mesh::Mesh(const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBn
       _el2V[iEl].push_back(iV);
       const int nPCV = _pc->nCoord(vert);
       bool isFV = false;
-      if (fixBndNodes)
-        isFV = (vert->onWhat()->dim() == _dim) && (toFix.find(vert) == toFix.end());
-      else
-        isFV = (vert->onWhat()->dim() >= 1) && (toFix.find(vert) == toFix.end());
+      if (nPCV > 0) {
+        if (fixBndNodes)
+          isFV = (vert->onWhat()->dim() == _dim) && (toFix.find(vert) == toFix.end());
+        else
+          isFV = (vert->onWhat()->dim() >= 1) && (toFix.find(vert) == toFix.end());
+      }
       if (isFV) {
         int iFV = addFreeVert(vert,iV,nPCV,toFix);
         _el2FV[iEl].push_back(iFV);
@@ -285,10 +288,9 @@ void Mesh::scaledJacAndGradients(int iEl, std::vector<double> &sJ,
                                  std::vector<double> &gSJ)
 {
   const JacobianBasis *jacBasis = _el[iEl]->getJacobianFuncSpace();
-  const int &numJacNodes = jacBasis->getNumJacNodes();
-  const int &numMapNodes = jacBasis->getNumMapNodes();
-  fullMatrix<double> JDJ (numJacNodes,3*numMapNodes+1);
-  fullMatrix<double> BDB (numJacNodes,3*numMapNodes+1);
+  const int &numJacNodes = _nBezEl[iEl];
+  const int &numMapNodes = _nNodEl[iEl];
+  fullMatrix<double> JDJ(numJacNodes,3*numMapNodes+1), BDB(numJacNodes,3*numMapNodes+1);
 
   // Coordinates of nodes
   fullMatrix<double> nodesXYZ(numMapNodes,3), normals(_dim,3);
@@ -301,11 +303,17 @@ void Mesh::scaledJacAndGradients(int iEl, std::vector<double> &sJ,
 
   // Calculate Jacobian and gradients, scale if 3D (already scaled by
   // regularization normals in 2D)
-  jacBasis->getSignedJacAndGradients(nodesXYZ,_scaledNormEl[iEl],JDJ);
+  if (_fastJacEval)
+    jacBasis->getSignedJacAndGradientsFast(nodesXYZ,_scaledNormEl[iEl],JDJ);
+  else
+    jacBasis->getSignedJacAndGradients(nodesXYZ,_scaledNormEl[iEl],JDJ);
   if (_dim == 3) JDJ.scale(_invStraightJac[iEl]);
 
   // Transform Jacobian and gradients from Lagrangian to Bezier basis
-  jacBasis->lag2Bez(JDJ,BDB);
+  if (_fastJacEval)
+    BDB = JDJ;
+  else
+    jacBasis->lag2Bez(JDJ,BDB);
 
   // Scaled jacobian
   for (int l = 0; l < numJacNodes; l++) sJ [l] = BDB (l,3*numMapNodes);
diff --git a/contrib/HighOrderMeshOptimizer/OptHomMesh.h b/contrib/HighOrderMeshOptimizer/OptHomMesh.h
index ec49b7717918ae9de808c777621c78bf4b6ec1e9..06876da687614a01987d7249b2bc954e7b2a57f2 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomMesh.h
+++ b/contrib/HighOrderMeshOptimizer/OptHomMesh.h
@@ -41,7 +41,7 @@
 class Mesh
 {
 public:
-  Mesh(const std::set<MElement*> &els, std::set<MVertex*> & toFix, bool fixBndNodes);
+  Mesh(const std::set<MElement*> &els, std::set<MVertex*> & toFix, bool fixBndNodes, bool fastJacEval);
 
   inline const int &nPC() { return _nPC; }
   inline int nVert() { return _vert.size(); }
@@ -75,6 +75,8 @@ private:
   int _dim;
   // Total nb. of parametric coordinates
   int _nPC;
+  // Use fast Jacobian estimation?
+  bool _fastJacEval;
   // List of elements
   std::vector<MElement*> _el;
   // Normals to 2D elements for Jacobian regularization and scaling
diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
index 5a988b76b987d5fe35721011384fe72c5702edb6..b9ca0aaae0ce7a2173f8404a10943fe1b8097e13 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
@@ -308,8 +308,12 @@ static void optimizeConnectedBlobs
     //std::ostringstream ossI1;
     //ossI1 << "initial_ITER_" << i << ".msh";
     //temp.mesh.writeMSH(ossI1.str().c_str());
-    int success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX,
-                                false, samples, p.itMax, p.optPassMax);
+    int success = -1;
+    if (temp.mesh.nPC() == 0)
+      Msg::Info("Blob %i has no degree of freedom, skipping", i+1);
+    else
+      success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN,
+                              p.BARRIER_MAX, false, samples, p.itMax, p.optPassMax);
     if (success >= 0 && p.BARRIER_MIN_METRIC > 0) {
       Msg::Info("Jacobian optimization succeed, starting svd optimization");
       success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN_METRIC, p.BARRIER_MAX,
diff --git a/contrib/HighOrderMeshOptimizer/ParamCoord.h b/contrib/HighOrderMeshOptimizer/ParamCoord.h
index e812d78d8da34c808de6ca3d854898a6479f6bb0..9b50e50280a609c0dd36b8cb078074538d32276f 100644
--- a/contrib/HighOrderMeshOptimizer/ParamCoord.h
+++ b/contrib/HighOrderMeshOptimizer/ParamCoord.h
@@ -92,7 +92,7 @@ public:
 class ParamCoordParent : public ParamCoord
 {
 public:
-  int nCoord(MVertex* vert) { return vert->onWhat()->dim(); }
+  int nCoord(MVertex* vert) { return vert->onWhat()->haveParametrization() ? vert->onWhat()->dim() : 0; }
   virtual void exportParamCoord(MVertex *v, const SPoint3 &uvw);
   virtual SPoint3 getUvw(MVertex* vert);
   virtual SPoint3 uvw2Xyz(MVertex* vert, const SPoint3 &uvw);