diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index a20c54a3b87c52c40660fd82a0c5bb5bf2ddc833..70661ddc11a70881e4aba468b7ab8fde10c3e2df 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -244,7 +244,7 @@ int GmshBatch()
   solver_batch_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
 #endif
 
-  if (false) {
+  if (true) {
   // 11/06/13 : This will be removed later !
     for (int i = 1; i < MSH_NUM_TYPE+1; ++i) {
       if (i == 76 || i == 77 || i == 78)
@@ -258,8 +258,10 @@ int GmshBatch()
         continue;
       }
       if (MElement::ParentTypeFromTag(i) == TYPE_PYR) {
-        Msg::Warning("ignoring pyramid %d", i);
-        continue;
+        if (i > 124 && i < 132) {
+          Msg::Warning("ignoring serendipity pyramid %d (bug in Bergot implementation)", i);
+          continue;
+        }
       }
       if (MElement::ParentTypeFromTag(i) == TYPE_POLYG) {
         Msg::Warning("ignoring polygone %d", i);
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 394720ec305f16ed6693d8e3e607e209c52d1def..2d7976a55cc851ef3d95890ad5cb239f8f692659 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -1280,13 +1280,20 @@ int MElement::getInfoMSH(const int typeMSH, const char **const name)
   case MSH_PYR_5   : if(name) *name = "Pyramid 5";        return 5;
   case MSH_PYR_13  : if(name) *name = "Pyramid 13";       return 5 + 8;
   case MSH_PYR_14  : if(name) *name = "Pyramid 14";       return 5 + 8 + 1;
-  case MSH_PYR_30  : if(name) *name = "Pyramid 30";       return 5 + 8*2 + 4*1 + 1*4 + 1;
-  case MSH_PYR_55  : if(name) *name = "Pyramid 55";       return 5 + 8*3 + 4*3 + 1*9 + 5;
-  case MSH_PYR_91  : if(name) *name = "Pyramid 91";       return 91;
-  case MSH_PYR_140 : if(name) *name = "Pyramid 140";      return 140;
-  case MSH_PYR_204 : if(name) *name = "Pyramid 204";      return 204;
-  case MSH_PYR_285 : if(name) *name = "Pyramid 285";      return 285;
-  case MSH_PYR_385 : if(name) *name = "Pyramid 385";      return 385;
+  case MSH_PYR_30  : if(name) *name = "Pyramid 30";       return 5 + 8*2 + 4*1  + 1*4  + 1;
+  case MSH_PYR_55  : if(name) *name = "Pyramid 55";       return 5 + 8*3 + 4*3  + 1*9  + 5;
+  case MSH_PYR_91  : if(name) *name = "Pyramid 91";       return 5 + 8*4 + 4*6  + 1*16 + 14;
+  case MSH_PYR_140 : if(name) *name = "Pyramid 140";      return 5 + 8*5 + 4*10 + 1*25 + 30;
+  case MSH_PYR_204 : if(name) *name = "Pyramid 204";      return 5 + 8*6 + 4*15 + 1*36 + 55;
+  case MSH_PYR_285 : if(name) *name = "Pyramid 285";      return 5 + 8*7 + 4*21 + 1*49 + 91;
+  case MSH_PYR_385 : if(name) *name = "Pyramid 385";      return 5 + 8*8 + 4*28 + 1*64 + 140;
+  case MSH_PYR_29  : if(name) *name = "Pyramid 29";       return 5 + 8*2 + 4*1  + 1*4;
+  case MSH_PYR_50  : if(name) *name = "Pyramid 50";       return 5 + 8*3 + 4*3  + 1*9;
+  case MSH_PYR_77  : if(name) *name = "Pyramid 77";       return 5 + 8*4 + 4*6  + 1*16;
+  case MSH_PYR_110 : if(name) *name = "Pyramid 110";      return 5 + 8*5 + 4*10 + 1*25;
+  case MSH_PYR_149 : if(name) *name = "Pyramid 149";      return 5 + 8*6 + 4*15 + 1*36;
+  case MSH_PYR_194 : if(name) *name = "Pyramid 194";      return 5 + 8*7 + 4*21 + 1*49;
+  case MSH_PYR_245 : if(name) *name = "Pyramid 245";      return 5 + 8*8 + 4*28 + 1*64;
   case MSH_POLYH_  : if(name) *name = "Polyhedron";       return 0;
   case MSH_PNT_SUB : if(name) *name = "Point Xfem";       return 1;
   case MSH_LIN_SUB : if(name) *name = "Line Xfem";        return 2;
diff --git a/Geo/MPyramid.h b/Geo/MPyramid.h
index 465240b9088a225192ce1cbfd312cdc69c8ebc33..19fdbc628d28c72a00d4125d9b702472a889265e 100644
--- a/Geo/MPyramid.h
+++ b/Geo/MPyramid.h
@@ -166,11 +166,12 @@ class MPyramid : public MElement {
   static int faces_pyramid(const int face, const int vert)
   {
     // only triangular faces
-    static const int f[4][3] = {
-      {0, 1, 4},
-      {3, 0, 4},
-      {1, 2, 4},
-      {2, 3, 4}
+    static const int f[5][4] = {
+      {0, 1, 4, -1},
+      {3, 0, 4, -1},
+      {1, 2, 4, -1},
+      {2, 3, 4, -1},
+      {0, 3, 2, 1}
     };
     return f[face][vert];
   }
diff --git a/Numeric/nodalBasis.cpp b/Numeric/nodalBasis.cpp
index 21a69e2eb5dbcf7960ecbc44dfe8de5907dc7022..8fb9be5916ba7239fdb1e3ace21f95734f152546 100644
--- a/Numeric/nodalBasis.cpp
+++ b/Numeric/nodalBasis.cpp
@@ -1606,7 +1606,7 @@ nodalBasis::nodalBasis(int tag)
       closureRef.resize(48, 0);
     }
     else {
-      if (order < 2) generateFaceClosurePrism(closures, order);
+      generateFaceClosurePrism(closures, order);
       generateFaceClosurePrismFull(fullClosures, closureRef, order);
     }
     break;
diff --git a/Numeric/pointsGenerators.cpp b/Numeric/pointsGenerators.cpp
index 5ae836323f1400b65c0b7fd3808dd3d6ead67b16..4d12d058af3f39c868b4564399e5abd6ef369840 100644
--- a/Numeric/pointsGenerators.cpp
+++ b/Numeric/pointsGenerators.cpp
@@ -9,6 +9,7 @@
 #include "MTetrahedron.h"
 #include "MHexahedron.h"
 #include "MPrism.h"
+#include "MPyramid.h"
 
 /* --- Lines --- */
 
@@ -962,7 +963,8 @@ fullMatrix<int> gmshGenerateMonomialsTetrahedron(int order, bool serendip)
 
 fullMatrix<int> gmshGenerateMonomialsPrism(int order, bool forSerendipPoints)
 {
-  int nbMonomials = forSerendipPoints ? 6 + (order-1)*9 : (order + 1) * (order + 1)*(order + 2)/2;
+  int nbMonomials = forSerendipPoints ? 6 + (order-1)*9 :
+                                        (order + 1) * (order + 1)*(order + 2)/2;
   fullMatrix<int> monomials(nbMonomials, 3);
 
   monomials(0, 0) = 0;
@@ -1028,9 +1030,7 @@ fullMatrix<int> gmshGenerateMonomialsPrism(int order, bool forSerendipPoints)
             i2 = MPrism::faces_prism(iface, 2);
             dudv.setAsProxy(dudvT);
           }
-          else {
-            continue;
-          }
+          else continue;
 
           int u[3];
           u[0] = (monomials(i1, 0) - monomials(i0, 0)) / order;
@@ -1068,7 +1068,8 @@ fullMatrix<int> gmshGenerateMonomialsPrism(int order, bool forSerendipPoints)
 
 fullMatrix<int> gmshGenerateMonomialsHexahedron(int order, bool forSerendipPoints)
 {
-  int nbMonomials = forSerendipPoints ? 8 + (order-1)*12 : (order+1)*(order+1)*(order+1);
+  int nbMonomials = forSerendipPoints ? 8 + (order-1)*12 :
+                                        (order+1)*(order+1)*(order+1);
   fullMatrix<int> monomials(nbMonomials, 3);
 
   monomials(0, 0) = 0;
@@ -1121,10 +1122,10 @@ fullMatrix<int> gmshGenerateMonomialsHexahedron(int order, bool forSerendipPoint
         }
       }
 
-      fullMatrix<int> dudv = gmshGenerateMonomialsQuadrangle(order - 2);
-      dudv.add(1);
-
       if (!forSerendipPoints) {
+        fullMatrix<int> dudv = gmshGenerateMonomialsQuadrangle(order - 2);
+        dudv.add(1);
+
         for (int iface = 0; iface < 6; ++iface) {
           int i0 = MHexahedron::faces_hexa(iface, 0);
           int i1 = MHexahedron::faces_hexa(iface, 1);
@@ -1155,3 +1156,97 @@ fullMatrix<int> gmshGenerateMonomialsHexahedron(int order, bool forSerendipPoint
   return monomials;
 }
 
+fullMatrix<int> gmshGenerateMonomialsPyramid(int order, bool forSerendipPoints)
+{
+  int nbMonomials = forSerendipPoints ? 5 + (order-1)*8 :
+                                        (order+1)*((order+1)+1)*(2*(order+1)+1)/6;
+  fullMatrix<int> monomials(nbMonomials, 3);
+
+  monomials(0, 0) = 0;
+  monomials(0, 1) = 0;
+  monomials(0, 2) = 0;
+
+  if (order > 0) {
+    monomials(1, 0) = order;
+    monomials(1, 1) = 0;
+    monomials(1, 2) = 0;
+
+    monomials(2, 0) = order;
+    monomials(2, 1) = order;
+    monomials(2, 2) = 0;
+
+    monomials(3, 0) = 0;
+    monomials(3, 1) = order;
+    monomials(3, 2) = 0;
+
+    monomials(4, 0) = 0;
+    monomials(4, 1) = 0;
+    monomials(4, 2) = order;
+
+    if (order > 1) {
+      int index = 5;
+      for (int iedge = 0; iedge < 8; ++iedge) {
+        int i0 = MPyramid::edges_pyramid(iedge, 0);
+        int i1 = MPyramid::edges_pyramid(iedge, 1);
+
+        int u_1 = (monomials(i1,0)-monomials(i0,0)) / order;
+        int u_2 = (monomials(i1,1)-monomials(i0,1)) / order;
+        int u_3 = (monomials(i1,2)-monomials(i0,2)) / order;
+
+        for (int i = 1; i < order; ++i, ++index) {
+          monomials(index, 0) = monomials(i0, 0) + i * u_1;
+          monomials(index, 1) = monomials(i0, 1) + i * u_2;
+          monomials(index, 2) = monomials(i0, 2) + i * u_3;
+        }
+      }
+
+      if (!forSerendipPoints) {
+        fullMatrix<int> dudvQ = gmshGenerateMonomialsQuadrangle(order - 2);
+        dudvQ.add(1);
+
+        fullMatrix<int> dudvT;
+        if (order > 2)  dudvT = gmshGenerateMonomialsTriangle(order - 3);
+        dudvT.add(1);
+
+        for (int iface = 0; iface < 5; ++iface) {
+          int i0, i1, i2;
+          i0 = MPyramid::faces_pyramid(iface, 0);
+          i1 = MPyramid::faces_pyramid(iface, 1);
+          fullMatrix<int> dudv;
+          if (MPyramid::faces_pyramid(iface, 3) != -1) {
+            i2 = MPyramid::faces_pyramid(iface, 3);
+            dudv.setAsProxy(dudvQ);
+          }
+          else if (order > 2) {
+            i2 = MPyramid::faces_pyramid(iface, 2);
+            dudv.setAsProxy(dudvT);
+          }
+          else continue;
+
+          int u[3];
+          u[0] = (monomials(i1, 0) - monomials(i0, 0)) / order;
+          u[1] = (monomials(i1, 1) - monomials(i0, 1)) / order;
+          u[2] = (monomials(i1, 2) - monomials(i0, 2)) / order;
+          int v[3];
+          v[0] = (monomials(i2, 0) - monomials(i0, 0)) / order;
+          v[1] = (monomials(i2, 1) - monomials(i0, 1)) / order;
+          v[2] = (monomials(i2, 2) - monomials(i0, 2)) / order;
+
+          for (int i = 0; i < dudv.size1(); ++i, ++index) {
+            monomials(index, 0) = monomials(i0, 0) + u[0] * dudv(i, 0) + v[0] * dudv(i, 1);
+            monomials(index, 1) = monomials(i0, 1) + u[1] * dudv(i, 0) + v[1] * dudv(i, 1);
+            monomials(index, 2) = monomials(i0, 2) + u[2] * dudv(i, 0) + v[2] * dudv(i, 1);
+          }
+        }
+
+        if (order > 2) {
+          fullMatrix<int> inner = gmshGenerateMonomialsPyramid(order - 3);
+          inner.add(1);
+          monomials.copy(inner, 0, nbMonomials - index, 0, 3, index, 0);
+        }
+      }
+    }
+  }
+  return monomials;
+}
+
diff --git a/Numeric/pointsGenerators.h b/Numeric/pointsGenerators.h
index 4524266ac9288c2cf14d727818128dd20bd86397..9529cefff67313747e2686d3b7b8b1f53b648e73 100644
--- a/Numeric/pointsGenerators.h
+++ b/Numeric/pointsGenerators.h
@@ -44,7 +44,8 @@ fullMatrix<int> gmshGenerateMonomialsHexahedron(int order, bool forSerendipPoint
 fullMatrix<int> gmshGenerateMonomialsPrism(int order, bool forSerendipPoints = false);
 //fullMatrix<int> gmshGenerateMonomialsPrismSerendipity(int order); //FIXME
 
-//fullMatrix<int> gmshGenerateMonomialsPyramid(int order, bool serendip);
+fullMatrix<int> gmshGenerateMonomialsPyramid(int order, bool forSerendipPoints = false);
+//fullMatrix<int> gmshGenerateMonomialsPyramidSerendipity(int order); //FIXME
 
 
 
diff --git a/Numeric/polynomialBasis.h b/Numeric/polynomialBasis.h
index c15e2eaed28a12507613e2505a256a7852f64c55..5c67c3580b3ef1f9548cbfed20be1bbefea358a1 100644
--- a/Numeric/polynomialBasis.h
+++ b/Numeric/polynomialBasis.h
@@ -75,8 +75,6 @@ class polynomialBasis : public nodalBasis
   polynomialBasis(int tag);
   ~polynomialBasis();
 
-  //int compareNewAlgoPointsWithOld() const;
-
   virtual inline int getNumShapeFunctions() const {return coefficients.size1();}
 
   virtual void f(double u, double v, double w, double *sf) const;
diff --git a/Numeric/pyramidalBasis.cpp b/Numeric/pyramidalBasis.cpp
index a977a06d6e5f0cd45d3cef115f7e2ec77e0a34a1..13c030b81b6c5d5c9e432d4f3fe855f9c05324e7 100644
--- a/Numeric/pyramidalBasis.cpp
+++ b/Numeric/pyramidalBasis.cpp
@@ -7,6 +7,15 @@
 #include "pointsGenerators.h"
 
 
+static void copy(const fullMatrix<int> &orig, fullMatrix<double> &b)
+{
+  b.resize(orig.size1(), orig.size2());
+  for (int i = 0; i < orig.size1(); ++i) {
+    for (int j = 0; j < orig.size2(); ++j) {
+      b(i, j) = static_cast<double>(orig(i, j));
+    }
+  }
+}
 
 pyramidalBasis::pyramidalBasis(int tag) : nodalBasis(tag)
 {
@@ -28,6 +37,21 @@ pyramidalBasis::pyramidalBasis(int tag) : nodalBasis(tag)
 
   delete[] fval;
 
+
+  // TEST NEW ALGO POINTS / MONOMIAL
+
+  monomials_newAlgo = gmshGenerateMonomialsPyramid(order, serendip);
+  copy(monomials_newAlgo, points_newAlgo);
+  if (order == 0) return;
+
+  for (int i = 0; i < points_newAlgo.size1(); ++i) {
+    points_newAlgo(i, 2) = points_newAlgo(i, 2) / order;
+    if (i != 4) {
+      const double duv = -1. + points_newAlgo(i, 2);
+      points_newAlgo(i, 0) = duv + points_newAlgo(i, 0) * 2. / order;
+      points_newAlgo(i, 1) = duv + points_newAlgo(i, 1) * 2. / order;
+    }
+  }
 }
 
 
@@ -55,7 +79,7 @@ void pyramidalBasis::f(double u, double v, double w, double *val) const
     val[i] = 0.;
     for (int j = 0; j < N; j++) val[i] += VDMinv(i,j)*fval[j];
   }
-  
+
   delete[] fval;
 
 }
@@ -77,7 +101,7 @@ void pyramidalBasis::f(const fullMatrix<double> &coord, fullMatrix<double> &sf)
       for (int j = 0; j < N; j++) sf(iPt,i) += VDMinv(i,j)*fval[j];
     }
   }
-  
+
   delete[] fval;
 
 }