diff --git a/Geo/discreteFace.cpp b/Geo/discreteFace.cpp
index e9090f7a6f4d4562f7a4745e8d13ae784489775a..3f3d6b8b185c341c4c67633efa8d4d44f76f6ca1 100644
--- a/Geo/discreteFace.cpp
+++ b/Geo/discreteFace.cpp
@@ -114,8 +114,8 @@ void discreteFace::createGeometry()
 
   int order = 1;
   int nPart = 2;
-  std::vector<triangulation*> part;
-  part.resize(nPart);
+  //std::vector<triangulation*> part;
+  //part.resize(nPart);
 #if defined(HAVE_ANN) && defined(HAVE_SOLVER)
 
   if (!_atlas.empty())return;
@@ -129,30 +129,30 @@ void discreteFace::createGeometry()
   init->my_GEdges = l_edges;
 
   toSplit.push(init);
-  int mygen, compteur=1;
+  //int mygen, compteur=1;//#debug
   Msg::Info("First Genus Value:");
-  //std::cin>>mygen;
-  mygen=1;
-  if(mygen!=0){//((toSplit.top())->genus()!=0){
+  
+  //mygen=1; //#debug
+  if((toSplit.top())->genus()!=0){// (mygen!=0){//#debug
    
     while( !toSplit.empty()){
-
+      std::vector<triangulation*> part;
       triangulation* tosplit = toSplit.top();
       toSplit.pop();
 
       split(tosplit,part,nPart);
       delete tosplit; // #mark
 
-      for(int i=0; i<nPart; i++){
-	Msg::Info("Partition %d Genus:",compteur);
-	std::cin>>mygen;
-	if(mygen!=0)//part[i]->genus()!=0)
+      for(unsigned int i=0; i<part.size(); i++){
+	//Msg::Info("Partition %d Genus:",compteur);//#debug
+	//std::cin>>mygen;//#debug
+	if(part[i]->genus()!=0)// (mygen!=0)//#debug
 	  toSplit.push(part[i]);
 	else{
 	  toParam.push_back(part[i]);
 	  part[i]->idNum=id++;
 	}
-	compteur++;
+	//compteur++; //#debug
       }// end for i
     }// !.empty()    
   }// end if it is not disk-like
@@ -308,45 +308,51 @@ void discreteFace::checkAndFixOrientation(){
   } // end while
 }
 
+void discreteFace::setupDiscreteVertex(GVertex*dv,MVertex*mv,std::set<MVertex*>*trash){
+  dv->mesh_vertices.push_back(mv);
+  mv->setEntity(dv);
+  this->model()->add(dv);
+  if (trash) trash->insert(mv);
+}
+
+void discreteFace::setupDiscreteEdge(discreteEdge*de,std::vector<MLine*>mlines,std::set<MVertex*>*trash){
+  this->model()->add(de);// new GEdge
+  de->lines = mlines;// associated MLine's
+  for(unsigned int i=1; i<mlines.size(); i++){//not the first vertex of the GEdge (neither the last one)
+    mlines[i]->getVertex(0)->setEntity(de);
+    de->mesh_vertices.push_back(mlines[i]->getVertex(0));
+    if(trash) trash->insert(mlines[i]->getVertex(0));
+  }	
+  de->createGeometry();
+}
+
+
 // split old GEdge's
 void discreteFace::splitDiscreteEdge ( GEdge *de , GVertex *gv, discreteEdge* newE[2]){
 
-  MVertex *vstart = de->getBeginVertex()->mesh_vertices[0];
-  //MVertex *vend   = de->getEndVertex()->mesh_vertices[0];
-
-  // We create a new Model vertex and we classify
-  /*
-  discreteVertex *newV = new discreteVertex (de->model(),NEWPOINT());
-  newV->mesh_vertices.push_back (v);
-  v->setEntity (newV);
-  de->model()->add(newV);*/
+  MVertex *vend = de->getEndVertex()->mesh_vertices[0];
   
-  // We create 2 new Model edges and we classify vertices
-  // The creation of discrete edge geometries have already been done (or not)
-  // FIXME !!!!!
-  //discreteEdge *newE[2];
   newE[0] = new discreteEdge (de->model(),NEWLINE(),de->getBeginVertex(),gv);
   newE[1] = new discreteEdge (de->model(),NEWLINE(),gv, de->getEndVertex());
-  de->model()->add(newE[0]);
-  de->model()->add(newE[1]);
+  //de->model()->add(newE[0]);
+  //de->model()->add(newE[1]);
   
   int current = 0;
-  
+  std::vector<MLine*> mlines;
   // assumption: the MLine's are sorted
   for (unsigned int i=0;i<de->lines.size();i++){
-    MLine *l = de->lines[i];
-    newE[current]->lines.push_back(l);
-    if (l->getVertex(0) != vstart && l->getVertex(0) != gv->mesh_vertices[0]) {
-      l->getVertex(0)->setEntity(newE[current]);
-      newE[current]->mesh_vertices.push_back(l->getVertex(0));
+    MLine *l = de->lines[i];    
+    mlines.push_back(l);   
+    if (l->getVertex(1) == gv->mesh_vertices[0] || l->getVertex(1) == vend){
+      setupDiscreteEdge(newE[current],mlines,NULL);
+      mlines.clear();// 
+      current++;
     }
-    if (l->getVertex(1) ==  gv->mesh_vertices[0]) current ++;
   }
-  for(int ie=0; ie<2; ie++)  newE[ie]->createGeometry();
+  //for(int ie=0; ie<2; ie++)  newE[ie]->createGeometry();  
   de->mesh_vertices.clear();
-  de->lines.clear();  
+  de->lines.clear();
   
-
   // We replace de by its 2 parts in every face that is adjacent to de
   std::list<GFace*> faces = de->faces();
   for (std::list<GFace*>::iterator it = faces.begin(); it != faces.end(); ++it){
@@ -367,11 +373,10 @@ void discreteFace::splitDiscreteEdge ( GEdge *de , GVertex *gv, discreteEdge* ne
 	df->l_edges.clear();
 	df->setBoundEdges (df->model(), tagEdges);
       }
-      else Msg::Fatal("discreteFace::splitDiscreteEdge \t This only applies to discrete geometries");      
+      else Msg::Fatal("discreteFace::splitDiscreteEdge \t This only applies to discrete geometries"); 
     }    
   }  
-  de->model()->remove(de);
-  
+  de->model()->remove(de);  
 }
 
 
@@ -395,70 +400,93 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti
 
     int temp = 0;
     for(int j=0; j<3; j++){ // edge by edge
-
       MEdge ed = current->getEdge(j);
       int nEd = trian->ed2tri[ed].size();
-
       if (nEd > 1){
 	std::vector<int> local = trian->ed2tri[ed];
 	nbh[idx[i]+temp] = local[0] == i ? local[1] : local[0];
 	temp++;
       }
-
     }// end for j
-
     idx[i+1] = idx[i]+temp;
 
   }// end for i
 
-
   int edgeCut;
   std::vector<int> part;
   part.resize(nVertex);
   int zero = 0;
   METIS_PartGraphRecursive(&nVertex,&(idx[0]),&(nbh[0]),NULL,NULL,&zero,&zero,&nPartitions,&zero,&edgeCut,&(part[0]));
 
+  std::map<MElement*,int> el2part;
   std::vector<std::vector<MElement*> > elem;
   elem.resize(nPartitions);
-
-  for(int i=0; i<nVertex; i++)
+  for(int i=0; i<nVertex; i++){
     elem[part[i]].push_back(trian->tri[i]);
+    el2part[trian->tri[i]] = part[i];
+  }  
+  //check connectivity  
+  for(int p=0; p<nPartitions; p++){// part by part
+    std::set<MElement*> celem(elem[p].begin(),elem[p].end());// current elements of the p-th part
+    std::queue<MElement*> my_todo; // todo list, for adjacency check - in order to check the connectivity of the part
+    std::map<MElement*,bool> check_todo; // help to complete todo list
+    std::vector<MElement*> temp = elem[p];
+    MElement* starter = temp[0];
+    my_todo.push(starter);
+    check_todo[starter] = true;
+    celem.erase(starter);// if the element is connected to the previous ones, it is removed from the set
+    while(!my_todo.empty()){
+      MElement* current = my_todo.front();
+      my_todo.pop();
+      for(int j=0; j<3; j++){// adjacency from edges
+	MEdge ed = current->getEdge(j);
+	if(trian->ed2tri[ed].size()>1){
+	  std::vector<int> oldnums = trian->ed2tri[ed];
+	  int on = trian->tri[oldnums[0]] == current ? oldnums[1] : oldnums[0];
+	  if(check_todo.find(trian->tri[on])==check_todo.end() && el2part[trian->tri[on]]==p){
+	    my_todo.push(trian->tri[on]);
+	    check_todo[trian->tri[on]] = true;
+	    celem.erase(trian->tri[on]);
+	  }	  
+	}
+      }// end for j
+    }// end while
+    if(!celem.empty()){// if the set is empty, it means that the part was connected
+      Msg::Info("discreteFace::split(), a partition is not connected: it is going to be fixed.");      
+      std::vector<MElement*> relem(celem.begin(),celem.end());// new part
+      for(unsigned int ie=0; ie<relem.size(); ie++)// updating the id part of the element belonging to the new part
+	el2part[relem[ie]] = nPartitions;
+      nPartitions++;
+      elem.push_back(relem);
+      std::set<MElement*> _elem(elem[p].begin(),elem[p].end());// updating the elements of the current part
+      for(std::set<MElement*>::iterator its=celem.begin(); its!=celem.end(); ++its)
+	_elem.erase(*its);
+      elem[p].clear();
+      std::vector<MElement*> upe(_elem.begin(),_elem.end());
+      elem[p] = upe;      
+    }
+  }// end for p
 
 
-  for(int i=0; i<nPartitions; i++)
-    partition[i] = new triangulation(elem[i],this);
-
-
-
-
-
-
+  for(int i=0; i<nPartitions; i++)// new triangulation of the connected parts
+    partition.push_back(new triangulation(elem[i],this));
 
+  //------------------------------------------------------//
   //---- setting topology, i.e. GEdge's and GVertex's ----//
-
+  //------------------------------------------------------//
   std::set<MVertex*> todelete; // vertices that do not belong to the GFace anymore
-  std::set<GEdge*> gGEdges(trian->my_GEdges.begin(),trian->my_GEdges.end());
-
-  for(int i=0; i<nPartitions; i++){
-  
-    // create new GEdge's
+  std::set<GEdge*> gGEdges(trian->my_GEdges.begin(),trian->my_GEdges.end());// current GEdges of the initial (old) triangulation
+  for(int i=0; i<nPartitions; i++){// each part is going ot be compared with the other ones      
     std::set<MEdge,Less_Edge> bordi = partition[i]->borderEdg;// edges defining the border(s) of the i-th new triangulation
-    
-
-    for(int ii=i+1; ii<nPartitions; ii++){// compare to the ii-th ones, with ii > i since ii < i have already been compared
-      
-
+    for(int ii=i+1; ii<nPartitions; ii++){// compare to the ii-th partitions, with ii > i since ii < i have already been compared
       std::map<MVertex*,MLine*> v02edg;//first vertex of the MLine
       std::set<MVertex*> first, last;
-      for(std::set<MEdge,Less_Edge>::iterator ie = bordi.begin();
-	  ie != bordi.end(); ++ie){// MEdge by MEdge of the i-th triangulation border(s)
-
+      for(std::set<MEdge,Less_Edge>::iterator ie = bordi.begin(); ie != bordi.end(); ++ie){// MEdge by MEdge of the i-th triangulation border(s)
 	std::set<MEdge,Less_Edge> bii = partition[ii]->borderEdg;// edges defining the border(s) of the ii-th new triangulation
-	if(bii.find(*ie)!=bii.end()){// if the border edge is common to both triangulations . . .
-
-	  v02edg[ie->getVertex(0)] = new MLine(ie->getVertex(0),ie->getVertex(1));// . . . a new MLine is created
+	if(bii.find(*ie)!=bii.end()){// if the border edge is common to both triangulations, then it is a future GEdge - composed of MLine's
+	  v02edg[ie->getVertex(0)] = new MLine(ie->getVertex(0),ie->getVertex(1));// a new MLine is created
 
-	  // identifying first and last vertices of GEdge's, if any
+	  // identifying first and last vertices of the future GEdge's, if any
 	  if( first.find(ie->getVertex(1)) != first.end() )
 	    first.erase(ie->getVertex(1));
 	  else
@@ -467,116 +495,83 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti
 	    last.erase(ie->getVertex(0));
 	  else
 	    first.insert(ie->getVertex(0));
-	}
-
+	}// end bii.find
       }//end for ie
 
-
-      //---- creation of the GEdge's from new MLine's ----//
-      
+      //---- creation of the GEdge's from new MLine's ----//      
       while(!first.empty()){// starting with nonloop GEdge's
-
-	GVertex *v[2];
-
+	GVertex *v[2];// a GEdge is defined by two GVertex
 	std::vector<MLine*> myLines;// MLine's of the current nonloop GEdge
 	std::set<MVertex*>::iterator itf = first.begin();
 	MVertex* cv0 = *itf;// starting with a first vertex
 	while(last.find(cv0) == last.end()){// until reaching the corresponding last vertex
 	  myLines.push_back(v02edg[cv0]);// push the correspong MLine
-	  v02edg.erase(cv0);// and erasing it from the "list"
+	  v02edg.erase(cv0);// and erasing it from the map
 	  cv0 = myLines.back()->getVertex(1);// next vertex
 	}// end last
-
 	std::vector<MVertex*> mvt; 
 	mvt.resize(2);
 	mvt[0] = *itf;
-	mvt[1] = cv0;
-	  
-	for(int imvt=0; imvt<2; imvt++){
-	  
-	  std::set<GEdge*>::iterator oe=gGEdges.begin();
-	  while(mvt[imvt]->onWhat() != *oe)
-	    ++oe;
-
-	  if (oe == gGEdges.end()) Msg::Error("discreteFace::split \t This Vertex is not on a GEdge !");	    
-	  GEdge* onit = *oe;
+	mvt[1] = cv0;	  
+	for(int imvt=0; imvt<2; imvt++){// creation of the GVertex, for new nonloop GEdge's	  
+	  std::set<GEdge*>::iterator oe=gGEdges.begin();// find the old GEdge that has the current new GVertex
+	  while(mvt[imvt]->onWhat() != *oe && mvt[imvt]->onWhat() != (*oe)->getBeginVertex() && mvt[imvt]->onWhat() != (*oe)->getEndVertex() && oe !=gGEdges.end())
+	    ++oe;	  
+	  if (oe == gGEdges.end()) Msg::Error("discreteFace::split \t This Vertex %d is not on a GEdge !",mvt[imvt]->getNum());	    
+	  GEdge* onit = *oe;// the new GVertex can already exist; if it is the case, there is no need to create a new one
 	  if(mvt[imvt] == onit->getBeginVertex()->mesh_vertices[0])
 	    v[imvt] = onit->getBeginVertex();
 	  else if (mvt[imvt] == onit->getEndVertex()->mesh_vertices[0])
 	    v[imvt] = onit->getEndVertex();
 	  else{
 	    v[imvt] = new discreteVertex (this->model(),NEWPOINT());
-	    v[imvt]->mesh_vertices.push_back(mvt[imvt]);
-	    mvt[imvt]->setEntity(v[imvt]);
-	    this->model()->add(v[imvt]);
+	    setupDiscreteVertex(v[imvt],mvt[imvt],NULL);
+	    printf("dv %d on GEdge (%d,%d)\n",v[imvt]->mesh_vertices[0]->getNum(),onit->getBeginVertex()->mesh_vertices[0]->getNum(),onit->getEndVertex()->mesh_vertices[0]->getNum());
 	    discreteEdge* de[2];	    	   
-	    gGEdges.erase(onit);
+	    gGEdges.erase(onit);// updating the GEdge's of the initial triangulation	  
 	    splitDiscreteEdge(onit,v[imvt],de);	    
 	    gGEdges.insert(de[0]);
-	    gGEdges.insert(de[1]);	    
+	    gGEdges.insert(de[1]);
 	  }// end else    
-	  
-	}// end imvt	
-
+	}// end imvt
+	// the new GEdge can be created with its GVertex
 	discreteEdge* internalE = new discreteEdge (this->model(),NEWLINE(),v[0],v[1]);
-	this->model()->add(internalE);// new GEdge
-	internalE->lines = myLines;// associated MLine's
-	for(unsigned int iml=1; iml<myLines.size(); iml++){//not the first vertex of the GEdge (neither the last one)
-	  myLines[iml]->getVertex(0)->setEntity(internalE);
-	  internalE->mesh_vertices.push_back(myLines[iml]->getVertex(0));
-	  todelete.insert(myLines[iml]->getVertex(0));
-	}
-	internalE->createGeometry();
+	setupDiscreteEdge(internalE,myLines,&todelete);		
 	partition[i]->my_GEdges.push_back(internalE);
 	partition[ii]->my_GEdges.push_back(internalE);	
 
 	first.erase(itf);// next first vertex of a nonloop GEdge
       }//end while first.empty()
-
-      	for(std::set<GEdge*>::iterator le=gGEdges.begin(); le!=gGEdges.end(); ++le){
-	  GEdge* ile = *le;	     
-	  MEdge edTest = ile->lines.front()->getEdge(0);
-	  if(bordi.find(edTest)!=bordi.end())
-	    partition[i]->my_GEdges.push_back(ile);	      	  
-	  else
-	    partition[ii]->my_GEdges.push_back(ile);	     
-	}
-
-      while(!v02edg.empty()){// remaining MLines for 'loop'GEdge's
-
+      // adding old-updated GEdge's to the corresponding partitions
+      for(std::set<GEdge*>::iterator le=gGEdges.begin(); le!=gGEdges.end(); ++le){
+	GEdge* ile = *le;
+	MEdge edTest = ile->lines.front()->getEdge(0);
+	if(bordi.find(edTest)!=bordi.end())
+	  partition[i]->my_GEdges.push_back(ile);	      	  
+	else
+	  partition[ii]->my_GEdges.push_back(ile);	     
+      }
+      // remaining MLines for 'loop'GEdge's
+      while(!v02edg.empty()){
 	discreteVertex* v;	  
 	std::vector<MLine*> my_MLines;
-
 	MVertex* cv0 = v02edg.begin()->first;
 	while(v02edg.find(cv0) != v02edg.end()){// a loop GEdge
 	  my_MLines.push_back(v02edg[cv0]);// current MLine of the loop
 	  v02edg.erase(cv0);// update the container
 	  cv0 = my_MLines.back()->getVertex(1);// next MLine of the loop
-	}
-	  
+	}	  
 	v = new discreteVertex (this->model(),NEWPOINT());
-	v->mesh_vertices.push_back(cv0);
-	cv0->setEntity(v);
-	this->model()->add(v);
-	todelete.insert(cv0);
-
+	setupDiscreteVertex(v,cv0,&todelete);
 	discreteEdge* gloop = new discreteEdge (this->model(),NEWLINE(),v,v);
-	this->model()->add(gloop);
-	gloop->lines = my_MLines;
-	for(unsigned int iml=1; iml<my_MLines.size(); iml++){//not the first vertex of the GEdge (neither the last one)
-	  my_MLines[iml]->getVertex(0)->setEntity(gloop);
-	  gloop->mesh_vertices.push_back(my_MLines[iml]->getVertex(0));
-	  todelete.insert(my_MLines[iml]->getVertex(0));
-	}
-	gloop->createGeometry();
+	setupDiscreteEdge(gloop,my_MLines,&todelete);
 	partition[i]->my_GEdges.push_back(gloop);
 	partition[ii]->my_GEdges.push_back(gloop);
-      }// end while v02edg.empty()
-      
-    }//end for ii
-    
+      }// end while v02edg.empty()      
+    }//end for ii    
   }// end for i
   
+  // update GFace mesh_vertices
   std::vector<MVertex*> newMV;
   for(unsigned int imv=0; imv<this->mesh_vertices.size(); imv++){
     MVertex* current = mesh_vertices[imv];
diff --git a/Geo/discreteFace.h b/Geo/discreteFace.h
index 76840461bea27ccbed891a4946e0162fa442979c..b8a5709dc00c815f7407c3703709880ee775039a 100644
--- a/Geo/discreteFace.h
+++ b/Geo/discreteFace.h
@@ -31,8 +31,9 @@ class discreteFace : public GFace {
   discreteFace(GModel *model, int num);
   virtual ~discreteFace() {}
   void checkAndFixOrientation();
+  void setupDiscreteVertex(GVertex*,MVertex*,std::set<MVertex*>*);
+  void setupDiscreteEdge(discreteEdge*,std::vector<MLine*>,std::set<MVertex*>*);
   void splitDiscreteEdge(GEdge*,GVertex*,discreteEdge*[2]);
-  void splitDiscreteFace(discreteFace*,std::vector<triangulation*>&,std::vector<GEdge*>&){};
   void split(triangulation*,std::vector<triangulation*>&,int);
   GPoint point(double par1, double par2) const;
   SPoint2 parFromPoint(const SPoint3 &p, bool onSurface=true) const;