diff --git a/Geo/MHexahedron.h b/Geo/MHexahedron.h
index 4bd51e2bec383ae453c3481cc6d22dabb0a15304..d9cd208432b15a268c3b549dded00391b18eb32b 100644
--- a/Geo/MHexahedron.h
+++ b/Geo/MHexahedron.h
@@ -484,22 +484,19 @@ class MHexahedronN : public MHexahedron {
   virtual const MVertex *getVertex(int num) const { return num < 8 ? _v[num] : _vs[num - 8]; }
 
   virtual int getNumEdgeVertices() const { return 12 * (_order - 1); }
-  virtual int getNumFaceVertices() const { return 6 * (_order - 1)*(_order - 1); }
+  virtual int getNumFaceVertices() const
+  {
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return 6 * (_order - 1)*(_order - 1);
+  }
   virtual int getNumVolumeVertices() const
   {
-    switch(getTypeForMSH()){
-    case MSH_HEX_27 :
-    case MSH_HEX_64 :
-    case MSH_HEX_125 :
-    case MSH_HEX_216 :
-    case MSH_HEX_343 :
-    case MSH_HEX_512 :
-    case MSH_HEX_729 :
-    case MSH_HEX_1000 :
-      return (_order - 1) * (_order - 1) * (_order - 1);
-    default:
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
       return 0;
-    }
+    else
+      return (_order - 1) * (_order - 1) * (_order - 1);
   }
   virtual int getNumEdgesRep();
   virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n);
diff --git a/Geo/MPrism.h b/Geo/MPrism.h
index 2e27dc44979ac6065f67698857faaf05473d3e8e..d304d810ea36e0f3ed9914d222776136388dbc91 100644
--- a/Geo/MPrism.h
+++ b/Geo/MPrism.h
@@ -411,8 +411,20 @@ class MPrismN : public MPrism {
   virtual MVertex *getVertex(int num){ return num < 6 ? _v[num] : _vs[num-6]; }
   virtual const MVertex *getVertex(int num) const{ return num < 6 ? _v[num] : _vs[num-6]; }
   virtual int getNumEdgeVertices() const { return 9*(_order-1); }
-  virtual int getNumFaceVertices() const { int n = _order-1; return n*((n-1)+3*n); }
-  virtual int getNumVolumeVertices() const { int n = _order-1; return _vs.size()-n*(9+(n-1)+3*n); }
+  virtual int getNumFaceVertices() const
+  {
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      int n = _order-1; return (n-1 + 3*n) * n;
+  }
+  virtual int getNumVolumeVertices() const
+  {
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      int n = _order-1; return n * (n * (n+1) / 2);
+  }
   virtual int getNumEdgesRep();
   virtual void getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n);
   virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
@@ -433,35 +445,35 @@ class MPrismN : public MPrism {
       return MSH_PRI_6;
     case 2:
       if (_vs.size() == 12) return MSH_PRI_18;
-      else if (_vs.size() == 9) return MSH_PRI_15;
+      if (_vs.size() == 9) return MSH_PRI_15;
       break;
     case 3:
       if (_vs.size() == 34) return MSH_PRI_40;
-      else if (_vs.size() == 18) return MSH_PRI_24;
+      if (_vs.size() == 18) return MSH_PRI_24;
       break;
     case 4:
       if (_vs.size() == 69) return MSH_PRI_75;
-      else if (_vs.size() == 27) return MSH_PRI_33;
+      if (_vs.size() == 27) return MSH_PRI_33;
       break;
     case 5:
       if (_vs.size() == 120) return MSH_PRI_126;
-      else if (_vs.size() == 36) return MSH_PRI_42;
+      if (_vs.size() == 36) return MSH_PRI_42;
       break;
     case 6:
       if (_vs.size() == 190) return MSH_PRI_196;
-      else if (_vs.size() == 45) return MSH_PRI_51;
+      if (_vs.size() == 45) return MSH_PRI_51;
       break;
     case 7:
       if (_vs.size() == 282) return MSH_PRI_288;
-      else if (_vs.size() == 54) return MSH_PRI_60;
+      if (_vs.size() == 54) return MSH_PRI_60;
       break;
     case 8:
       if (_vs.size() == 399) return MSH_PRI_405;
-      else if (_vs.size() == 63) return MSH_PRI_69;
+      if (_vs.size() == 63) return MSH_PRI_69;
       break;
     case 9:
       if (_vs.size() == 544) return MSH_PRI_550;
-      else if (_vs.size() == 72) return MSH_PRI_78;
+      if (_vs.size() == 72) return MSH_PRI_78;
       break;
     }
     Msg::Error("No tag matches a p%d prism with %d vertices", _order, 6+_vs.size());
diff --git a/Geo/MPyramid.h b/Geo/MPyramid.h
index 82cd1f1400d2cd7cf640f8648b94c6892082e5f4..b230682f28a3b2b35be764113383f4f59780ff9e 100644
--- a/Geo/MPyramid.h
+++ b/Geo/MPyramid.h
@@ -251,7 +251,10 @@ class MPyramidN : public MPyramid {
   virtual int getNumEdgeVertices() const { return 8 * (_order - 1); }
   virtual int getNumFaceVertices() const
   {
-    return (_order-1)*(_order-1) + 4 * ((_order - 1) * (_order - 2)) / 2;
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return (_order-1)*(_order-1) + 4 * ((_order - 1) * (_order - 2)) / 2;
   }
   virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
   {
@@ -279,16 +282,10 @@ class MPyramidN : public MPyramid {
   }
   virtual int getNumVolumeVertices() const
   {
-    switch(getTypeForMSH()){
-    case MSH_PYR_30 : return 1;
-    case MSH_PYR_55 : return 5;
-    case MSH_PYR_91 : return 14;
-    case MSH_PYR_140 : return 30;
-    case MSH_PYR_204 : return 55;
-    case MSH_PYR_285 : return 91;
-    case MSH_PYR_385 : return 140;
-    default : return 0;
-    }
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return (_order-2) * ((_order-2)+1) * (2*(_order-2)+1) / 6;
   }
   virtual int getTypeForMSH() const
   {
diff --git a/Geo/MQuadrangle.h b/Geo/MQuadrangle.h
index 18e1b6588644a42e2a8b463ae0ebd5e435589782..90fca18b9ce43a3e7db34273507964fec23cc881 100644
--- a/Geo/MQuadrangle.h
+++ b/Geo/MQuadrangle.h
@@ -375,10 +375,10 @@ class MQuadrangleN : public MQuadrangle {
   virtual const MVertex *getVertex(int num) const{ return num < 4 ? _v[num] : _vs[num - 4]; }
   virtual int getNumFaceVertices() const
   {
-    if(_order > 1 && (int)_vs.size() + 4 == (_order + 1) * (_order + 1))
-      return (_order - 1) * (_order - 1);
-    else
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
       return 0;
+    else
+      return  (_order - 1) * (_order - 1);
   }
   virtual int getNumEdgeVertices() const { return 4 * (_order - 1); }
   virtual int getNumEdgesRep();
diff --git a/Geo/MTetrahedron.h b/Geo/MTetrahedron.h
index dbee7499b6b23eadf09c1a93da012686e3e0b753..b33033a13b6382d1292662eedaa12ba0c769f552 100644
--- a/Geo/MTetrahedron.h
+++ b/Geo/MTetrahedron.h
@@ -334,7 +334,10 @@ class MTetrahedronN : public MTetrahedron {
   virtual int getNumEdgeVertices() const { return 6 * (_order - 1); }
   virtual int getNumFaceVertices() const
   {
-    return 4 * ((_order - 1) * (_order - 2)) / 2;
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return  4 * ((_order - 1) * (_order - 2)) / 2;
   }
   virtual void getEdgeVertices(const int num, std::vector<MVertex*> &v) const
   {
@@ -370,16 +373,10 @@ class MTetrahedronN : public MTetrahedron {
   }
   virtual int getNumVolumeVertices() const
   {
-    switch(getTypeForMSH()){
-    case MSH_TET_35 : return 1;
-    case MSH_TET_56 : return 4;
-    case MSH_TET_84 : return 10;
-    case MSH_TET_120 : return 20;
-    case MSH_TET_165 : return 35;
-    case MSH_TET_220 : return 56;
-    case MSH_TET_286 : return 84;
-    default : return 0;
-    }
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return  ((_order - 1) * (_order - 2) * (_order - 3)) / 6;
   }
   virtual int getTypeForMSH() const
   {
diff --git a/Geo/MTriangle.h b/Geo/MTriangle.h
index 7670de8dbbe8a82ac3f972fa12d6bc9ce919fd26..d4eac411c36d8baddd663675c6fcffb57cb2a222 100644
--- a/Geo/MTriangle.h
+++ b/Geo/MTriangle.h
@@ -279,23 +279,10 @@ class MTriangleN : public MTriangle {
   virtual const MVertex *getVertex(int num) const { return num < 3 ? _v[num] : _vs[num - 3]; }
   virtual int getNumFaceVertices() const
   {
-    if(_order == 3 && _vs.size() == 6) return 0;
-    if(_order == 3 && _vs.size() == 7) return 1;
-    if(_order == 4 && _vs.size() == 9) return 0;
-    if(_order == 4 && _vs.size() == 12) return 3;
-    if(_order == 5 && _vs.size() == 12) return 0;
-    if(_order == 5  && _vs.size() == 18) return 6;
-    if(_order == 6  && _vs.size() == 25) return 10;
-    if(_order == 7  && _vs.size() == 33) return 12;
-    if(_order == 8  && _vs.size() == 42) return 15;
-    if(_order == 9  && _vs.size() == 52) return 21;
-    if(_order == 10 && _vs.size() == 63) return 28;
-    if(_order == 6  && _vs.size() == 15) return 0;
-    if(_order == 7  && _vs.size() == 18) return 0;
-    if(_order == 8  && _vs.size() == 21) return 0;
-    if(_order == 9  && _vs.size() == 24) return 0;
-    if(_order == 10  && _vs.size() == 27) return 0;
-    return 0;
+    if (ElementType::SerendipityFromTag(getTypeForMSH()) > 0)
+      return 0;
+    else
+      return  (_order - 1) * (_order - 2) / 2;
   }
   virtual void xyz2uvw(double xyz[3], double uvw[3]) const { MElement::xyz2uvw(xyz, uvw); }
   virtual int getNumEdgeVertices() const { return 3 * (_order - 1); }
diff --git a/Numeric/ElementType.cpp b/Numeric/ElementType.cpp
index 21863cd01bc515ca0634ebf1c0555deea6fc8d24..9736e6d384f7428e7e7addc35bb8c196d8ed0f53 100644
--- a/Numeric/ElementType.cpp
+++ b/Numeric/ElementType.cpp
@@ -322,6 +322,9 @@ int ElementType::DimensionFromTag(int tag)
   }
 }
 
+// Gives > 0 if element tag is in Serendipity Family.
+// Gives < 2 if element tag is in 'Normal' Family.
+// 1 is for element that is either Serendipity or not !
 int ElementType::SerendipityFromTag(int tag)
 {
   switch (tag) {