diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index a7dd1906ce8793f24ade025e12c9a6537c78c36c..7a0eab8af78e71ac2bf2020e8a385854278b21a2 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1135,6 +1135,9 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "MshFilePartitioned" , opt_mesh_msh_file_partitioned , 0. , 
     "Split MSH file by mesh partition" },
 
+  { F|O, "PartitionByExtrusion" , opt_mesh_partition_by_extrusion, 0. ,
+    "Special partitioner that annotates all all extruded elements to the same node as the source element" },
+    
   { F, "NbHexahedra" , opt_mesh_nb_hexahedra , 0. , 
     "Number of hexahedra in the current mesh (read-only)" },
   { F, "NbNodes" , opt_mesh_nb_nodes , 0. , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index f1077ee93827502e99760f2a756bdab6fa607ec3..a94e6f4856569800df16e3b803c94c048ec71d8d 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5811,6 +5811,14 @@ double opt_mesh_partition_partitioner(OPT_ARGS_NUM)
   }
   return CTX::instance()->partitionOptions.partitioner;
 }
+double opt_mesh_partition_by_extrusion(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET) {
+    const int ival = (int)val;
+    CTX::instance()->partitionOptions.partitionByExtrusion = ival;
+  }
+  return CTX::instance()->partitionOptions.partitionByExtrusion;
+}
 
 double opt_mesh_partition_num(OPT_ARGS_NUM)
 {
diff --git a/Common/Options.h b/Common/Options.h
index 5a7cbc189f33cfd2f31ad040147b2082816548ed..58eccd97a9a4a3b6247c2fb6e57c87caaed45107 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -563,6 +563,7 @@ double opt_mesh_partition_chaco_terminal_propogation(OPT_ARGS_NUM);
 double opt_mesh_partition_metis_algorithm(OPT_ARGS_NUM);
 double opt_mesh_partition_metis_edge_matching(OPT_ARGS_NUM);
 double opt_mesh_partition_metis_refine_algorithm(OPT_ARGS_NUM);
+double opt_mesh_partition_by_extrusion(OPT_ARGS_NUM);
 double opt_mesh_clip(OPT_ARGS_NUM);
 double opt_solver_listen(OPT_ARGS_NUM);
 double opt_solver_plugins(OPT_ARGS_NUM);
diff --git a/Geo/ExtrudeParams.cpp b/Geo/ExtrudeParams.cpp
index 8841de0dd7b4a9e5ff762b783ea32d401024bf8b..ea12b7d9990d0de2bf7e6e489aa4a79b46cea1e2 100644
--- a/Geo/ExtrudeParams.cpp
+++ b/Geo/ExtrudeParams.cpp
@@ -21,7 +21,7 @@ static void Projette(double p[3], double mat[3][3])
   p[2] = Z;
 }
 
-ExtrudeParams::ExtrudeParams(int ModeEx)
+ExtrudeParams::ExtrudeParams(int ModeEx) : elementMap(this)
 {
   geo.Mode = ModeEx;
   geo.Source = -1;
@@ -121,3 +121,76 @@ double ExtrudeParams::u(int iLayer, int iElemLayer)
   double t = (double)iElemLayer / (double)mesh.NbElmLayer[iLayer];
   return t0 + t * (t1 - t0);
 }
+
+ExtrudeParams::ExtrusionElementMap::ExtrusionElementMap(ExtrudeParams*const parent)
+{
+ _parent = parent;
+}
+
+std::vector< MElement* >* ExtrudeParams::ExtrusionElementMap::getExtrudedElems(MElement* source)
+{
+  std::map<MElement*,std::vector<MElement*> >::iterator it = _extrudedElements.find(source);
+  if(it != _extrudedElements.end())
+    return &(it->second);
+  return NULL;
+}
+void ExtrudeParams::ExtrusionElementMap::clear()
+{
+  _extrudedElements.clear();
+}
+
+bool ExtrudeParams::ExtrusionElementMap::empty()
+{
+  return _extrudedElements.empty();
+}
+
+void ExtrudeParams::ExtrusionElementMap::addExtrudedElem(MElement* source, MElement* extrudedElem)
+{
+  std::map<MElement*,std::vector<MElement*> >::iterator it = _extrudedElements.find(source);
+  if(it != _extrudedElements.end())
+    it->second.push_back(extrudedElem);
+  else {
+   std::vector<MElement*>* vec = new std::vector<MElement*>();
+   int totalNbElems = 0;
+   for (int i = 0;i<_parent->mesh.NbLayer;i++)
+     totalNbElems += _parent->mesh.NbElmLayer[i];
+   vec->reserve(totalNbElems);
+   vec->push_back(extrudedElem);
+   _extrudedElements.insert(std::pair<MElement*,std::vector<MElement*> >(source,*vec));
+  }
+  SPoint3 np = extrudedElem->barycenter(), sp = source->barycenter();
+//   if(extrudedElem->getDim() == 3)
+//   printf("Inst (%.3f,%.3f,%.3f) -> (%.3f,%.3f,%.3f) %p->%p\n",sp.x(),sp.y(),sp.z(),np.x(),np.y(),np.z(),source,extrudedElem);
+}
+
+// Propagates the partition information from the source elements to the extruded elements.
+// Increments the partition sizes if partitionSizes is given as argument.
+// For efficient looping, this routine is within ExtrusionElementMap class.
+void ExtrudeParams::ExtrusionElementMap::propagatePartitionInformation(std::vector< int >* partitionSizes)
+{
+  if (_extrudedElements.empty())
+    Msg::Error("No extrusion information found!");
+  std::map<MElement*,std::vector<MElement*> >::iterator columnit;
+  for(columnit=_extrudedElements.begin(); columnit != _extrudedElements.end(); columnit++) {
+    MElement* sourceElem = (*columnit).first;
+    if(!sourceElem) {
+      Msg::Warning("No source found!");
+      continue;
+    }
+    std::vector<MElement*> extrudedElements = (*columnit).second;
+//     if(!extrudedElements) {
+// //       Msg::Warning("No element vector found!");
+//       continue;
+//     }
+    for(int iE = 0;iE < extrudedElements.size();iE++) {
+      if(extrudedElements[iE]) {
+        extrudedElements[iE]->setPartition(sourceElem->getPartition());
+        if (partitionSizes)
+          ++(*partitionSizes)[sourceElem->getPartition()-1];
+//     SPoint3 np = extrudedElements[iE]->barycenter(), sp = sourceElem->barycenter();
+//     if(extrudedElements[iE]->getDim() == 3)
+//     printf("Read (%.3f,%.3f,%.3f) %d -> (%.3f,%.3f,%.3f) %d %p->%p\n",sp.x(),sp.y(),sp.z(),extrudedElements[iE]->getPartition() ,np.x(),np.y(),np.z(),sourceElem->getPartition(),sourceElem,extrudedElements[iE]);
+      }
+    }
+  }
+}
diff --git a/Geo/ExtrudeParams.h b/Geo/ExtrudeParams.h
index 532b99c84b4a3025e440bd3925f1192ed85d00d0..ce6c344f0437f97121a0a4d27bde4f46f1cd2cff 100644
--- a/Geo/ExtrudeParams.h
+++ b/Geo/ExtrudeParams.h
@@ -10,6 +10,7 @@
 #include <map>
 #include <string>
 #include "SmoothData.h"
+#include "MElement.h"
 
 // geo.Mode
 #define EXTRUDED_ENTITY 1
@@ -23,6 +24,19 @@
 
 class ExtrudeParams{
 public :
+  class ExtrusionElementMap {
+    private:
+      ExtrudeParams* _parent;
+      // maps source element to all extruded elements
+      std::map<MElement*,std::vector<MElement*> > _extrudedElements;
+    public:
+      ExtrusionElementMap(ExtrudeParams* const parent);
+      std::vector<MElement*>* getExtrudedElems(MElement* source);
+      void addExtrudedElem(MElement* source,MElement* extrudedElem);
+      void clear();
+      bool empty();
+      void propagatePartitionInformation(std::vector<int>* partitionSizes = NULL);
+  } elementMap;
   static smooth_data *normals;
   ExtrudeParams(int Mode = EXTRUDED_ENTITY);
   void fill(int type,
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 421d93724aa22dfef1115f37d0f9383c417d51a4..3585a71a1e34d3384ce7d4997669fcfbf421187a 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -315,7 +315,7 @@ void MElement::xyz2uvw(double xyz[3], double uvw[3])
   uvw[0] = uvw[1] = uvw[2] = 0.;
   int iter = 1, maxiter = 20;
   double error = 1., tol = 1.e-6;
-
+  
   while (error > tol && iter < maxiter){
     double jac[3][3];
     if(!getJacobian(uvw[0], uvw[1], uvw[2], jac)) break;
diff --git a/Geo/MPrism.cpp b/Geo/MPrism.cpp
index 6039f44b8dbd52881c1ccca093c4c7321fa3574b..29de1872482827a7e120ed038081956818cfa0ae 100644
--- a/Geo/MPrism.cpp
+++ b/Geo/MPrism.cpp
@@ -53,6 +53,20 @@ const polynomialBasis* MPrism::getFunctionSpace(int o) const
   return 0;
 }
 
+double MPrism::getInnerRadius()
+{
+  double dist[3], k = 0.;
+  double triEdges[3] = {0,1,3};
+  for (int i = 0; i < 3; i++){
+    MEdge e = getEdge(triEdges[i]);
+    dist[i] = e.getVertex(0)->distance(e.getVertex(1));
+    k += 0.5 * dist[i];
+  }
+  double radTri = sqrt(k * (k - dist[0]) * (k - dist[1]) * (k - dist[2])) / k;
+  double radVert = 0.5*getVertex(0)->distance(getVertex(3));
+  return std::min(radTri,radVert);
+}
+
 void MPrism::getFaceInfo(const MFace &face, int &ithFace, int &sign, int &rot) const
 {
   for (ithFace = 0; ithFace < 5; ithFace++){
diff --git a/Geo/MPrism.h b/Geo/MPrism.h
index 68713e0920897958be6732cb0ebe32e4d54cd7b8..1efd463a12dc71f453883f202d1b48e663543aef 100644
--- a/Geo/MPrism.h
+++ b/Geo/MPrism.h
@@ -62,6 +62,7 @@ class MPrism : public MElement {
   ~MPrism(){}
   virtual int getDim() const { return 3; }
   virtual int getNumVertices() const { return 6; }
+  virtual double getInnerRadius();
   virtual MVertex *getVertex(int num){ return _v[num]; }
   virtual MVertex *getVertexMED(int num)
   {
diff --git a/Mesh/meshGEdgeExtruded.cpp b/Mesh/meshGEdgeExtruded.cpp
index 7bac2545a2852fd5ce00e3d2f120d9c2d7d23873..c06de9aaf21a90deca6f06e69c8fae9cdd43b25d 100644
--- a/Mesh/meshGEdgeExtruded.cpp
+++ b/Mesh/meshGEdgeExtruded.cpp
@@ -54,13 +54,13 @@ int MeshExtrudedCurve(GEdge *ge)
   if(!ep || !ep->mesh.ExtrudeMesh)
     return 0;
 
+  GEdge *from = ge->model()->getEdgeByTag(std::abs(ep->geo.Source));
   if(ep->geo.Mode == EXTRUDED_ENTITY) {
     // curve is extruded from a point
     extrudeMesh(ge->getBeginVertex(), ge);
   }
   else {
     // curve is a copy of another curve (the "top" of the extrusion)
-    GEdge *from = ge->model()->getEdgeByTag(std::abs(ep->geo.Source));
     if(!from){
       Msg::Error("Unknown source curve %d for extrusion", ep->geo.Source);
       return 0;
@@ -74,8 +74,14 @@ int MeshExtrudedCurve(GEdge *ge)
       ge->getBeginVertex()->mesh_vertices[0] : ge->mesh_vertices[i - 1];
     MVertex *v1 = (i == ge->mesh_vertices.size()) ? 
       ge->getEndVertex()->mesh_vertices[0] : ge->mesh_vertices[i];
-    ge->lines.push_back(new MLine(v0, v1));
+    MLine* newElem = new MLine(v0, v1);
+    ge->lines.push_back(newElem);
+    if(ep->geo.Mode == COPIED_ENTITY) {
+      // Extrusion information is only stored for copied edges
+      // (the source of extruded edge is a vertex, not an element)
+      MElement* sourceElem = from->getMeshElement(i);
+      ep->elementMap.addExtrudedElem(sourceElem,newElem);
+    }
   }
-
   return 1;
 }
diff --git a/Mesh/meshGFaceExtruded.cpp b/Mesh/meshGFaceExtruded.cpp
index 780b408e4d2bbe38745db8779eec8c38f498f7eb..8e7e254c0e2072537e4309b8a647fc4254f9ca22 100644
--- a/Mesh/meshGFaceExtruded.cpp
+++ b/Mesh/meshGFaceExtruded.cpp
@@ -12,34 +12,45 @@
 #include "Context.h"
 #include "GmshMessage.h"
 
+static void addTriangle(MVertex* v1, MVertex* v2, MVertex* v3, GFace *to, MElement* source) {
+  MTriangle* newTri = new MTriangle(v1, v2, v3);
+  to->triangles.push_back(newTri);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newTri);
+}
+
+static void addQuadrangle(MVertex* v1, MVertex* v2, MVertex* v3, MVertex* v4, GFace *to, MElement* source) {
+  MQuadrangle* newQuad = new MQuadrangle(v1, v2, v3, v4);
+  to->quadrangles.push_back(newQuad);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newQuad);
+}
+
 static void createQuaTri(std::vector<MVertex*> &v, GFace *to,
-                         std::set<std::pair<MVertex*, MVertex*> > *constrainedEdges)
+                         std::set<std::pair<MVertex*, MVertex*> > *constrainedEdges,MLine* source)
 {
   ExtrudeParams *ep = to->meshAttributes.extrude;
-
   if(v[0] == v[1] || v[1] == v[3])
-    to->triangles.push_back(new MTriangle(v[0], v[3], v[2]));
+    addTriangle(v[0], v[3], v[2],to,source);
   else if(v[0] == v[2] || v[2] == v[3])
-    to->triangles.push_back(new MTriangle(v[0], v[1], v[3]));
+    addTriangle(v[0], v[1], v[3],to,source);
   else if(v[0] == v[3] || v[1] == v[2])
     Msg::Error("Uncoherent extruded quadrangle in surface %d", to->tag());
   else{
     if(ep->mesh.Recombine){
-      to->quadrangles.push_back(new MQuadrangle(v[0], v[1], v[3], v[2]));
+      addQuadrangle(v[0], v[1], v[3], v[2],to,source);
     }
     else if(!constrainedEdges){
-      to->triangles.push_back(new MTriangle(v[0], v[1], v[3]));
-      to->triangles.push_back(new MTriangle(v[0], v[3], v[2]));
+      addTriangle(v[0], v[1], v[3],to,source);
+      addTriangle(v[0], v[3], v[2],to,source);
     }
     else{
       std::pair<MVertex*, MVertex*> p(std::min(v[1], v[2]), std::max(v[1], v[2]));
       if(constrainedEdges->count(p)){
-        to->triangles.push_back(new MTriangle(v[2], v[1], v[0]));
-        to->triangles.push_back(new MTriangle(v[2], v[3], v[1]));
+        addTriangle(v[2], v[1], v[0],to,source);
+        addTriangle(v[2], v[3], v[1],to,source);
       }
       else{
-        to->triangles.push_back(new MTriangle(v[2], v[3], v[0]));
-        to->triangles.push_back(new MTriangle(v[0], v[3], v[1]));
+        addTriangle(v[2], v[3], v[0],to,source);
+        addTriangle(v[0], v[3], v[1],to,source);
       }
     }
   }
@@ -100,7 +111,7 @@ static void extrudeMesh(GEdge *from, GFace *to,
           }
           verts.push_back(*itp);
         }
-        createQuaTri(verts, to, constrainedEdges);
+        createQuaTri(verts, to, constrainedEdges,from->lines[i]);
       }
     }
   }
@@ -143,7 +154,7 @@ static void copyMesh(GFace *from, GFace *to,
       }
       verts.push_back(*itp);
     }
-    to->triangles.push_back(new MTriangle(verts));
+    addTriangle(verts[0],verts[1],verts[2],to,from->triangles[i]);
   }
   for(unsigned int i = 0; i < from->quadrangles.size(); i++){
     std::vector<MVertex*> verts;
@@ -164,7 +175,7 @@ static void copyMesh(GFace *from, GFace *to,
       }
       verts.push_back(*itp);
     }
-    to->quadrangles.push_back(new MQuadrangle(verts));
+    addQuadrangle(verts[0],verts[1],verts[2],verts[3],to,from->quadrangles[i]);
   }
 }
 
diff --git a/Mesh/meshGRegionExtruded.cpp b/Mesh/meshGRegionExtruded.cpp
index 3aaea62fd7d9b43b8e756f336f5eb4085a0d51e0..72dcff796ede15fc1b4facec63b912f29f2283e5 100644
--- a/Mesh/meshGRegionExtruded.cpp
+++ b/Mesh/meshGRegionExtruded.cpp
@@ -17,7 +17,30 @@
 #include "Context.h"
 #include "GmshMessage.h"
 
-static void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to)
+static void addTetrahedron(MVertex* v1, MVertex* v2, MVertex* v3, MVertex* v4, GRegion *to, MElement* source) {
+  MTetrahedron* newElem = new MTetrahedron(v1, v2, v3, v4);
+  to->tetrahedra.push_back(newElem);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newElem);
+}
+
+static void addPyramid(MVertex* v1, MVertex* v2, MVertex* v3, MVertex* v4, MVertex* v5, GRegion *to, MElement* source) {
+  MPyramid* newElem = new MPyramid(v1, v2, v3, v4, v5);
+  to->pyramids.push_back(newElem);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newElem);
+}
+
+static void addPrism(MVertex* v1, MVertex* v2, MVertex* v3, MVertex* v4, MVertex* v5, MVertex* v6, GRegion *to, MElement* source) {
+  MPrism* newElem = new MPrism(v1, v2, v3, v4, v5, v6);
+  to->prisms.push_back(newElem);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newElem);
+}
+static void addHexahedron(MVertex* v1, MVertex* v2, MVertex* v3, MVertex* v4, MVertex* v5, MVertex* v6, MVertex* v7, MVertex* v8, GRegion *to, MElement* source) {
+  MHexahedron* newElem = new MHexahedron(v1, v2, v3, v4, v5, v6, v7, v8);
+  to->hexahedra.push_back(newElem);
+  to->meshAttributes.extrude->elementMap.addExtrudedElem((MElement*)source,(MElement*)newElem);
+}
+
+static void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to, MElement* source)
 {
   int dup[3];
   int j = 0;
@@ -27,27 +50,27 @@ static void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to)
 
   if(j == 2) {
     if(dup[0] == 0 && dup[1] == 1)
-      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[5]));
+      addTetrahedron(v[0], v[1], v[2], v[5],to,source);
     else if(dup[0] == 1 && dup[1] == 2)
-      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[3]));
+      addTetrahedron(v[0], v[1], v[2], v[3],to,source);
     else
-      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[4]));
+      addTetrahedron(v[0], v[1], v[2], v[4],to,source);
   }
   else if(j == 1) {
     if(dup[0] == 0)
-      to->pyramids.push_back(new MPyramid(v[1], v[4], v[5], v[2], v[0]));
+      addPyramid(v[1], v[4], v[5], v[2], v[0],to,source);
     else if(dup[0] == 1)
-      to->pyramids.push_back(new MPyramid(v[0], v[2], v[5], v[3], v[1]));
+      addPyramid(v[0], v[2], v[5], v[3], v[1],to,source);
     else
-      to->pyramids.push_back(new MPyramid(v[0], v[1], v[4], v[3], v[2]));
+      addPyramid(v[0], v[1], v[4], v[3], v[2],to,source);
   }
   else {
-    to->prisms.push_back(new MPrism(v));
+    addPrism(v[0], v[1], v[2], v[3], v[4], v[5],to,source);
     if(j) Msg::Error("Degenerated prism in extrusion of volume %d", to->tag());
   }
 }
 
-static void createHexPri(std::vector<MVertex*> &v, GRegion *to)
+static void createHexPri(std::vector<MVertex*> &v, GRegion *to, MElement* source)
 {
   int dup[4];
   int j = 0;
@@ -57,26 +80,26 @@ static void createHexPri(std::vector<MVertex*> &v, GRegion *to)
   
   if(j == 2) {
     if(dup[0] == 0 && dup[1] == 1)
-      to->prisms.push_back(new MPrism(v[0], v[3], v[7], v[1], v[2], v[6]));
+      addPrism(v[0], v[3], v[7], v[1], v[2], v[6],to,source);
     else if(dup[0] == 1 && dup[1] == 2)
-      to->prisms.push_back(new MPrism(v[0], v[1], v[4], v[3], v[2], v[7]));
+      addPrism(v[0], v[1], v[4], v[3], v[2], v[7],to,source);
     else if(dup[0] == 2 && dup[1] == 3)
-      to->prisms.push_back(new MPrism(v[0], v[3], v[4], v[1], v[2], v[5]));
+      addPrism(v[0], v[3], v[4], v[1], v[2], v[5],to,source);
     else if(dup[0] == 0 && dup[1] == 3)
-      to->prisms.push_back(new MPrism(v[0], v[1], v[5], v[3], v[2], v[6]));
+      addPrism(v[0], v[1], v[5], v[3], v[2], v[6],to,source);
     else
       Msg::Error("Uncoherent hexahedron in extrusion of volume %d", to->tag());
   }
   else {
-    to->hexahedra.push_back(new MHexahedron(v));
+    addHexahedron(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],to,source);
     if(j) Msg::Error("Degenerated hexahedron in extrusion of volume %d", to->tag());
   }
 }
 
-static void createTet(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, GRegion *to)
+static void createTet(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, GRegion *to, MElement* source)
 {
   if(v1 != v2 && v1 != v3 && v1 != v4 && v2 != v3 && v2 != v4 && v3 != v4)
-    to->tetrahedra.push_back(new MTetrahedron(v1, v2, v3, v4));
+    addTetrahedron(v1, v2, v3, v4,to,source);
 }
 
 static int getExtrudedVertices(MElement *ele, ExtrudeParams *ep, int j, int k, 
@@ -140,8 +163,9 @@ static void extrudeMesh(GFace *from, GRegion *to,
     for(int j = 0; j < ep->mesh.NbLayer; j++) {
       for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
         std::vector<MVertex*> verts;
-        if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, verts) == 6)
-          createPriPyrTet(verts, to);
+        if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, verts) == 6) {
+          createPriPyrTet(verts, to,from->triangles[i]);
+        }
       }
     }
   }
@@ -155,7 +179,7 @@ static void extrudeMesh(GFace *from, GRegion *to,
         for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
           std::vector<MVertex*> verts;
           if(getExtrudedVertices(from->quadrangles[i], ep, j, k, pos, verts) == 8)
-            createHexPri(verts, to);
+            createHexPri(verts, to, from->quadrangles[i]);
         }
       }
     }
@@ -360,51 +384,52 @@ static void phase3(GRegion *gr,
   if(!from) return;
 
   for(unsigned int i = 0; i < from->triangles.size(); i++){
+    MTriangle* tri = from->triangles[i];
     for(int j = 0; j < ep->mesh.NbLayer; j++) {
       for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
         std::vector<MVertex*> v;
-        if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, v) == 6){
+        if(getExtrudedVertices(tri, ep, j, k, pos, v) == 6){
           if(edgeExists(v[3], v[1], edges) &&
              edgeExists(v[4], v[2], edges) &&
              edgeExists(v[3], v[2], edges)) {
-            createTet(v[0], v[1], v[2], v[3], gr);
-            createTet(v[3], v[4], v[5], v[2], gr);
-            createTet(v[1], v[3], v[4], v[2], gr);
+            createTet(v[0], v[1], v[2], v[3], gr, tri);
+            createTet(v[3], v[4], v[5], v[2], gr, tri);
+            createTet(v[1], v[3], v[4], v[2], gr, tri);
           }
           else if(edgeExists(v[3], v[1], edges) &&
                   edgeExists(v[1], v[5], edges) &&
                   edgeExists(v[3], v[2], edges)) {
-            createTet(v[0], v[1], v[2], v[3], gr);
-            createTet(v[3], v[4], v[5], v[1], gr);
-            createTet(v[3], v[1], v[5], v[2], gr);
+            createTet(v[0], v[1], v[2], v[3], gr, tri);
+            createTet(v[3], v[4], v[5], v[1], gr, tri);
+            createTet(v[3], v[1], v[5], v[2], gr, tri);
           }
           else if(edgeExists(v[3], v[1], edges) &&
                   edgeExists(v[1], v[5], edges) &&
                   edgeExists(v[5], v[0], edges)) {
-            createTet(v[0], v[1], v[2], v[5], gr);
-            createTet(v[3], v[4], v[5], v[1], gr);
-            createTet(v[1], v[3], v[5], v[0], gr);
+            createTet(v[0], v[1], v[2], v[5], gr, tri);
+            createTet(v[3], v[4], v[5], v[1], gr, tri);
+            createTet(v[1], v[3], v[5], v[0], gr, tri);
           }
           else if(edgeExists(v[4], v[0], edges) &&
                   edgeExists(v[4], v[2], edges) &&
                   edgeExists(v[3], v[2], edges)) {
-            createTet(v[0], v[1], v[2], v[4], gr);
-            createTet(v[3], v[4], v[5], v[2], gr);
-            createTet(v[0], v[3], v[4], v[2], gr);
+            createTet(v[0], v[1], v[2], v[4], gr, tri);
+            createTet(v[3], v[4], v[5], v[2], gr, tri);
+            createTet(v[0], v[3], v[4], v[2], gr, tri);
           }
           else if(edgeExists(v[4], v[0], edges) &&
                   edgeExists(v[4], v[2], edges) &&
                   edgeExists(v[5], v[0], edges)) {
-            createTet(v[0], v[1], v[2], v[4], gr);
-            createTet(v[3], v[4], v[5], v[0], gr);
-            createTet(v[0], v[2], v[4], v[5], gr);
+            createTet(v[0], v[1], v[2], v[4], gr, tri);
+            createTet(v[3], v[4], v[5], v[0], gr, tri);
+            createTet(v[0], v[2], v[4], v[5], gr, tri);
           }
           else if(edgeExists(v[4], v[0], edges) &&
                   edgeExists(v[1], v[5], edges) &&
                   edgeExists(v[5], v[0], edges)) {
-            createTet(v[0], v[1], v[2], v[5], gr);
-            createTet(v[3], v[4], v[5], v[0], gr);
-            createTet(v[0], v[1], v[4], v[5], gr);
+            createTet(v[0], v[1], v[2], v[5], gr, tri);
+            createTet(v[3], v[4], v[5], v[0], gr, tri);
+            createTet(v[0], v[1], v[4], v[5], gr, tri);
           }
         }
       }
@@ -429,7 +454,6 @@ int SubdivideExtrudedMesh(GModel *m)
   }
 
   if(regions.empty()) return 0;
-
   Msg::Info("Subdividing extruded mesh");
 
   // create edges on lateral sides of "prisms"
@@ -465,36 +489,59 @@ int SubdivideExtrudedMesh(GModel *m)
     for(unsigned int i = 0; i < gr->pyramids.size(); i++)
       delete gr->pyramids[i];
     gr->pyramids.clear();
+    gr->meshAttributes.extrude->elementMap.clear(); // reconstruct extrusion info
     phase3(gr, pos, edges);
-  }
 
-  // re-Extrude bounding surfaces using edges as constraint
-  std::set<GFace*> faces;
-  for(unsigned int i = 0; i < regions.size(); i++){
-    std::list<GFace*> f = regions[i]->faces();
-    faces.insert(f.begin(), f.end());
-  }
-  for(std::set<GFace*>::iterator it = faces.begin(); it != faces.end(); it++){
-    ExtrudeParams *ep = (*it)->meshAttributes.extrude;
-    if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY && 
-       !ep->mesh.Recombine){
-      GFace *gf = *it;
-      Msg::Info("Remeshing surface %d", gf->tag());
-      for(unsigned int i = 0; i < gf->triangles.size(); i++) 
-        delete gf->triangles[i];
-      gf->triangles.clear();
-      for(unsigned int i = 0; i < gf->quadrangles.size(); i++) 
-        delete gf->quadrangles[i];
-      gf->quadrangles.clear();
-      MeshExtrudedSurface(gf, &edges);
+    // re-Extrude bounding surfaces using edges as constraint
+    std::list<GFace*> faces = gr->faces();
+    for(std::list<GFace*>::iterator it = faces.begin(); it != faces.end(); it++){
+      ExtrudeParams *ep = (*it)->meshAttributes.extrude;
+      if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY && 
+        !ep->mesh.Recombine){
+        GFace *gf = *it;
+        Msg::Info("Remeshing surface %d", gf->tag());
+        for(unsigned int i = 0; i < gf->triangles.size(); i++) 
+          delete gf->triangles[i];
+        gf->triangles.clear();
+        for(unsigned int i = 0; i < gf->quadrangles.size(); i++) 
+          delete gf->quadrangles[i];
+        gf->quadrangles.clear();
+        ep->elementMap.clear(); // reconstruct extrusion info
+        MeshExtrudedSurface(gf, &edges);
+      }
     }
   }
+  
+//   std::set<GFace*> faces;
+//   for(unsigned int i = 0; i < regions.size(); i++){
+//     std::list<GFace*> f = regions[i]->faces();
+//     faces.insert(f.begin(), f.end());
+//   }
+//   for(std::set<GFace*>::iterator it = faces.begin(); it != faces.end(); it++){
+//     ExtrudeParams *ep = (*it)->meshAttributes.extrude;
+//     if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY && 
+//        !ep->mesh.Recombine){
+//       GFace *gf = *it;
+//       Msg::Info("Remeshing surface %d", gf->tag());
+//       for(unsigned int i = 0; i < gf->triangles.size(); i++) 
+//         delete gf->triangles[i];
+//       gf->triangles.clear();
+//       for(unsigned int i = 0; i < gf->quadrangles.size(); i++) 
+//         delete gf->quadrangles[i];
+//       gf->quadrangles.clear();
+//       ep->elementMap.clear(); // reconstruct extrusion info
+//       MeshExtrudedSurface(gf, &edges);
+//     }
+//   }
+
 
   // carve holes if any
+  // TODO: update extrusion information
   for(unsigned int i = 0; i < regions.size(); i++){
     GRegion *gr = regions[i];
     ExtrudeParams *ep = gr->meshAttributes.extrude;
     if(ep->mesh.Holes.size()){
+      ep->elementMap.clear();
       std::map<int, std::pair<double, std::vector<int> > >::iterator it;
       for(it = ep->mesh.Holes.begin(); it != ep->mesh.Holes.end(); it++)
         carveHole(gr, it->first, it->second.first, it->second.second);
diff --git a/Mesh/meshPartition.cpp b/Mesh/meshPartition.cpp
index e50c3ad8981d5992dc3ac331841ef4046dba0f94..5f84c66b7bcb09442dbd90464541aa16307f03df 100644
--- a/Mesh/meshPartition.cpp
+++ b/Mesh/meshPartition.cpp
@@ -28,6 +28,7 @@
 #include "discreteFace.h"
 #include "GFaceCompound.h"
 #include "Context.h"
+#include "ExtrudeParams.h"
 
 
 //--Prototype for Chaco interface
@@ -84,14 +85,14 @@ struct BoElemGr;
 typedef std::vector<BoElemGr> BoElemGrVec;
 
 int MakeGraph(GModel *const model, Graph &graph,
-              BoElemGrVec *const boElemGrVec = 0);
+              meshPartitionOptions &options, BoElemGrVec *const boElemGrVec = 0);
 
 template <unsigned DIM, typename EntIter, typename EntIterBE>
 void MakeGraphDIM(const EntIter begin, const EntIter end,
                   const EntIterBE beginBE, const EntIterBE endBE,
                   Graph &graph, BoElemGrVec *const boElemGrVec);
 
-
+                  
 /*******************************************************************************
  *
  * Routine partitionMesh
@@ -120,7 +121,7 @@ int RenumberMesh(GModel *const model, meshPartitionOptions &options, std::vector
   BoElemGrVec boElemGrVec;
   int ier;
   Msg::StatusBar(1, true, "Building graph...");
-  ier = MakeGraph(model, graph, &boElemGrVec);
+  ier = MakeGraph(model, graph, options, &boElemGrVec);
   Msg::StatusBar(1, true, "Renumbering graph...");
   if(!ier) ier = RenumberGraph(graph, options);
   if(ier) {
@@ -262,21 +263,74 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options)
   BoElemGrVec boElemGrVec;
   int ier;
   Msg::StatusBar(1, true, "Building graph...");
-  ier = MakeGraph(model, graph, &boElemGrVec);
+  ier = MakeGraph(model, graph, options, &boElemGrVec);
   Msg::StatusBar(1, true, "Partitioning graph...");
   if(!ier) ier = PartitionGraph(graph, options);
   if(ier) {
     Msg::StatusBar(1, false, "Mesh");
     return 1;
   }
-
+    
   // Count partition sizes and assign partitions to internal elements
   std::vector<int> ssize(options.num_partitions, 0);
   const int n = graph.getNumVertex();
   for(int i = 0; i != n; ++i) {
-    ++ssize[graph.partition[i] - 1];
+    if (!options.partitionByExtrusion)
+      ++ssize[graph.partition[i] - 1];
     graph.element[i]->setPartition(graph.partition[i]);
   }
+  // Assign partitions to boundary elements
+  const int nb = boElemGrVec.size();
+  for(int i = 0; i != nb; ++i) {
+    boElemGrVec[i].elem->setPartition(graph.partition[boElemGrVec[i].grVert]);
+  }
+  // propagate partition information to extruded elements
+  if (options.partitionByExtrusion) {
+    unsigned numElem[5];
+    const int meshDim = model->getNumMeshElements(numElem);
+    switch(meshDim) {
+      case 2:
+      // assing partitions for 2D faces and count number of elems in each partition
+      for (GModel:: fiter fit = model->firstFace(); fit != model->lastFace(); fit++) {
+        ExtrudeParams* epFace = (*fit)->meshAttributes.extrude;
+        GEdge *sourceEdge = model->getEdgeByTag(std::abs(epFace->geo.Source));
+        epFace->elementMap.propagatePartitionInformation(&ssize);
+        // loop over extruded edges to set partitions
+        std::list<GEdge*> regionEdges = (*fit)->edges();
+        for (std::list<GEdge*>::iterator eit = regionEdges.begin(); eit != regionEdges.end(); eit++) {
+          ExtrudeParams* epEdge = (*eit)->meshAttributes.extrude;
+          if((*eit)!=sourceEdge && epEdge && !epEdge->elementMap.empty())
+            epEdge->elementMap.propagatePartitionInformation();
+        }
+      }
+        break;
+      case 3:
+      // assing partitions for 3D volumes and count number of elems in each partition
+      for (GModel:: riter rit = model->firstRegion(); rit != model->lastRegion(); rit++) {
+        ExtrudeParams* epRegion = (*rit)->meshAttributes.extrude;
+        GFace *sourceFace = model->getFaceByTag(std::abs(epRegion->geo.Source));
+        epRegion->elementMap.propagatePartitionInformation(&ssize);
+        // loop over extruded faces to set partitions
+        std::list<GFace*> regionFaces = (*rit)->faces();
+        for (std::list<GFace*>::iterator fit = regionFaces.begin(); fit != regionFaces.end(); fit++) {
+          if ((*fit) == sourceFace)
+            continue;
+          ExtrudeParams* epFace = (*fit)->meshAttributes.extrude;
+          epFace->elementMap.propagatePartitionInformation();
+          // loop over bounding edges to set partitions
+          std::list<GEdge*> edges = (*fit)->edges();
+          GEdge *sourceEdge = model->getEdgeByTag(std::abs(epFace->geo.Source));
+          for (std::list<GEdge*>::iterator eit = edges.begin(); eit != edges.end(); eit++) {
+            ExtrudeParams* epEdge = (*eit)->meshAttributes.extrude;
+            if((*eit)!=sourceEdge && epEdge && epEdge->geo.Mode == COPIED_ENTITY)
+              // extruded edges have no source elements (extruded from vertex)
+              epEdge->elementMap.propagatePartitionInformation();
+          }
+        }
+      } // TODO: generalize to 2D too
+      break;
+    }
+  }
   int sMin = graph.getNumVertex();
   int sMax = 0;
   for(int i = 0; i != options.num_partitions; ++i) {
@@ -286,12 +340,6 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options)
   model->setMinPartitionSize(sMin);
   model->setMaxPartitionSize(sMax);
 
-  // Assign partitions to boundary elements
-  const int nb = boElemGrVec.size();
-  for(int i = 0; i != nb; ++i) {
-    boElemGrVec[i].elem->setPartition(graph.partition[boElemGrVec[i].grVert]);
-  }
-
   model->recomputeMeshPartitions();
 
   if (options.createPartitionBoundaries || options.createGhostCells)
@@ -500,7 +548,7 @@ int RenumberGraph(Graph &graph, meshPartitionOptions &options)
  *
  ******************************************************************************/
 
-int MakeGraph(GModel *const model, Graph &graph, BoElemGrVec *const boElemGrVec)
+int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options, BoElemGrVec *const boElemGrVec)
 {
 
   enum {
@@ -516,15 +564,15 @@ int MakeGraph(GModel *const model, Graph &graph, BoElemGrVec *const boElemGrVec)
     ElemTypePolyg = 2
   };
 
-  int ier = 0;  
+  int ier = 0;
 //   switch(partitionScope) {
 //   case PartitionEntireDomain:
-
+  if(!options.partitionByExtrusion){
 /*--------------------------------------------------------------------*
  * Make a graph for the entire domain
  *--------------------------------------------------------------------*/
 
-    {
+    
 
 //--Get the dimension of the mesh and count the numbers of elements
 
@@ -584,6 +632,79 @@ int MakeGraph(GModel *const model, Graph &graph, BoElemGrVec *const boElemGrVec)
         break;
       }
     }
+    else {
+/*--------------------------------------------------------------------*
+ * Create graph for extrusion source entity (propagate group ids later)
+ *--------------------------------------------------------------------*/
+      unsigned tmp[5];
+      const int meshDim = model->getNumMeshElements(tmp);
+      if(meshDim < 2) {
+        Msg::Error("No mesh elements were found");
+        return 1;
+      }
+      std::vector<const GEntity*> sourceEntities;
+      std::set<const GEntity*> bannedEntities;
+      unsigned numElem[5] = {0,0,0,0,0};
+      switch(meshDim) {
+        case 2:
+          for(GModel::fiter it = model->firstFace(); it != model->lastFace(); ++it){
+            ExtrudeParams* ep = (*it)->meshAttributes.extrude;
+            const GEdge *edge = model->getEdgeByTag(std::abs(ep->geo.Source));
+            if(!edge){
+              Msg::Error("Unknown source edge %d for extrusion", ep->geo.Source);
+              continue;
+            }
+            // mark face for partitioning if not associated to already processed face
+            if (bannedEntities.find(edge) == bannedEntities.end()) {
+              sourceEntities.push_back(edge);
+              edge->getNumMeshElements(numElem);
+            }
+            // do not allow partitioning of the extruded edges
+            std::list<GEdge*> edges = (*it)->edges();
+            for(std::list<GEdge*>::iterator eit = edges.begin(); eit != edges.end(); eit++) {
+              bannedEntities.insert((*eit));
+            }
+          }
+          break;
+        case 3:
+          for(GModel::riter it = model->firstRegion(); it != model->lastRegion(); ++it){
+            ExtrudeParams* ep = (*it)->meshAttributes.extrude;
+            const GFace *face = model->getFaceByTag(std::abs(ep->geo.Source));
+            if(!face){
+              Msg::Error("Unknown source surface %d for extrusion", ep->geo.Source);
+              continue;
+            }
+            // mark face for partitioning if not associated to already processed region
+            if (bannedEntities.find(face) == bannedEntities.end()) {
+              sourceEntities.push_back(face);
+              face->getNumMeshElements(numElem);
+            }
+            // do not allow partitioning of the extruded faces
+            std::list<GFace*> faces = (*it)->faces();
+            for(std::list<GFace*>::iterator fit = faces.begin(); fit != faces.end(); fit++) {
+              bannedEntities.insert((*fit));
+            }
+          }
+          break;
+      }
+      // build a graph only on the source entities
+      try {
+        // Allocate memory for the graph
+        const int numGrVert = numElem[ElemTypeTri] + numElem[ElemTypeQuad]
+                              + numElem[ElemTypePolyg];
+        const int maxGrEdge = (numElem[ElemTypeTri]*3 + numElem[ElemTypeQuad]*4
+                                + numElem[ElemTypePolyg]*4)/2;
+        graph.allocate(numGrVert, maxGrEdge);
+        // Make the graph
+        MakeGraphDIM<2>(sourceEntities.begin(), sourceEntities.end(),
+                        model->firstEdge(), model->lastEdge(), graph,
+                        boElemGrVec);
+      }
+      catch (...){
+        Msg::Error("Exception thrown during graph generation");
+        ier = 2;
+      }
+    }
 //     break;
     
 //   case PartitionByPhysical:
diff --git a/Mesh/meshPartitionOptions.h b/Mesh/meshPartitionOptions.h
index d4f73da384dcf2217ab964a63d6d7394fe9a7550..2867ab086c199ae2f31b4778e8a87a064e9f0ede 100644
--- a/Mesh/meshPartitionOptions.h
+++ b/Mesh/meshPartitionOptions.h
@@ -69,6 +69,8 @@ struct meshPartitionOptions
                                         // 3 - Random boundary refinement (with
                                         //     minimization of connectivity
                                         //     along sub-domains)
+  int partitionByExtrusion;            // if true, all extruded elements belong
+                                       // to the same partition as the source element
 
 //--NODAL WEIGHT
   std::vector<int> nodalWeights;
@@ -109,6 +111,7 @@ struct meshPartitionOptions
     refine_algorithm = 3;
     createPartitionBoundaries = true;
     createGhostCells = true;
+    partitionByExtrusion =false;
   }
 
 };
diff --git a/benchmarks/extrude/partitionByExtrusion_spirale.geo b/benchmarks/extrude/partitionByExtrusion_spirale.geo
new file mode 100644
index 0000000000000000000000000000000000000000..401625dbd92c90af69489b991aed89a75a140829
--- /dev/null
+++ b/benchmarks/extrude/partitionByExtrusion_spirale.geo
@@ -0,0 +1,115 @@
+// Extrusion and rotation. Christophe Geuzaine, Feb 2002.
+
+lc = 0.005;
+lc2 = 4*lc;
+
+Point(1)={0.09,0,0,lc};
+Point(2)={0.11,0,0,lc};
+Point(3)={0,0.09,0,lc};
+Point(4)={0,0.11,0,lc};
+Point(5)={0.2,0.09,0,lc};
+Point(6)={0.2,0.11,0,lc};
+Point(7)={0.09,0.2,0,lc};
+Point(8)={0.11,0.2,0,lc};
+Point(9)={0.09,0.09,0,lc2};
+Point(10)={0.09,0.11,0,lc2};
+Point(11)={0.11,0.11,0,lc2};
+Point(12)={0.11,0.09,0,lc2};
+
+Line(1) = {1,2};
+Line(2) = {2,12};
+Line(3) = {12,5};
+Line(4) = {5,6};
+Line(5) = {6,11};
+Line(6) = {11,8};
+Line(7) = {8,7};
+Line(8) = {7,10};
+Line(9) = {10,4};
+Line(10) = {4,3};
+Line(11) = {3,9};
+Line(12) = {9,1};
+
+Line Loop(13) = {2,3,4,5,6,7,8,9,10,11,12,1};
+Plane Surface(14) = {13};
+
+turns = 1/3;
+zz = 0.01;
+cc = 0.1;
+
+Extrude Surface {news-1, {0,0,2*zz}, {0,0,1} , {cc,cc,0} , 0}
+                { Layers {2}; Recombine; };
+
+For j In {1:3}
+  Extrude Surface {news-1, {0,0,zz}, {0,0,1} , {cc,cc,0} , Pi/(40*(4-j))}
+                  { Layers {1}; Recombine; };
+EndFor
+
+For j In {1:turns*8}
+  Extrude Surface {news-1, {0,0,10*zz}, {0,0,1} , {cc,cc,0} , Pi/4}
+                  { Layers {10}; Recombine; };
+EndFor
+
+For j In {1:3}
+  Extrude Surface {news-1, {0,0,zz}, {0,0,1} , {cc,cc,0} , Pi/(40*j)}
+                  { Layers {1}; Recombine; };
+EndFor
+
+Extrude Surface {news-1, {0,0,2*zz}, {0,0,1} , {cc,cc,0} , 0}
+                { Layers {2}; Recombine; };
+
+p = newp;
+
+Point(p+1000)={0.1, -0.02, 0,lc};
+Point(p+1001)={0.1, -0.01, 0,lc};
+Point(p+1002)={0.1, -0.02, 0.01,lc};
+Point(p+1003)={0.1, -0.03, 0,lc};
+Point(p+1004)={0.1, -0.02, -0.01,lc};
+
+Circle(1635) = {p+1001,p+1000,p+1002};
+Circle(1636) = {p+1002,p+1000,p+1003};
+Circle(1637) = {p+1003,p+1000,p+1004};
+Circle(1638) = {p+1004,p+1000,p+1001};
+
+Line Loop(1639) = {1635,1636,1637,1638};
+Plane Surface(1640) = {1639};
+
+turns = 2;
+zz = 0.01/4;
+
+For j In {1:8*turns}
+  Extrude Surface {news-1, {0,0,10*zz}, {0,0,1} , {cc,cc,0} , Pi/4}
+                  { Layers {10}; Recombine; };
+EndFor
+
+Point(p+4000)={0.1, -0.02 + 0.24, 0, lc};
+Point(p+4001)={0.1, -0.01 + 0.24, 0, lc};
+Point(p+4002)={0.1, -0.02 + 0.24, 0.01, lc};
+Point(p+4003)={0.1, -0.03 + 0.24, 0, lc};
+Point(p+4004)={0.1, -0.02 + 0.24, -0.01, lc};
+Circle(4635) = {p+4001,p+4000,p+4002};
+Circle(4636) = {p+4002,p+4000,p+4003};
+Circle(4637) = {p+4003,p+4000,p+4004};
+Circle(4638) = {p+4004,p+4000,p+4001};
+
+Line Loop(4639) = {4635,4636,4637,4638};
+Plane Surface(4640) = {4639};
+
+For j In {1:8*turns}
+  Extrude Surface {news-1, {0,0,10*zz}, {0,0,1} , {cc,cc,0} , Pi/4}
+                  { Layers {10}; Recombine; };
+EndFor
+
+// options
+Mesh.PartitionByExtrusion=1; // forces partitioning by columns
+Mesh.NbPartitions=20;
+Mesh.ColorCarousel = 3;
+Mesh.SurfaceFaces= 1;
+Mesh.VolumeEdges = 0;
+Mesh.VolumeFaces = 1;
+Mesh.Color.Zero = {255,0,0};
+Mesh.Color.One = {0,0,255};
+Mesh.Color.Two = {0,255,0};
+Mesh.Color.Three = {255,255,0};
+Mesh.Color.Four = {255,0,255};
+Mesh.Color.Six = {255,128,0};
+Mesh.Color.Seven = {64,128,32};