diff --git a/Geo/discreteDiskFace.cpp b/Geo/discreteDiskFace.cpp
index 017b76c684ffc53b558b379d32198ffcca3695e7..d8a00a4727f7897e726afcfdcbd3a1ce141df8bc 100644
--- a/Geo/discreteDiskFace.cpp
+++ b/Geo/discreteDiskFace.cpp
@@ -203,13 +203,14 @@ static bool orderVertices(const double &tot_length, const std::vector<MVertex*>
 				(next->z() - first->z()) * (next->z() - first->z()) );
 
     coord.push_back(coord[coord.size()-1] + length / tot_length);
-
+    
     first = next;
 
   }
   return true;
 }
 
+/*BUILDER*/
 discreteDiskFace::discreteDiskFace(GFace *gf, triangulation* diskTriangulation,
                                    int p, std::vector<GFace*> *CAD) :
   GFace(gf->model(),123), _parent (gf), _ddft(NULL), oct(NULL)
@@ -280,9 +281,8 @@ discreteDiskFace::discreteDiskFace(GFace *gf, triangulation* diskTriangulation,
   geoTriangulation = new triangulation(discrete_triangles,gf);
 
   allNodes = geoTriangulation->vert;
-  _U0 = geoTriangulation->bord.rbegin()->second;
   _totLength = geoTriangulation->bord.rbegin()->first;
-
+  _U0 = geoTriangulation->bord.rbegin()->second;
 
   orderVertices(_totLength, _U0, _coords);
 
@@ -290,14 +290,14 @@ discreteDiskFace::discreteDiskFace(GFace *gf, triangulation* diskTriangulation,
   buildOct(CAD);
 
   if (!checkOrientationUV()){
-    Msg::Info("discreteDIskFace:: parametrization is not one-to-one; fixing "
+    Msg::Info("discreteDiskFace:: parametrization is not one-to-one; fixing "
               "the discrete system.");
     parametrize(true);
     buildOct(CAD);
   }
-
   putOnView();
 }
+/*end BUILDER*/
 
 discreteDiskFace::~discreteDiskFace()
 {
@@ -356,8 +356,14 @@ bool discreteDiskFace::parametrize(bool one2one) const
   for(size_t i = 0; i < _U0.size(); i++){
     MVertex *v = _U0[i];
     const double theta = 2 * M_PI * _coords[i];
-    myAssemblerU.fixVertex(v, 0, 1, cos(theta));
-    myAssemblerV.fixVertex(v, 0, 1, sin(theta));
+    if(i%_order==0){
+      myAssemblerU.fixVertex(v, 0, 1, cos(theta));
+      myAssemblerV.fixVertex(v, 0, 1, sin(theta));
+    }
+    else{//#TEST
+      myAssemblerU.fixVertex(v, 0, 1,1./_order*((_order-(i%_order))*cos(2*M_PI*_coords[i-(i%_order)])+(i%_order)*cos(2*M_PI*_coords[i+(_order-(i%_order))])));
+      myAssemblerV.fixVertex(v, 0, 1,1./_order*((_order-(i%_order))*sin(2*M_PI*_coords[i-(i%_order)])+(i%_order)*sin(2*M_PI*_coords[i+(_order-(i%_order))])));
+    }
   }
 
   for(size_t i = 0; i < discrete_triangles.size(); ++i){
diff --git a/Geo/discreteDiskFace.h b/Geo/discreteDiskFace.h
index 20124e03a95015b4da7c368f7f700fd011bdd48c..bf333efa787ba241f98ae5324964e86a529add39 100644
--- a/Geo/discreteDiskFace.h
+++ b/Geo/discreteDiskFace.h
@@ -57,8 +57,10 @@ class triangulation {
   GFace *gf;
   int idNum; // number of identification, for hashing purposes
 
-  int genus()
-  {
+  std::list<GEdge*> my_GEdges;
+  
+  //methods
+  int genus(){
     return ( -vert.size() + ed2tri.size() - tri.size() + 2 - bord.size() )/2;
   }
 
diff --git a/Geo/discreteFace.cpp b/Geo/discreteFace.cpp
index e9a69c260501d39828fb1dca0c664e064268ca04..3edbdf2455f24e92194fdb9fe27495d65e00e87c 100644
--- a/Geo/discreteFace.cpp
+++ b/Geo/discreteFace.cpp
@@ -105,12 +105,11 @@ void discreteFace::secondDer(const SPoint2 &param,
   return;
 }
 
-// FIXME PAB ----> really create an atlas !!!!!!!!!!!!!!!
 void discreteFace::createGeometry()
 {
   checkAndFixOrientation();
 
-  int order = 1;
+  int order = 2;
   int nPart = 2;
   std::vector<triangulation*> part;
   part.resize(nPart);
@@ -122,7 +121,11 @@ void discreteFace::createGeometry()
   std::stack<triangulation*>  toSplit;
   std::vector<triangulation*> toParam;
   std::vector<MElement*> tem(triangles.begin(),triangles.end());
-  toSplit.push(new triangulation(tem,this));
+
+  triangulation* init = new triangulation(tem,this);
+  init->my_GEdges = l_edges;
+
+  toSplit.push(init);  
   if((toSplit.top())->genus()!=0){
     
     while( !toSplit.empty()){
@@ -139,6 +142,7 @@ void discreteFace::createGeometry()
 	else{
 	  toParam.push_back(part[i]);
 	  part[i]->idNum=id++;
+	  // discreteEdges
 	}
       }// end for i      
     }
@@ -148,10 +152,11 @@ void discreteFace::createGeometry()
     toParam.push_back(toSplit.top());
     toSplit.top()->idNum=id++;
   }
-
-  for(unsigned int i=0; i<toParam.size(); i++){
+  
+  for(unsigned int i=0; i<toParam.size(); i++){     
+    std::vector<MElement*> mytri = toParam[i]->tri;
     discreteDiskFace *df = new discreteDiskFace (this,toParam[i], order,(_CAD.empty() ? NULL : &_CAD));
-    df->replaceEdges(l_edges);// #FIXME
+    df->replaceEdges(toParam[i]->my_GEdges);
     _atlas.push_back(df);
   }  
 #endif
@@ -215,7 +220,7 @@ void discreteFace::checkAndFixOrientation(){
   
   // first of all, all the triangles have to be oriented in the same way
   std::map<MEdge,std::vector<MElement*>,Less_Edge> ed2tri; // edge to 1 or 2 triangle(s)
-
+ 
   for(unsigned int i = 0; i < triangles.size(); ++i){
     MElement *e = triangles[i];
     for(int j = 0; j <  e->getNumEdges() ; j++){
@@ -281,7 +286,7 @@ void discreteFace::checkAndFixOrientation(){
 	    if (!(current->getVertex(k!=2 ?k+1 : 0 ) == neigs[i]->getVertex(j!=0 ? j-1 : 2) ||
 		  current->getVertex(k!=0 ?k-1 : 2 ) == neigs[i]->getVertex(j!=2 ? j+1 : 0))){
 	      neigs[i]->reverse();
-	      Msg::Info("discreteDiskFace: triangle %d has been reoriented.",neigs[i]->getNum());
+	      Msg::Info("discreteFace: triangle %d has been reoriented.",neigs[i]->getNum());
 	    }
 	    break;
 	  }
@@ -315,8 +320,8 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti
       
       MEdge ed = current->getEdge(j);
       int nEd = trian->ed2tri[ed].size();
-      
-      if (nEd > 1){
+
+      if (nEd > 1){	
 	std::vector<int> local = trian->ed2tri[ed];
 	nbh[idx[i]+temp] = local[0] == i ? local[1] : local[0];
 	temp++;
@@ -333,17 +338,138 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti
   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]);
-  // CONNEC
+  METIS_PartGraphRecursive(&nVertex,&(idx[0]),&(nbh[0]),NULL,NULL,&zero,&zero,&nPartitions,&zero,&edgeCut,&(part[0]));
+
   std::vector<std::vector<MElement*> > elem;
   elem.resize(nPartitions);
 
   for(int i=0; i<nVertex; i++)
     elem[part[i]].push_back(trian->tri[i]);
-
+  
   for(int i=0; i<nPartitions; i++)
     partition[i] = new triangulation(elem[i],this);
   
+  
+
+  for(int i=0; i<nPartitions; i++){// setting GEdge's
+
+    //"update" old GEdge's
+    std::list<GEdge*> upGed = partition[i]->my_GEdges;// old GEdge's list
+    for(std::list<GEdge*>::iterator cGedg=trian->my_GEdges.begin(); cGedg!=trian->my_GEdges.end(); cGedg++){// GEdge by GEdge
+      std::set<MVertex*> first, last;
+      double lc = 0.;
+      std::vector<MLine*> upMli;     
+      for(unsigned int k=0; k<(*cGedg)->lines.size(); k++){// MLine by MLine (for a GEdge)
+	MLine* cMli = (*cGedg)->lines[k];
+	std::set<MVertex*>::iterator mvit0 = partition[i]->vert.find(cMli->getVertex(0));
+	std::set<MVertex*>::iterator mvit1 = partition[i]->vert.find(cMli->getVertex(1));
+	if(mvit0 != partition[i]->vert.end() && mvit1 != partition[i]->vert.end()){// check if the MLine belong to this part
+
+	  if( first.find(cMli->getVertex(1)) != first.end() )
+	    first.erase(cMli->getVertex(1));
+	  else
+	    last.insert(cMli->getVertex(1));
+	  
+	  if( last.find(cMli->getVertex(0)) != last.end() )
+	    last.erase(cMli->getVertex(0));
+	  else
+	    first.insert(cMli->getVertex(0));
+	  
+	  upMli.push_back(cMli);
+	  lc += cMli->getLength();
+
+	}
+      }// end for k  
+      GVertex *v0, *v1;
+      if(first.empty()){
+	v0 = this->model()->addVertex(upMli[0]->getVertex(0)->x(),upMli[0]->getVertex(0)->y(),upMli[0]->getVertex(0)->z(),1.);//#fixme
+	v1 = v0;
+      }
+      else{
+	v0 = this->model()->addVertex((*(first.begin()))->x(),(*(first.begin()))->y(),(*(first.begin()))->z(),1.);//#fixme
+	v1 = this->model()->addVertex((*(last.begin()))->x(),(*(last.begin()))->y(),(*(last.begin()))->z(),1.);
+      }
+      upGed.push_back(this->model()->addLine(v0,v1));
+      upGed.back()->lines = upMli;
+    }// end for j
+    
+    
+    // create new GEdge's
+    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
+      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) 
+
+	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
+
+	  // identifying first and last vertices of GEdge's, if any
+	  if( first.find(ie->getVertex(1)) != first.end() )
+	    first.erase(ie->getVertex(1));
+	  else
+	    last.insert(ie->getVertex(1));	  
+	  if( last.find(ie->getVertex(0)) != last.end() )
+	    last.erase(ie->getVertex(0));
+	  else
+	    first.insert(ie->getVertex(0));	  	  
+	}
+
+      }//end for ie
+
+
+      while(!v02edg.empty()){// creation of the GEdge's from new MLine's
+	
+	GVertex *v0, *v1;
+	
+	while(!first.empty()){// starting with nonloop GEdge's
+	  
+	  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"
+	    cv0 = myLines.back()->getVertex(1);// next vertex
+	  }
+	  
+	  v0 = this->model()->addVertex((*itf)->x(),myLines[0]->getVertex(0)->y(),myLines[0]->getVertex(0)->z(),1.);
+	  v1 = this->model()->addVertex(cv0->x(),cv0->y(),cv0->z(),1.);
+	  
+	  GEdge* toadd = this->model()->addLine(v0,v1);// new GEdge
+	  toadd->lines = myLines;// associated MLine's
+	  
+	  partition[i]->my_GEdges.push_back(toadd);
+	  partition[ii]->my_GEdges.push_back(toadd);
+	  
+	  first.erase(itf);// next first vertex of a nonloop GEdge
+	}//end while first.empty()
+	
+	std::vector<MLine*> my_MLines;// remaining MLines for 'loop'GEdge's
+	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	  	  
+	}
+
+	v0 =  this->model()->addVertex(cv0->x(),cv0->y(),cv0->z(),1.);
+	v1 = v0;
+
+	GEdge* to_add = this->model()->addLine(v0,v1);
+	to_add->lines = my_MLines;
+
+	partition[i]->my_GEdges.push_back(to_add);
+	partition[ii]->my_GEdges.push_back(to_add);
+	
+      }// end while v02edg.empty()
+      
+    }//end for ii
+    
+  }// end for i
 
   return;
 }
diff --git a/Geo/discreteFace.h b/Geo/discreteFace.h
index 8b4abfb2d473e9ee83585593c8760afdab9f8431..5b7071fdd33c34a12a7e19d86794fa4e0e848c35 100644
--- a/Geo/discreteFace.h
+++ b/Geo/discreteFace.h
@@ -15,6 +15,7 @@
 #include "meshPartition.h"
 #include "MTriangle.h"
 #include "MEdge.h"
+#include "MLine.h"
 #include <stdlib.h>
 
 class discreteDiskFace;