diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp
index 0ef87ad82679a4c6dbf1b8c368766eb14fdcd64d..b6459c6ed8e73b8637cfae1f04e950c505ba8fbc 100644
--- a/Numeric/JacobianBasis.cpp
+++ b/Numeric/JacobianBasis.cpp
@@ -9,40 +9,40 @@
 #include <vector>
 #include "polynomialBasis.h"
 
-// Bezier Exposants
-static fullMatrix<double> generate1DExposants(int order)
+// Bezier Exponents
+static fullMatrix<double> generate1DExponents(int order)
 {
-  fullMatrix<double> exposants(order + 1, 1);
-  exposants(0, 0) = 0;
+  fullMatrix<double> exponents(order + 1, 1);
+  exponents(0, 0) = 0;
   if (order > 0) {
-    exposants(1, 0) = order;
-    for (int i = 2; i < order + 1; i++) exposants(i, 0) = i - 1;
+    exponents(1, 0) = order;
+    for (int i = 2; i < order + 1; i++) exponents(i, 0) = i - 1;
   }
 
-  return exposants;
+  return exponents;
 }
 
-static fullMatrix<double> generateExposantsTriangle(int order)
+static fullMatrix<double> generateExponentsTriangle(int order)
 {
   int nbPoints = (order + 1) * (order + 2) / 2;
-  fullMatrix<double> exposants(nbPoints, 2);
+  fullMatrix<double> exponents(nbPoints, 2);
 
-  exposants(0, 0) = 0;
-  exposants(0, 1) = 0;
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
 
   if (order > 0) {
-    exposants(1, 0) = order;
-    exposants(1, 1) = 0;
-    exposants(2, 0) = 0;
-    exposants(2, 1) = order;
+    exponents(1, 0) = order;
+    exponents(1, 1) = 0;
+    exponents(2, 0) = 0;
+    exponents(2, 1) = order;
 
     if (order > 1) {
       int index = 3, ksi = 0, eta = 0;
 
       for (int i = 0; i < order - 1; i++, index++) {
         ksi++;
-        exposants(index, 0) = ksi;
-        exposants(index, 1) = eta;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
       }
 
       ksi = order;
@@ -50,8 +50,8 @@ static fullMatrix<double> generateExposantsTriangle(int order)
       for (int i = 0; i < order - 1; i++, index++) {
         ksi--;
         eta++;
-        exposants(index, 0) = ksi;
-        exposants(index, 1) = eta;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
       }
 
       eta = order;
@@ -59,35 +59,35 @@ static fullMatrix<double> generateExposantsTriangle(int order)
 
       for (int i = 0; i < order - 1; i++, index++) {
         eta--;
-        exposants(index, 0) = ksi;
-        exposants(index, 1) = eta;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
       }
 
       if (order > 2) {
-        fullMatrix<double> inner = generateExposantsTriangle(order - 3);
+        fullMatrix<double> inner = generateExponentsTriangle(order - 3);
         inner.add(1);
-        exposants.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
       }
     }
   }
 
-  return exposants;
+  return exponents;
 }
-static fullMatrix<double> generateExposantsQuad(int order)
+static fullMatrix<double> generateExponentsQuad(int order)
 {
   int nbPoints = (order+1)*(order+1);
-  fullMatrix<double> exposants(nbPoints, 2);
+  fullMatrix<double> exponents(nbPoints, 2);
 
-  exposants(0, 0) = 0;
-  exposants(0, 1) = 0;
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
 
   if (order > 0) {
-    exposants(1, 0) = order;
-    exposants(1, 1) = 0;
-    exposants(2, 0) = order;
-    exposants(2, 1) = order;
-    exposants(3, 0) = 0;
-    exposants(3, 1) = order;
+    exponents(1, 0) = order;
+    exponents(1, 1) = 0;
+    exponents(2, 0) = order;
+    exponents(2, 1) = order;
+    exponents(3, 0) = 0;
+    exponents(3, 1) = order;
 
     if (order > 1) {
       int index = 4;
@@ -96,21 +96,21 @@ static fullMatrix<double> generateExposantsQuad(int order)
         int p0 = edges[iedge][0];
         int p1 = edges[iedge][1];
         for (int i = 1; i < order; i++, index++) {
-          exposants(index, 0) = exposants(p0, 0) + i*(exposants(p1,0)-exposants(p0,0))/order;
-          exposants(index, 1) = exposants(p0, 1) + i*(exposants(p1,1)-exposants(p0,1))/order;
+          exponents(index, 0) = exponents(p0, 0) + i*(exponents(p1,0)-exponents(p0,0))/order;
+          exponents(index, 1) = exponents(p0, 1) + i*(exponents(p1,1)-exponents(p0,1))/order;
         }
       }
       if (order > 2) {
-        fullMatrix<double> inner = generateExposantsQuad(order - 2);
+        fullMatrix<double> inner = generateExponentsQuad(order - 2);
         inner.add(1);
-        exposants.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
       }
     }
   }
 
-  //  exposants.print("expq");
+  //  exponents.print("expq");
 
-  return exposants;
+  return exponents;
 }
 static int nbdoftriangle(int order) { return (order + 1) * (order + 2) / 2; }
 
@@ -274,58 +274,58 @@ static void nodepositionface3(int order,  double *u,  double *v,  double *w)
    }
 }
 
-static fullMatrix<double> generateExposantsTetrahedron(int order)
+static fullMatrix<double> generateExponentsTetrahedron(int order)
 {
   int nbPoints = (order + 1) * (order + 2) * (order + 3) / 6;
 
-  fullMatrix<double> exposants(nbPoints, 3);
+  fullMatrix<double> exponents(nbPoints, 3);
 
-  exposants(0, 0) = 0;
-  exposants(0, 1) = 0;
-  exposants(0, 2) = 0;
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
+  exponents(0, 2) = 0;
 
   if (order > 0) {
-    exposants(1, 0) = order;
-    exposants(1, 1) = 0;
-    exposants(1, 2) = 0;
+    exponents(1, 0) = order;
+    exponents(1, 1) = 0;
+    exponents(1, 2) = 0;
 
-    exposants(2, 0) = 0;
-    exposants(2, 1) = order;
-    exposants(2, 2) = 0;
+    exponents(2, 0) = 0;
+    exponents(2, 1) = order;
+    exponents(2, 2) = 0;
 
-    exposants(3, 0) = 0;
-    exposants(3, 1) = 0;
-    exposants(3, 2) = order;
+    exponents(3, 0) = 0;
+    exponents(3, 1) = 0;
+    exponents(3, 2) = order;
 
     // edges e5 and e6 switched in original version, opposite direction
     // the template has been defined in table edges_tetra and faces_tetra (MElement.h)
 
     if (order > 1) {
       for (int k = 0; k < (order - 1); k++) {
-        exposants(4 + k, 0) = k + 1;
-        exposants(4 +      order - 1  + k, 0) = order - 1 - k;
-        exposants(4 + 2 * (order - 1) + k, 0) = 0;
-        exposants(4 + 3 * (order - 1) + k, 0) = 0;
-        // exposants(4 + 4 * (order - 1) + k, 0) = order - 1 - k;
-        // exposants(4 + 5 * (order - 1) + k, 0) = 0.;
-        exposants(4 + 4 * (order - 1) + k, 0) = 0;
-        exposants(4 + 5 * (order - 1) + k, 0) = k+1;
-
-        exposants(4 + k, 1) = 0;
-        exposants(4 +      order - 1  + k, 1) = k + 1;
-        exposants(4 + 2 * (order - 1) + k, 1) = order - 1 - k;
-        exposants(4 + 3 * (order - 1) + k, 1) = 0;
-        //         exposants(4 + 4 * (order - 1) + k, 1) = 0.;
-        //         exposants(4 + 5 * (order - 1) + k, 1) = order - 1 - k;
-        exposants(4 + 4 * (order - 1) + k, 1) = k+1;
-        exposants(4 + 5 * (order - 1) + k, 1) = 0;
-
-        exposants(4 + k, 2) = 0;
-        exposants(4 +      order - 1  + k, 2) = 0;
-        exposants(4 + 2 * (order - 1) + k, 2) = 0;
-        exposants(4 + 3 * (order - 1) + k, 2) = order - 1 - k;
-        exposants(4 + 4 * (order - 1) + k, 2) = order - 1 - k;
-        exposants(4 + 5 * (order - 1) + k, 2) = order - 1 - k;
+        exponents(4 + k, 0) = k + 1;
+        exponents(4 +      order - 1  + k, 0) = order - 1 - k;
+        exponents(4 + 2 * (order - 1) + k, 0) = 0;
+        exponents(4 + 3 * (order - 1) + k, 0) = 0;
+        // exponents(4 + 4 * (order - 1) + k, 0) = order - 1 - k;
+        // exponents(4 + 5 * (order - 1) + k, 0) = 0.;
+        exponents(4 + 4 * (order - 1) + k, 0) = 0;
+        exponents(4 + 5 * (order - 1) + k, 0) = k+1;
+
+        exponents(4 + k, 1) = 0;
+        exponents(4 +      order - 1  + k, 1) = k + 1;
+        exponents(4 + 2 * (order - 1) + k, 1) = order - 1 - k;
+        exponents(4 + 3 * (order - 1) + k, 1) = 0;
+        //         exponents(4 + 4 * (order - 1) + k, 1) = 0.;
+        //         exponents(4 + 5 * (order - 1) + k, 1) = order - 1 - k;
+        exponents(4 + 4 * (order - 1) + k, 1) = k+1;
+        exponents(4 + 5 * (order - 1) + k, 1) = 0;
+
+        exponents(4 + k, 2) = 0;
+        exponents(4 +      order - 1  + k, 2) = 0;
+        exponents(4 + 2 * (order - 1) + k, 2) = 0;
+        exponents(4 + 3 * (order - 1) + k, 2) = order - 1 - k;
+        exponents(4 + 4 * (order - 1) + k, 2) = order - 1 - k;
+        exponents(4 + 5 * (order - 1) + k, 2) = order - 1 - k;
       }
 
       if (order > 2) {
@@ -341,9 +341,9 @@ static fullMatrix<double> generateExposantsTetrahedron(int order)
         // u-v plane
 
         for (int i = 0; i < nbdofface; i++){
-          exposants(ns + i, 0) = u[i] * (order - 3) + 1;
-          exposants(ns + i, 1) = v[i] * (order - 3) + 1;
-          exposants(ns + i, 2) = w[i] * (order - 3);
+          exponents(ns + i, 0) = u[i] * (order - 3) + 1;
+          exponents(ns + i, 1) = v[i] * (order - 3) + 1;
+          exponents(ns + i, 2) = w[i] * (order - 3);
         }
 
         ns = ns + nbdofface;
@@ -353,9 +353,9 @@ static fullMatrix<double> generateExposantsTetrahedron(int order)
         nodepositionface1(order - 3, u, v, w);
 
         for (int i=0; i < nbdofface; i++){
-          exposants(ns + i, 0) = u[i] * (order - 3) + 1;
-          exposants(ns + i, 1) = v[i] * (order - 3) ;
-          exposants(ns + i, 2) = w[i] * (order - 3) + 1;
+          exponents(ns + i, 0) = u[i] * (order - 3) + 1;
+          exponents(ns + i, 1) = v[i] * (order - 3) ;
+          exponents(ns + i, 2) = w[i] * (order - 3) + 1;
         }
 
         // v-w plane
@@ -365,9 +365,9 @@ static fullMatrix<double> generateExposantsTetrahedron(int order)
         nodepositionface2(order - 3, u, v, w);
 
         for (int i = 0; i < nbdofface; i++){
-          exposants(ns + i, 0) = u[i] * (order - 3);
-          exposants(ns + i, 1) = v[i] * (order - 3) + 1;
-          exposants(ns + i, 2) = w[i] * (order - 3) + 1;
+          exponents(ns + i, 0) = u[i] * (order - 3);
+          exponents(ns + i, 1) = v[i] * (order - 3) + 1;
+          exponents(ns + i, 2) = w[i] * (order - 3) + 1;
         }
 
         // u-v-w plane
@@ -377,9 +377,9 @@ static fullMatrix<double> generateExposantsTetrahedron(int order)
         nodepositionface3(order - 3, u, v, w);
 
         for (int i = 0; i < nbdofface; i++){
-          exposants(ns + i, 0) = u[i] * (order - 3) + 1;
-          exposants(ns + i, 1) = v[i] * (order - 3) + 1;
-          exposants(ns + i, 2) = w[i] * (order - 3) + 1;
+          exponents(ns + i, 0) = u[i] * (order - 3) + 1;
+          exponents(ns + i, 1) = v[i] * (order - 3) + 1;
+          exponents(ns + i, 2) = w[i] * (order - 3) + 1;
         }
 
         ns = ns + nbdofface;
@@ -390,129 +390,115 @@ static fullMatrix<double> generateExposantsTetrahedron(int order)
 
         if (order > 3) {
 
-          fullMatrix<double> interior = generateExposantsTetrahedron(order - 4);
+          fullMatrix<double> interior = generateExponentsTetrahedron(order - 4);
           for (int k = 0; k < interior.size1(); k++) {
-            exposants(ns + k, 0) = 1 + interior(k, 0);
-            exposants(ns + k, 1) = 1 + interior(k, 1);
-            exposants(ns + k, 2) = 1 + interior(k, 2);
+            exponents(ns + k, 0) = 1 + interior(k, 0);
+            exponents(ns + k, 1) = 1 + interior(k, 1);
+            exponents(ns + k, 2) = 1 + interior(k, 2);
           }
         }
       }
     }
   }
 
-  return exposants;
+  return exponents;
 }
 
-static fullMatrix<double> generateExposantsPrism(int order)
+static fullMatrix<double> generateExponentsPrism(int order)
 {
-//  int nbMonomials = (order + 1) * (order + 1) * (order + 2) / 2;
-//
-//  fullMatrix<double> monomials(nbMonomials, 3);
-//  int index = 0;
-//  fullMatrix<double> lineMonoms = generate1DMonomials(order);
-//  fullMatrix<double> triMonoms = generateExposantsTriangle(order);
-//  // store monomials in right order
-//  for (int currentOrder = 0; currentOrder <= order; currentOrder++) {
-//    int orderT = currentOrder, orderL = currentOrder;
-//    for (orderL = 0; orderL < currentOrder; orderL++) {
-//      // do all permutations of monoms for orderL, orderT
-//      int iL = orderL;
-//      for (int iT = (orderT)*(orderT+1)/2; iT < (orderT+1)*(orderT+2)/2 ;iT++) {
-//        monomials(index,0) = triMonoms(iT,0);
-//        monomials(index,1) = triMonoms(iT,1);
-//        monomials(index,2) = lineMonoms(iL,0);
-//        index ++;
-//      }
-//    }
-//    orderL = currentOrder;
-//    for (orderT = 0; orderT <= currentOrder; orderT++) {
-//      int iL = orderL;
-//      for (int iT = (orderT)*(orderT+1)/2; iT < (orderT+1)*(orderT+2)/2 ;iT++) {
-//        monomials(index,0) = triMonoms(iT,0);
-//        monomials(index,1) = triMonoms(iT,1);
-//        monomials(index,2) = lineMonoms(iL,0);
-//        index ++;
-//      }
-//    }    
-//  }
-////   monomials.print("Pri monoms");
-//  return monomials;
-
-  //const double prism18Pts[18][3] = {
- //   {0, 0, -1}, // 0
- //   {1, 0, -1}, // 1
- //   {0, 1, -1}, // 2
- //   {0, 0, 1},  // 3
- //   {1, 0, 1},  // 4
- //   {0, 1, 1},  // 5
- //   {0.5, 0, -1},  // 6
- //   {0, 0.5, -1},  // 7
- //   {0, 0, 0},  // 8
- //   {0.5, 0.5, -1},  // 9
- //   {1, 0, 0},  // 10
- //   {0, 1, 0},  // 11
- //   {0.5, 0, 1},  // 12
- //   {0, 0.5, 1},  // 13
- //   {0.5, 0.5, 1},  // 14
- //   {0.5, 0, 0},  // 15
- //   {0, 0.5, 0},  // 16
- //   {0.5, 0.5, 0},  // 17
- // };
-
   int nbPoints = (order + 1)*(order + 1)*(order + 2)/2;
-  fullMatrix<double> exposants(nbPoints, 3);
+  fullMatrix<double> exponents(nbPoints, 3);
 
   int index = 0;
-  fullMatrix<double> triExp = generateExposantsTriangle(order);
-  fullMatrix<double> lineExp = generate1DExposants(order);
-
- /* if (order == 2)
-    for (int i =0; i<18; i++)
-      for (int j=0; j<3;j++)
-        exposants(i,j) = prism18Pts[i][j];
-  else*/
-  {
-    for (int i = 0; i < 3; i++) {
-      exposants(index,0) = triExp(i,0);
-      exposants(index,1) = triExp(i,1);
-      exposants(index,2) = lineExp(0,0);
-      index ++;
-      exposants(index,0) = triExp(i,0);
-      exposants(index,1) = triExp(i,1);
-      exposants(index,2) = lineExp(1,0);
+  fullMatrix<double> triExp = generateExponentsTriangle(order);
+  fullMatrix<double> lineExp = generate1DExponents(order);
+  // First exponents (i < 3) must relate to corner
+  for (int i = 0; i < triExp.size1(); i++) {
+    exponents(index,0) = triExp(i,0);
+    exponents(index,1) = triExp(i,1);
+    exponents(index,2) = lineExp(0,0);
+    index ++;
+    exponents(index,0) = triExp(i,0);
+    exponents(index,1) = triExp(i,1);
+    exponents(index,2) = lineExp(1,0);
+    index ++;
+  }
+  for (int j = 2; j <lineExp.size1() ; j++) {
+    for (int i = 0; i < triExp.size1(); i++) {
+      exponents(index,0) = triExp(i,0);
+      exponents(index,1) = triExp(i,1);
+      exponents(index,2) = lineExp(j,0);
       index ++;
     }
-    for (int i = 3; i < triExp.size1(); i++) {
-      exposants(index,0) = triExp(i,0);
-      exposants(index,1) = triExp(i,1);
-      exposants(index,2) = lineExp(0,0);
-      index ++;
-      exposants(index,0) = triExp(i,0);
-      exposants(index,1) = triExp(i,1);
-      exposants(index,2) = lineExp(1,0);
-      index ++;
+  }
+
+  return exponents;
+}
+
+static fullMatrix<double> generateExponentsHex(int order)
+{
+  int nbPoints = (order+1) * (order+1) * (order+1);
+  fullMatrix<double> exponents(nbPoints, 3);
+  
+  if (order == 0) {
+    exponents(0, 0) = .0;
+    return exponents;
+  }
+
+  int index = 0;
+  fullMatrix<double> lineExp = generate1DExponents(order);
+
+  for (int i = 0; i < 2; ++i) {
+    for (int j = 0; i < 2; ++j) {
+      for (int k = 0; i < 2; ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
+      }
     }
-    for (int j = 2; j <lineExp.size1() ; j++) {
-      for (int i = 0; i < triExp.size1(); i++) {
-        exposants(index,0) = triExp(i,0);
-        exposants(index,1) = triExp(i,1);
-        exposants(index,2) = lineExp(j,0);
-        index ++;
+  }
+  
+  for (int i = 2; i < lineExp.size1(); ++i) {
+    for (int j = 0; i < 2; ++j) {
+      for (int k = 0; i < 2; ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
+      }
+    }
+  }
+  for (int i = 0; i < lineExp.size1(); ++i) {
+    for (int j = 2; i < lineExp.size1(); ++j) {
+      for (int k = 0; i < 2; ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
+      }
+    }
+  }
+  for (int i = 0; i < lineExp.size1(); ++i) {
+    for (int j = 0; i < lineExp.size1(); ++j) {
+      for (int k = 2; i < lineExp.size1(); ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
       }
     }
   }
 
-  return exposants;
+  return exponents;
 }
 
 // Sampling Points
 static fullMatrix<double> generate1DPoints(int order)
 {
   fullMatrix<double> line(order + 1, 1);
-  line(0,0) = 0;
+  line(0,0) = .0;
   if (order > 0) {
-    line(0, 0) = 0.;
     line(1, 0) = 1.;
     double dd = 1. / order;
     for (int i = 2; i < order + 1; i++) line(i, 0) = dd * (i - 1);
@@ -521,6 +507,118 @@ static fullMatrix<double> generate1DPoints(int order)
   return line;
 }
 
+static fullMatrix<double> gmshGeneratePointsTriangle(int order, bool serendip)
+{
+  int nbPoints = serendip ? 3 * order : (order + 1) * (order + 2) / 2;
+  fullMatrix<double> point(nbPoints, 2);
+
+  point(0, 0) = 0;
+  point(0, 1) = 0;
+
+  if (order > 0) {
+    double dd = 1. / order;
+
+    point(1, 0) = 1;
+    point(1, 1) = 0;
+    point(2, 0) = 0;
+    point(2, 1) = 1;
+
+    int index = 3;
+
+    if (order > 1) {
+
+      double ksi = 0;
+      double eta = 0;
+
+      for (int i = 0; i < order - 1; i++, index++) {
+        ksi += dd;
+        point(index, 0) = ksi;
+        point(index, 1) = eta;
+      }
+
+      ksi = 1.;
+
+      for (int i = 0; i < order - 1; i++, index++) {
+        ksi -= dd;
+        eta += dd;
+        point(index, 0) = ksi;
+        point(index, 1) = eta;
+      }
+
+      eta = 1.;
+      ksi = 0.;
+
+      for (int i = 0; i < order - 1; i++, index++) {
+        eta -= dd;
+        point(index, 0) = ksi;
+        point(index, 1) = eta;
+      }
+
+      if (order > 2 && !serendip) {
+        fullMatrix<double> inner = gmshGeneratePointsTriangle(order - 3, serendip);
+        inner.scale(1. - 3. * dd);
+        inner.add(dd);
+        point.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+      }
+    }
+  }
+  return point;
+}
+
+static fullMatrix<double> generatePointsQuadRecur(int order, bool serendip)
+{
+  int nbPoints = serendip ? order*4 : (order+1)*(order+1);
+  fullMatrix<double> point(nbPoints, 2);
+
+  if (order > 0) {
+    point(0, 0) = -1;
+    point(0, 1) = -1;
+    point(1, 0) = 1;
+    point(1, 1) = -1;
+    point(2, 0) = 1;
+    point(2, 1) = 1;
+    point(3, 0) = -1;
+    point(3, 1) = 1;
+
+    if (order > 1) {
+      int index = 4;
+      const static int edges[4][2]={{0,1},{1,2},{2,3},{3,0}};
+      for (int iedge=0; iedge<4; iedge++) {
+        int p0 = edges[iedge][0];
+        int p1 = edges[iedge][1];
+        for (int i = 1; i < order; i++, index++) {
+          point(index, 0) = point(p0, 0) + i*(point(p1,0)-point(p0,0))/order;
+          point(index, 1) = point(p0, 1) + i*(point(p1,1)-point(p0,1))/order;
+        }
+      }
+      if (order >= 2 && !serendip) {
+        fullMatrix<double> inner = generatePointsQuadRecur(order - 2, false);
+        inner.scale(1. - 2./order);
+        point.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+      }
+    }
+  }
+  else {
+    point(0, 0) = 0;
+    point(0, 1) = 0;
+  }
+
+
+  return point;
+}
+
+static fullMatrix<double> generatePointsQuad(int order, bool serendip)
+{
+  fullMatrix<double>  point = generatePointsQuadRecur(order, serendip);
+  // rescale to [0,1] x [0,1]
+  for (int i=0;i<point.size1();i++){
+    point(i,0) = (1.+point(i,0))*.5;
+    point(i,1) = (1.+point(i,1))*.5;
+  }
+  return point;
+}
+
+
 static fullMatrix<double> gmshGeneratePointsTetrahedron(int order, bool serendip)
 {
   int nbPoints =
@@ -657,64 +755,6 @@ static fullMatrix<double> gmshGeneratePointsTetrahedron(int order, bool serendip
   return point;
 }
 
-static fullMatrix<double> gmshGeneratePointsTriangle(int order, bool serendip)
-{
-  int nbPoints = serendip ? 3 * order : (order + 1) * (order + 2) / 2;
-  fullMatrix<double> point(nbPoints, 2);
-
-  point(0, 0) = 0;
-  point(0, 1) = 0;
-
-  if (order > 0) {
-    double dd = 1. / order;
-
-    point(1, 0) = 1;
-    point(1, 1) = 0;
-    point(2, 0) = 0;
-    point(2, 1) = 1;
-
-    int index = 3;
-
-    if (order > 1) {
-
-      double ksi = 0;
-      double eta = 0;
-
-      for (int i = 0; i < order - 1; i++, index++) {
-        ksi += dd;
-        point(index, 0) = ksi;
-        point(index, 1) = eta;
-      }
-
-      ksi = 1.;
-
-      for (int i = 0; i < order - 1; i++, index++) {
-        ksi -= dd;
-        eta += dd;
-        point(index, 0) = ksi;
-        point(index, 1) = eta;
-      }
-
-      eta = 1.;
-      ksi = 0.;
-
-      for (int i = 0; i < order - 1; i++, index++) {
-        eta -= dd;
-        point(index, 0) = ksi;
-        point(index, 1) = eta;
-      }
-
-      if (order > 2 && !serendip) {
-        fullMatrix<double> inner = gmshGeneratePointsTriangle(order - 3, serendip);
-        inner.scale(1. - 3. * dd);
-        inner.add(dd);
-        point.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
-      }
-    }
-  }
-  return point;
-}
-
 static fullMatrix<double> generatePointsPrism(int order, bool serendip)
 {
   const double prism18Pts[18][3] = {
@@ -762,64 +802,32 @@ static fullMatrix<double> generatePointsPrism(int order, bool serendip)
   return point;
 }
 
-static fullMatrix<double> generatePointsQuadRecur(int order, bool serendip)
+static fullMatrix<double> generatePointsHex(int order, bool serendip)
 {
-  int nbPoints = serendip ? order*4 : (order+1)*(order+1);
-  fullMatrix<double> point(nbPoints, 2);
-
-  if (order > 0) {
-    point(0, 0) = -1;
-    point(0, 1) = -1;
-    point(1, 0) = 1;
-    point(1, 1) = -1;
-    point(2, 0) = 1;
-    point(2, 1) = 1;
-    point(3, 0) = -1;
-    point(3, 1) = 1;
-
-    if (order > 1) {
-      int index = 4;
-      const static int edges[4][2]={{0,1},{1,2},{2,3},{3,0}};
-      for (int iedge=0; iedge<4; iedge++) {
-        int p0 = edges[iedge][0];
-        int p1 = edges[iedge][1];
-        for (int i = 1; i < order; i++, index++) {
-          point(index, 0) = point(p0, 0) + i*(point(p1,0)-point(p0,0))/order;
-          point(index, 1) = point(p0, 1) + i*(point(p1,1)-point(p0,1))/order;
-        }
-      }
-      if (order >= 2 && !serendip) {
-        fullMatrix<double> inner = generatePointsQuadRecur(order - 2, false);
-        inner.scale(1. - 2./order);
-        point.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+  int nbPoints = (order+1) * (order+1) * (order+1);
+  fullMatrix<double> point(nbPoints, 3);
+  
+  fullMatrix<double> linePoints = generate1DPoints(order);
+  int index = 0;
+    
+  for (int i = 0; i < linePoints.size1(); ++i) {
+    for (int j = 0; j < linePoints.size1(); ++j) {
+      for (int k = 0; k < linePoints.size1(); ++k) {
+        point(index, 0) = linePoints(i, 0);
+        point(index, 1) = linePoints(j, 0);
+        point(index, 2) = linePoints(k, 0);
+        ++index;
       }
     }
   }
-  else {
-    point(0, 0) = 0;
-    point(0, 1) = 0;
-  }
-
 
   return point;
 }
 
-static fullMatrix<double> generatePointsQuad(int order, bool serendip){
-  fullMatrix<double>  point = generatePointsQuadRecur(order, serendip);
-  // rescale to [0,1] x [0,1]
-  for (int i=0;i<point.size1();i++){
-    point(i,0) = (1.+point(i,0))*.5;
-    point(i,1) = (1.+point(i,1))*.5;
-  }
-  return point;
-}
-
-
 // Sub Control Points
 static std::vector< fullMatrix<double> > generateSubPointsLine(int order)
 {
   std::vector< fullMatrix<double> > subPoints(2);
-  fullMatrix<double> prox;
   
   subPoints[0] = generate1DPoints(order);
   subPoints[0].scale(.5);
@@ -853,6 +861,29 @@ static std::vector< fullMatrix<double> > generateSubPointsTriangle(int order)
   return subPoints;
 }
 
+static std::vector< fullMatrix<double> > generateSubPointsQuad(int order)
+{
+  std::vector< fullMatrix<double> > subPoints(4);
+  fullMatrix<double> prox;
+  
+  subPoints[0] = generatePointsQuad(order, false);
+  subPoints[0].scale(.5);
+
+  subPoints[1].copy(subPoints[0]);
+  prox.setAsProxy(subPoints[1], 0, 1);
+  prox.add(.5);
+
+  subPoints[2].copy(subPoints[0]);
+  prox.setAsProxy(subPoints[2], 1, 1);
+  prox.add(.5);
+
+  subPoints[3].copy(subPoints[1]);
+  prox.setAsProxy(subPoints[3], 1, 1);
+  prox.add(.5);
+
+  return subPoints;
+}
+
 static std::vector< fullMatrix<double> > generateSubPointsTetrahedron(int order)
 {
   std::vector< fullMatrix<double> > subPoints(8);
@@ -923,12 +954,12 @@ static std::vector< fullMatrix<double> > generateSubPointsTetrahedron(int order)
   return subPoints;
 }
 
-static std::vector< fullMatrix<double> > generateSubPointsQuad(int order)
+static std::vector< fullMatrix<double> > generateSubPointsPrism(int order)
 {
-  std::vector< fullMatrix<double> > subPoints(4);
+  std::vector< fullMatrix<double> > subPoints(8);
   fullMatrix<double> prox;
   
-  subPoints[0] = generatePointsQuad(order, false);
+  subPoints[0] = generatePointsPrism(order, false);
   subPoints[0].scale(.5);
 
   subPoints[1].copy(subPoints[0]);
@@ -939,19 +970,36 @@ static std::vector< fullMatrix<double> > generateSubPointsQuad(int order)
   prox.setAsProxy(subPoints[2], 1, 1);
   prox.add(.5);
 
-  subPoints[3].copy(subPoints[1]);
-  prox.setAsProxy(subPoints[3], 1, 1);
+  subPoints[3].copy(subPoints[0]);
+  prox.setAsProxy(subPoints[3], 0, 2);
+  prox.scale(-1.);
+  prox.add(.5);
+
+  subPoints[4].copy(subPoints[0]);
+  prox.setAsProxy(subPoints[4], 2, 1);
+  prox.add(.5);
+
+  subPoints[5].copy(subPoints[1]);
+  prox.setAsProxy(subPoints[5], 2, 1);
+  prox.add(.5);
+
+  subPoints[6].copy(subPoints[2]);
+  prox.setAsProxy(subPoints[6], 2, 1);
+  prox.add(.5);
+
+  subPoints[7].copy(subPoints[3]);
+  prox.setAsProxy(subPoints[7], 2, 1);
   prox.add(.5);
 
   return subPoints;
 }
 
-static std::vector< fullMatrix<double> > generateSubPointsPrism(int order)
+static std::vector< fullMatrix<double> > generateSubPointsHex(int order)
 {
   std::vector< fullMatrix<double> > subPoints(8);
   fullMatrix<double> prox;
   
-  subPoints[0] = generatePointsPrism(order, false);
+  subPoints[0] = generatePointsHex(order, false);
   subPoints[0].scale(.5);
 
   subPoints[1].copy(subPoints[0]);
@@ -962,9 +1010,8 @@ static std::vector< fullMatrix<double> > generateSubPointsPrism(int order)
   prox.setAsProxy(subPoints[2], 1, 1);
   prox.add(.5);
 
-  subPoints[3].copy(subPoints[0]);
-  prox.setAsProxy(subPoints[3], 0, 2);
-  prox.scale(-1.);
+  subPoints[3].copy(subPoints[1]);
+  prox.setAsProxy(subPoints[3], 1, 1);
   prox.add(.5);
 
   subPoints[4].copy(subPoints[0]);
@@ -1007,56 +1054,58 @@ static int nChoosek(int n, int k)
 
 
 static fullMatrix<double> generateBez2LagMatrix
-  (const fullMatrix<double> &exposant, const fullMatrix<double> &point,
+  (const fullMatrix<double> &exponent, const fullMatrix<double> &point,
    int order, int dimSimplex)
 {
   
-  if(exposant.size1() != point.size1() || exposant.size2() != point.size2()){
+  if(exponent.size1() != point.size1() || exponent.size2() != point.size2()){
     Msg::Fatal("Wrong sizes for Bezier coefficients generation %d %d -- %d %d",
-      exposant.size1(),point.size1(),
-      exposant.size2(),point.size2());
+      exponent.size1(),point.size1(),
+      exponent.size2(),point.size2());
     return fullMatrix<double>(1, 1);
   }
 
-  int ndofs = exposant.size1();
-  int dim = exposant.size2();
+  int ndofs = exponent.size1();
+  int dim = exponent.size2();
 
-  fullMatrix<double> Vandermonde(ndofs, ndofs);
+  fullMatrix<double> bez2Lag(ndofs, ndofs);
   for (int i = 0; i < ndofs; i++) {
     for (int j = 0; j < ndofs; j++) {
       double dd = 1.;
-
-      double pointCompl = 1.;
-      int exposantCompl = order;
-      for (int k = 0; k < dimSimplex; k++) {
-        dd *= nChoosek(exposantCompl, (int) exposant(i, k))
-          * pow(point(j, k), exposant(i, k));
-        pointCompl -= point(j, k);
-        exposantCompl -= (int) exposant(i, k);
+      
+      {
+        double pointCompl = 1.;
+        int exponentCompl = order;
+        for (int k = 0; k < dimSimplex; k++) {
+          dd *= nChoosek(exponentCompl, (int) exponent(i, k))
+            * pow(point(j, k), exponent(i, k));
+          pointCompl -= point(j, k);
+          exponentCompl -= (int) exponent(i, k);
+        }
+        dd *= pow(pointCompl, exponentCompl);
       }
-      dd *= pow(pointCompl, exposantCompl);
-
+      
       for (int k = dimSimplex; k < dim; k++)
-        dd *= nChoosek(order, (int) exposant(i, k))
-            * pow(point(j, k), exposant(i, k))
-            * pow(1. - point(j, k), order - exposant(i, k));
-
-      Vandermonde(j, i) = dd;
+        dd *= nChoosek(order, (int) exponent(i, k))
+            * pow(point(j, k), exponent(i, k))
+            * pow(1. - point(j, k), order - exponent(i, k));
+      
+      bez2Lag(j, i) = dd;
     }
   }
-  return Vandermonde;
+  return bez2Lag;
 }
 
 
 
-static fullMatrix<double> generateDivisor
-  (const fullMatrix<double> &exposants, const std::vector< fullMatrix<double> > &subPoints,
+static fullMatrix<double> generateSubDivisor
+  (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints,
    const fullMatrix<double> &lag2Bez, int order, int dimSimplex)
 {
-  if (exposants.size1() != lag2Bez.size1() || exposants.size1() != lag2Bez.size2()){
+  if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){
     Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d",
-      exposants.size1(), lag2Bez.size1(),
-      exposants.size1(), lag2Bez.size2());
+      exponents.size1(), lag2Bez.size1(),
+      exponents.size1(), lag2Bez.size2());
     return fullMatrix<double>(1, 1);
   }
 
@@ -1064,15 +1113,15 @@ static fullMatrix<double> generateDivisor
   int nbSubPts = nbPts * subPoints.size();
 
   fullMatrix<double> intermediate2(nbPts, nbPts);
-  fullMatrix<double> divisor(nbSubPts, nbPts);
+  fullMatrix<double> subDivisor(nbSubPts, nbPts);
 
   for (unsigned int i = 0; i < subPoints.size(); i++) {
     fullMatrix<double> intermediate1 =
-      generateBez2LagMatrix(exposants, subPoints[i], order, dimSimplex);
+      generateBez2LagMatrix(exponents, subPoints[i], order, dimSimplex);
     lag2Bez.mult(intermediate1, intermediate2);
-    divisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0);
+    subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0);
   }
-  return divisor;
+  return subDivisor;
 }
 
 
@@ -1080,41 +1129,6 @@ static fullMatrix<double> generateDivisor
 static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &points
   , const fullMatrix<double> &monomials, const fullMatrix<double> &coefficients)
 {
-
-  /*{
-    Msg::Info("Printing vector jacobian':");
-    int ni = points.size1();
-    int nj = points.size2();
-    Msg::Info("  ");
-    for(int I = 0; I < ni; I++){
-        Msg::Info("%lf - %lf", points(I, 0), points(I, 1));
-    }
-    Msg::Info(" ");
-  }
-  {
-    Msg::Info("Printing vector jacobian':");
-    int ni = monomials.size1();
-    int nj = monomials.size2();
-    Msg::Info("  ");
-    for(int I = 0; I < ni; I++){
-        Msg::Info("%lf - %lf", monomials(I, 0), monomials(I, 1));
-    }
-    Msg::Info(" ");
-  }
-  {
-    Msg::Info("Printing vector jacobian':");
-    int ni = coefficients.size1();
-    int nj = coefficients.size2();
-    Msg::Info("  ");
-    for(int I = 0; I < ni; I++){
-      Msg::Info("  ");
-      for(int J = 0; J < nj; J++){
-        Msg::Info("%lf", coefficients(J, I));
-      }
-    }
-    Msg::Info(" ");
-  }*/
-
   int nbPts = points.size1();
   int nbDofs = monomials.size1();
   int dim = points.size2();
@@ -1130,14 +1144,14 @@ static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &poi
     default :
       return;
   }
-
+  
   double dx, dy, dz;
-
+  
   switch (dim) {
     case 3 :
       for (int i = 0; i < nbDofs; i++) {
         for (int k = 0; k < nbPts; k++) {
-
+          
           if ((int) monomials(i, 0) > 0) {
             dx = pow( points(k, 0), monomials(i, 0)-1 ) * monomials(i, 0)
                * pow( points(k, 1), monomials(i, 1) )
@@ -1162,7 +1176,7 @@ static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &poi
         }
       }
       return;
-
+    
     case 2 :
       for (int i = 0; i < nbDofs; i++) {
         for (int k = 0; k < nbPts; k++) {
@@ -1182,7 +1196,7 @@ static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &poi
         }
       }
       return;
-
+    
     case 1 :
       for (int i = 0; i < nbDofs; i++) {
         for (int k = 0; k < nbPts; k++) {
@@ -1197,8 +1211,8 @@ static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &poi
   }
   return;
 }
-std::map<int, bezierBasis> bezierBasis::_bbs;
 
+std::map<int, bezierBasis> bezierBasis::_bbs;
 const bezierBasis *bezierBasis::find(int tag)
 {
   std::map<int, bezierBasis>::const_iterator it = _bbs.find(tag);
@@ -1212,13 +1226,13 @@ const bezierBasis *bezierBasis::find(int tag)
   switch (F->parentType) {
     case TYPE_PNT :
       B.numLagPts = 1;
-      B.exposants = generate1DExposants(0);
+      B.exponents = generate1DExponents(0);
       B.points    = generate1DPoints(0);
       dimSimplex = 0;
       break;
     case TYPE_LIN : {
       B.numLagPts = 2;
-      B.exposants = generate1DExposants(F->order);
+      B.exponents = generate1DExponents(F->order);
       B.points    = generate1DPoints(F->order);
       dimSimplex = 0;
       subPoints = generateSubPointsLine(0);
@@ -1226,77 +1240,85 @@ const bezierBasis *bezierBasis::find(int tag)
     }
     case TYPE_TRI : {
       B.numLagPts = 3;
-      B.exposants = generateExposantsTriangle(F->order);
+      B.exponents = generateExponentsTriangle(F->order);
       B.points    = gmshGeneratePointsTriangle(F->order,false);
       dimSimplex = 2;
       subPoints = generateSubPointsTriangle(F->order);
       break;
     }
-    case TYPE_TET : {
-      B.numLagPts = 4;
-      B.exposants = generateExposantsTetrahedron(F->order);
-      B.points    = gmshGeneratePointsTetrahedron(F->order,false);
-      dimSimplex = 3;
-      subPoints = generateSubPointsTetrahedron(F->order);
-      break;
-    }
     case TYPE_QUA : {
       B.numLagPts = 4;
-      B.exposants = generateExposantsQuad(F->order);
+      B.exponents = generateExponentsQuad(F->order);
       B.points    = generatePointsQuad(F->order,false);
       dimSimplex = 0;
       subPoints = generateSubPointsQuad(F->order);
       //      B.points.print("points");
       break;
     }
-    case TYPE_PRI : {
+    case TYPE_TET : {
       B.numLagPts = 4;
-      B.exposants = generateExposantsPrism(F->order);
+      B.exponents = generateExponentsTetrahedron(F->order);
+      B.points    = gmshGeneratePointsTetrahedron(F->order,false);
+      dimSimplex = 3;
+      subPoints = generateSubPointsTetrahedron(F->order);
+      break;
+    }
+    case TYPE_PRI : {
+      B.numLagPts = 6;
+      B.exponents = generateExponentsPrism(F->order);
       B.points    = generatePointsPrism(F->order, false);
       dimSimplex = 2;
       subPoints = generateSubPointsPrism(F->order);
       break;
     }
+    case TYPE_HEX : {
+      B.numLagPts = 8;
+      B.exponents = generateExponentsHex(F->order);
+      B.points    = generatePointsHex(F->order, false);
+      dimSimplex = 0;
+      subPoints = generateSubPointsHex(F->order);
+      break;
+    }
     default : {
       Msg::Error("Unknown function space %d: reverting to TET_1", tag);
       F = polynomialBases::find(MSH_TET_1);
       B.numLagPts = 4;
-      B.exposants = generateExposantsTetrahedron(0);
+      B.exponents = generateExponentsTetrahedron(0);
       B.points    = gmshGeneratePointsTetrahedron(0, false);
       dimSimplex = 3;
       subPoints = generateSubPointsTetrahedron(0);
     }
   }
-  B.matrixBez2Lag = generateBez2LagMatrix(B.exposants, B.points, F->order, dimSimplex);
+  B.matrixBez2Lag = generateBez2LagMatrix(B.exponents, B.points, F->order, dimSimplex);
   B.matrixBez2Lag.invert(B.matrixLag2Bez);
-  B.divisor = generateDivisor(B.exposants, subPoints, B.matrixLag2Bez, F->order, dimSimplex);
+  B.subDivisor = generateSubDivisor(B.exponents, subPoints, B.matrixLag2Bez, F->order, dimSimplex);
 
   B.numDivisions = (int) pow(2., (int) B.points.size2());
   return &B;
 }
 
-std::map<int, JacobianBasis> JacobianBasis::fs;
-
+std::map<int, JacobianBasis> JacobianBasis::_fs;
 const JacobianBasis *JacobianBasis::find(int tag)
 {
-  std::map<int, JacobianBasis>::const_iterator it = fs.find(tag);
-  if (it != fs.end())
+  std::map<int, JacobianBasis>::const_iterator it = _fs.find(tag);
+  if (it != _fs.end())
     return &it->second;
-  JacobianBasis &B = fs[tag];
+  JacobianBasis &J = _fs[tag];
   const polynomialBasis *F = polynomialBases::find(tag);
   int jacobianOrder;
   switch (F->parentType) {
     case TYPE_PNT : jacobianOrder = 0; break;
     case TYPE_LIN : jacobianOrder = F->order - 1; break;
     case TYPE_TRI : jacobianOrder = 2 * (F->order - 1); break;
-    case TYPE_TET : jacobianOrder = 3 * (F->order - 1); break;
     case TYPE_QUA : jacobianOrder = 2 * F->order - 1; break;
-    case TYPE_PRI : jacobianOrder = F->order * 3 - 1; break; // o=3*ord-2 on triangle base and =3*ord-1 for third dimension
+    case TYPE_TET : jacobianOrder = 3 * (F->order - 1); break;
+    case TYPE_PRI : jacobianOrder = 3 * F->order - 1; break;
+    case TYPE_HEX : jacobianOrder = 3 * F->order - 1; break;
     default :
       Msg::Error("Unknown function space %d: reverting to TET_4", tag);
       jacobianOrder = 0;
   }
-  B.bezier = bezierBasis::find(polynomialBasis::getTag(F->parentType, jacobianOrder, false));
-  generateGradShapes(B, B.bezier->points, F->monomials, F->coefficients);
-  return &B;
+  J.bezier = bezierBasis::find(polynomialBasis::getTag(F->parentType, jacobianOrder, false));
+  generateGradShapes(J, J.bezier->points, F->monomials, F->coefficients);
+  return &J;
 }
diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h
index afad782618e0c8c145dc1e13c2c169066cbc002a..6080b87e8f71286c6a6fdbde17b002324ffb7cb2 100644
--- a/Numeric/JacobianBasis.h
+++ b/Numeric/JacobianBasis.h
@@ -15,22 +15,22 @@ class bezierBasis {
  public :
   int numLagPts;
   int numDivisions;
-  fullMatrix<double> exposants; //exposants of Bezier FF
+    // The 'numLagPts' first exponents are related to 'Lagrangian' values
+  fullMatrix<double> exponents; //exposants of Bezier FF
   fullMatrix<double> points; //sampling point
   fullMatrix<double> matrixLag2Bez, matrixBez2Lag;
-  fullMatrix<double> divisor;
+  fullMatrix<double> subDivisor;
   static const bezierBasis *find(int);
 };
 
 class JacobianBasis {
+ private:
+  static std::map<int, JacobianBasis> _fs;
  public :
   const bezierBasis *bezier;
   fullMatrix<double> gradShapeMatX;
   fullMatrix<double> gradShapeMatY;
   fullMatrix<double> gradShapeMatZ;
- private:
-  static std::map<int, JacobianBasis> fs;
- public:
   static const JacobianBasis *find(int);
 };