From 36ccac01c945b192d2b2ebf0d03d43c6eab50a06 Mon Sep 17 00:00:00 2001
From: Amaury Johnan <amjohnen@gmail.com>
Date: Thu, 6 Jun 2013 20:35:07 +0000
Subject: [PATCH] Structure Bases. All find/create functions are now in
 BasisFactory

---
 Geo/MHexahedron.cpp                           |   80 +-
 Geo/MLine.cpp                                 |   42 +-
 Geo/MPoint.h                                  |    4 +-
 Geo/MPrism.cpp                                |   20 +-
 Geo/MPyramid.cpp                              |   46 +-
 Geo/MQuadrangle.cpp                           |   84 +-
 Geo/MTetrahedron.cpp                          |   76 +-
 Geo/MTriangle.cpp                             |   86 +-
 Geo/discreteEdge.cpp                          |    2 +-
 Mesh/HighOrder.cpp                            |   80 +-
 Mesh/meshGFaceRecombine.h                     |    2 +-
 Numeric/BasisFactory.cpp                      |   37 +-
 Numeric/BasisFactory.h                        |   11 +-
 Numeric/CMakeLists.txt                        |   11 +-
 Numeric/JacobianBasis.cpp                     | 1087 +----------------
 Numeric/JacobianBasis.h                       |   19 +-
 Numeric/bezierBasis.cpp                       | 1069 ++++++++++++++++
 Numeric/bezierBasis.h                         |   30 +
 Numeric/jacobiPolynomials.h                   |    2 +-
 Numeric/legendrePolynomials.h                 |    2 +-
 Numeric/nodalBasis.cpp                        |    2 +-
 Numeric/polynomialBasis.h                     |   10 +-
 Plugin/AnalyseCurvedMesh.cpp                  |    2 +-
 Post/PViewDataList.cpp                        |    2 +-
 contrib/DiscreteIntegration/Integration3D.cpp |   10 +-
 contrib/DiscreteIntegration/Integration3D.h   |    2 +-
 contrib/HighOrderMeshOptimizer/OptHomMesh.h   |    2 +-
 27 files changed, 1426 insertions(+), 1394 deletions(-)
 create mode 100644 Numeric/bezierBasis.cpp
 create mode 100644 Numeric/bezierBasis.h

diff --git a/Geo/MHexahedron.cpp b/Geo/MHexahedron.cpp
index 52d0a067f5..29cfc61496 100644
--- a/Geo/MHexahedron.cpp
+++ b/Geo/MHexahedron.cpp
@@ -198,31 +198,31 @@ const nodalBasis* MHexahedron::getFunctionSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_HEX_1);
-    case 1: return BasisFactory::create(MSH_HEX_8);
-    case 2: return BasisFactory::create(MSH_HEX_20);
-    case 3: return BasisFactory::create(MSH_HEX_56);
-    case 4: return BasisFactory::create(MSH_HEX_98);
-    case 5: return BasisFactory::create(MSH_HEX_152);
-    case 6: return BasisFactory::create(MSH_HEX_218);
-    case 7: return BasisFactory::create(MSH_HEX_296);
-    case 8: return BasisFactory::create(MSH_HEX_386);
-    case 9: return BasisFactory::create(MSH_HEX_488);
+    case 0: return BasisFactory::getNodalBasis(MSH_HEX_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_HEX_8);
+    case 2: return BasisFactory::getNodalBasis(MSH_HEX_20);
+    case 3: return BasisFactory::getNodalBasis(MSH_HEX_56);
+    case 4: return BasisFactory::getNodalBasis(MSH_HEX_98);
+    case 5: return BasisFactory::getNodalBasis(MSH_HEX_152);
+    case 6: return BasisFactory::getNodalBasis(MSH_HEX_218);
+    case 7: return BasisFactory::getNodalBasis(MSH_HEX_296);
+    case 8: return BasisFactory::getNodalBasis(MSH_HEX_386);
+    case 9: return BasisFactory::getNodalBasis(MSH_HEX_488);
     default: Msg::Error("Order %d hex function space not implemented", order); break;
     }
   }
   else {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_HEX_1);
-    case 1: return BasisFactory::create(MSH_HEX_8);
-    case 2: return BasisFactory::create(MSH_HEX_27);
-    case 3: return BasisFactory::create(MSH_HEX_64);
-    case 4: return BasisFactory::create(MSH_HEX_125);
-    case 5: return BasisFactory::create(MSH_HEX_216);
-    case 6: return BasisFactory::create(MSH_HEX_343);
-    case 7: return BasisFactory::create(MSH_HEX_512);
-    case 8: return BasisFactory::create(MSH_HEX_729);
-    case 9: return BasisFactory::create(MSH_HEX_1000);
+    case 0: return BasisFactory::getNodalBasis(MSH_HEX_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_HEX_8);
+    case 2: return BasisFactory::getNodalBasis(MSH_HEX_27);
+    case 3: return BasisFactory::getNodalBasis(MSH_HEX_64);
+    case 4: return BasisFactory::getNodalBasis(MSH_HEX_125);
+    case 5: return BasisFactory::getNodalBasis(MSH_HEX_216);
+    case 6: return BasisFactory::getNodalBasis(MSH_HEX_343);
+    case 7: return BasisFactory::getNodalBasis(MSH_HEX_512);
+    case 8: return BasisFactory::getNodalBasis(MSH_HEX_729);
+    case 9: return BasisFactory::getNodalBasis(MSH_HEX_1000);
     default: Msg::Error("Order %d hex function space not implemented", order); break;
     }
   }
@@ -237,31 +237,31 @@ const JacobianBasis* MHexahedron::getJacobianFuncSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 0: return JacobianBasis::find(MSH_HEX_1);
-    case 1: return JacobianBasis::find(MSH_HEX_8);
-    case 2: return JacobianBasis::find(MSH_HEX_20);
-    case 3: return JacobianBasis::find(MSH_HEX_56);
-    case 4: return JacobianBasis::find(MSH_HEX_98);
-    case 5: return JacobianBasis::find(MSH_HEX_152);
-    case 6: return JacobianBasis::find(MSH_HEX_218);
-    case 7: return JacobianBasis::find(MSH_HEX_296);
-    case 8: return JacobianBasis::find(MSH_HEX_386);
-    case 9: return JacobianBasis::find(MSH_HEX_488);
+    case 0: return BasisFactory::getJacobianBasis(MSH_HEX_1);
+    case 1: return BasisFactory::getJacobianBasis(MSH_HEX_8);
+    case 2: return BasisFactory::getJacobianBasis(MSH_HEX_20);
+    case 3: return BasisFactory::getJacobianBasis(MSH_HEX_56);
+    case 4: return BasisFactory::getJacobianBasis(MSH_HEX_98);
+    case 5: return BasisFactory::getJacobianBasis(MSH_HEX_152);
+    case 6: return BasisFactory::getJacobianBasis(MSH_HEX_218);
+    case 7: return BasisFactory::getJacobianBasis(MSH_HEX_296);
+    case 8: return BasisFactory::getJacobianBasis(MSH_HEX_386);
+    case 9: return BasisFactory::getJacobianBasis(MSH_HEX_488);
     default: Msg::Error("Order %d hex incomplete Jacobian function space not implemented", order); break;
     }
   }
   else {
     switch (order) {
-    case 0: return JacobianBasis::find(MSH_HEX_1);
-    case 1: return JacobianBasis::find(MSH_HEX_8);
-    case 2: return JacobianBasis::find(MSH_HEX_27);
-    case 3: return JacobianBasis::find(MSH_HEX_64);
-    case 4: return JacobianBasis::find(MSH_HEX_125);
-    case 5: return JacobianBasis::find(MSH_HEX_216);
-    case 6: return JacobianBasis::find(MSH_HEX_343);
-    case 7: return JacobianBasis::find(MSH_HEX_512);
-    case 8: return JacobianBasis::find(MSH_HEX_729);
-    case 9: return JacobianBasis::find(MSH_HEX_1000);
+    case 0: return BasisFactory::getJacobianBasis(MSH_HEX_1);
+    case 1: return BasisFactory::getJacobianBasis(MSH_HEX_8);
+    case 2: return BasisFactory::getJacobianBasis(MSH_HEX_27);
+    case 3: return BasisFactory::getJacobianBasis(MSH_HEX_64);
+    case 4: return BasisFactory::getJacobianBasis(MSH_HEX_125);
+    case 5: return BasisFactory::getJacobianBasis(MSH_HEX_216);
+    case 6: return BasisFactory::getJacobianBasis(MSH_HEX_343);
+    case 7: return BasisFactory::getJacobianBasis(MSH_HEX_512);
+    case 8: return BasisFactory::getJacobianBasis(MSH_HEX_729);
+    case 9: return BasisFactory::getJacobianBasis(MSH_HEX_1000);
     default: Msg::Error("Order %d hex Jacobian function space not implemented", order); break;
     }
   }
diff --git a/Geo/MLine.cpp b/Geo/MLine.cpp
index 91d9404595..7b33b69a68 100644
--- a/Geo/MLine.cpp
+++ b/Geo/MLine.cpp
@@ -16,17 +16,17 @@ const nodalBasis* MLine::getFunctionSpace(int o) const
   int order = (o == -1) ? getPolynomialOrder() : o;
   
   switch (order) {
-  case 0: return BasisFactory::create(MSH_LIN_1);
-  case 1: return BasisFactory::create(MSH_LIN_2);
-  case 2: return BasisFactory::create(MSH_LIN_3);
-  case 3: return BasisFactory::create(MSH_LIN_4);
-  case 4: return BasisFactory::create(MSH_LIN_5);
-  case 5: return BasisFactory::create(MSH_LIN_6);
-  case 6: return BasisFactory::create(MSH_LIN_7);
-  case 7: return BasisFactory::create(MSH_LIN_8);
-  case 8: return BasisFactory::create(MSH_LIN_9);
-  case 9: return BasisFactory::create(MSH_LIN_10);
-  case 10: return BasisFactory::create(MSH_LIN_11);
+  case 0: return BasisFactory::getNodalBasis(MSH_LIN_1);
+  case 1: return BasisFactory::getNodalBasis(MSH_LIN_2);
+  case 2: return BasisFactory::getNodalBasis(MSH_LIN_3);
+  case 3: return BasisFactory::getNodalBasis(MSH_LIN_4);
+  case 4: return BasisFactory::getNodalBasis(MSH_LIN_5);
+  case 5: return BasisFactory::getNodalBasis(MSH_LIN_6);
+  case 6: return BasisFactory::getNodalBasis(MSH_LIN_7);
+  case 7: return BasisFactory::getNodalBasis(MSH_LIN_8);
+  case 8: return BasisFactory::getNodalBasis(MSH_LIN_9);
+  case 9: return BasisFactory::getNodalBasis(MSH_LIN_10);
+  case 10: return BasisFactory::getNodalBasis(MSH_LIN_11);
   default: Msg::Error("Order %d line function space not implemented", order);
   }
   return 0;
@@ -37,16 +37,16 @@ const JacobianBasis* MLine::getJacobianFuncSpace(int o) const
   int order = (o == -1) ? getPolynomialOrder() : o;
   
   switch (order) {
-  case 1: return JacobianBasis::find(MSH_LIN_2);
-  case 2: return JacobianBasis::find(MSH_LIN_3);
-  case 3: return JacobianBasis::find(MSH_LIN_4);
-  case 4: return JacobianBasis::find(MSH_LIN_5);
-  case 5: return JacobianBasis::find(MSH_LIN_6);
-  case 6: return JacobianBasis::find(MSH_LIN_7);
-  case 7: return JacobianBasis::find(MSH_LIN_8);
-  case 8: return JacobianBasis::find(MSH_LIN_9);
-  case 9: return JacobianBasis::find(MSH_LIN_10);
-  case 10: return JacobianBasis::find(MSH_LIN_11);
+  case 1: return BasisFactory::getJacobianBasis(MSH_LIN_2);
+  case 2: return BasisFactory::getJacobianBasis(MSH_LIN_3);
+  case 3: return BasisFactory::getJacobianBasis(MSH_LIN_4);
+  case 4: return BasisFactory::getJacobianBasis(MSH_LIN_5);
+  case 5: return BasisFactory::getJacobianBasis(MSH_LIN_6);
+  case 6: return BasisFactory::getJacobianBasis(MSH_LIN_7);
+  case 7: return BasisFactory::getJacobianBasis(MSH_LIN_8);
+  case 8: return BasisFactory::getJacobianBasis(MSH_LIN_9);
+  case 9: return BasisFactory::getJacobianBasis(MSH_LIN_10);
+  case 10: return BasisFactory::getJacobianBasis(MSH_LIN_11);
   default: Msg::Error("Order %d line function space not implemented", order);
   }
   return 0;
diff --git a/Geo/MPoint.h b/Geo/MPoint.h
index 66ae8582c1..08ccc7fbc1 100644
--- a/Geo/MPoint.h
+++ b/Geo/MPoint.h
@@ -63,11 +63,11 @@ class MPoint : public MElement {
   }
   virtual const nodalBasis* getFunctionSpace(int o) const
   {
-    return BasisFactory::create(MSH_PNT);
+    return BasisFactory::getNodalBasis(MSH_PNT);
   }
   virtual const JacobianBasis* getJacobianFuncSpace(int o) const
   {
-    return JacobianBasis::find(MSH_PNT);
+    return BasisFactory::getJacobianBasis(MSH_PNT);
   }
   virtual bool isInside(double u, double v, double w) const
   {
diff --git a/Geo/MPrism.cpp b/Geo/MPrism.cpp
index f364c55674..508bf117d7 100644
--- a/Geo/MPrism.cpp
+++ b/Geo/MPrism.cpp
@@ -40,17 +40,17 @@ const nodalBasis* MPrism::getFunctionSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_PRI_1);
-    case 1: return BasisFactory::create(MSH_PRI_6);
-    case 2: return BasisFactory::create(MSH_PRI_18);
+    case 0: return BasisFactory::getNodalBasis(MSH_PRI_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_PRI_6);
+    case 2: return BasisFactory::getNodalBasis(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_PRI_1);
-    case 1: return BasisFactory::create(MSH_PRI_6);
-    case 2: return BasisFactory::create(MSH_PRI_18);
+    case 0: return BasisFactory::getNodalBasis(MSH_PRI_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_PRI_6);
+    case 2: return BasisFactory::getNodalBasis(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
@@ -65,15 +65,15 @@ const JacobianBasis* MPrism::getJacobianFuncSpace(int o) const
   
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 1: return JacobianBasis::find(MSH_PRI_6);
-    case 2: return JacobianBasis::find(MSH_PRI_18);
+    case 1: return BasisFactory::getJacobianBasis(MSH_PRI_6);
+    case 2: return BasisFactory::getJacobianBasis(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
   else { 
     switch (order) {
-    case 1: return JacobianBasis::find(MSH_PRI_6);
-    case 2: return JacobianBasis::find(MSH_PRI_18);
+    case 1: return BasisFactory::getJacobianBasis(MSH_PRI_6);
+    case 2: return BasisFactory::getJacobianBasis(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
diff --git a/Geo/MPyramid.cpp b/Geo/MPyramid.cpp
index f6e3c41307..1a44f7c4b6 100644
--- a/Geo/MPyramid.cpp
+++ b/Geo/MPyramid.cpp
@@ -35,31 +35,31 @@ const nodalBasis* MPyramid::getFunctionSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 1: return BasisFactory::create(MSH_PYR_5);
-    case 2: return BasisFactory::create(MSH_PYR_14);
-    case 0: return BasisFactory::create(MSH_PYR_1);
-    case 3: return BasisFactory::create(MSH_PYR_29);
-    case 4: return BasisFactory::create(MSH_PYR_50);
-    case 5: return BasisFactory::create(MSH_PYR_77);
-    case 6: return BasisFactory::create(MSH_PYR_110);
-    case 7: return BasisFactory::create(MSH_PYR_149);
-    case 8: return BasisFactory::create(MSH_PYR_194);
-    case 9: return BasisFactory::create(MSH_PYR_245);
+    case 1: return BasisFactory::getNodalBasis(MSH_PYR_5);
+    case 2: return BasisFactory::getNodalBasis(MSH_PYR_14);
+    case 0: return BasisFactory::getNodalBasis(MSH_PYR_1);
+    case 3: return BasisFactory::getNodalBasis(MSH_PYR_29);
+    case 4: return BasisFactory::getNodalBasis(MSH_PYR_50);
+    case 5: return BasisFactory::getNodalBasis(MSH_PYR_77);
+    case 6: return BasisFactory::getNodalBasis(MSH_PYR_110);
+    case 7: return BasisFactory::getNodalBasis(MSH_PYR_149);
+    case 8: return BasisFactory::getNodalBasis(MSH_PYR_194);
+    case 9: return BasisFactory::getNodalBasis(MSH_PYR_245);
     default: Msg::Error("Order %d pyramid function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_PYR_1);
-    case 1: return BasisFactory::create(MSH_PYR_5);
-    case 2: return BasisFactory::create(MSH_PYR_14);
-    case 3: return BasisFactory::create(MSH_PYR_30);
-    case 4: return BasisFactory::create(MSH_PYR_55);
-    case 5: return BasisFactory::create(MSH_PYR_91);
-    case 6: return BasisFactory::create(MSH_PYR_140);
-    case 7: return BasisFactory::create(MSH_PYR_204);
-    case 8: return BasisFactory::create(MSH_PYR_285);
-    case 9: return BasisFactory::create(MSH_PYR_385);
+    case 0: return BasisFactory::getNodalBasis(MSH_PYR_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_PYR_5);
+    case 2: return BasisFactory::getNodalBasis(MSH_PYR_14);
+    case 3: return BasisFactory::getNodalBasis(MSH_PYR_30);
+    case 4: return BasisFactory::getNodalBasis(MSH_PYR_55);
+    case 5: return BasisFactory::getNodalBasis(MSH_PYR_91);
+    case 6: return BasisFactory::getNodalBasis(MSH_PYR_140);
+    case 7: return BasisFactory::getNodalBasis(MSH_PYR_204);
+    case 8: return BasisFactory::getNodalBasis(MSH_PYR_285);
+    case 9: return BasisFactory::getNodalBasis(MSH_PYR_385);
     default: Msg::Error("Order %d pyramid function space not implemented", order);
     }
   }
@@ -71,9 +71,9 @@ const JacobianBasis* MPyramid::getJacobianFuncSpace(int o) const
   int order = (o == -1) ? getPolynomialOrder() : o;
 
   switch (order) {
-    case 1: return JacobianBasis::find(MSH_PYR_5);
-    case 2: return JacobianBasis::find(MSH_PYR_14);
-    case 3: return JacobianBasis::find(MSH_PYR_30);
+    case 1: return BasisFactory::getJacobianBasis(MSH_PYR_5);
+    case 2: return BasisFactory::getJacobianBasis(MSH_PYR_14);
+    case 3: return BasisFactory::getJacobianBasis(MSH_PYR_30);
     default: Msg::Error("Order %d pyramid function space not implemented", order); break;
   }
 
diff --git a/Geo/MQuadrangle.cpp b/Geo/MQuadrangle.cpp
index 6808e69e23..0f6b54877c 100644
--- a/Geo/MQuadrangle.cpp
+++ b/Geo/MQuadrangle.cpp
@@ -25,31 +25,31 @@ const nodalBasis* MQuadrangle::getFunctionSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-      case 0: return BasisFactory::create(MSH_QUA_1);
-      case 1: return BasisFactory::create(MSH_QUA_4);
-      case 2: return BasisFactory::create(MSH_QUA_8);
-      case 3: return BasisFactory::create(MSH_QUA_12);
-      case 4: return BasisFactory::create(MSH_QUA_16I);
-      case 5: return BasisFactory::create(MSH_QUA_20);
-      case 6: return BasisFactory::create(MSH_QUA_24);
-      case 7: return BasisFactory::create(MSH_QUA_28);
-      case 8: return BasisFactory::create(MSH_QUA_32);
-      case 9: return BasisFactory::create(MSH_QUA_36I);
-      case 10: return BasisFactory::create(MSH_QUA_40);
+      case 0: return BasisFactory::getNodalBasis(MSH_QUA_1);
+      case 1: return BasisFactory::getNodalBasis(MSH_QUA_4);
+      case 2: return BasisFactory::getNodalBasis(MSH_QUA_8);
+      case 3: return BasisFactory::getNodalBasis(MSH_QUA_12);
+      case 4: return BasisFactory::getNodalBasis(MSH_QUA_16I);
+      case 5: return BasisFactory::getNodalBasis(MSH_QUA_20);
+      case 6: return BasisFactory::getNodalBasis(MSH_QUA_24);
+      case 7: return BasisFactory::getNodalBasis(MSH_QUA_28);
+      case 8: return BasisFactory::getNodalBasis(MSH_QUA_32);
+      case 9: return BasisFactory::getNodalBasis(MSH_QUA_36I);
+      case 10: return BasisFactory::getNodalBasis(MSH_QUA_40);
     }
   }
   switch (order) {
-    case 0: return BasisFactory::create(MSH_QUA_1);
-    case 1: return BasisFactory::create(MSH_QUA_4);
-    case 2: return BasisFactory::create(MSH_QUA_9);
-    case 3: return BasisFactory::create(MSH_QUA_16);
-    case 4: return BasisFactory::create(MSH_QUA_25);
-    case 5: return BasisFactory::create(MSH_QUA_36);
-    case 6: return BasisFactory::create(MSH_QUA_49);
-    case 7: return BasisFactory::create(MSH_QUA_64);
-    case 8: return BasisFactory::create(MSH_QUA_81);
-    case 9: return BasisFactory::create(MSH_QUA_100);
-    case 10: return BasisFactory::create(MSH_QUA_121);
+    case 0: return BasisFactory::getNodalBasis(MSH_QUA_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_QUA_4);
+    case 2: return BasisFactory::getNodalBasis(MSH_QUA_9);
+    case 3: return BasisFactory::getNodalBasis(MSH_QUA_16);
+    case 4: return BasisFactory::getNodalBasis(MSH_QUA_25);
+    case 5: return BasisFactory::getNodalBasis(MSH_QUA_36);
+    case 6: return BasisFactory::getNodalBasis(MSH_QUA_49);
+    case 7: return BasisFactory::getNodalBasis(MSH_QUA_64);
+    case 8: return BasisFactory::getNodalBasis(MSH_QUA_81);
+    case 9: return BasisFactory::getNodalBasis(MSH_QUA_100);
+    case 10: return BasisFactory::getNodalBasis(MSH_QUA_121);
     default: Msg::Error("Order %d quadrangle function space not implemented", order);
   }
   return 0;
@@ -63,29 +63,29 @@ const JacobianBasis* MQuadrangle::getJacobianFuncSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-      case 1: return JacobianBasis::find(MSH_QUA_4);
-      case 2: return JacobianBasis::find(MSH_QUA_8);
-      case 3: return JacobianBasis::find(MSH_QUA_12);
-      case 4: return JacobianBasis::find(MSH_QUA_16I);
-      case 5: return JacobianBasis::find(MSH_QUA_20);
-      case 6: return JacobianBasis::find(MSH_QUA_24);
-      case 7: return JacobianBasis::find(MSH_QUA_28);
-      case 8: return JacobianBasis::find(MSH_QUA_32);
-      case 9: return JacobianBasis::find(MSH_QUA_36I);
-      case 10: return JacobianBasis::find(MSH_QUA_40);
+      case 1: return BasisFactory::getJacobianBasis(MSH_QUA_4);
+      case 2: return BasisFactory::getJacobianBasis(MSH_QUA_8);
+      case 3: return BasisFactory::getJacobianBasis(MSH_QUA_12);
+      case 4: return BasisFactory::getJacobianBasis(MSH_QUA_16I);
+      case 5: return BasisFactory::getJacobianBasis(MSH_QUA_20);
+      case 6: return BasisFactory::getJacobianBasis(MSH_QUA_24);
+      case 7: return BasisFactory::getJacobianBasis(MSH_QUA_28);
+      case 8: return BasisFactory::getJacobianBasis(MSH_QUA_32);
+      case 9: return BasisFactory::getJacobianBasis(MSH_QUA_36I);
+      case 10: return BasisFactory::getJacobianBasis(MSH_QUA_40);
     }
   }
   switch (order) {
-    case 1: return JacobianBasis::find(MSH_QUA_4);
-    case 2: return JacobianBasis::find(MSH_QUA_9);
-    case 3: return JacobianBasis::find(MSH_QUA_16);
-    case 4: return JacobianBasis::find(MSH_QUA_25);
-    case 5: return JacobianBasis::find(MSH_QUA_36);
-    case 6: return JacobianBasis::find(MSH_QUA_49);
-    case 7: return JacobianBasis::find(MSH_QUA_64);
-    case 8: return JacobianBasis::find(MSH_QUA_81);
-    case 9: return JacobianBasis::find(MSH_QUA_100);
-    case 10: return JacobianBasis::find(MSH_QUA_121);
+    case 1: return BasisFactory::getJacobianBasis(MSH_QUA_4);
+    case 2: return BasisFactory::getJacobianBasis(MSH_QUA_9);
+    case 3: return BasisFactory::getJacobianBasis(MSH_QUA_16);
+    case 4: return BasisFactory::getJacobianBasis(MSH_QUA_25);
+    case 5: return BasisFactory::getJacobianBasis(MSH_QUA_36);
+    case 6: return BasisFactory::getJacobianBasis(MSH_QUA_49);
+    case 7: return BasisFactory::getJacobianBasis(MSH_QUA_64);
+    case 8: return BasisFactory::getJacobianBasis(MSH_QUA_81);
+    case 9: return BasisFactory::getJacobianBasis(MSH_QUA_100);
+    case 10: return BasisFactory::getJacobianBasis(MSH_QUA_121);
     default: Msg::Error("Order %d quadrangle function space not implemented", order);
   }
   return 0;
diff --git a/Geo/MTetrahedron.cpp b/Geo/MTetrahedron.cpp
index 5d1d29a0b1..af35188863 100644
--- a/Geo/MTetrahedron.cpp
+++ b/Geo/MTetrahedron.cpp
@@ -8,7 +8,7 @@
 #include "Numeric.h"
 #include "Context.h"
 #include "BasisFactory.h"
-#include "JacobianBasis.h"
+
 
 #if defined(HAVE_MESH)
 #include "qualityMeasures.h"
@@ -108,33 +108,33 @@ const nodalBasis* MTetrahedron::getFunctionSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_TET_1);
-    case 1: return BasisFactory::create(MSH_TET_4);
-    case 2: return BasisFactory::create(MSH_TET_10);
-    case 3: return BasisFactory::create(MSH_TET_20);
-    case 4: return BasisFactory::create(MSH_TET_34);
-    case 5: return BasisFactory::create(MSH_TET_52);
-    case 6: return BasisFactory::create(MSH_TET_74);
-    case 7: return BasisFactory::create(MSH_TET_100);
-    case 8: return BasisFactory::create(MSH_TET_130);
-    case 9: return BasisFactory::create(MSH_TET_164);
-    case 10: return BasisFactory::create(MSH_TET_202);
+    case 0: return BasisFactory::getNodalBasis(MSH_TET_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_TET_4);
+    case 2: return BasisFactory::getNodalBasis(MSH_TET_10);
+    case 3: return BasisFactory::getNodalBasis(MSH_TET_20);
+    case 4: return BasisFactory::getNodalBasis(MSH_TET_34);
+    case 5: return BasisFactory::getNodalBasis(MSH_TET_52);
+    case 6: return BasisFactory::getNodalBasis(MSH_TET_74);
+    case 7: return BasisFactory::getNodalBasis(MSH_TET_100);
+    case 8: return BasisFactory::getNodalBasis(MSH_TET_130);
+    case 9: return BasisFactory::getNodalBasis(MSH_TET_164);
+    case 10: return BasisFactory::getNodalBasis(MSH_TET_202);
     default: Msg::Error("Order %d tetrahedron function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_TET_1);
-    case 1: return BasisFactory::create(MSH_TET_4);
-    case 2: return BasisFactory::create(MSH_TET_10);
-    case 3: return BasisFactory::create(MSH_TET_20);
-    case 4: return BasisFactory::create(MSH_TET_35);
-    case 5: return BasisFactory::create(MSH_TET_56);
-    case 6: return BasisFactory::create(MSH_TET_84);
-    case 7: return BasisFactory::create(MSH_TET_120);
-    case 8: return BasisFactory::create(MSH_TET_165);
-    case 9: return BasisFactory::create(MSH_TET_220);
-    case 10: return BasisFactory::create(MSH_TET_286);
+    case 0: return BasisFactory::getNodalBasis(MSH_TET_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_TET_4);
+    case 2: return BasisFactory::getNodalBasis(MSH_TET_10);
+    case 3: return BasisFactory::getNodalBasis(MSH_TET_20);
+    case 4: return BasisFactory::getNodalBasis(MSH_TET_35);
+    case 5: return BasisFactory::getNodalBasis(MSH_TET_56);
+    case 6: return BasisFactory::getNodalBasis(MSH_TET_84);
+    case 7: return BasisFactory::getNodalBasis(MSH_TET_120);
+    case 8: return BasisFactory::getNodalBasis(MSH_TET_165);
+    case 9: return BasisFactory::getNodalBasis(MSH_TET_220);
+    case 10: return BasisFactory::getNodalBasis(MSH_TET_286);
     default: Msg::Error("Order %d tetrahedron function space not implemented", order);
     }
   }
@@ -149,26 +149,26 @@ const JacobianBasis* MTetrahedron::getJacobianFuncSpace(int o) const
 
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 1: return JacobianBasis::find(MSH_TET_4);
-    case 2: return JacobianBasis::find(MSH_TET_10);
-    case 3: return JacobianBasis::find(MSH_TET_20);
-    case 4: return JacobianBasis::find(MSH_TET_34);
-    case 5: return JacobianBasis::find(MSH_TET_52);
+    case 1: return BasisFactory::getJacobianBasis(MSH_TET_4);
+    case 2: return BasisFactory::getJacobianBasis(MSH_TET_10);
+    case 3: return BasisFactory::getJacobianBasis(MSH_TET_20);
+    case 4: return BasisFactory::getJacobianBasis(MSH_TET_34);
+    case 5: return BasisFactory::getJacobianBasis(MSH_TET_52);
     default: Msg::Error("Order %d tetrahedron function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 1: return JacobianBasis::find(MSH_TET_4);
-    case 2: return JacobianBasis::find(MSH_TET_10);
-    case 3: return JacobianBasis::find(MSH_TET_20);
-    case 4: return JacobianBasis::find(MSH_TET_35);
-    case 5: return JacobianBasis::find(MSH_TET_56);
-    case 6: return JacobianBasis::find(MSH_TET_84);
-    case 7: return JacobianBasis::find(MSH_TET_120);
-    case 8: return JacobianBasis::find(MSH_TET_165);
-    case 9: return JacobianBasis::find(MSH_TET_220);
-    case 10: return JacobianBasis::find(MSH_TET_286);
+    case 1: return BasisFactory::getJacobianBasis(MSH_TET_4);
+    case 2: return BasisFactory::getJacobianBasis(MSH_TET_10);
+    case 3: return BasisFactory::getJacobianBasis(MSH_TET_20);
+    case 4: return BasisFactory::getJacobianBasis(MSH_TET_35);
+    case 5: return BasisFactory::getJacobianBasis(MSH_TET_56);
+    case 6: return BasisFactory::getJacobianBasis(MSH_TET_84);
+    case 7: return BasisFactory::getJacobianBasis(MSH_TET_120);
+    case 8: return BasisFactory::getJacobianBasis(MSH_TET_165);
+    case 9: return BasisFactory::getJacobianBasis(MSH_TET_220);
+    case 10: return BasisFactory::getJacobianBasis(MSH_TET_286);
     default: Msg::Error("Order %d tetrahedron function space not implemented", order);
     }
   }
diff --git a/Geo/MTriangle.cpp b/Geo/MTriangle.cpp
index 49d68dee7b..3c73eb8de4 100644
--- a/Geo/MTriangle.cpp
+++ b/Geo/MTriangle.cpp
@@ -127,33 +127,33 @@ const nodalBasis* MTriangle::getFunctionSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_TRI_1);
-    case 1: return BasisFactory::create(MSH_TRI_3);
-    case 2: return BasisFactory::create(MSH_TRI_6);
-    case 3: return BasisFactory::create(MSH_TRI_9);
-    case 4: return BasisFactory::create(MSH_TRI_12);
-    case 5: return BasisFactory::create(MSH_TRI_15I);
-    case 6: return BasisFactory::create(MSH_TRI_18);
-    case 7: return BasisFactory::create(MSH_TRI_21I);
-    case 8: return BasisFactory::create(MSH_TRI_24);
-    case 9: return BasisFactory::create(MSH_TRI_27);
-    case 10: return BasisFactory::create(MSH_TRI_30);
+    case 0: return BasisFactory::getNodalBasis(MSH_TRI_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_TRI_3);
+    case 2: return BasisFactory::getNodalBasis(MSH_TRI_6);
+    case 3: return BasisFactory::getNodalBasis(MSH_TRI_9);
+    case 4: return BasisFactory::getNodalBasis(MSH_TRI_12);
+    case 5: return BasisFactory::getNodalBasis(MSH_TRI_15I);
+    case 6: return BasisFactory::getNodalBasis(MSH_TRI_18);
+    case 7: return BasisFactory::getNodalBasis(MSH_TRI_21I);
+    case 8: return BasisFactory::getNodalBasis(MSH_TRI_24);
+    case 9: return BasisFactory::getNodalBasis(MSH_TRI_27);
+    case 10: return BasisFactory::getNodalBasis(MSH_TRI_30);
     default: Msg::Error("Order %d triangle incomplete function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 0: return BasisFactory::create(MSH_TRI_1);
-    case 1: return BasisFactory::create(MSH_TRI_3);
-    case 2: return BasisFactory::create(MSH_TRI_6);
-    case 3: return BasisFactory::create(MSH_TRI_10);
-    case 4: return BasisFactory::create(MSH_TRI_15);
-    case 5: return BasisFactory::create(MSH_TRI_21);
-    case 6: return BasisFactory::create(MSH_TRI_28);
-    case 7: return BasisFactory::create(MSH_TRI_36);
-    case 8: return BasisFactory::create(MSH_TRI_45);
-    case 9: return BasisFactory::create(MSH_TRI_55);
-    case 10: return BasisFactory::create(MSH_TRI_66);
+    case 0: return BasisFactory::getNodalBasis(MSH_TRI_1);
+    case 1: return BasisFactory::getNodalBasis(MSH_TRI_3);
+    case 2: return BasisFactory::getNodalBasis(MSH_TRI_6);
+    case 3: return BasisFactory::getNodalBasis(MSH_TRI_10);
+    case 4: return BasisFactory::getNodalBasis(MSH_TRI_15);
+    case 5: return BasisFactory::getNodalBasis(MSH_TRI_21);
+    case 6: return BasisFactory::getNodalBasis(MSH_TRI_28);
+    case 7: return BasisFactory::getNodalBasis(MSH_TRI_36);
+    case 8: return BasisFactory::getNodalBasis(MSH_TRI_45);
+    case 9: return BasisFactory::getNodalBasis(MSH_TRI_55);
+    case 10: return BasisFactory::getNodalBasis(MSH_TRI_66);
     default: Msg::Error("Order %d triangle function space not implemented", order);
     }
   }
@@ -169,32 +169,32 @@ const JacobianBasis* MTriangle::getJacobianFuncSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-    case 0: return JacobianBasis::find(MSH_TRI_1);
-    case 1: return JacobianBasis::find(MSH_TRI_3);
-    case 2: return JacobianBasis::find(MSH_TRI_6);
-    case 3: return JacobianBasis::find(MSH_TRI_9);
-    case 4: return JacobianBasis::find(MSH_TRI_12);
-    case 5: return JacobianBasis::find(MSH_TRI_15I);
-    case 6: return JacobianBasis::find(MSH_TRI_18);
-    case 7: return JacobianBasis::find(MSH_TRI_21I);
-    case 8: return JacobianBasis::find(MSH_TRI_24);
-    case 9: return JacobianBasis::find(MSH_TRI_27);
-    case 10: return JacobianBasis::find(MSH_TRI_30);
+    case 0: return BasisFactory::getJacobianBasis(MSH_TRI_1);
+    case 1: return BasisFactory::getJacobianBasis(MSH_TRI_3);
+    case 2: return BasisFactory::getJacobianBasis(MSH_TRI_6);
+    case 3: return BasisFactory::getJacobianBasis(MSH_TRI_9);
+    case 4: return BasisFactory::getJacobianBasis(MSH_TRI_12);
+    case 5: return BasisFactory::getJacobianBasis(MSH_TRI_15I);
+    case 6: return BasisFactory::getJacobianBasis(MSH_TRI_18);
+    case 7: return BasisFactory::getJacobianBasis(MSH_TRI_21I);
+    case 8: return BasisFactory::getJacobianBasis(MSH_TRI_24);
+    case 9: return BasisFactory::getJacobianBasis(MSH_TRI_27);
+    case 10: return BasisFactory::getJacobianBasis(MSH_TRI_30);
     default: Msg::Error("Order %d triangle incomplete function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 1: return JacobianBasis::find(MSH_TRI_3);
-    case 2: return JacobianBasis::find(MSH_TRI_6);
-    case 3: return JacobianBasis::find(MSH_TRI_10);
-    case 4: return JacobianBasis::find(MSH_TRI_15);
-    case 5: return JacobianBasis::find(MSH_TRI_21);
-    case 6: return JacobianBasis::find(MSH_TRI_28);
-    case 7: return JacobianBasis::find(MSH_TRI_36);
-    case 8: return JacobianBasis::find(MSH_TRI_45);
-    case 9: return JacobianBasis::find(MSH_TRI_55);
-    case 10: return JacobianBasis::find(MSH_TRI_66);
+    case 1: return BasisFactory::getJacobianBasis(MSH_TRI_3);
+    case 2: return BasisFactory::getJacobianBasis(MSH_TRI_6);
+    case 3: return BasisFactory::getJacobianBasis(MSH_TRI_10);
+    case 4: return BasisFactory::getJacobianBasis(MSH_TRI_15);
+    case 5: return BasisFactory::getJacobianBasis(MSH_TRI_21);
+    case 6: return BasisFactory::getJacobianBasis(MSH_TRI_28);
+    case 7: return BasisFactory::getJacobianBasis(MSH_TRI_36);
+    case 8: return BasisFactory::getJacobianBasis(MSH_TRI_45);
+    case 9: return BasisFactory::getJacobianBasis(MSH_TRI_55);
+    case 10: return BasisFactory::getJacobianBasis(MSH_TRI_66);
     default: Msg::Error("Order %d triangle function space not implemented", order);
     }
   }
diff --git a/Geo/discreteEdge.cpp b/Geo/discreteEdge.cpp
index c79bd36304..7ce3f119ff 100644
--- a/Geo/discreteEdge.cpp
+++ b/Geo/discreteEdge.cpp
@@ -501,7 +501,7 @@ double discreteEdge::curvature(double par) const
   double c0, c1;
   Curvature& curvature  = Curvature::getInstance();
   if( !Curvature::valueAlreadyComputed() ) {
-    std::cout << "Need to compute discrete curvature (in discreteEdge)" << std::endl;
+    Msg::Warning("Need to compute discrete curvature (in discreteEdge)");
     Curvature::typeOfCurvature type = Curvature::RUSIN; //RUSIN; //RBF
     curvature.computeCurvature(model(), type); 
   }
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index dbc93f24e1..59f54a2bb0 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -472,14 +472,14 @@ static int getNewFacePoints(int numPrimaryFacePoints, int nPts, fullMatrix<doubl
     switch (nPts){
     case 0 : break;
     case 1 : break;
-    case 2 : points = BasisFactory::create(MSH_TRI_10)->points; start = 9; break;
-    case 3 : points = BasisFactory::create(MSH_TRI_15)->points; start = 12; break;
-    case 4 : points = BasisFactory::create(MSH_TRI_21)->points; start = 15; break;
-    case 5 : points = BasisFactory::create(MSH_TRI_28)->points; start = 18; break;
-    case 6 : points = BasisFactory::create(MSH_TRI_36)->points; start = 21; break;
-    case 7 : points = BasisFactory::create(MSH_TRI_45)->points; start = 24; break;
-    case 8 : points = BasisFactory::create(MSH_TRI_55)->points; start = 27; break;
-    case 9 : points = BasisFactory::create(MSH_TRI_66)->points; start = 30; break;
+    case 2 : points = BasisFactory::getNodalBasis(MSH_TRI_10)->points; start = 9; break;
+    case 3 : points = BasisFactory::getNodalBasis(MSH_TRI_15)->points; start = 12; break;
+    case 4 : points = BasisFactory::getNodalBasis(MSH_TRI_21)->points; start = 15; break;
+    case 5 : points = BasisFactory::getNodalBasis(MSH_TRI_28)->points; start = 18; break;
+    case 6 : points = BasisFactory::getNodalBasis(MSH_TRI_36)->points; start = 21; break;
+    case 7 : points = BasisFactory::getNodalBasis(MSH_TRI_45)->points; start = 24; break;
+    case 8 : points = BasisFactory::getNodalBasis(MSH_TRI_55)->points; start = 27; break;
+    case 9 : points = BasisFactory::getNodalBasis(MSH_TRI_66)->points; start = 30; break;
     default :
       Msg::Error("getFaceVertices not implemented for order %i", nPts +1);
       break;
@@ -488,14 +488,14 @@ static int getNewFacePoints(int numPrimaryFacePoints, int nPts, fullMatrix<doubl
   case 4:
     switch (nPts){
     case 0 : break;
-    case 1 : points = BasisFactory::create(MSH_QUA_9)->points; break;
-    case 2 : points = BasisFactory::create(MSH_QUA_16)->points; break;
-    case 3 : points = BasisFactory::create(MSH_QUA_25)->points; break;
-    case 4 : points = BasisFactory::create(MSH_QUA_36)->points; break;
-    case 5 : points = BasisFactory::create(MSH_QUA_49)->points; break;
-    case 6 : points = BasisFactory::create(MSH_QUA_64)->points; break;
-    case 7 : points = BasisFactory::create(MSH_QUA_81)->points; break;
-    case 8 : points = BasisFactory::create(MSH_QUA_100)->points; break;
+    case 1 : points = BasisFactory::getNodalBasis(MSH_QUA_9)->points; break;
+    case 2 : points = BasisFactory::getNodalBasis(MSH_QUA_16)->points; break;
+    case 3 : points = BasisFactory::getNodalBasis(MSH_QUA_25)->points; break;
+    case 4 : points = BasisFactory::getNodalBasis(MSH_QUA_36)->points; break;
+    case 5 : points = BasisFactory::getNodalBasis(MSH_QUA_49)->points; break;
+    case 6 : points = BasisFactory::getNodalBasis(MSH_QUA_64)->points; break;
+    case 7 : points = BasisFactory::getNodalBasis(MSH_QUA_81)->points; break;
+    case 8 : points = BasisFactory::getNodalBasis(MSH_QUA_100)->points; break;
     default :
       Msg::Error("getFaceVertices not implemented for order %i", nPts +1);
       break;
@@ -599,15 +599,15 @@ static void getRegionVertices(GRegion *gr, MElement *incomplete, MElement *ele,
     case 0: return;
     case 1: return;
     case 2:
-      BasisFactory::create(MSH_TET_20)->points.print();
-      points = BasisFactory::create(MSH_TET_20)->points; break;
-    case 3: points = BasisFactory::create(MSH_TET_35)->points; break;
-    case 4: points = BasisFactory::create(MSH_TET_56)->points; break;
-    case 5: points = BasisFactory::create(MSH_TET_84)->points; break;
-    case 6: points = BasisFactory::create(MSH_TET_120)->points; break;
-    case 7: points = BasisFactory::create(MSH_TET_165)->points; break;
-    case 8: points = BasisFactory::create(MSH_TET_220)->points; break;
-    case 9: points = BasisFactory::create(MSH_TET_286)->points; break;
+      BasisFactory::getNodalBasis(MSH_TET_20)->points.print();
+      points = BasisFactory::getNodalBasis(MSH_TET_20)->points; break;
+    case 3: points = BasisFactory::getNodalBasis(MSH_TET_35)->points; break;
+    case 4: points = BasisFactory::getNodalBasis(MSH_TET_56)->points; break;
+    case 5: points = BasisFactory::getNodalBasis(MSH_TET_84)->points; break;
+    case 6: points = BasisFactory::getNodalBasis(MSH_TET_120)->points; break;
+    case 7: points = BasisFactory::getNodalBasis(MSH_TET_165)->points; break;
+    case 8: points = BasisFactory::getNodalBasis(MSH_TET_220)->points; break;
+    case 9: points = BasisFactory::getNodalBasis(MSH_TET_286)->points; break;
     default:
       Msg::Error("getRegionVertices not implemented for order %i", nPts+1);
       break;
@@ -617,14 +617,14 @@ static void getRegionVertices(GRegion *gr, MElement *incomplete, MElement *ele,
   case TYPE_HEX :
     switch (nPts){
     case 0: return;
-    case 1: points = BasisFactory::create(MSH_HEX_27)->points; break;
-    case 2: points = BasisFactory::create(MSH_HEX_64)->points; break;
-    case 3: points = BasisFactory::create(MSH_HEX_125)->points; break;
-    case 4: points = BasisFactory::create(MSH_HEX_216)->points; break;
-    case 5: points = BasisFactory::create(MSH_HEX_343)->points; break;
-    case 6: points = BasisFactory::create(MSH_HEX_512)->points; break;
-    case 7: points = BasisFactory::create(MSH_HEX_729)->points; break;
-    case 8: points = BasisFactory::create(MSH_HEX_1000)->points; break;
+    case 1: points = BasisFactory::getNodalBasis(MSH_HEX_27)->points; break;
+    case 2: points = BasisFactory::getNodalBasis(MSH_HEX_64)->points; break;
+    case 3: points = BasisFactory::getNodalBasis(MSH_HEX_125)->points; break;
+    case 4: points = BasisFactory::getNodalBasis(MSH_HEX_216)->points; break;
+    case 5: points = BasisFactory::getNodalBasis(MSH_HEX_343)->points; break;
+    case 6: points = BasisFactory::getNodalBasis(MSH_HEX_512)->points; break;
+    case 7: points = BasisFactory::getNodalBasis(MSH_HEX_729)->points; break;
+    case 8: points = BasisFactory::getNodalBasis(MSH_HEX_1000)->points; break;
     default :
       Msg::Error("getRegionVertices not implemented for order %i", nPts+1);
       break;
@@ -635,13 +635,13 @@ static void getRegionVertices(GRegion *gr, MElement *incomplete, MElement *ele,
     switch (nPts){
     case 0:
     case 1: return;
-    case 2: points = BasisFactory::create(MSH_PYR_30)->points; break;
-    case 3: points = BasisFactory::create(MSH_PYR_55)->points; break;
-    case 4: points = BasisFactory::create(MSH_PYR_91)->points; break;
-    case 5: points = BasisFactory::create(MSH_PYR_140)->points; break;
-    case 6: points = BasisFactory::create(MSH_PYR_204)->points; break;
-    case 7: points = BasisFactory::create(MSH_PYR_285)->points; break;
-    case 8: points = BasisFactory::create(MSH_PYR_385)->points; break;
+    case 2: points = BasisFactory::getNodalBasis(MSH_PYR_30)->points; break;
+    case 3: points = BasisFactory::getNodalBasis(MSH_PYR_55)->points; break;
+    case 4: points = BasisFactory::getNodalBasis(MSH_PYR_91)->points; break;
+    case 5: points = BasisFactory::getNodalBasis(MSH_PYR_140)->points; break;
+    case 6: points = BasisFactory::getNodalBasis(MSH_PYR_204)->points; break;
+    case 7: points = BasisFactory::getNodalBasis(MSH_PYR_285)->points; break;
+    case 8: points = BasisFactory::getNodalBasis(MSH_PYR_385)->points; break;
     default :
       Msg::Error("getRegionVertices not implemented for order %i", nPts+1);
       break;
diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h
index 486f70f366..94c7cc8f61 100644
--- a/Mesh/meshGFaceRecombine.h
+++ b/Mesh/meshGFaceRecombine.h
@@ -416,7 +416,7 @@ class Rec2DChange {
     void *_info;
   
   public :
-    Rec2DChange() {Msg::Error("[Rec2DChange] I should not be created in this manner");}
+    Rec2DChange() {Msg::Fatal("[Rec2DChange] I should not be created in this manner");}
     Rec2DChange(int);
     Rec2DChange(Rec2DEdge*, bool toHide = false);
     Rec2DChange(Rec2DVertex*, bool toHide = false);
diff --git a/Numeric/BasisFactory.cpp b/Numeric/BasisFactory.cpp
index 46adb2e19f..36730f5950 100644
--- a/Numeric/BasisFactory.cpp
+++ b/Numeric/BasisFactory.cpp
@@ -11,9 +11,11 @@
 #include "BasisFactory.h"
 
 std::map<int, nodalBasis*> BasisFactory::fs;
+std::map<int, JacobianBasis*> BasisFactory::js;
+std::map<int, bezierBasis*> BasisFactory::bs;
 
-const nodalBasis* BasisFactory::create(int elementType) {
-
+const nodalBasis* BasisFactory::getNodalBasis(int elementType)
+{
   // If the Basis has already been built, return it.
   std::map<int, nodalBasis*>::const_iterator it = fs.find(elementType);
   if (it != fs.end()) {
@@ -22,7 +24,7 @@ const nodalBasis* BasisFactory::create(int elementType) {
   // Get the parent type to see which kind of basis
   // we want to create
   int parentType = MElement::ParentTypeFromTag(elementType);
-  nodalBasis* B = 0;
+  nodalBasis* F = NULL;
 
   switch(parentType) {
     case(TYPE_PNT):
@@ -32,19 +34,40 @@ const nodalBasis* BasisFactory::create(int elementType) {
     case(TYPE_PRI):
     case(TYPE_TET):
     case(TYPE_HEX):
-      B = new polynomialBasis(elementType);
+      F = new polynomialBasis(elementType);
       break;
     case(TYPE_PYR):
-      B = new pyramidalBasis(elementType);
+      F = new pyramidalBasis(elementType);
       break;
     default:
       Msg::Error("Unknown type of element.");
-      return 0;
+      return NULL;
   }
 
   // FIXME: check if already exists to deallocate if necessary
-  fs.insert(std::make_pair(elementType, B));
+  fs.insert(std::make_pair(elementType, F));
 
   return fs[elementType];
+}
+
+const bezierBasis* BasisFactory::getBezierBasis(int elementType)
+{
+  std::map<int, bezierBasis*>::const_iterator it = bs.find(elementType);
+  if (it != bs.end())
+    return it->second;
+
+  bezierBasis* B = new bezierBasis(elementType);
+  if (B) bs.insert(std::make_pair(elementType, B));
+  return B;
+}
+
+const JacobianBasis* BasisFactory::getJacobianBasis(int elementType)
+{
+  std::map<int, JacobianBasis*>::const_iterator it = js.find(elementType);
+  if (it != js.end())
+    return it->second;
 
+  JacobianBasis* J = new JacobianBasis(elementType);
+  if (J) js.insert(std::make_pair(elementType, J));
+  return J;
 }
diff --git a/Numeric/BasisFactory.h b/Numeric/BasisFactory.h
index 7932c3eae3..af4f6d7e98 100644
--- a/Numeric/BasisFactory.h
+++ b/Numeric/BasisFactory.h
@@ -9,16 +9,21 @@
 #include "MElement.h"
 #include "MPyramid.h"
 #include "nodalBasis.h"
+#include "JacobianBasis.h"
+
 
 class BasisFactory
 {
   private:
     static std::map<int, nodalBasis*> fs;
+    static std::map<int, bezierBasis*> bs;
+    static std::map<int, JacobianBasis*> js;
 
   public:
-    // Caution: the returned pointer should be
-    // checked against 0.
-    static const nodalBasis* create(int elementType);
+    // Caution: the returned pointer can be NULL
+    static const nodalBasis* getNodalBasis(int elementType);
+    static const bezierBasis* getBezierBasis(int elementType);
+    static const JacobianBasis* getJacobianBasis(int elementType);
 };
 
 #endif
diff --git a/Numeric/CMakeLists.txt b/Numeric/CMakeLists.txt
index 0931e65645..231bfe602c 100644
--- a/Numeric/CMakeLists.txt
+++ b/Numeric/CMakeLists.txt
@@ -8,12 +8,13 @@ set(SRC
     fullMatrix.cpp
   BasisFactory.cpp
     nodalBasis.cpp
-    polynomialBasis.cpp
+	polynomialBasis.cpp
+	pyramidalBasis.cpp
+	BergotBasis.cpp
+	jacobiPolynomials.cpp
+	legendrePolynomials.cpp
+    bezierBasis.cpp
     JacobianBasis.cpp
-    BergotBasis.cpp
-    pyramidalBasis.cpp
-    jacobiPolynomials.cpp
-    legendrePolynomials.cpp
   pointsGenerators.cpp
   GaussIntegration.cpp
     GaussQuadratureLin.cpp
diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp
index 8ac87aa574..4b4e661032 100644
--- a/Numeric/JacobianBasis.cpp
+++ b/Numeric/JacobianBasis.cpp
@@ -5,7 +5,7 @@
 
 #include "GmshDefines.h"
 #include "GmshMessage.h"
-#include "JacobianBasis.h"
+
 #include <vector>
 #include "polynomialBasis.h"
 #include "pyramidalBasis.h"
@@ -13,1068 +13,6 @@
 #include "BasisFactory.h"
 #include "Numeric.h"
 
-// Bezier Exponents
-static fullMatrix<double> generate1DExponents(int order)
-{
-  fullMatrix<double> exponents(order + 1, 1);
-  exponents(0, 0) = 0;
-  if (order > 0) {
-    exponents(1, 0) = order;
-    for (int i = 2; i < order + 1; i++) exponents(i, 0) = i - 1;
-  }
-
-  return exponents;
-}
-
-static fullMatrix<double> generateExponentsTriangle(int order)
-{
-  int nbPoints = (order + 1) * (order + 2) / 2;
-  fullMatrix<double> exponents(nbPoints, 2);
-
-  exponents(0, 0) = 0;
-  exponents(0, 1) = 0;
-
-  if (order > 0) {
-    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++;
-        exponents(index, 0) = ksi;
-        exponents(index, 1) = eta;
-      }
-
-      ksi = order;
-
-      for (int i = 0; i < order - 1; i++, index++) {
-        ksi--;
-        eta++;
-        exponents(index, 0) = ksi;
-        exponents(index, 1) = eta;
-      }
-
-      eta = order;
-      ksi = 0;
-
-      for (int i = 0; i < order - 1; i++, index++) {
-        eta--;
-        exponents(index, 0) = ksi;
-        exponents(index, 1) = eta;
-      }
-
-      if (order > 2) {
-        fullMatrix<double> inner = generateExponentsTriangle(order - 3);
-        inner.add(1);
-        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
-      }
-    }
-  }
-
-  return exponents;
-}
-static fullMatrix<double> generateExponentsQuad(int order)
-{
-  int nbPoints = (order+1)*(order+1);
-  fullMatrix<double> exponents(nbPoints, 2);
-
-  exponents(0, 0) = 0;
-  exponents(0, 1) = 0;
-
-  if (order > 0) {
-    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;
-      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++) {
-          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 = generateExponentsQuad(order - 2);
-        inner.add(1);
-        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
-      }
-    }
-  }
-
-  //  exponents.print("expq");
-
-  return exponents;
-}
-static int nbdoftriangle(int order) { return (order + 1) * (order + 2) / 2; }
-
-static void nodepositionface0(int order, double *u, double *v, double *w)
-{ // uv surface - orientation v0-v2-v1
-  int ndofT = nbdoftriangle(order);
-  if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
-
-  u[0]= 0.;    v[0]= 0.;    w[0] = 0.;
-  u[1]= 0.;    v[1]= order; w[1] = 0.;
-  u[2]= order; v[2]= 0.;    w[2] = 0.;
-
-  // edges
-  for (int k = 0; k < (order - 1); k++){
-    u[3 + k] = 0.;
-    v[3 + k] = k + 1;
-    w[3 + k] = 0.;
-
-    u[3 + order - 1 + k] = k + 1;
-    v[3 + order - 1 + k] = order - 1 - k ;
-    w[3 + order - 1 + k] = 0.;
-
-    u[3 + 2 * (order - 1) + k] = order - 1 - k;
-    v[3 + 2 * (order - 1) + k] = 0.;
-    w[3 + 2 * (order - 1) + k] = 0.;
-  }
-
-  if (order > 2){
-    int nbdoftemp = nbdoftriangle(order - 3);
-    nodepositionface0(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
-                      &w[3 + 3* (order - 1)]);
-    for (int k = 0; k < nbdoftemp; k++){
-      u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-      v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-      w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3);
-    }
-  }
-  for (int k = 0; k < ndofT; k++){
-    u[k] = u[k] / order;
-    v[k] = v[k] / order;
-    w[k] = w[k] / order;
-  }
-}
-
-static void nodepositionface1(int order, double *u, double *v, double *w)
-{ // uw surface - orientation v0-v1-v3
-  int ndofT = nbdoftriangle(order);
-  if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
-
-  u[0] = 0.;    v[0]= 0.;  w[0] = 0.;
-  u[1] = order; v[1]= 0.;  w[1] = 0.;
-  u[2] = 0.;    v[2]= 0.;  w[2] = order;
-  // edges
-  for (int k = 0; k < (order - 1); k++){
-    u[3 + k] = k + 1;
-    v[3 + k] = 0.;
-    w[3 + k] = 0.;
-
-    u[3 + order - 1 + k] = order - 1 - k;
-    v[3 + order - 1 + k] = 0.;
-    w[3 + order - 1+ k ] = k + 1;
-
-    u[3 + 2 * (order - 1) + k] = 0. ;
-    v[3 + 2 * (order - 1) + k] = 0.;
-    w[3 + 2 * (order - 1) + k] = order - 1 - k;
-  }
-  if (order > 2){
-    int nbdoftemp = nbdoftriangle(order - 3);
-    nodepositionface1(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order -1 )],
-      &w[3 + 3 * (order - 1)]);
-    for (int k = 0; k < nbdoftemp; k++){
-      u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-      v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3);
-      w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-    }
-  }
-  for (int k = 0; k < ndofT; k++){
-    u[k] = u[k] / order;
-    v[k] = v[k] / order;
-    w[k] = w[k] / order;
-  }
-}
-
-static void nodepositionface2(int order, double *u, double *v, double *w)
-{ // vw surface - orientation v0-v3-v2
-   int ndofT = nbdoftriangle(order);
-   if (order == 0) { u[0] = 0.; v[0] = 0.; return; }
-
-   u[0]= 0.; v[0]= 0.;    w[0] = 0.;
-   u[1]= 0.; v[1]= 0.;    w[1] = order;
-   u[2]= 0.; v[2]= order; w[2] = 0.;
-   // edges
-   for (int k = 0; k < (order - 1); k++){
-
-     u[3 + k] = 0.;
-     v[3 + k] = 0.;
-     w[3 + k] = k + 1;
-
-     u[3 + order - 1 + k] = 0.;
-     v[3 + order - 1 + k] = k + 1;
-     w[3 + order - 1 + k] = order - 1 - k;
-
-     u[3 + 2 * (order - 1) + k] = 0.;
-     v[3 + 2 * (order - 1) + k] = order - 1 - k;
-     w[3 + 2 * (order - 1) + k] = 0.;
-   }
-   if (order > 2){
-     int nbdoftemp = nbdoftriangle(order - 3);
-     nodepositionface2(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
-                       &w[3 + 3 * (order - 1)]);
-     for (int k = 0; k < nbdoftemp; k++){
-       u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3);
-       v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-       w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-     }
-   }
-   for (int k = 0; k < ndofT; k++){
-     u[k] = u[k] / order;
-     v[k] = v[k] / order;
-     w[k] = w[k] / order;
-   }
-}
-
-static void nodepositionface3(int order,  double *u,  double *v,  double *w)
-{ // uvw surface  - orientation v3-v1-v2
-   int ndofT = nbdoftriangle(order);
-   if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
-
-   u[0]= 0.;    v[0]= 0.;    w[0] = order;
-   u[1]= order; v[1]= 0.;    w[1] = 0.;
-   u[2]= 0.;    v[2]= order; w[2] = 0.;
-   // edges
-   for (int k = 0; k < (order - 1); k++){
-
-     u[3 + k] = k + 1;
-     v[3 + k] = 0.;
-     w[3 + k] = order - 1 - k;
-
-     u[3 + order - 1 + k] = order - 1 - k;
-     v[3 + order - 1 + k] = k + 1;
-     w[3 + order - 1 + k] = 0.;
-
-     u[3 + 2 * (order - 1) + k] = 0.;
-     v[3 + 2 * (order - 1) + k] = order - 1 - k;
-     w[3 + 2 * (order - 1) + k] = k + 1;
-   }
-   if (order > 2){
-     int nbdoftemp = nbdoftriangle(order - 3);
-     nodepositionface3(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
-                       &w[3 + 3 * (order - 1)]);
-     for (int k = 0; k < nbdoftemp; k++){
-       u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-       v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-       w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
-     }
-   }
-   for (int k = 0; k < ndofT; k++){
-     u[k] = u[k] / order;
-     v[k] = v[k] / order;
-     w[k] = w[k] / order;
-   }
-}
-
-static fullMatrix<double> generateExponentsTetrahedron(int order)
-{
-  int nbPoints = (order + 1) * (order + 2) * (order + 3) / 6;
-
-  fullMatrix<double> exponents(nbPoints, 3);
-
-  exponents(0, 0) = 0;
-  exponents(0, 1) = 0;
-  exponents(0, 2) = 0;
-
-  if (order > 0) {
-    exponents(1, 0) = order;
-    exponents(1, 1) = 0;
-    exponents(1, 2) = 0;
-
-    exponents(2, 0) = 0;
-    exponents(2, 1) = order;
-    exponents(2, 2) = 0;
-
-    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++) {
-        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) {
-        int ns = 4 + 6 * (order - 1);
-        int nbdofface = nbdoftriangle(order - 3);
-
-        double *u = new double[nbdofface];
-        double *v = new double[nbdofface];
-        double *w = new double[nbdofface];
-
-        nodepositionface0(order - 3, u, v, w);
-
-        // u-v plane
-
-        for (int i = 0; i < nbdofface; i++){
-          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;
-
-        // u-w plane
-
-        nodepositionface1(order - 3, u, v, w);
-
-        for (int i=0; i < nbdofface; i++){
-          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
-
-        ns = ns + nbdofface;
-
-        nodepositionface2(order - 3, u, v, w);
-
-        for (int i = 0; i < nbdofface; i++){
-          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
-
-        ns = ns + nbdofface;
-
-        nodepositionface3(order - 3, u, v, w);
-
-        for (int i = 0; i < nbdofface; i++){
-          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;
-
-        delete [] u;
-        delete [] v;
-        delete [] w;
-
-        if (order > 3) {
-
-          fullMatrix<double> interior = generateExponentsTetrahedron(order - 4);
-          for (int k = 0; k < interior.size1(); k++) {
-            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 exponents;
-}
-
-static fullMatrix<double> generateExponentsPrism(int order)
-{
-  int nbPoints = (order + 1)*(order + 1)*(order + 2)/2;
-  fullMatrix<double> exponents(nbPoints, 3);
-
-  int index = 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 ++;
-    }
-  }
-
-  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; j < 2; ++j) {
-      for (int k = 0; k < 2; ++k) {
-        exponents(index, 0) = lineExp(i, 0);
-        exponents(index, 1) = lineExp(j, 0);
-        exponents(index, 2) = lineExp(k, 0);
-        ++index;
-      }
-    }
-  }
-
-  for (int i = 2; i < lineExp.size1(); ++i) {
-    for (int j = 0; j < 2; ++j) {
-      for (int k = 0; k < 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; j < lineExp.size1(); ++j) {
-      for (int k = 0; k < 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; j < lineExp.size1(); ++j) {
-      for (int k = 2; k < lineExp.size1(); ++k) {
-        exponents(index, 0) = lineExp(i, 0);
-        exponents(index, 1) = lineExp(j, 0);
-        exponents(index, 2) = lineExp(k, 0);
-        ++index;
-      }
-    }
-  }
-
-  return exponents;
-}
-
-// Sampling Points
-static fullMatrix<double> generate1DPoints(int order)
-{
-  fullMatrix<double> line(order + 1, 1);
-  line(0,0) = .0;
-  if (order > 0) {
-    line(1, 0) = 1.;
-    double dd = 1. / order;
-    for (int i = 2; i < order + 1; i++) line(i, 0) = dd * (i - 1);
-  }
-
-  return line;
-}
-
-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> generatePointsPrism(int order, bool serendip)
-{
-  const double prism18Pts[18][3] = {
-    {0, 0, 0}, // 0
-    {1, 0, 0}, // 1
-    {0, 1, 0}, // 2
-    {0, 0, 1},  // 3
-    {1, 0, 1},  // 4
-    {0, 1, 1},  // 5
-    {.5, 0, 0},  // 6
-    {0, .5, 0},  // 7
-    {0, 0, .5},  // 8
-    {.5, .5, 0},  // 9
-    {1, 0, .5},  // 10
-    {0, 1, .5},  // 11
-    {.5, 0, 1},  // 12
-    {0, .5, 1},  // 13
-    {.5, .5, 1},  // 14
-    {.5, 0, .5},  // 15
-    {0, .5, .5},  // 16
-    {.5, .5, .5},  // 17
-  };
-
-  int nbPoints = (order + 1)*(order + 1)*(order + 2)/2;
-  fullMatrix<double> point(nbPoints, 3);
-
-  int index = 0;
-
-  if (order == 2)
-    for (int i =0; i<18; i++)
-      for (int j=0; j<3;j++)
-        point(i,j) = prism18Pts[i][j];
-  else {
-    fullMatrix<double> triPoints = gmshGeneratePointsTriangle(order,false);
-    fullMatrix<double> linePoints = generate1DPoints(order);
-    for (int j = 0; j <linePoints.size1() ; j++) {
-      for (int i = 0; i < triPoints.size1(); i++) {
-        point(index,0) = triPoints(i,0);
-        point(index,1) = triPoints(i,1);
-        point(index,2) = linePoints(j,0);
-        index ++;
-      }
-    }
-  }
-  return point;
-}
-
-static fullMatrix<double> generatePointsHex(int order, bool serendip)
-{
-  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;
-      }
-    }
-  }
-
-  return point;
-}
-
-// Sub Control Points
-static std::vector< fullMatrix<double> > generateSubPointsLine(int order)
-{
-  std::vector< fullMatrix<double> > subPoints(2);
-
-  subPoints[0] = generate1DPoints(order);
-  subPoints[0].scale(.5);
-
-  subPoints[1].copy(subPoints[0]);
-  subPoints[1].add(.5);
-
-  return subPoints;
-}
-
-static std::vector< fullMatrix<double> > generateSubPointsTriangle(int order)
-{
-  std::vector< fullMatrix<double> > subPoints(4);
-  fullMatrix<double> prox;
-
-  subPoints[0] = gmshGeneratePointsTriangle(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[0]);
-  subPoints[3].scale(-1.);
-  subPoints[3].add(.5);
-
-  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);
-  fullMatrix<double> prox1;
-  fullMatrix<double> prox2;
-
-  subPoints[0] = gmshGeneratePointsTetrahedron(order, false);
-  subPoints[0].scale(.5);
-
-  subPoints[1].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[1], 0, 1);
-  prox1.add(.5);
-
-  subPoints[2].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[2], 1, 1);
-  prox1.add(.5);
-
-  subPoints[3].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[3], 2, 1);
-  prox1.add(.5);
-
-  // u := .5-u-w
-  // v := .5-v-w
-  // w := w
-  subPoints[4].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[4], 0, 2);
-  prox1.scale(-1.);
-  prox1.add(.5);
-  prox1.setAsProxy(subPoints[4], 0, 1);
-  prox2.setAsProxy(subPoints[4], 2, 1);
-  prox1.add(prox2, -1.);
-  prox1.setAsProxy(subPoints[4], 1, 1);
-  prox1.add(prox2, -1.);
-
-  // u := u
-  // v := .5-v
-  // w := w+v
-  subPoints[5].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[5], 2, 1);
-  prox2.setAsProxy(subPoints[5], 1, 1);
-  prox1.add(prox2);
-  prox2.scale(-1.);
-  prox2.add(.5);
-
-  // u := .5-u
-  // v := v
-  // w := w+u
-  subPoints[6].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[6], 2, 1);
-  prox2.setAsProxy(subPoints[6], 0, 1);
-  prox1.add(prox2);
-  prox2.scale(-1.);
-  prox2.add(.5);
-
-  // u := u+w
-  // v := v+w
-  // w := .5-w
-  subPoints[7].copy(subPoints[0]);
-  prox1.setAsProxy(subPoints[7], 0, 1);
-  prox2.setAsProxy(subPoints[7], 2, 1);
-  prox1.add(prox2);
-  prox1.setAsProxy(subPoints[7], 1, 1);
-  prox1.add(prox2);
-  prox2.scale(-1.);
-  prox2.add(.5);
-
-
-  return subPoints;
-}
-
-static std::vector< fullMatrix<double> > generateSubPointsPrism(int order)
-{
-  std::vector< fullMatrix<double> > subPoints(8);
-  fullMatrix<double> prox;
-
-  subPoints[0] = generatePointsPrism(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[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> > generateSubPointsHex(int order)
-{
-  std::vector< fullMatrix<double> > subPoints(8);
-  fullMatrix<double> prox;
-
-  subPoints[0] = generatePointsHex(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);
-
-  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;
-}
-
-// Matrices generation
-static int nChoosek(int n, int k)
-{
-  if (n < k || k < 0) {
-    Msg::Error("Wrong argument for combination.");
-    return 1;
-  }
-
-  if (k > n/2) k = n-k;
-  if (k == 1)
-    return n;
-  if (k == 0)
-    return 1;
-
-  int c = 1;
-  for (int i = 1; i <= k; i++, n--) (c *= n) /= i;
-  return c;
-}
-
-
-static fullMatrix<double> generateBez2LagMatrix
-  (const fullMatrix<double> &exponent, const fullMatrix<double> &point,
-   int order, int dimSimplex)
-{
-
-  if(exponent.size1() != point.size1() || exponent.size2() != point.size2()){
-    Msg::Fatal("Wrong sizes for Bezier coefficients generation %d %d -- %d %d",
-      exponent.size1(),point.size1(),
-      exponent.size2(),point.size2());
-    return fullMatrix<double>(1, 1);
-  }
-
-  int ndofs = exponent.size1();
-  int dim = exponent.size2();
-
-  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 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);
-      }
-
-      for (int k = dimSimplex; k < dim; k++)
-        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 bez2Lag;
-}
-
-
-
-static fullMatrix<double> generateSubDivisor
-  (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints,
-   const fullMatrix<double> &lag2Bez, int order, int dimSimplex)
-{
-  if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){
-    Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d",
-      exponents.size1(), lag2Bez.size1(),
-      exponents.size1(), lag2Bez.size2());
-    return fullMatrix<double>(1, 1);
-  }
-
-  int nbPts = lag2Bez.size1();
-  int nbSubPts = nbPts * subPoints.size();
-
-  fullMatrix<double> intermediate2(nbPts, nbPts);
-  fullMatrix<double> subDivisor(nbSubPts, nbPts);
-
-  for (unsigned int i = 0; i < subPoints.size(); i++) {
-    fullMatrix<double> intermediate1 =
-      generateBez2LagMatrix(exponents, subPoints[i], order, dimSimplex);
-    lag2Bez.mult(intermediate1, intermediate2);
-    subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0);
-  }
-  return subDivisor;
-}
-
-
-
-// Convert Bezier points to Lagrange points
-static fullMatrix<double> bez2LagPoints(bool dim1, bool dim2, bool dim3, const fullMatrix<double> &bezierPoints)
-{
-
-  // FIXME BUG for 2nd order quads we seem to try to access bezierPoints(i, 2);
-  // but bezierPoints only has 2 columns
-
-  const int numPt = bezierPoints.size1();
-  fullMatrix<double> lagPoints(numPt,3);
-
-  for (int i=0; i<numPt; i++) {
-    lagPoints(i,0) = dim1 ? -1. + 2*bezierPoints(i,0) : bezierPoints(i,0);
-    lagPoints(i,1) = dim2 ? -1. + 2*bezierPoints(i,1) : bezierPoints(i,1);
-    lagPoints(i,2) = dim3 ? -1. + 2*bezierPoints(i,2) : bezierPoints(i,2);
-  }
-
-  return lagPoints;
-
-}
-
-
-
-std::map<int, bezierBasis> bezierBasis::_bbs;
-const bezierBasis *bezierBasis::find(int tag)
-{
-  std::map<int, bezierBasis>::const_iterator it = _bbs.find(tag);
-  if (it != _bbs.end())
-    return &it->second;
-
-  bezierBasis &B = _bbs[tag];
-  B.order = MElement::OrderFromTag(tag);
-
-  if (MElement::ParentTypeFromTag(tag) == TYPE_PYR) {
-    B.dim = 3;
-    B.numLagPts = 5;
-    B.bezierPoints = gmshGeneratePointsPyramid(B.order,false);
-    B.lagPoints = B.bezierPoints;
-    B.matrixLag2Bez.resize(B.bezierPoints.size1(),B.bezierPoints.size1(),0.);
-    B.matrixBez2Lag.resize(B.bezierPoints.size1(),B.bezierPoints.size1(),0.);
-    for (int i=0; i<B.matrixBez2Lag.size1(); ++i) {
-      B.matrixLag2Bez(i,i) = 1.;
-      B.matrixBez2Lag(i,i) = 1.;
-    }
-    // TODO: Implement subdidivsor
-  }
-  else {
-    int dimSimplex;
-    std::vector< fullMatrix<double> > subPoints;
-    switch (MElement::ParentTypeFromTag(tag)) {
-      case TYPE_PNT :
-        B.dim = 0;
-        B.numLagPts = 1;
-        B.exponents = generate1DExponents(0);
-        B.bezierPoints = generate1DPoints(0);
-        B.lagPoints = B.bezierPoints;
-        dimSimplex = 0;
-        break;
-      case TYPE_LIN : {
-        B.dim = 1;
-        B.numLagPts = 2;
-        B.exponents = generate1DExponents(B.order);
-        B.bezierPoints = generate1DPoints(B.order);
-        B.lagPoints = bez2LagPoints(true,false,false,B.bezierPoints);
-        dimSimplex = 0;
-        subPoints = generateSubPointsLine(0);
-        break;
-      }
-      case TYPE_TRI : {
-        B.dim = 2;
-        B.numLagPts = 3;
-        B.exponents = generateExponentsTriangle(B.order);
-        B.bezierPoints = gmshGeneratePointsTriangle(B.order,false);
-        B.lagPoints = B.bezierPoints;
-        dimSimplex = 2;
-        subPoints = generateSubPointsTriangle(B.order);
-        break;
-      }
-      case TYPE_QUA : {
-        B.dim = 2;
-        B.numLagPts = 4;
-        B.exponents = generateExponentsQuad(B.order);
-        B.bezierPoints = generatePointsQuad(B.order,false);
-        B.lagPoints = bez2LagPoints(true,true,false,B.bezierPoints);
-        dimSimplex = 0;
-        subPoints = generateSubPointsQuad(B.order);
-        //      B.points.print("points");
-        break;
-      }
-      case TYPE_TET : {
-        B.dim = 3;
-        B.numLagPts = 4;
-        B.exponents = generateExponentsTetrahedron(B.order);
-        B.bezierPoints = gmshGeneratePointsTetrahedron(B.order,false);
-        B.lagPoints = B.bezierPoints;
-        dimSimplex = 3;
-        subPoints = generateSubPointsTetrahedron(B.order);
-        break;
-      }
-      case TYPE_PRI : {
-        B.dim = 3;
-        B.numLagPts = 6;
-        B.exponents = generateExponentsPrism(B.order);
-        B.bezierPoints = generatePointsPrism(B.order, false);
-        B.lagPoints = bez2LagPoints(false,false,true,B.bezierPoints);
-        dimSimplex = 2;
-        subPoints = generateSubPointsPrism(B.order);
-        break;
-      }
-      case TYPE_HEX : {
-        B.dim = 3;
-        B.numLagPts = 8;
-        B.exponents = generateExponentsHex(B.order);
-        B.bezierPoints = generatePointsHex(B.order, false);
-        B.lagPoints = bez2LagPoints(true,true,true,B.bezierPoints);
-        dimSimplex = 0;
-        subPoints = generateSubPointsHex(B.order);
-        break;
-      }
-      default : {
-        Msg::Error("Unknown function space %d: reverting to TET_1", tag);
-        B.dim = 3;
-        B.numLagPts = 4;
-        B.exponents = generateExponentsTetrahedron(0);
-        B.bezierPoints = gmshGeneratePointsTetrahedron(0, false);
-        B.lagPoints = B.bezierPoints;
-        dimSimplex = 3;
-        subPoints = generateSubPointsTetrahedron(0);
-        break;
-      }
-    }
-    B.matrixBez2Lag = generateBez2LagMatrix(B.exponents, B.bezierPoints, B.order, dimSimplex);
-    B.matrixBez2Lag.invert(B.matrixLag2Bez);
-    B.subDivisor = generateSubDivisor(B.exponents, subPoints, B.matrixLag2Bez, B.order, dimSimplex);
-    B.numDivisions = (int) pow(2., (int) B.bezierPoints.size2());
-  }
-
-  return &B;
-}
-
-
 
 JacobianBasis::JacobianBasis(int tag)
 {
@@ -1113,10 +51,10 @@ JacobianBasis::JacobianBasis(int tag)
   }
 
   // Store Bezier basis
-  bezier = bezierBasis::find(jacType);
+  bezier = BasisFactory::getBezierBasis(jacType);
 
   // Store shape function gradients of mapping at Jacobian nodes
-  const nodalBasis *mapBasis = BasisFactory::create(tag);
+  const nodalBasis *mapBasis = BasisFactory::getNodalBasis(tag);
   fullMatrix<double> allDPsi;
   mapBasis->df(getPoints(), allDPsi);
   numJacNodes = getPoints().size1();
@@ -1132,7 +70,7 @@ JacobianBasis::JacobianBasis(int tag)
     }
 
   // Compute matrix for lifting from primary Jacobian basis to Jacobian basis
-  const nodalBasis *primJacBasis = BasisFactory::create(primJacType);
+  const nodalBasis *primJacBasis = BasisFactory::getNodalBasis(primJacType);
   numPrimJacNodes = primJacBasis->getNumShapeFunctions();
   matrixPrimJac2Jac.resize(numJacNodes,numPrimJacNodes);
   primJacBasis->f(getPoints(),matrixPrimJac2Jac);
@@ -1140,7 +78,7 @@ JacobianBasis::JacobianBasis(int tag)
   // Compute shape function gradients of primary mapping at barycenter,
   // in order to compute normal to straight element
   const int primMapType = polynomialBasis::getTag(parentType, 1, false);
-  const nodalBasis *primMapBasis = BasisFactory::create(primMapType);
+  const nodalBasis *primMapBasis = BasisFactory::getNodalBasis(primMapType);
   numPrimMapNodes = primMapBasis->getNumShapeFunctions();
   double xBar = 0., yBar = 0., zBar = 0.;
   for (int i=0; i<numPrimMapNodes; i++) {
@@ -1168,21 +106,6 @@ JacobianBasis::JacobianBasis(int tag)
 
 
 
-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()) return it->second;
-
-  JacobianBasis *B = new JacobianBasis(tag);
-  _fs.insert(std::make_pair(tag, B));
-  return B;
-
-}
-
-
-
 // Computes (unit) normals to straight line element at barycenter (with norm of gradient as return value)
 double JacobianBasis::getPrimNormals1D(const fullMatrix<double> &nodesXYZ, fullMatrix<double> &result) const
 {
diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h
index 8901c1d9a5..2e8f52b23c 100644
--- a/Numeric/JacobianBasis.h
+++ b/Numeric/JacobianBasis.h
@@ -8,28 +8,12 @@
 
 #include <map>
 #include <vector>
+#include "bezierBasis.h"
 #include "fullMatrix.h"
 
-class MElement;
-
-class bezierBasis {
- private :
-  static std::map<int, bezierBasis> _bbs;
- public :
-  int dim, order;
-  int numLagPts;
-  int numDivisions;
-  // the 'numLagPts' first exponents are related to 'Lagrangian' values
-  fullMatrix<double> exponents; // exponents of Bezier FF
-  fullMatrix<double> bezierPoints, lagPoints; // sampling point
-  fullMatrix<double> matrixLag2Bez, matrixBez2Lag;
-  fullMatrix<double> subDivisor;
-  static const bezierBasis *find(int);
-};
 
 class JacobianBasis {
  private:
-  static std::map<int, JacobianBasis*> _fs;
   const bezierBasis *bezier;
   fullMatrix<double> gradShapeMatX, gradShapeMatY, gradShapeMatZ;
   fullVector<double> primGradShapeBarX, primGradShapeBarY, primGradShapeBarZ;
@@ -37,7 +21,6 @@ class JacobianBasis {
   int numJacNodes, numMapNodes, numPrimJacNodes, numPrimMapNodes;
   inline const fullMatrix<double> &getPoints() const { return bezier->lagPoints; }
  public :
-  static const JacobianBasis *find(int);
   JacobianBasis(int tag);
   inline int getNumJacNodes() const { return numJacNodes; }
   inline int getNumMapNodes() const { return numMapNodes; }
diff --git a/Numeric/bezierBasis.cpp b/Numeric/bezierBasis.cpp
new file mode 100644
index 0000000000..9f0592dc93
--- /dev/null
+++ b/Numeric/bezierBasis.cpp
@@ -0,0 +1,1069 @@
+// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+
+#include "GmshDefines.h"
+#include "GmshMessage.h"
+#include <vector>
+#include "polynomialBasis.h"
+#include "pyramidalBasis.h"
+#include "pointsGenerators.h"
+#include "BasisFactory.h"
+#include "Numeric.h"
+
+// Bezier Exponents
+static fullMatrix<double> generate1DExponents(int order)
+{
+  fullMatrix<double> exponents(order + 1, 1);
+  exponents(0, 0) = 0;
+  if (order > 0) {
+    exponents(1, 0) = order;
+    for (int i = 2; i < order + 1; i++) exponents(i, 0) = i - 1;
+  }
+
+  return exponents;
+}
+
+static fullMatrix<double> generateExponentsTriangle(int order)
+{
+  int nbPoints = (order + 1) * (order + 2) / 2;
+  fullMatrix<double> exponents(nbPoints, 2);
+
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
+
+  if (order > 0) {
+    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++;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
+      }
+
+      ksi = order;
+
+      for (int i = 0; i < order - 1; i++, index++) {
+        ksi--;
+        eta++;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
+      }
+
+      eta = order;
+      ksi = 0;
+
+      for (int i = 0; i < order - 1; i++, index++) {
+        eta--;
+        exponents(index, 0) = ksi;
+        exponents(index, 1) = eta;
+      }
+
+      if (order > 2) {
+        fullMatrix<double> inner = generateExponentsTriangle(order - 3);
+        inner.add(1);
+        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+      }
+    }
+  }
+
+  return exponents;
+}
+static fullMatrix<double> generateExponentsQuad(int order)
+{
+  int nbPoints = (order+1)*(order+1);
+  fullMatrix<double> exponents(nbPoints, 2);
+
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
+
+  if (order > 0) {
+    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;
+      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++) {
+          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 = generateExponentsQuad(order - 2);
+        inner.add(1);
+        exponents.copy(inner, 0, nbPoints - index, 0, 2, index, 0);
+      }
+    }
+  }
+
+  //  exponents.print("expq");
+
+  return exponents;
+}
+static int nbdoftriangle(int order) { return (order + 1) * (order + 2) / 2; }
+
+static void nodepositionface0(int order, double *u, double *v, double *w)
+{ // uv surface - orientation v0-v2-v1
+  int ndofT = nbdoftriangle(order);
+  if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
+
+  u[0]= 0.;    v[0]= 0.;    w[0] = 0.;
+  u[1]= 0.;    v[1]= order; w[1] = 0.;
+  u[2]= order; v[2]= 0.;    w[2] = 0.;
+
+  // edges
+  for (int k = 0; k < (order - 1); k++){
+    u[3 + k] = 0.;
+    v[3 + k] = k + 1;
+    w[3 + k] = 0.;
+
+    u[3 + order - 1 + k] = k + 1;
+    v[3 + order - 1 + k] = order - 1 - k ;
+    w[3 + order - 1 + k] = 0.;
+
+    u[3 + 2 * (order - 1) + k] = order - 1 - k;
+    v[3 + 2 * (order - 1) + k] = 0.;
+    w[3 + 2 * (order - 1) + k] = 0.;
+  }
+
+  if (order > 2){
+    int nbdoftemp = nbdoftriangle(order - 3);
+    nodepositionface0(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
+                      &w[3 + 3* (order - 1)]);
+    for (int k = 0; k < nbdoftemp; k++){
+      u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+      v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+      w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3);
+    }
+  }
+  for (int k = 0; k < ndofT; k++){
+    u[k] = u[k] / order;
+    v[k] = v[k] / order;
+    w[k] = w[k] / order;
+  }
+}
+
+static void nodepositionface1(int order, double *u, double *v, double *w)
+{ // uw surface - orientation v0-v1-v3
+  int ndofT = nbdoftriangle(order);
+  if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
+
+  u[0] = 0.;    v[0]= 0.;  w[0] = 0.;
+  u[1] = order; v[1]= 0.;  w[1] = 0.;
+  u[2] = 0.;    v[2]= 0.;  w[2] = order;
+  // edges
+  for (int k = 0; k < (order - 1); k++){
+    u[3 + k] = k + 1;
+    v[3 + k] = 0.;
+    w[3 + k] = 0.;
+
+    u[3 + order - 1 + k] = order - 1 - k;
+    v[3 + order - 1 + k] = 0.;
+    w[3 + order - 1+ k ] = k + 1;
+
+    u[3 + 2 * (order - 1) + k] = 0. ;
+    v[3 + 2 * (order - 1) + k] = 0.;
+    w[3 + 2 * (order - 1) + k] = order - 1 - k;
+  }
+  if (order > 2){
+    int nbdoftemp = nbdoftriangle(order - 3);
+    nodepositionface1(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order -1 )],
+      &w[3 + 3 * (order - 1)]);
+    for (int k = 0; k < nbdoftemp; k++){
+      u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+      v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3);
+      w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+    }
+  }
+  for (int k = 0; k < ndofT; k++){
+    u[k] = u[k] / order;
+    v[k] = v[k] / order;
+    w[k] = w[k] / order;
+  }
+}
+
+static void nodepositionface2(int order, double *u, double *v, double *w)
+{ // vw surface - orientation v0-v3-v2
+   int ndofT = nbdoftriangle(order);
+   if (order == 0) { u[0] = 0.; v[0] = 0.; return; }
+
+   u[0]= 0.; v[0]= 0.;    w[0] = 0.;
+   u[1]= 0.; v[1]= 0.;    w[1] = order;
+   u[2]= 0.; v[2]= order; w[2] = 0.;
+   // edges
+   for (int k = 0; k < (order - 1); k++){
+
+     u[3 + k] = 0.;
+     v[3 + k] = 0.;
+     w[3 + k] = k + 1;
+
+     u[3 + order - 1 + k] = 0.;
+     v[3 + order - 1 + k] = k + 1;
+     w[3 + order - 1 + k] = order - 1 - k;
+
+     u[3 + 2 * (order - 1) + k] = 0.;
+     v[3 + 2 * (order - 1) + k] = order - 1 - k;
+     w[3 + 2 * (order - 1) + k] = 0.;
+   }
+   if (order > 2){
+     int nbdoftemp = nbdoftriangle(order - 3);
+     nodepositionface2(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
+                       &w[3 + 3 * (order - 1)]);
+     for (int k = 0; k < nbdoftemp; k++){
+       u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3);
+       v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+       w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+     }
+   }
+   for (int k = 0; k < ndofT; k++){
+     u[k] = u[k] / order;
+     v[k] = v[k] / order;
+     w[k] = w[k] / order;
+   }
+}
+
+static void nodepositionface3(int order,  double *u,  double *v,  double *w)
+{ // uvw surface  - orientation v3-v1-v2
+   int ndofT = nbdoftriangle(order);
+   if (order == 0) { u[0] = 0.; v[0] = 0.; w[0] = 0.; return; }
+
+   u[0]= 0.;    v[0]= 0.;    w[0] = order;
+   u[1]= order; v[1]= 0.;    w[1] = 0.;
+   u[2]= 0.;    v[2]= order; w[2] = 0.;
+   // edges
+   for (int k = 0; k < (order - 1); k++){
+
+     u[3 + k] = k + 1;
+     v[3 + k] = 0.;
+     w[3 + k] = order - 1 - k;
+
+     u[3 + order - 1 + k] = order - 1 - k;
+     v[3 + order - 1 + k] = k + 1;
+     w[3 + order - 1 + k] = 0.;
+
+     u[3 + 2 * (order - 1) + k] = 0.;
+     v[3 + 2 * (order - 1) + k] = order - 1 - k;
+     w[3 + 2 * (order - 1) + k] = k + 1;
+   }
+   if (order > 2){
+     int nbdoftemp = nbdoftriangle(order - 3);
+     nodepositionface3(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)],
+                       &w[3 + 3 * (order - 1)]);
+     for (int k = 0; k < nbdoftemp; k++){
+       u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+       v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+       w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.;
+     }
+   }
+   for (int k = 0; k < ndofT; k++){
+     u[k] = u[k] / order;
+     v[k] = v[k] / order;
+     w[k] = w[k] / order;
+   }
+}
+
+static fullMatrix<double> generateExponentsTetrahedron(int order)
+{
+  int nbPoints = (order + 1) * (order + 2) * (order + 3) / 6;
+
+  fullMatrix<double> exponents(nbPoints, 3);
+
+  exponents(0, 0) = 0;
+  exponents(0, 1) = 0;
+  exponents(0, 2) = 0;
+
+  if (order > 0) {
+    exponents(1, 0) = order;
+    exponents(1, 1) = 0;
+    exponents(1, 2) = 0;
+
+    exponents(2, 0) = 0;
+    exponents(2, 1) = order;
+    exponents(2, 2) = 0;
+
+    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++) {
+        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) {
+        int ns = 4 + 6 * (order - 1);
+        int nbdofface = nbdoftriangle(order - 3);
+
+        double *u = new double[nbdofface];
+        double *v = new double[nbdofface];
+        double *w = new double[nbdofface];
+
+        nodepositionface0(order - 3, u, v, w);
+
+        // u-v plane
+
+        for (int i = 0; i < nbdofface; i++){
+          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;
+
+        // u-w plane
+
+        nodepositionface1(order - 3, u, v, w);
+
+        for (int i=0; i < nbdofface; i++){
+          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
+
+        ns = ns + nbdofface;
+
+        nodepositionface2(order - 3, u, v, w);
+
+        for (int i = 0; i < nbdofface; i++){
+          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
+
+        ns = ns + nbdofface;
+
+        nodepositionface3(order - 3, u, v, w);
+
+        for (int i = 0; i < nbdofface; i++){
+          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;
+
+        delete [] u;
+        delete [] v;
+        delete [] w;
+
+        if (order > 3) {
+
+          fullMatrix<double> interior = generateExponentsTetrahedron(order - 4);
+          for (int k = 0; k < interior.size1(); k++) {
+            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 exponents;
+}
+
+static fullMatrix<double> generateExponentsPrism(int order)
+{
+  int nbPoints = (order + 1)*(order + 1)*(order + 2)/2;
+  fullMatrix<double> exponents(nbPoints, 3);
+
+  int index = 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 ++;
+    }
+  }
+
+  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; j < 2; ++j) {
+      for (int k = 0; k < 2; ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
+      }
+    }
+  }
+
+  for (int i = 2; i < lineExp.size1(); ++i) {
+    for (int j = 0; j < 2; ++j) {
+      for (int k = 0; k < 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; j < lineExp.size1(); ++j) {
+      for (int k = 0; k < 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; j < lineExp.size1(); ++j) {
+      for (int k = 2; k < lineExp.size1(); ++k) {
+        exponents(index, 0) = lineExp(i, 0);
+        exponents(index, 1) = lineExp(j, 0);
+        exponents(index, 2) = lineExp(k, 0);
+        ++index;
+      }
+    }
+  }
+
+  return exponents;
+}
+
+// Sampling Points
+static fullMatrix<double> generate1DPoints(int order)
+{
+  fullMatrix<double> line(order + 1, 1);
+  line(0,0) = .0;
+  if (order > 0) {
+    line(1, 0) = 1.;
+    double dd = 1. / order;
+    for (int i = 2; i < order + 1; i++) line(i, 0) = dd * (i - 1);
+  }
+
+  return line;
+}
+
+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> generatePointsPrism(int order, bool serendip)
+{
+  const double prism18Pts[18][3] = {
+    {0, 0, 0}, // 0
+    {1, 0, 0}, // 1
+    {0, 1, 0}, // 2
+    {0, 0, 1},  // 3
+    {1, 0, 1},  // 4
+    {0, 1, 1},  // 5
+    {.5, 0, 0},  // 6
+    {0, .5, 0},  // 7
+    {0, 0, .5},  // 8
+    {.5, .5, 0},  // 9
+    {1, 0, .5},  // 10
+    {0, 1, .5},  // 11
+    {.5, 0, 1},  // 12
+    {0, .5, 1},  // 13
+    {.5, .5, 1},  // 14
+    {.5, 0, .5},  // 15
+    {0, .5, .5},  // 16
+    {.5, .5, .5},  // 17
+  };
+
+  int nbPoints = (order + 1)*(order + 1)*(order + 2)/2;
+  fullMatrix<double> point(nbPoints, 3);
+
+  int index = 0;
+
+  if (order == 2)
+    for (int i =0; i<18; i++)
+      for (int j=0; j<3;j++)
+        point(i,j) = prism18Pts[i][j];
+  else {
+    fullMatrix<double> triPoints = gmshGeneratePointsTriangle(order,false);
+    fullMatrix<double> linePoints = generate1DPoints(order);
+    for (int j = 0; j <linePoints.size1() ; j++) {
+      for (int i = 0; i < triPoints.size1(); i++) {
+        point(index,0) = triPoints(i,0);
+        point(index,1) = triPoints(i,1);
+        point(index,2) = linePoints(j,0);
+        index ++;
+      }
+    }
+  }
+  return point;
+}
+
+static fullMatrix<double> generatePointsHex(int order, bool serendip)
+{
+  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;
+      }
+    }
+  }
+
+  return point;
+}
+
+// Sub Control Points
+static std::vector< fullMatrix<double> > generateSubPointsLine(int order)
+{
+  std::vector< fullMatrix<double> > subPoints(2);
+
+  subPoints[0] = generate1DPoints(order);
+  subPoints[0].scale(.5);
+
+  subPoints[1].copy(subPoints[0]);
+  subPoints[1].add(.5);
+
+  return subPoints;
+}
+
+static std::vector< fullMatrix<double> > generateSubPointsTriangle(int order)
+{
+  std::vector< fullMatrix<double> > subPoints(4);
+  fullMatrix<double> prox;
+
+  subPoints[0] = gmshGeneratePointsTriangle(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[0]);
+  subPoints[3].scale(-1.);
+  subPoints[3].add(.5);
+
+  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);
+  fullMatrix<double> prox1;
+  fullMatrix<double> prox2;
+
+  subPoints[0] = gmshGeneratePointsTetrahedron(order, false);
+  subPoints[0].scale(.5);
+
+  subPoints[1].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[1], 0, 1);
+  prox1.add(.5);
+
+  subPoints[2].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[2], 1, 1);
+  prox1.add(.5);
+
+  subPoints[3].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[3], 2, 1);
+  prox1.add(.5);
+
+  // u := .5-u-w
+  // v := .5-v-w
+  // w := w
+  subPoints[4].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[4], 0, 2);
+  prox1.scale(-1.);
+  prox1.add(.5);
+  prox1.setAsProxy(subPoints[4], 0, 1);
+  prox2.setAsProxy(subPoints[4], 2, 1);
+  prox1.add(prox2, -1.);
+  prox1.setAsProxy(subPoints[4], 1, 1);
+  prox1.add(prox2, -1.);
+
+  // u := u
+  // v := .5-v
+  // w := w+v
+  subPoints[5].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[5], 2, 1);
+  prox2.setAsProxy(subPoints[5], 1, 1);
+  prox1.add(prox2);
+  prox2.scale(-1.);
+  prox2.add(.5);
+
+  // u := .5-u
+  // v := v
+  // w := w+u
+  subPoints[6].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[6], 2, 1);
+  prox2.setAsProxy(subPoints[6], 0, 1);
+  prox1.add(prox2);
+  prox2.scale(-1.);
+  prox2.add(.5);
+
+  // u := u+w
+  // v := v+w
+  // w := .5-w
+  subPoints[7].copy(subPoints[0]);
+  prox1.setAsProxy(subPoints[7], 0, 1);
+  prox2.setAsProxy(subPoints[7], 2, 1);
+  prox1.add(prox2);
+  prox1.setAsProxy(subPoints[7], 1, 1);
+  prox1.add(prox2);
+  prox2.scale(-1.);
+  prox2.add(.5);
+
+
+  return subPoints;
+}
+
+static std::vector< fullMatrix<double> > generateSubPointsPrism(int order)
+{
+  std::vector< fullMatrix<double> > subPoints(8);
+  fullMatrix<double> prox;
+
+  subPoints[0] = generatePointsPrism(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[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> > generateSubPointsHex(int order)
+{
+  std::vector< fullMatrix<double> > subPoints(8);
+  fullMatrix<double> prox;
+
+  subPoints[0] = generatePointsHex(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);
+
+  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;
+}
+
+// Matrices generation
+static int nChoosek(int n, int k)
+{
+  if (n < k || k < 0) {
+    Msg::Error("Wrong argument for combination.");
+    return 1;
+  }
+
+  if (k > n/2) k = n-k;
+  if (k == 1)
+    return n;
+  if (k == 0)
+    return 1;
+
+  int c = 1;
+  for (int i = 1; i <= k; i++, n--) (c *= n) /= i;
+  return c;
+}
+
+
+static fullMatrix<double> generateBez2LagMatrix
+  (const fullMatrix<double> &exponent, const fullMatrix<double> &point,
+   int order, int dimSimplex)
+{
+
+  if(exponent.size1() != point.size1() || exponent.size2() != point.size2()){
+    Msg::Fatal("Wrong sizes for Bezier coefficients generation %d %d -- %d %d",
+      exponent.size1(),point.size1(),
+      exponent.size2(),point.size2());
+    return fullMatrix<double>(1, 1);
+  }
+
+  int ndofs = exponent.size1();
+  int dim = exponent.size2();
+
+  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 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);
+      }
+
+      for (int k = dimSimplex; k < dim; k++)
+        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 bez2Lag;
+}
+
+
+
+static fullMatrix<double> generateSubDivisor
+  (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints,
+   const fullMatrix<double> &lag2Bez, int order, int dimSimplex)
+{
+  if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){
+    Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d",
+      exponents.size1(), lag2Bez.size1(),
+      exponents.size1(), lag2Bez.size2());
+    return fullMatrix<double>(1, 1);
+  }
+
+  int nbPts = lag2Bez.size1();
+  int nbSubPts = nbPts * subPoints.size();
+
+  fullMatrix<double> intermediate2(nbPts, nbPts);
+  fullMatrix<double> subDivisor(nbSubPts, nbPts);
+
+  for (unsigned int i = 0; i < subPoints.size(); i++) {
+    fullMatrix<double> intermediate1 =
+      generateBez2LagMatrix(exponents, subPoints[i], order, dimSimplex);
+    lag2Bez.mult(intermediate1, intermediate2);
+    subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0);
+  }
+  return subDivisor;
+}
+
+
+
+// Convert Bezier points to Lagrange points
+static fullMatrix<double> bez2LagPoints(bool dim1, bool dim2, bool dim3, const fullMatrix<double> &bezierPoints)
+{
+
+  // FIXME BUG for 2nd order quads we seem to try to access bezierPoints(i, 2);
+  // but bezierPoints only has 2 columns
+
+  const int numPt = bezierPoints.size1();
+  fullMatrix<double> lagPoints(numPt,3);
+
+  for (int i=0; i<numPt; i++) {
+    lagPoints(i,0) = dim1 ? -1. + 2*bezierPoints(i,0) : bezierPoints(i,0);
+    lagPoints(i,1) = dim2 ? -1. + 2*bezierPoints(i,1) : bezierPoints(i,1);
+    lagPoints(i,2) = dim3 ? -1. + 2*bezierPoints(i,2) : bezierPoints(i,2);
+  }
+
+  return lagPoints;
+
+}
+
+
+bezierBasis::bezierBasis(int tag)
+{
+  order = MElement::OrderFromTag(tag);
+
+  if (MElement::ParentTypeFromTag(tag) == TYPE_PYR) {
+    dim = 3;
+    numLagPts = 5;
+    bezierPoints = gmshGeneratePointsPyramid(order,false);
+    lagPoints = bezierPoints;
+    matrixLag2Bez.resize(bezierPoints.size1(), bezierPoints.size1(), false);
+    matrixBez2Lag.resize(bezierPoints.size1(), bezierPoints.size1(), false);
+    for (int i=0; i<matrixBez2Lag.size1(); ++i) {
+      matrixLag2Bez(i,i) = 1.;
+      matrixBez2Lag(i,i) = 1.;
+    }
+    // TODO: Implement subdidivsor
+  }
+  else {
+    int dimSimplex;
+    std::vector< fullMatrix<double> > subPoints;
+    switch (MElement::ParentTypeFromTag(tag)) {
+      case TYPE_PNT :
+        dim = 0;
+        numLagPts = 1;
+        exponents = generate1DExponents(0);
+        bezierPoints = generate1DPoints(0);
+        lagPoints = bezierPoints;
+        dimSimplex = 0;
+        break;
+      case TYPE_LIN : {
+        dim = 1;
+        numLagPts = 2;
+        exponents = generate1DExponents(order);
+        bezierPoints = generate1DPoints(order);
+        lagPoints = bez2LagPoints(true,false,false,bezierPoints);
+        dimSimplex = 0;
+        subPoints = generateSubPointsLine(0);
+        break;
+      }
+      case TYPE_TRI : {
+        dim = 2;
+        numLagPts = 3;
+        exponents = generateExponentsTriangle(order);
+        bezierPoints = gmshGeneratePointsTriangle(order,false);
+        lagPoints = bezierPoints;
+        dimSimplex = 2;
+        subPoints = generateSubPointsTriangle(order);
+        break;
+      }
+      case TYPE_QUA : {
+        dim = 2;
+        numLagPts = 4;
+        exponents = generateExponentsQuad(order);
+        bezierPoints = generatePointsQuad(order,false);
+        lagPoints = bez2LagPoints(true,true,false,bezierPoints);
+        dimSimplex = 0;
+        subPoints = generateSubPointsQuad(order);
+        //      points.print("points");
+        break;
+      }
+      case TYPE_TET : {
+        dim = 3;
+        numLagPts = 4;
+        exponents = generateExponentsTetrahedron(order);
+        bezierPoints = gmshGeneratePointsTetrahedron(order,false);
+        lagPoints = bezierPoints;
+        dimSimplex = 3;
+        subPoints = generateSubPointsTetrahedron(order);
+        break;
+      }
+      case TYPE_PRI : {
+        dim = 3;
+        numLagPts = 6;
+        exponents = generateExponentsPrism(order);
+        bezierPoints = generatePointsPrism(order, false);
+        lagPoints = bez2LagPoints(false,false,true,bezierPoints);
+        dimSimplex = 2;
+        subPoints = generateSubPointsPrism(order);
+        break;
+      }
+      case TYPE_HEX : {
+        dim = 3;
+        numLagPts = 8;
+        exponents = generateExponentsHex(order);
+        bezierPoints = generatePointsHex(order, false);
+        lagPoints = bez2LagPoints(true,true,true,bezierPoints);
+        dimSimplex = 0;
+        subPoints = generateSubPointsHex(order);
+        break;
+      }
+      default : {
+        Msg::Error("Unknown function space %d: reverting to TET_1", tag);
+        dim = 3;
+        numLagPts = 4;
+        exponents = generateExponentsTetrahedron(0);
+        bezierPoints = gmshGeneratePointsTetrahedron(0, false);
+        lagPoints = bezierPoints;
+        dimSimplex = 3;
+        subPoints = generateSubPointsTetrahedron(0);
+        break;
+      }
+    }
+    Msg::Info("%d %d %d %d %d %d", exponents.size1(), exponents.size2(), bezierPoints.size1(), bezierPoints.size2(), order, dimSimplex);
+    matrixBez2Lag = generateBez2LagMatrix(exponents, bezierPoints, order, dimSimplex);
+    Msg::Info("%d %d %d %d", matrixBez2Lag.size1(), matrixBez2Lag.size2(), matrixLag2Bez.size1(), matrixLag2Bez.size2());
+    Msg::Info("%f %f %f %f", bezierPoints(0, 0), bezierPoints(0, 1), exponents(0, 0), exponents(0, 1));
+    matrixBez2Lag.invert(matrixLag2Bez);
+    subDivisor = generateSubDivisor(exponents, subPoints, matrixLag2Bez, order, dimSimplex);
+    numDivisions = (int) pow(2., (int) bezierPoints.size2());
+  }
+}
diff --git a/Numeric/bezierBasis.h b/Numeric/bezierBasis.h
new file mode 100644
index 0000000000..e8241ff6b7
--- /dev/null
+++ b/Numeric/bezierBasis.h
@@ -0,0 +1,30 @@
+// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _BEZIER_BASIS_H_
+#define _BEZIER_BASIS_H_
+
+#include <map>
+#include <vector>
+#include "fullMatrix.h"
+
+class bezierBasis {
+ private :
+ public :
+  int dim, order;
+  int numLagPts;
+  int numDivisions;
+  // the 'numLagPts' first exponents are related to 'Lagrangian' values
+  bezierBasis() {Msg::Fatal("Should not be created this way");};
+  bezierBasis(int tag);
+  fullMatrix<double> exponents; // exponents of Bezier FF
+  fullMatrix<double> bezierPoints, lagPoints; // sampling point
+  fullMatrix<double> matrixLag2Bez, matrixBez2Lag;
+  fullMatrix<double> subDivisor;
+};
+
+#endif
+
+
diff --git a/Numeric/jacobiPolynomials.h b/Numeric/jacobiPolynomials.h
index 9d83f5077f..b3d510c341 100644
--- a/Numeric/jacobiPolynomials.h
+++ b/Numeric/jacobiPolynomials.h
@@ -11,7 +11,7 @@
 class JacobiPolynomials {
 
  public:
-  JacobiPolynomials() {};
+  JacobiPolynomials() : n(0) {};
   JacobiPolynomials(double a, double b, int o);
   ~JacobiPolynomials();
 
diff --git a/Numeric/legendrePolynomials.h b/Numeric/legendrePolynomials.h
index f7fd118ddf..381e62e249 100644
--- a/Numeric/legendrePolynomials.h
+++ b/Numeric/legendrePolynomials.h
@@ -11,7 +11,7 @@
 class LegendrePolynomials {
 
  public:
-  LegendrePolynomials() {};
+  LegendrePolynomials() : n(0) {};
   LegendrePolynomials(int o);
   ~LegendrePolynomials();
 
diff --git a/Numeric/nodalBasis.cpp b/Numeric/nodalBasis.cpp
index 81675224b7..38126f89c9 100644
--- a/Numeric/nodalBasis.cpp
+++ b/Numeric/nodalBasis.cpp
@@ -1141,7 +1141,7 @@ static void generateFaceClosureHex(nodalBasis::clCont &closure, int order,
                                    bool serendip, const fullMatrix<double> &points)
 {
   closure.clear();
-  const nodalBasis &fsFace = *BasisFactory::create(nodalBasis::getTag(TYPE_QUA, order, serendip));
+  const nodalBasis &fsFace = *BasisFactory::getNodalBasis(nodalBasis::getTag(TYPE_QUA, order, serendip));
   for (int iRotate = 0; iRotate < 4; iRotate++){
     for (int iSign = 1; iSign >= -1; iSign -= 2){
       for (int iFace = 0; iFace < 6; iFace++) {
diff --git a/Numeric/polynomialBasis.h b/Numeric/polynomialBasis.h
index 4516507d35..0c09ef633c 100644
--- a/Numeric/polynomialBasis.h
+++ b/Numeric/polynomialBasis.h
@@ -30,8 +30,7 @@ inline double pow_int(const double &a, const int &n)
   case 5 :
     {
       const double a2 = a*a;
-      const double a3 = a*a*a;
-      return a2*a3;
+      return a2*a2*a;
     }
   case 6 :
     {
@@ -51,9 +50,8 @@ inline double pow_int(const double &a, const int &n)
     }
   case 9 :
     {
-      const double a2 = a*a;
-      const double a4 = a2*a2;
-      return a4*a4*a;
+      const double a3 = a*a*a;
+      return a3*a3*a3;
     }
   case 10 :
     {
@@ -93,7 +91,7 @@ class polynomialBasis : public nodalBasis
   virtual void df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const;
   virtual void df(double u, double v, double w, double grads[][3]) const;
   virtual void ddf(double u, double v, double w, double hess[][3][3]) const;
-  virtual  void dddf(double u, double v, double w, double third[][3][3][3]) const;
+  virtual void dddf(double u, double v, double w, double third[][3][3][3]) const;
 
   virtual int getNumShapeFunctions() const;
 
diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp
index 05e5653bde..1e4f5438ce 100644
--- a/Plugin/AnalyseCurvedMesh.cpp
+++ b/Plugin/AnalyseCurvedMesh.cpp
@@ -6,7 +6,7 @@
 #include "Gmsh.h"
 #include "GModel.h"
 #include "GmshMessage.h"
-#include "JacobianBasis.h"
+
 #include "polynomialBasis.h"
 #include "AnalyseCurvedMesh.h"
 #include "Context.h"
diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp
index 01feaae979..211bb22467 100644
--- a/Post/PViewDataList.cpp
+++ b/Post/PViewDataList.cpp
@@ -903,7 +903,7 @@ void PViewDataList::setOrder2(int type)
   case TYPE_PRI: typeMSH = MSH_PRI_18; break;
   // case TYPE_PYR: typeMSH = MSH_PYR_14; break;
   }
-  const polynomialBasis *fs = (polynomialBasis*)BasisFactory::create(typeMSH);
+  const polynomialBasis *fs = (polynomialBasis*)BasisFactory::getNodalBasis(typeMSH);
   if(!fs){
     Msg::Error("Could not find polynomial function space for element type %d",
                typeMSH);
diff --git a/contrib/DiscreteIntegration/Integration3D.cpp b/contrib/DiscreteIntegration/Integration3D.cpp
index 478fd0cace..3d2dbaba46 100644
--- a/contrib/DiscreteIntegration/Integration3D.cpp
+++ b/contrib/DiscreteIntegration/Integration3D.cpp
@@ -1045,7 +1045,7 @@ bool DI_ElementLessThan::operator()(const DI_Element *e1, const DI_Element *e2)
 const nodalBasis* DI_Line::getFunctionSpace(int o) const{
   int order = (o == -1) ? getPolynomialOrder() : o;
   int tag = polynomialBasis::getTag(TYPE_LIN, order);
-  return BasisFactory::create(tag);
+  return BasisFactory::getNodalBasis(tag);
 }
 
 void DI_Line::computeIntegral() {
@@ -1066,7 +1066,7 @@ const nodalBasis* DI_Triangle::getFunctionSpace(int o) const
 {
   int order = (o == -1) ? getPolynomialOrder() : o;
   int tag = polynomialBasis::getTag(TYPE_TRI, order);
-  return BasisFactory::create(tag);
+  return BasisFactory::getNodalBasis(tag);
 }
 void DI_Triangle::computeIntegral() {
   integral_ = TriSurf(pt(0), pt(1), pt(2));
@@ -1090,7 +1090,7 @@ double DI_Triangle::quality() const {
 const nodalBasis* DI_Quad::getFunctionSpace(int o) const{
  int order = (o == -1) ? getPolynomialOrder() : o;
   int tag = polynomialBasis::getTag(TYPE_QUA, order);
-  return BasisFactory::create(tag);
+  return BasisFactory::getNodalBasis(tag);
 }
 
 void DI_Quad::computeIntegral() {
@@ -1114,7 +1114,7 @@ void DI_Quad::computeIntegral() {
 const nodalBasis* DI_Tetra::getFunctionSpace(int o) const{
  int order = (o == -1) ? getPolynomialOrder() : o;
   int tag = polynomialBasis::getTag(TYPE_TET, order);
-  return BasisFactory::create(tag);
+  return BasisFactory::getNodalBasis(tag);
 }
 
 void DI_Tetra::computeIntegral() {
@@ -1129,7 +1129,7 @@ double DI_Tetra::quality() const {
 const nodalBasis* DI_Hexa::getFunctionSpace(int o) const{
   int order = (o == -1) ? getPolynomialOrder() : o;
   int tag = polynomialBasis::getTag(TYPE_HEX, order);
-  return BasisFactory::create(tag);
+  return BasisFactory::getNodalBasis(tag);
 }
 void DI_Hexa::computeIntegral() {
     integral_ = TetraVol(pt(0), pt(1), pt(3), pt(4)) + TetraVol(pt(1), pt(4), pt(5), pt(7))
diff --git a/contrib/DiscreteIntegration/Integration3D.h b/contrib/DiscreteIntegration/Integration3D.h
index c791cfc1fb..132405c539 100644
--- a/contrib/DiscreteIntegration/Integration3D.h
+++ b/contrib/DiscreteIntegration/Integration3D.h
@@ -49,7 +49,7 @@ class DI_Point
             const std::vector<gLevelset *> &RPNi) : x_(x), y_(y), z_(z) {computeLs(e, RPNi);}
   virtual ~DI_Point(){}
   virtual const nodalBasis* getFunctionSpace(int o) const
-  { return BasisFactory::create(MSH_PNT); }
+  { return BasisFactory::getNodalBasis(MSH_PNT); }
   virtual void getShapeFunctions(double u, double v, double w, double s[], int o)
   {
     s[0] = 1.;
diff --git a/contrib/HighOrderMeshOptimizer/OptHomMesh.h b/contrib/HighOrderMeshOptimizer/OptHomMesh.h
index 481d6a2b8e..e8f526c165 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomMesh.h
+++ b/contrib/HighOrderMeshOptimizer/OptHomMesh.h
@@ -8,7 +8,7 @@
 #include "MVertex.h"
 #include "ParamCoord.h"
 #include "polynomialBasis.h"
-#include "JacobianBasis.h"
+
 
 
 
-- 
GitLab