diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp
index aae88152ff08426b16e16a3641588e454414fe50..305f283d3e462f4d6fd21e6a44a2bf3f8dbd9cb7 100644
--- a/Geo/GFaceCompound.cpp
+++ b/Geo/GFaceCompound.cpp
@@ -467,7 +467,7 @@ bool GFaceCompound::parametrize() const
     Msg::Info("Parametrization failed using standard techniques : moving to convex combination");
     coordinates.clear(); 
     Octree_Delete(oct);
-    fillNeumannBCS();
+    //fillNeumannBCS();
     parametrize(ITERU,CONVEXCOMBINATION);
     parametrize(ITERV,CONVEXCOMBINATION);
     buildOct();
@@ -974,14 +974,14 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const
       myAssembler.numberVertex(t->getVertex(2), 0, 1); 
     }    
   }
-  if (tom == CONVEXCOMBINATION){
-    for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
-      MTriangle *t = (*it2);
-      myAssembler.numberVertex(t->getVertex(0), 0, 1);
-      myAssembler.numberVertex(t->getVertex(1), 0, 1);
-      myAssembler.numberVertex(t->getVertex(2), 0, 1); 
-    }   
-  }
+//   if (tom == CONVEXCOMBINATION){
+//     for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
+//       MTriangle *t = (*it2);
+//       myAssembler.numberVertex(t->getVertex(0), 0, 1);
+//       myAssembler.numberVertex(t->getVertex(1), 0, 1);
+//       myAssembler.numberVertex(t->getVertex(2), 0, 1); 
+//     }   
+//   }
   
 
   Msg::Debug("Creating term %d dofs numbered %d fixed",
@@ -998,10 +998,10 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const
 	laplace.addToMatrix(myAssembler, &se);
       }
     }
-    for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
-      SElement se((*it2));
-      laplace.addToMatrix(myAssembler, &se);
-    }
+//     for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
+//       SElement se((*it2));
+//       laplace.addToMatrix(myAssembler, &se);
+//     }
   }
   else {
     laplaceTerm laplace(model(), 1, &ONE);
@@ -1185,10 +1185,10 @@ void GFaceCompound::computeNormals() const
     for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){
       MTriangle *t = (*it)->triangles[i];
       t->getJacobian(0, 0, 0, J);
-      // SVector3 n (J[2][0],J[2][1],J[2][2]);
-      SVector3 d1(J[0][0], J[0][1], J[0][2]);
-      SVector3 d2(J[1][0], J[1][1], J[1][2]);
-      SVector3 n = crossprod(d1, d2);
+      SVector3 n (J[2][0],J[2][1],J[2][2]);
+      //SVector3 d1(J[0][0], J[0][1], J[0][2]);
+      //SVector3 d2(J[1][0], J[1][1], J[1][2]);
+      //SVector3 n = crossprod(d1, d2);
       n.normalize();
       for(int j = 0; j < 3; j++){
 	std::map<MVertex*, SVector3>::iterator itn = _normals.find(t->getVertex(j));
@@ -1253,7 +1253,7 @@ GPoint GFaceCompound::point(double par1, double par2) const
     return lt->gf->point(pv.x(),pv.y());
   }
   
-  const bool LINEARMESH = false;
+  const bool LINEARMESH = true; //false
 
   if(LINEARMESH){
 
@@ -1285,7 +1285,7 @@ GPoint GFaceCompound::point(double par1, double par2) const
     w32 = dot(lt->v2 - lt->v3, n3);
     w31 = dot(lt->v1 - lt->v3, n3);
     w13 = dot(lt->v3 - lt->v1, n1);
-    b210 = (2*lt->v1 + lt->v2 -w12*n1)*0.333; 
+    b210 = (2*lt->v1 + lt->v2-w12*n1)*0.333; 
     b120 = (2*lt->v2 + lt->v1-w21*n2)*0.333;
     b021 = (2*lt->v2 + lt->v3-w23*n2)*0.333;
     b012 = (2*lt->v3 + lt->v2-w32*n3)*0.333;
@@ -1515,7 +1515,7 @@ bool GFaceCompound::checkAspectRatio() const
   bool paramOK = true;
   if(allNodes.empty()) buildAllNodes();
   
-  double limit =  1.e15 ;
+  double limit =  1.e15;
   double areaMax = 0.0;
   int nb = 0;
   std::list<GFace*>::const_iterator it = _compound.begin();
@@ -1548,7 +1548,8 @@ bool GFaceCompound::checkAspectRatio() const
     SBoundingBox3d bboxH = bounds();
     double H = norm(SVector3(bboxH.max(), bboxH.min()));
     double D = getSizeBB(_U0);
-    int split =  (int)ceil(.7*H/D);
+    double eta = H/D;
+    int split =  (int)ceil(eta/3);
     nbSplit = std::max(split,2); 
     //printf("H=%g, D=%g split=%d nbSplit=%d \n", H, D, split, nbSplit);
     Msg::Info("Partition geometry in N=%d parts", nbSplit);
diff --git a/Geo/discreteEdge.cpp b/Geo/discreteEdge.cpp
index 4100580492699e02033e0dfee575a302ade63358..01c2d9fd16ba287b907a4e45a7cc4ac7559e813a 100644
--- a/Geo/discreteEdge.cpp
+++ b/Geo/discreteEdge.cpp
@@ -400,7 +400,7 @@ GPoint discreteEdge::point(double par) const
   MVertex *vB = lines[iEdge]->getVertex(0);
   MVertex *vE = lines[iEdge]->getVertex(1);
 
-  const bool LINEARMESH = false;
+  const bool LINEARMESH = true; //false;
   
   if (LINEARMESH){
     //linear Lagrange mesh
diff --git a/Mesh/multiscalePartition.cpp b/Mesh/multiscalePartition.cpp
index 84d282eaa39b48e4741123473d4cee1ccb41c00e..a4b7f8e6e3a48ec21fb429c280f1dd06838fb3b1 100644
--- a/Mesh/multiscalePartition.cpp
+++ b/Mesh/multiscalePartition.cpp
@@ -23,11 +23,9 @@ static void recur_connect (MVertex *v,
 
 }
 
-static int connected_bounds (std::vector<MEdge> &edges)
+static int connected_bounds (std::vector<MEdge> &edges,  std::vector<std::vector<MEdge> > &boundaries)
 {
 
-  std::vector<std::vector<MEdge> > regions;
-  
   std::multimap<MVertex*,MEdge> v2e;
   for (int i=0;i<edges.size();++i){
     for (int j=0;j<edges[i].getNumVertices();j++){
@@ -40,15 +38,17 @@ static int connected_bounds (std::vector<MEdge> &edges)
     recur_connect (v2e.begin()->first,v2e,group,touched);
     std::vector<MEdge> temp;
     temp.insert(temp.begin(), group.begin(), group.end());
-    regions.push_back(temp);
+    boundaries.push_back(temp);
     for ( std::set<MVertex*>::iterator it = touched.begin() ; it != touched.end();++it)
       v2e.erase(*it);
   }
 
-  return regions.size();
+  return boundaries.size();
 }
 
-static int getGenus (std::vector<MElement *> &elements){ 
+
+static int getGenus (std::vector<MElement *> &elements,  
+		     std::vector<std::vector<MEdge> > &boundaries){ 
 
  //We suppose MElements are simply connected
  
@@ -80,7 +80,7 @@ static int getGenus (std::vector<MElement *> &elements){
 	 bEdges.erase(std::find(bEdges.begin(), bEdges.end(),me));
     }    
   }    
-  nbBounds = connected_bounds(bEdges);
+  nbBounds = connected_bounds(bEdges, boundaries);
   int genus = (int)(-poincare + 2 - nbBounds)/2;
 
   //printf("************** partition has %d boundaries and genus =%d \n", nbBounds, genus);
@@ -89,31 +89,66 @@ static int getGenus (std::vector<MElement *> &elements){
 
 }
 
-// static int getGeomAspectRatio (std::vector<MElement *> &elements){ 
+static int getAspectRatio (std::vector<MElement *> &elements, 
+			      std::vector<std::vector<MEdge> > &boundaries)
+{ 
+ 
+  std::set<MVertex*> vs;
+  for(unsigned int i = 0; i < elements.size(); i++){
+    MElement *e = elements[i];
+    for(int j = 0; j < e->getNumVertices(); j++){
+      vs.insert(e->getVertex(j));
+    }
+  }
+ SBoundingBox3d bb;
+ SOrientedBoundingBox obbox ;
+  std::vector<SPoint3> vertices;
+  for (std::set<MVertex* >::iterator it = vs.begin(); it != vs.end(); it++){
+    SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z());
+    vertices.push_back(pt);
+    bb +=pt;
+  }
+   
+//  obb =  SOrientedBoundingBox::buildOBB(vertices);
+//  double H = obbox.getMaxSize(); 
+ double H = norm(SVector3(bb.max(), bb.min()));
+ 
+ double D = 0.0;
+  if (boundaries.size() == 0){
+    D=1.;
+  }
+  else{
+    for (int i=0; i< boundaries.size(); i++){
+      std::set<MVertex*> vb;
+      std::vector<MEdge> iBound = boundaries[i];
+      for (int j=0; j< iBound.size(); j++){
+	MEdge e = iBound[j];
+	vb.insert(e.getVertex(0));
+	vb.insert(e.getVertex(1));
+      }
+      std::vector<SPoint3> vBounds;
+      for (std::set<MVertex* >::iterator it = vb.begin(); it != vb.end(); it++){
+	SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z());
+	vBounds.push_back(pt);
+      }
+      SOrientedBoundingBox obboxD = SOrientedBoundingBox::buildOBB(vBounds);
+      D = std::max(D, obboxD.getMaxSize());
+    }
+  }
+  int eta = (int)ceil(H/D);
+
+  return eta;
 
-//   std::set<MVertex*> vs;
-//   for(unsigned int i = 0; i < elements.size(); i++){
-//     MElement *e = elements[i];
-//     for(int j = 0; j < e->getNumVertices(); j++){
-//       vs.insert(e->getVertex(j));
-//     }
-//   }
-  
-//   std::vector<SPoint3> vertices;
-//   for (std::set<MVertex* >::iterator it = vs.begin(); it != vs.end(); it++){
-//     SPoint3 pt((*it)->x(),(*it)->y(), (*it)->z());
-//     vertices.push_back(pt);
-//   }
-
-//   SOrientedBoundingBox obbox = SOrientedBoundingBox::buildOBB(vertices);
-//   double eta = obbox.getMaxSize()/obbox.getMinSize();
-  
-//   printf("aspect ratio = %g (max=%g, min=%g)\n", eta, obbox.getMaxSize(), obbox.getMinSize() );
+}
+static void getGenusAndRatio(std::vector<MElement *> &elements, int & genus, int &eta){
 
-//   return eta;
+  std::vector<std::vector<MEdge> > boundaries;
+  genus = getGenus(elements, boundaries);  
+  eta = getAspectRatio(elements, boundaries);
 
-// }
+  return;
 
+}
 static void partitionRegions (std::vector<MElement*> &elements, 
 			      std::vector<std::vector<MElement*> > &regions){
   
@@ -127,6 +162,7 @@ static void partitionRegions (std::vector<MElement*> &elements,
 
 }
 
+
 multiscalePartition::multiscalePartition (std::vector<MElement *> &elements, 
 					  meshPartitionOptions &_options){
   
@@ -144,6 +180,13 @@ multiscalePartition::multiscalePartition (std::vector<MElement *> &elements,
   totalParts = assembleAllPartitions();
 
 }
+void multiscalePartition:: setNumberOfPartitions(int &nbParts)
+{
+  options.num_partitions = nbParts;
+   if ( options.partitioner == 1){
+     options.mesh_dims[0] = nbParts;
+   }
+}
 
 void multiscalePartition::partition(partitionLevel & level){
 #if defined(HAVE_METIS) || defined(HAVE_CHACO)
@@ -161,20 +204,23 @@ void multiscalePartition::partition(partitionLevel & level){
     nextLevel->region = i;
 
     levels.push_back(nextLevel);
-
-    int genus = getGenus(regions[i]);
+    int genus, eta;
+    getGenusAndRatio(regions[i], genus, eta);
     if (genus < 0) {
       Msg::Error("Genus partition is negative G=%d!", genus);
       exit(1);
     }
-    if (genus != 0 ){
-      Msg::Info("Multiscale partition, level %d region %d  is %d-GENUS -> partition",
-		nextLevel->recur,nextLevel->region, genus);
+    if (genus != 0 || eta > 4 ){
+      int nbParts = std::max(genus+2, (int)eta/4);
+      setNumberOfPartitions(nbParts);
+      Msg::Info("Multiscale partition, level %d region %d  is %d-GENUS (ETA=%d) ---> partition %d parts",
+		nextLevel->recur,nextLevel->region, genus, eta, nbParts);
+      
       partition(*nextLevel);
     }
     else {
-      Msg::Info("Multiscale Partition, level %d, region %d is ZERO-GENUS", 
-		nextLevel->recur,nextLevel->region);
+      Msg::Info("Multiscale Partition, level %d, region %d is ZERO-GENUS (ETA=%d)", 
+		nextLevel->recur,nextLevel->region, eta);
     }
      
 }
@@ -185,7 +231,6 @@ void multiscalePartition::partition(partitionLevel & level){
 int multiscalePartition::assembleAllPartitions(){
 
   int nbParts =  1;   
-  //int nbLevel = options.num_partitions;
 
   for (int i = 0; i< levels.size(); i++){
     partitionLevel *iLevel = levels[i];
@@ -199,6 +244,13 @@ int multiscalePartition::assembleAllPartitions(){
     }
   }
 
+  Msg::Info("-----------------------------------------------------------");
+  Msg::Info("Multiscale Partition SUCCESSFULLY PERFORMED : %d parts", nbParts-1);
+  Msg::Info("-----------------------------------------------------------");
+ 
+
   return nbParts-1;
 
+ 
+
 }
diff --git a/Mesh/multiscalePartition.h b/Mesh/multiscalePartition.h
index 4d3db6d9e8e68d5d238c03958b1f81f21417b35d..0a5e1538d7fb1ecd7530a8ab0d58788020097d66 100644
--- a/Mesh/multiscalePartition.h
+++ b/Mesh/multiscalePartition.h
@@ -32,6 +32,7 @@ class multiscalePartition{
   multiscalePartition(std::vector<MElement *> &elements, 
 		      meshPartitionOptions &options);
   int assembleAllPartitions();
+  void setNumberOfPartitions(int &nbParts);
   int getNumberOfParts(){return totalParts;}
 };
 
diff --git a/contrib/Chaco/main/Gmsh_printf.cpp b/contrib/Chaco/main/Gmsh_printf.cpp
index 2f35dd581db66346c964c759a1c848ce1c484fa8..4ae2d6c75e348b41822f8491f2508c82bffe39d2 100644
--- a/contrib/Chaco/main/Gmsh_printf.cpp
+++ b/contrib/Chaco/main/Gmsh_printf.cpp
@@ -7,7 +7,7 @@
 #include <cstring>
 #include "GmshMessage.h"
 
-// Overload the printf statements in Chaco to write using Msg::Direct in gmsh
+// Overload the printf statements in Chaco to write using Msg::Debug in gmsh
 
 extern "C" int Gmsh_printf(const char *fmt, ...)
 {
@@ -23,17 +23,17 @@ extern "C" int Gmsh_printf(const char *fmt, ...)
   char *p = std::strtok(str, "\n");
   if(p) {
     // If more than 1 leading '\n', print a blank line
-    if(p - str > 1) Msg::Direct(" ");
+    if(p - str > 1) Msg::Debug(" ");
     std::strcpy(buf, p);
-    Msg::Direct(buf);
+    Msg::Debug(buf);
     // New line for each interior '\n'
     while((p = std::strtok(NULL, "\n"))) {
       std::strcpy(buf, p);
-      Msg::Direct(buf);
+      Msg::Debug(buf);
     }
   }
   // If more than 1 trailing '\n', or only "\n" in the string, print a blank
   // line.
-  if(*last == '\n') Msg::Direct(" ");
+  if(*last == '\n') Msg::Debug(" ");
   return 0;
 }
diff --git a/contrib/Chaco/misc/countup_mesh.c b/contrib/Chaco/misc/countup_mesh.c
index 5d1ae7171ae11618b59833384a4e2f12e1723a8b..4e84eac5efce7ad435e0e78965369edfd9e088e6 100644
--- a/contrib/Chaco/misc/countup_mesh.c
+++ b/contrib/Chaco/misc/countup_mesh.c
@@ -241,22 +241,22 @@ int       using_ewgts;		/* are edge weights being used? */
     }
     ncuts /= 2;
     nhops /= 2;
-    printf("\n");
-    printf("                            Total      Max/Set      Min/Set\n");
-    printf("                            -----      -------      -------\n");
-    printf("Set Size:             %11d  %11d  %11d\n",
+    Gmsh_printf("\n");
+    Gmsh_printf("                            Total      Max/Set      Min/Set\n");
+    Gmsh_printf("                            -----      -------      -------\n");
+    Gmsh_printf("Set Size:             %11d  %11d  %11d\n",
     	tot_size, max_size, min_size);
-    printf("Edge Cuts:            %11g  %11g  %11g\n",
+    Gmsh_printf("Edge Cuts:            %11g  %11g  %11g\n",
     	ncuts, maxcuts, mincuts);
-    printf("Mesh Hops:            %11g  %11g  %11g\n",
+    Gmsh_printf("Mesh Hops:            %11g  %11g  %11g\n",
     	nhops, maxhops, minhops);
-    printf("Boundary Vertices:    %11g  %11g  %11g\n",
+    Gmsh_printf("Boundary Vertices:    %11g  %11g  %11g\n",
     	total_bdyvtxs, maxbdy, minbdy);
-    printf("Boundary Vertex Hops: %11g  %11g  %11g\n",
+    Gmsh_printf("Boundary Vertex Hops: %11g  %11g  %11g\n",
     	bdyvtx_hops_tot, bdyvtx_hops_max, bdyvtx_hops_min);
-    printf("Adjacent Sets:        %11d  %11d  %11d\n",
+    Gmsh_printf("Adjacent Sets:        %11d  %11d  %11d\n",
     	total_neighbors, maxneighbors, minneighbors);
-    printf("Internal Vertices:    %11d  %11d  %11d\n\n",
+    Gmsh_printf("Internal Vertices:    %11d  %11d  %11d\n\n",
     	total_internal, max_internal, min_internal);
 
 
diff --git a/contrib/Chaco/submain/submain.c b/contrib/Chaco/submain/submain.c
index 24d9155c0008e9a9f68173b77c589f308f5c6973..ff34e0b65eb11b88aa659df239a2ccd026255fe2 100644
--- a/contrib/Chaco/submain/submain.c
+++ b/contrib/Chaco/submain/submain.c
@@ -172,7 +172,7 @@ long      seed;			/* for random graph mutations */
     }
 
     if (PRINT_HEADERS) {
-        printf("\n\nStarting to partition ...\n\n");
+        Gmsh_printf("\n\nStarting to partition ...\n\n");
 	if (Output_File != NULL ) {
             fprintf(Output_File,
 	    "\n\nStarting to partition ... (residual, warning and error messages only)\n\n");