diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp
index 05ac767ff314e18ae7352b9473f3128e7b03d707..7b8980fdd9f5d1446ee02092e72db09ee268b7e2 100644
--- a/Numeric/JacobianBasis.cpp
+++ b/Numeric/JacobianBasis.cpp
@@ -25,7 +25,10 @@ namespace {
   }
 }
 
-GradientBasis::GradientBasis(int tag, int order)
+GradientBasis::GradientBasis(int tag, int order) :
+    _type(ElementType::ParentTypeFromTag(tag)),
+    _idealDifferent(_type == TYPE_TRI || _type == TYPE_PRI ||
+                    _type == TYPE_TET || _type == TYPE_PYR)
 {
   const int type = ElementType::ParentTypeFromTag(tag);
 
@@ -90,6 +93,41 @@ void GradientBasis::getGradientsFromNodes(const fullMatrix<double> &nodes,
   if (dxyzdZ) gradShapeMatZ.mult(nodes, *dxyzdZ);
 }
 
+void GradientBasis::mapFromIdealElement(fullMatrix<double> *dxyzdX,
+                                        fullMatrix<double> *dxyzdY,
+                                        fullMatrix<double> *dxyzdZ) const
+{
+  if (_idealDifferent) {
+    if (_type == TYPE_PYR) {
+      dxyzdZ->scale(.5);
+      return;
+    }
+
+    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:
+    {
+      static const double cTet[3] = {-3./2/std::sqrt(6),
+                                     -1./2/std::sqrt(2),
+                                     std::sqrt(1.5)};
+      dxyzdZ->scale(cTet[2]);
+      dxyzdZ->axpy(*dxyzdX, cTet[0]);
+      dxyzdZ->axpy(*dxyzdY, cTet[1]);
+    }
+    }
+  }
+}
+
 JacobianBasis::JacobianBasis(int tag, int jacOrder) :
     _bezier(NULL), _tag(tag), _dim(ElementType::DimensionFromTag(tag)),
     _jacOrder(jacOrder >= 0 ? jacOrder : jacobianOrder(tag))
@@ -324,6 +362,7 @@ inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<do
       fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3);
       gSMatX.mult(nodesXYZ, dxyzdX);
       gSMatY.mult(nodesXYZ, dxyzdY);
+      if (!scaling) _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, NULL);
       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);
@@ -339,6 +378,7 @@ inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<do
       gSMatX.mult(nodesXYZ, dxyzdX);
       gSMatY.mult(nodesXYZ, dxyzdY);
       gSMatZ.mult(nodesXYZ, dxyzdZ);
+      if (!scaling) _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, &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);
@@ -425,6 +465,11 @@ inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<do
       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);
+      if (!scaling) {
+        _gradBasis->mapFromIdealElement(&dxdX, &dxdY, NULL);
+        _gradBasis->mapFromIdealElement(&dydX, &dydY, NULL);
+        _gradBasis->mapFromIdealElement(&dzdX, &dzdY, NULL);
+      }
       for (int iEl = 0; iEl < numEl; iEl++) {
         fullMatrix<double> nodesXYZ(numPrimMapNodes,3);
         for (int i = 0; i < numPrimMapNodes; i++) {
@@ -455,6 +500,11 @@ inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<do
       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);
+      if (!scaling) {
+        _gradBasis->mapFromIdealElement(&dxdX, &dxdY, &dxdZ);
+        _gradBasis->mapFromIdealElement(&dydX, &dydY, &dydZ);
+        _gradBasis->mapFromIdealElement(&dzdX, &dzdY, &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),
@@ -543,6 +593,7 @@ void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes, const fullMat
       fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3);
       gSMatX.mult(nodesXYZ, dxyzdX);
       gSMatY.mult(nodesXYZ, dxyzdY);
+      _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, NULL);
       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);
@@ -572,6 +623,7 @@ void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes, const fullMat
       gSMatX.mult(nodesXYZ, dxyzdX);
       gSMatY.mult(nodesXYZ, dxyzdY);
       gSMatZ.mult(nodesXYZ, dxyzdZ);
+      _gradBasis->mapFromIdealElement(&dxyzdX, &dxyzdY, &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);
@@ -672,122 +724,6 @@ void JacobianBasis::interpolate(const fullVector<double> &jacobian,
   getBezier()->interpolate(bezM, uvw, result);
 }
 
-fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order)
-{
-  const int nbMonomials = (order+3)*(order+3)*(order+1);
-  fullMatrix<double> monomials(nbMonomials, 3);
-
-  if (order == 0) {
-    fullMatrix<double> prox, quad = gmshGenerateMonomialsQuadrangle(2);
-    prox.setAsProxy(monomials, 0, 2);
-    prox.setAll(quad);
-    // monomials has been initialized to 0, so third column is ok
-    return monomials;
-  }
-
-  monomials(0, 0) = 0;
-  monomials(0, 1) = 0;
-  monomials(0, 2) = 0;
-
-  monomials(1, 0) = order+2;
-  monomials(1, 1) = 0;
-  monomials(1, 2) = 0;
-
-  monomials(2, 0) = order+2;
-  monomials(2, 1) = order+2;
-  monomials(2, 2) = 0;
-
-  monomials(3, 0) = 0;
-  monomials(3, 1) = order+2;
-  monomials(3, 2) = 0;
-
-  monomials(4, 0) = 0;
-  monomials(4, 1) = 0;
-  monomials(4, 2) = order;
-
-  monomials(5, 0) = order+2;
-  monomials(5, 1) = 0;
-  monomials(5, 2) = order;
-
-  monomials(6, 0) = order+2;
-  monomials(6, 1) = order+2;
-  monomials(6, 2) = order;
-
-  monomials(7, 0) = 0;
-  monomials(7, 1) = order+2;
-  monomials(7, 2) = order;
-
-  int index = 8;
-
-  static const int bottom_edges[4][2] = {
-    {0, 1},
-    {1, 2},
-    {2, 3},
-    {3, 0}
-  };
-
-  // bottom & top "edges"
-  for (int iedge = 0; iedge < 4; ++iedge) {
-    int i0 = bottom_edges[iedge][0];
-    int i1 = bottom_edges[iedge][1];
-
-    int u_1 = (monomials(i1,0)-monomials(i0,0)) / (order + 2);
-    int u_2 = (monomials(i1,1)-monomials(i0,1)) / (order + 2);
-
-    for (int i = 1; i < order + 2; ++i, ++index) {
-      monomials(index, 0) = monomials(i0, 0) + i * u_1;
-      monomials(index, 1) = monomials(i0, 1) + i * u_2;
-      monomials(index, 2) = 0;
-    }
-    for (int i = 1; i < order + 2; ++i, ++index) {
-      monomials(index, 0) = monomials(i0, 0) + i * u_1;
-      monomials(index, 1) = monomials(i0, 1) + i * u_2;
-      monomials(index, 2) = order;
-    }
-  }
-
-  // bottom & top "face"
-  fullMatrix<double> uv = gmshGenerateMonomialsQuadrangle(order);
-  uv.add(1);
-  for (int i = 0; i < uv.size1(); ++i, ++index) {
-    monomials(index, 0) = uv(i, 0);
-    monomials(index, 1) = uv(i, 1);
-    monomials(index, 2) = 0;
-  }
-  for (int i = 0; i < uv.size1(); ++i, ++index) {
-    monomials(index, 0) = uv(i, 0);
-    monomials(index, 1) = uv(i, 1);
-    monomials(index, 2) = order;
-  }
-
-  // other monomials
-  uv = gmshGenerateMonomialsQuadrangle(order + 2);
-  for (int k = 1; k < order; ++k) {
-    for (int i = 0; i < uv.size1(); ++i, ++index) {
-      monomials(index, 0) = uv(i, 0);
-      monomials(index, 1) = uv(i, 1);
-      monomials(index, 2) = k;
-    }
-  }
-
-  return monomials;
-}
-
-fullMatrix<double> JacobianBasis::generateJacPointsPyramid(int order)
-{
-  fullMatrix<double> points = generateJacMonomialsPyramid(order);
-
-  const double p = order + 2;
-  for (int i = 0; i < points.size1(); ++i) {
-    points(i, 2) = points(i, 2) / p;
-    const double scale = 1. - points(i, 2);
-    points(i, 0) = (-1. + 2. * points(i, 0) / p) * scale;
-    points(i, 1) = (-1. + 2. * points(i, 1) / p) * scale;
-  }
-
-  return points;
-}
-
 int JacobianBasis::jacobianOrder(int tag)
 {
   const int parentType = ElementType::ParentTypeFromTag(tag);
diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h
index 894b088ce396e476d255153562fe3f540f363991..ca744f6e57d0176f8972b3d64c2ff3bfabc8124d 100644
--- a/Numeric/JacobianBasis.h
+++ b/Numeric/JacobianBasis.h
@@ -16,8 +16,11 @@ class GradientBasis {
  public:
   fullMatrix<double> gradShapeMatX, gradShapeMatY, gradShapeMatZ;
 
- public :
+ private:
+  const int _type;
+  const bool _idealDifferent;
 
+ public:
   GradientBasis(int tag, int order);
 
   int getNumSamplingPoints() const {return gradShapeMatX.size1();}
@@ -27,6 +30,9 @@ class GradientBasis {
                              fullMatrix<double> *dxyzdX,
                              fullMatrix<double> *dxyzdY,
                              fullMatrix<double> *dxyzdZ) const;
+  void mapFromIdealElement(fullMatrix<double> *dxyzdX,
+                           fullMatrix<double> *dxyzdY,
+                           fullMatrix<double> *dxyzdZ) const;
 };
 
 
@@ -116,8 +122,6 @@ class JacobianBasis {
   //
   static int jacobianOrder(int tag);
   static int jacobianOrder(int parentType, int order);
-  static fullMatrix<double> generateJacMonomialsPyramid(int order);
-  static fullMatrix<double> generateJacPointsPyramid(int order);
 
 
  private :
diff --git a/Numeric/MetricBasis.cpp b/Numeric/MetricBasis.cpp
index 9b7c6e8fa819b8b7398c75ad6cfbc9e54707a9ac..c5701a234883050525fa47de553eabad304e23ae 100644
--- a/Numeric/MetricBasis.cpp
+++ b/Numeric/MetricBasis.cpp
@@ -151,7 +151,7 @@ double MetricBasis::getMinSampledR(MElement *el, int deg) const
       samplingPoints = gmshGeneratePointsHexahedron(deg,false);
       break;
     case TYPE_PYR :
-      samplingPoints = JacobianBasis::generateJacPointsPyramid(deg);
+      samplingPoints = gmshGeneratePointsPyramidGeneral(true, deg+1, deg);
       break;
     default :
       Msg::Error("Unknown Jacobian function space for element type %d", el->getType());
@@ -877,6 +877,7 @@ void MetricBasis::_fillCoeff(const GradientBasis *gradients,
     {
       fullMatrix<double> dxydX(nSampPnts,2), dxydY(nSampPnts,2);
       gradients->getGradientsFromNodes(nodes, &dxydX, &dxydY, NULL);
+      gradients->mapFromIdealElement(&dxydX, &dxydY, NULL);
 
       coeff.resize(nSampPnts, 3);
       for (int i = 0; i < nSampPnts; i++) {
@@ -895,6 +896,7 @@ void MetricBasis::_fillCoeff(const GradientBasis *gradients,
     {
       fullMatrix<double> dxyzdX(nSampPnts,3), dxyzdY(nSampPnts,3), dxyzdZ(nSampPnts,3);
       gradients->getGradientsFromNodes(nodes, &dxyzdX, &dxyzdY, &dxyzdZ);
+      gradients->mapFromIdealElement(&dxyzdX, &dxyzdY, &dxyzdZ);
 
       coeff.resize(nSampPnts, 7);
       for (int i = 0; i < nSampPnts; i++) {
diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp
index 6041849a1b130f088bf777ea00fa480edaf6697e..e9671a2d0f82414b06fef4fa68e44df66ee0a896 100644
--- a/Plugin/AnalyseCurvedMesh.cpp
+++ b/Plugin/AnalyseCurvedMesh.cpp
@@ -164,7 +164,6 @@ PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
         _computeMinR(dim);
         Msg::StatusBar(true, "... Done computing metric (%g seconds)", Cpu()-time);
         _printStatMetric();
-        return 0;
       }
     }
   }
@@ -395,6 +394,7 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinR(int dim)
       }
     }
   }
+
   _computedR[dim-1] = true;
 }