Index: /issm/trunk/src/c/Makefile.am
===================================================================
--- /issm/trunk/src/c/Makefile.am	(revision 5094)
+++ /issm/trunk/src/c/Makefile.am	(revision 5095)
@@ -67,6 +67,6 @@
 					./objects/Bamg/Triangle.cpp\
 					./objects/Bamg/Triangle.h\
-					./objects/Bamg/Triangles.cpp\
-					./objects/Bamg/Triangles.h\
+					./objects/Bamg/Mesh.cpp\
+					./objects/Bamg/Mesh.h\
 					./objects/Bamg/MeshVertex.cpp\
 					./objects/Bamg/MeshVertex.h\
@@ -603,6 +603,6 @@
 					./objects/Bamg/Triangle.cpp\
 					./objects/Bamg/Triangle.h\
-					./objects/Bamg/Triangles.h\
-					./objects/Bamg/Triangles.cpp\
+					./objects/Bamg/Mesh.h\
+					./objects/Bamg/Mesh.cpp\
 					./objects/Bamg/MeshVertex.cpp\
 					./objects/Bamg/MeshVertex.h\
Index: /issm/trunk/src/c/modules/BamgConvertMeshx/BamgConvertMeshx.cpp
===================================================================
--- /issm/trunk/src/c/modules/BamgConvertMeshx/BamgConvertMeshx.cpp	(revision 5094)
+++ /issm/trunk/src/c/modules/BamgConvertMeshx/BamgConvertMeshx.cpp	(revision 5095)
@@ -25,5 +25,5 @@
 	// read mesh
 	if(verbose) printf("Reading mesh\n");
-	Triangles Th(index,x,y,nods,nels); 
+	Mesh Th(index,x,y,nods,nels); 
 
 	//write mesh and geometry
Index: /issm/trunk/src/c/modules/Bamgx/Bamgx.cpp
===================================================================
--- /issm/trunk/src/c/modules/Bamgx/Bamgx.cpp	(revision 5094)
+++ /issm/trunk/src/c/modules/Bamgx/Bamgx.cpp	(revision 5095)
@@ -24,6 +24,6 @@
 	double costheta=2;
 	double hminaniso=1e-100; 
-	Triangles* Thr=NULL;
-	Triangles* Thb=NULL;
+	Mesh* Thr=NULL;
+	Mesh* Thb=NULL;
 
 	/*Bamg options*/
@@ -61,5 +61,5 @@
 		//generate mesh
 		if (verbosity>1) printf("   Generating Mesh...\n");
-		Triangles Th(maxnbv,Gh,bamgopts);
+		Mesh Th(maxnbv,Gh,bamgopts);
 
 		//Split corners if requested
@@ -89,5 +89,5 @@
 		if (verbosity>0) printf("Anisotropic mesh adaptation\n");
 		if (verbosity>1) printf("   Processing initial mesh and geometry...\n");
-		Triangles BTh(bamggeom_in,bamgmesh_in,bamgopts); 
+		Mesh BTh(bamggeom_in,bamgmesh_in,bamgopts); 
 
 		//Make Quadtree from background mesh
@@ -166,5 +166,5 @@
 		if (verbosity>1) printf("   Generating Mesh...\n");
 		Thr=&BTh,Thb=0;
-		Triangles & Th( *(0 ?  new Triangles(*Thr,&Thr->Gh,Thb,maxnbv) :  new Triangles(maxnbv,BTh,bamgopts,bamgopts->KeepVertices)));
+		Mesh & Th( *(0 ?  new Mesh(*Thr,&Thr->Gh,Thb,maxnbv) :  new Mesh(maxnbv,BTh,bamgopts,bamgopts->KeepVertices)));
 		if (Thr != &BTh) delete Thr;
 
Index: /issm/trunk/src/c/modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp
===================================================================
--- /issm/trunk/src/c/modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp	(revision 5094)
+++ /issm/trunk/src/c/modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp	(revision 5095)
@@ -60,5 +60,5 @@
 	// read background mesh 
 	if (verbose) printf("Reading mesh\n");
-	Triangles Th(index_data,x_data,y_data,nods_data,nels_data); 
+	Mesh Th(index_data,x_data,y_data,nods_data,nels_data); 
 	Th.ReMakeTriangleContainingTheVertex();
 
Index: /issm/trunk/src/c/objects/Bamg/DoubleAndInt.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/DoubleAndInt.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/DoubleAndInt.h	(revision 5095)
@@ -7,5 +7,5 @@
 
 	class DoubleAndInt {
-		//class used by Triangles::MakeQuadrangles
+		//class used by Mesh::MakeQuadrangles
 
 		public:
Index: /issm/trunk/src/c/objects/Bamg/Edge.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Edge.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/Edge.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "Edge.h"
-#include "Triangles.h"
+#include "Mesh.h"
 #include "Geometry.h"
 
@@ -14,5 +14,5 @@
 	/*Methods*/
 	/*FUNCTION Edge::Set {{{1*/
-	void Edge::Set(const Triangles & Th ,long i,Triangles & ThNew){ 
+	void Edge::Set(const Mesh & Th ,long i,Mesh & ThNew){ 
 		*this = Th.edges[i];
 		v[0] = ThNew.vertices + Th.Number(v[0]);    
Index: /issm/trunk/src/c/objects/Bamg/Edge.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Edge.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/Edge.h	(revision 5095)
@@ -11,5 +11,5 @@
 
 	//classes
-	class Triangles;
+	class Mesh;
 	
 	class Edge {
@@ -41,5 +41,5 @@
 				return adj[0]==&e ? 0 : 1;
 			}
-			void Set(const Triangles &,long,Triangles &);
+			void Set(const Mesh &,long,Mesh &);
 			void Echo(void);
 
Index: /issm/trunk/src/c/objects/Bamg/Geometry.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Geometry.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/Geometry.cpp	(revision 5095)
@@ -874,5 +874,5 @@
 					printf("That bug might come from:\n");
 					printf(" 1)  a mesh edge  containing more than %i geometrical edges\n",mxe/2);
-					printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
+					printf(" 2)  code bug : be sure that we call   Mesh::SetVertexFieldOn() before\n");
 					printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
 					ISSMERROR("see above");
@@ -894,5 +894,5 @@
 				printf("That bug might come from:\n");
 				printf(" 1)  a mesh edge  contening more than %i geometrical edges\n",mxe/2);
-				printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
+				printf(" 2)  code bug : be sure that we call   Mesh::SetVertexFieldOn() before\n");
 				printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
 				ISSMERROR("see above");
Index: /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.cpp	(revision 5095)
@@ -10,5 +10,5 @@
 	/*Methods*/
 	/*FUNCTION ListofIntersectionTriangles::SplitEdge{{{1*/
-	void ListofIntersectionTriangles::SplitEdge(const Triangles & Bh, const R2 &A,const R2  &B,int nbegin) {
+	void ListofIntersectionTriangles::SplitEdge(const Mesh & Bh, const R2 &A,const R2  &B,int nbegin) {
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ListofIntersectionTriangles)*/
 
Index: /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/ListofIntersectionTriangles.h	(revision 5095)
@@ -69,5 +69,5 @@
 			int   NewItem(Triangle * tt,double d0,double d1,double d2);
 			int   NewItem(R2,const Metric & );
-			void  SplitEdge(const Triangles & ,const R2 &,const R2  &,int nbegin=0); 
+			void  SplitEdge(const Mesh & ,const R2 &,const R2  &,int nbegin=0); 
 			double Length(); 
 			long  NewPoints(MeshVertex *,long & nbv,long nbvx);
Index: /issm/trunk/src/c/objects/Bamg/Mesh.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Mesh.cpp	(revision 5095)
+++ /issm/trunk/src/c/objects/Bamg/Mesh.cpp	(revision 5095)
@@ -0,0 +1,5868 @@
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+#include <ctime>
+
+#include "../objects.h"
+
+namespace bamg {
+
+	static const  Direction NoDirOfSearch=Direction();
+	long NbUnSwap =0;
+
+	/*Constructors/Destructors*/
+	/*FUNCTION Mesh::Mesh(BamgGeom* bamggeom,BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
+	Mesh::Mesh(BamgGeom* bamggeom,BamgMesh* bamgmesh, BamgOpts* bamgopts):Gh(*(new Geometry())),BTh(*this){ 
+
+		/*Initialize fields*/
+		PreInit(0);
+
+		/*Read Geometry if provided*/
+		if(bamggeom->Edges) {
+			Gh.ReadGeometry(bamggeom,bamgopts);
+			Gh.AfterRead();
+		}
+
+		/*Read background mesh*/
+		ReadMesh(bamgmesh,bamgopts);
+
+		/*Build Geometry if not provided*/
+		if(bamggeom->Edges==NULL) {
+			/*Recreate geometry if needed*/
+			printf("WARNING: mesh present but no geometry found. Reconstructing...\n");
+			BuildGeometryFromMesh(bamgopts);
+			Gh.AfterRead();
+		}
+
+		/*Set integer coordinates*/
+		SetIntCoor();
+
+		/*Fill holes and generate mesh properties*/
+		ReconstructExistingMesh();
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::Mesh(double* index,double* x,double* y,int nods,int nels){{{1*/
+	Mesh::Mesh(double* index,double* x,double* y,int nods,int nels):Gh(*(new Geometry())),BTh(*this){
+
+		PreInit(0);
+		ReadMesh(index,x,y,nods,nels);
+		SetIntCoor();
+		ReconstructExistingMesh();
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::Mesh(const Mesh & Tho,const int *flag ,const int *bb){{{1*/
+	Mesh::Mesh(const Mesh & Tho,const int *flag ,const int *bb,BamgOpts* bamgopts) : Gh(*(new Geometry())), BTh(*this) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
+
+		  int i,k,itadj;
+		  int kt=0;
+		  int * kk    = new int [Tho.nbv];
+		  long * reft = new long[Tho.nbt];
+		  long nbInT =    Tho.TriangleReferenceList(reft);
+		  long * refv = new long[Tho.nbv];
+
+		  for (i=0;i<Tho.nbv;i++)
+			kk[i]=-1;
+		  for (i=0;i<Tho.nbv;i++)
+			refv[i]=0;
+		  int nbNewBedge =0;
+		  //  int nbOldBedge =0;  
+		  for (i=0;i<Tho.nbt;i++)
+			if(  reft[i] >=0 && flag[i]) 
+			  {
+				const Triangle & t = Tho.triangles[i];
+				kt++;
+				kk[Tho.Number(t[0])]=1;
+				kk[Tho.Number(t[1])]=1;
+				kk[Tho.Number(t[2])]=1;
+				itadj=Tho.Number(t.TriangleAdj(0));
+				if (  reft[itadj] >=0 && !flag[itadj])
+				  { nbNewBedge++;
+					refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
+					refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
+				  }
+				itadj=Tho.Number(t.TriangleAdj(1));
+				if (  reft[itadj] >=0 && !flag[itadj])
+				  { nbNewBedge++;
+					refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
+					refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
+					itadj=Tho.Number(t.TriangleAdj(2));
+					if (  reft[itadj] >=0 && !flag[itadj])
+					  { nbNewBedge++;
+						refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
+						refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
+			  }
+		  k=0;
+		  for (i=0;i<Tho.nbv;i++){
+			  if (kk[i]>=0) kk[i]=k++;
+			}
+		  printf("   number of vertices %i, remove = %i\n",k,Tho.nbv - k);
+		  printf("   number of triangles %i, remove = %i\n",kt,nbInT-kt);
+		  printf("   number of New boundary edge %i\n",nbNewBedge);
+		  long inbvx =k;
+		  PreInit(inbvx);
+		  for (i=0;i<Tho.nbv;i++)
+			if (kk[i]>=0) 
+			  {
+				vertices[nbv] = Tho.vertices[i];
+				if (!vertices[nbv].ref())
+				 vertices[nbv].ReferenceNumber = refv[i];
+				nbv++;
+			  }
+		  if (inbvx != nbv){
+			  ISSMERROR("inbvx != nbv");
+		  }
+		  for (i=0;i<Tho.nbt;i++)
+			if(  reft[i] >=0 && flag[i]) 
+			  {
+				const Triangle & t = Tho.triangles[i];
+				int i0 = Tho.Number(t[0]);
+				int i1 = Tho.Number(t[1]);
+				int i2 = Tho.Number(t[2]);
+				if (i0<0 || i1<0 || i2<0){
+					ISSMERROR("i0<0 || i1<0 || i2< 0");
+				}
+				if (i0>=Tho.nbv || i1>=Tho.nbv || i2>=Tho.nbv){
+					ISSMERROR("i0>=Tho.nbv || i1>=Tho.nbv || i2>=Tho.nbv");
+				}
+				triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
+				triangles[nbt].color = Tho.subdomains[reft[i]].ref; 
+				nbt++;           
+			  }
+		  if (kt!=nbt){
+			  ISSMERROR("kt!=nbt");
+		  }
+		  if (nbt==0 && nbv==0) {
+			  ISSMERROR("All triangles have been removed");
+		  }
+		  delete [] kk;
+		  delete [] reft;
+		  delete [] refv;
+		  //double cutoffradian = 10.0/180.0*Pi;
+		  BuildGeometryFromMesh(bamgopts);
+		  Gh.AfterRead(); 
+		  SetIntCoor();
+		  ReconstructExistingMesh();
+
+		  if (!NbSubDomains){
+			  ISSMERROR("NbSubDomains==0");
+		  }
+		  if (!subdomains[0].head || !subdomains[0].head->link){
+			  ISSMERROR("!subdomains[0].head || !subdomains[0].head->link");
+		  }
+
+	  }
+	/*}}}1*/
+	/*FUNCTION Mesh::Mesh(Mesh & Th,Geometry * pGh,Mesh * pBth,long nbvxx) COPY{{{1*/
+	Mesh::Mesh(Mesh & Th,Geometry * pGh,Mesh * pBth,long nbvxx)
+	  : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this)) {
+		  /*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
+		  Gh.NbRef++;
+		  nbvxx = Max(nbvxx,Th.nbv); 
+		  long i;
+		  // do all the allocation to be sure all the pointer existe
+
+		  PreInit(nbvxx);// to make the allocation 
+		  // copy of triangles
+		  nt=Th.nt;
+		  nbv = Th.nbv;
+		  nbt = Th.nbt;
+		  nbiv = Th.nbiv;
+		  nbe = Th.nbe;
+		  NbSubDomains = Th.NbSubDomains;
+		  NbOutT = Th.NbOutT;
+		  NbOfQuad =  Th.NbOfQuad ;
+		  NbOfSwapTriangle =0;
+		  NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
+		  if(NbVerticesOnGeomVertex)
+			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
+		  NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
+		  if (NbVerticesOnGeomEdge)
+			VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
+		  if (& BTh == & Th.BTh){ // same background 
+			  BTh.NbRef++;
+			  NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
+			  if(NbVertexOnBThVertex)
+				VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
+			  NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
+			  if(NbVertexOnBThEdge)
+				VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
+			 }
+		  else { // no add on background mesh 
+			  BTh.NbRef++;
+			  NbVertexOnBThVertex=0;
+			  VertexOnBThVertex=0;
+			  NbVertexOnBThEdge=0;
+			  VertexOnBThEdge=0;
+			 }
+
+
+		  if(nbe)
+			edges = new Edge[nbe];
+		  if(NbSubDomains)
+			subdomains = new SubDomain[NbSubDomains];
+		  pmin = Th.pmin;
+		  pmax = Th.pmax;
+		  coefIcoor = Th.coefIcoor;
+		  for(i=0;i<nbt;i++)
+			triangles[i].Set(Th.triangles[i],Th,*this);
+		  for(i=0;i<nbe;i++)
+			edges[i].Set(Th,i,*this);
+		  for(i=0;i<nbv;i++)
+			vertices[i].Set(Th.vertices[i],Th,*this);
+		  for(i=0;i<NbSubDomains;i++)  
+			subdomains[i].Set(Th,i,*this);
+		  for (i=0;i<NbVerticesOnGeomVertex;i++)
+			VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
+		  for (i=0;i<NbVerticesOnGeomEdge;i++)
+			VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
+		  quadtree=0;
+
+	  }
+	/*}}}1*/
+	/*FUNCTION Mesh::~Mesh(){{{1*/
+	Mesh::~Mesh() {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
+
+		long int verbose=2;
+		//if(vertices)  delete [] vertices; //TEST  crash if not commented
+		if(edges)     delete [] edges;
+		if(triangles) delete [] triangles;
+		if(quadtree)  delete quadtree;
+		//if(ordre)     delete [] ordre; //TEST  crash if not commented
+		if( subdomains) delete []  subdomains;
+		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
+		if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
+		if (VertexOnBThVertex) delete [] VertexOnBThVertex;
+		if (VertexOnBThEdge) delete [] VertexOnBThEdge;
+
+		if (&Gh) {
+			if (Gh.NbRef>0) Gh.NbRef--;
+			else if (Gh.NbRef==0) delete &Gh;
+		}
+		if (&BTh && (&BTh != this)) {
+			if (BTh.NbRef>0) BTh.NbRef--;
+			else if (BTh.NbRef==0) delete &BTh;
+		}
+		PreInit(0); // set all to zero 
+	}
+	/*}}}1*/
+
+	/*IO*/
+	/*FUNCTION Mesh::ReadMesh(double* index,double* x,double* y,int nods,int nels){{{1*/
+	void Mesh::ReadMesh(double* index,double* x,double* y,int nods,int nels){
+
+		double Hmin = HUGE_VAL;// the infinie value 
+		long i1,i2,i3,iref;
+		long i,j;
+		Metric M1(1);
+		int verbose=0;
+
+		nbv=nods;
+		nbvx=nbv;
+		nbt=nels;
+		nbiv=nbvx;
+
+		//Vertices
+		if (verbose) printf("Reading vertices (%i)\n",nbv);
+		vertices=(MeshVertex*)xmalloc(nbv*sizeof(MeshVertex));
+		ordre=(MeshVertex**)xmalloc(nbv*sizeof(MeshVertex*));
+		for (i=0;i<nbv;i++){
+			vertices[i].r.x=x[i];
+			vertices[i].r.y=y[i];
+			vertices[i].ReferenceNumber=1;
+			vertices[i].DirOfSearch =NoDirOfSearch;
+			vertices[i].m=M1;
+			vertices[i].color=0;
+		}
+		nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
+
+		//Triangles
+		if (verbose) printf("Reading triangles (%i)\n",nbt);
+		triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
+		//other triangles will be added for each edge
+		for (i=0;i<nbt;i++){
+			Triangle & t = triangles[i];
+			i1=(long)index[i*3+0]-1; //for C indexing
+			i2=(long)index[i*3+1]-1; //for C indexing
+			i3=(long)index[i*3+2]-1; //for C indexing
+			t=Triangle(this,i1,i2,i3);
+			t.color=1;
+		}
+
+		/*Recreate geometry: */
+		if (verbose) printf("Building Geometry\n");
+		BuildGeometryFromMesh();
+		if (verbose) printf("Completing geometry\n");
+		Gh.AfterRead();
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
+	void Mesh::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){
+
+		int verbose;
+		double Hmin = HUGE_VAL;// the infinie value 
+		long i1,i2,i3,iref;
+		long i,j;
+		long ifgeom=0;
+		Metric M1(1);
+
+		verbose=bamgopts->verbose;
+
+		nbv=bamgmesh->VerticesSize[0];
+		nbvx=nbv;
+		nbt=bamgmesh->TrianglesSize[0];
+		nbiv=nbvx;
+
+		//Vertices
+		if(bamgmesh->Vertices){
+			if(verbose>5) printf("      processing Vertices\n");
+
+			vertices=(MeshVertex*)xmalloc(nbv*sizeof(MeshVertex));
+			ordre=(MeshVertex**)xmalloc(nbv*sizeof(MeshVertex*));
+
+			for (i=0;i<nbv;i++){
+				vertices[i].r.x=bamgmesh->Vertices[i*3+0];
+				vertices[i].r.y=bamgmesh->Vertices[i*3+1];
+				vertices[i].ReferenceNumber=(long)bamgmesh->Vertices[i*3+2];
+				vertices[i].DirOfSearch =NoDirOfSearch;
+				vertices[i].m=M1;
+				vertices[i].color=0;
+			}
+			nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
+		}
+		else{
+			if(verbose>5) ISSMERROR("no Vertices found in the initial mesh");
+		}
+
+		//Triangles
+		if(bamgmesh->Triangles){
+			if(verbose>5) printf("      processing Triangles\n");
+			triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
+			//other triangles will be added for each edge
+			for (i=0;i<nbt;i++){
+				Triangle & t = triangles[i];
+				i1=(long)bamgmesh->Triangles[i*4+0]-1; //for C indexing
+				i2=(long)bamgmesh->Triangles[i*4+1]-1; //for C indexing
+				i3=(long)bamgmesh->Triangles[i*4+2]-1; //for C indexing
+				t=Triangle(this,i1,i2,i3);
+				t.color=(long)bamgmesh->Triangles[i*4+3];
+			}
+		}
+		else{
+			if(verbose>5) ISSMERROR("no Triangles found in the initial mesh");
+		}
+
+		//Quadrilaterals
+		if(bamgmesh->Quadrilaterals){
+			if(verbose>5) printf("      processing Quadrilaterals\n");
+			long i1,i2,i3,i4,iref;
+			triangles =new Triangle[nbt];
+			for (i=0;i<bamgmesh->QuadrilateralsSize[0];i++){
+				//divide the quad into two triangles
+				Triangle & t1 = triangles[2*i];
+				Triangle & t2 = triangles[2*i+1];
+				i1=(long)bamgmesh->Quadrilaterals[i*5+0]-1; //for C indexing
+				i2=(long)bamgmesh->Quadrilaterals[i*5+1]-1; //for C indexing
+				i3=(long)bamgmesh->Quadrilaterals[i*5+2]-1; //for C indexing
+				i4=(long)bamgmesh->Quadrilaterals[i*5+3]-1; //for C indexing
+				t1=Triangle(this,i1,i2,i3);
+				t2=Triangle(this,i3,i4,i1);
+				t1.color=(long)bamgmesh->Quadrilaterals[i*5+4];
+				t2.color=(long)bamgmesh->Quadrilaterals[i*5+4];
+				t1.SetHidden(OppositeEdge[1]); // two times  because the adj was not created 
+				t2.SetHidden(OppositeEdge[1]); 
+			}
+		}
+
+		//VerticesOnGeometricEdge
+		if(bamgmesh->VerticesOnGeometricEdge){
+			if(verbose>5) printf("      processing VerticesOnGeometricEdge\n");
+			NbVerticesOnGeomEdge=bamgmesh->VerticesOnGeometricEdgeSize[0];
+			VerticesOnGeomEdge= new  VertexOnGeom[NbVerticesOnGeomEdge] ;
+			for (i=0;i<NbVerticesOnGeomEdge;i++){
+				long  i1,i2;
+				double s;
+				i1=(long)  bamgmesh->VerticesOnGeometricEdge[i*3+0]-1; //for C indexing
+				i2=(long)  bamgmesh->VerticesOnGeometricEdge[i*3+1]-1; //for C indexing
+				s =(double)bamgmesh->VerticesOnGeometricEdge[i*3+2];
+				VerticesOnGeomEdge[i]=VertexOnGeom(vertices[i1],Gh.edges[i2],s);
+			}
+		}
+
+		//VerticesOnGeometricVertex
+		if(bamgmesh->VerticesOnGeometricVertexSize[0]){
+			if(verbose>5) printf("      processing VerticesOnGeometricVertex\n");
+			NbVerticesOnGeomVertex=bamgmesh->VerticesOnGeometricVertexSize[0];
+			VerticesOnGeomVertex  = new  VertexOnGeom[NbVerticesOnGeomVertex] ;
+			for (i=0;i<NbVerticesOnGeomVertex;i++){
+				long  i1,i2;
+				i1=(long)bamgmesh->VerticesOnGeometricVertex[i*2+0]-1; //for C indexing
+				i2=(long)bamgmesh->VerticesOnGeometricVertex[i*2+1]-1; //for C indexing
+				VerticesOnGeomVertex[i]=VertexOnGeom(vertices[i1],Gh.vertices[i2]);
+			}
+		}
+
+		//Edges
+		if (bamgmesh->Edges){
+			int i1,i2;
+			double* len=NULL;
+
+			if(verbose>5) printf("      processing Edges\n");
+			nbe=bamgmesh->EdgesSize[0];
+			edges= new Edge[nbe];
+			//initialize length of each edge (used to provided metric)
+			len= new double[nbv];
+			for(i=0;i<nbv;i++) len[i]=0;
+
+			for (i=0;i<nbe;i++){
+				i1=(int)bamgmesh->Edges[i*3+0]-1; //-1 for C indexing
+				i2=(int)bamgmesh->Edges[i*3+1]-1; //-1 for C indexing
+				edges[i].ref=(long)bamgmesh->Edges[i*3+2];
+				edges[i].v[0]= vertices +i1;
+				edges[i].v[1]= vertices +i2;
+				edges[i].adj[0]=NULL;
+				edges[i].adj[1]=NULL;
+				R2 x12=vertices[i2].r-vertices[i1].r;
+				double l12=sqrt((x12,x12));
+
+				//prepare metric
+				vertices[i1].color++;
+				vertices[i2].color++;
+				len[i1]+=l12;
+				len[i2]+=l12;
+				Hmin = Min(Hmin,l12);
+			}
+
+			// definition  the default of the given mesh size 
+			for (i=0;i<nbv;i++){
+				if (vertices[i].color>0) 
+				 vertices[i].m=Metric(len[i]/(double)vertices[i].color);
+				else 
+				 vertices[i].m=Metric(Hmin);
+			}
+			delete [] len;
+
+			// construction of edges[].adj 
+			for (i=0;i<nbv;i++){ 
+				vertices[i].color=(vertices[i].color ==2) ?-1:-2;
+			}
+			for (i=0;i<nbe;i++){
+				for (j=0;j<2;j++) { 
+					MeshVertex *v=edges[i].v[j];
+					long i0=v->color,j0;
+					if(i0==-1){
+						v->color=i*2+j;
+					}
+					else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
+						j0 = i0%2;
+						i0 = i0/2;
+						ISSMASSERT(v==edges[i0 ].v[j0]);
+						edges[i ].adj[j ] =edges +i0;
+						edges[i0].adj[j0] =edges +i ;
+						v->color = -3;
+					}
+				}
+			}
+		}
+
+		//EdgeOnGeometricEdge
+		if(bamgmesh->EdgesOnGeometricEdge){
+			if(verbose>5) printf("      processing EdgesOnGeometricEdge\n");
+			int i1,i2,i,j;
+			i2=bamgmesh->EdgesOnGeometricEdgeSize[0];
+			for (i1=0;i1<i2;i1++) {
+				i=(int)bamgmesh->EdgesOnGeometricEdge[i1*2+0]-1; //C indexing
+				j=(int)bamgmesh->EdgesOnGeometricEdge[i1*2+1]-1; //C indexing
+				//Check value
+				if(!(i>=0 && j>=0 && i<nbe && j<Gh.nbe)) {
+					ISSMERROR("ReadMesh error: EdgesOnGeometricEdge edge provided (line %i: [%i %i]) is incorrect (must be positive, [0<i<nbe=%i 0<j<Gh.nbe=%i]",i1+1,i+1,j+1,nbe,Gh.nbe);
+				}
+				edges[i].onGeometry=Gh.edges+j;
+			}
+		}
+
+		//hVertices
+		if(bamgmesh->hVertices){
+			if(verbose>5) printf("      processing hVertices\n");
+			for (i=0;i< nbv;i++){
+				if (!isnan(bamgmesh->hVertices[i])){
+					vertices[i].m=Metric((double)bamgmesh->hVertices[i]);
+				}
+			}
+		}
+
+		//SubDomain
+		if(bamgmesh->SubDomains){
+			long i3,head,sens;
+			if(verbose>5) printf("      processing SubDomains\n");
+			NbSubDomains=bamgmesh->SubDomainsSize[0];
+			subdomains = new SubDomain [ NbSubDomains ];
+			for (i=0;i<NbSubDomains;i++) {
+				i3  =(int)bamgmesh->SubDomains[i*3+0];
+				head=(int)bamgmesh->SubDomains[i*3+1]-1;//C indexing
+				sens=(int)bamgmesh->SubDomains[i*3+2];
+				if (i3!=23) ISSMERROR("Bad Subdomain definition: first number should be 3");
+				if (head<0 || head>=nbt) ISSMERROR("Bad Subdomain definition: head should in [1 %i] (triangle number)",nbt);
+				subdomains[i].head = triangles+head;
+			}
+		}
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::WriteMesh {{{1*/
+	void Mesh::WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts){
+
+		/*Intermediary*/
+		int i,j,k,num,i1,i2;
+		long n;
+		int* head_1=NULL;
+		int* next_1=NULL;
+		int* connectivitysize_1=NULL;
+		int  connectivitymax_1=0;
+
+		/*Get options*/
+		int verbose=bamgopts->verbose;
+
+		/*Initialize output*/
+		BamgMeshInit(bamgmesh);
+
+		/*Build reft that holds the number the subdomain number of each triangle, and the real numbering of the elements*/
+		long* reft = new long[nbt];
+		long* numt = new long[nbt];
+		long nbInT = TriangleReferenceList(reft);
+		TriangleIntNumbering(numt);
+
+		/*Chaining algorithm used to generate connectivity tables and other outputs*/
+
+		//Memory Allocation
+		head_1=(int*)xmalloc(nbv*sizeof(int));
+		next_1=(int*)xmalloc(3*nbt*sizeof(int));
+		connectivitysize_1=(int*)xmalloc(nbv*sizeof(int));
+
+		//Initialization
+		for (i=0;i<nbv;i++) head_1[i]=-1;
+		for (i=0;i<nbv;i++) connectivitysize_1[i]=0;
+		k=0;
+		//Chains generation
+		for (i=0;i<nbt;i++) {
+			//Do not take into account outside triangles (reft<0)
+			if (reft[i]>=0){
+				for (j=0;j<3;j++){
+					int v=Number(triangles[i][j]); //jth vertex of the ith triangle
+					if (k>3*nbt-1 || k<0) ISSMERROR("k = %i, nbt = %i",k,nbt);
+					next_1[k]=head_1[v];
+					if (v>nbv-1 || v<0)   ISSMERROR("v = %i, nbv = %i",v,nbv);
+					head_1[v]=k++;
+					connectivitysize_1[v]+=1;
+				}
+			}
+		}
+		//Get maximum connectivity
+		connectivitymax_1=0;
+		for (i=0;i<nbv;i++){
+			if (connectivitysize_1[i]>connectivitymax_1) connectivitymax_1=connectivitysize_1[i];
+		}
+
+		/*OK, now build outputs*/
+
+		/*Vertices*/
+		if(verbose>5) printf("      writing Vertices\n");
+		bamgmesh->VerticesSize[0]=nbv;
+		bamgmesh->VerticesSize[1]=3;
+		if (nbv){
+			bamgmesh->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
+			for (i=0;i<nbv;i++){
+				bamgmesh->Vertices[i*3+0]=vertices[i].r.x;
+				bamgmesh->Vertices[i*3+1]=vertices[i].r.y;
+				bamgmesh->Vertices[i*3+2]=vertices[i].ref();
+			}
+		}
+
+		/*Edges*/
+		if(verbose>5) printf("      writing Edges\n");
+		bamgmesh->EdgesSize[0]=nbe;
+		bamgmesh->EdgesSize[1]=3;
+		int NumIssmSegments=0;
+		if (nbe){
+			bamgmesh->Edges=(double*)xmalloc(3*nbe*sizeof(double));
+			for (i=0;i<nbe;i++){
+				bamgmesh->Edges[i*3+0]=Number(edges[i][0])+1; //back to M indexing
+				bamgmesh->Edges[i*3+1]=Number(edges[i][1])+1; //back to M indexing
+				bamgmesh->Edges[i*3+2]=edges[i].ref;
+				if(edges[i].onGeometry){
+					NumIssmSegments++;
+				}
+			}
+		}
+
+		/*Element edges*/
+		if(verbose>5) printf("      writing element edges\n");
+		SetOfEdges4* edge4=new SetOfEdges4(nbt*3,nbv);
+		double* elemedge=NULL;
+		elemedge=(double*)xmalloc(3*nbt*sizeof(double));
+		for (i=0;i<3*nbt;i++) elemedge[i]=NAN;
+		k=0;
+		for (i=0;i<nbt;i++){
+			//Do not take into account outside triangles (reft<0)
+			if (reft[i]>=0){
+				for  (j=0;j<3;j++) {
+					i1=Number(triangles[i][VerticesOfTriangularEdge[j][0]]);
+					i2=Number(triangles[i][VerticesOfTriangularEdge[j][1]]);
+					n =edge4->SortAndFind(i1,i2);
+					if (n==-1){
+						//first time
+						n=edge4->SortAndAdd(i1,i2);
+						elemedge[n*2+0]=double(k);
+					}
+					else{
+						//second time
+						elemedge[n*2+1]=double(k);
+					}
+				}
+				k++;
+			}
+		}
+		bamgmesh->IssmEdgesSize[0]=edge4->nb();
+		bamgmesh->IssmEdgesSize[1]=4;
+		bamgmesh->IssmEdges=(double*)xmalloc(4*edge4->nb()*sizeof(double));
+		for (i=0;i<edge4->nb();i++){
+			/*Invert first two vertices if necessary*/
+			bool found=false;
+			for (j=0;j<3;j++){
+				if (triangles[(int)elemedge[2*i+0]](j)==vertices+edge4->i(i)){
+					if (triangles[(int)elemedge[2*i+0]]((j+1)%3)==vertices+edge4->j(i)){
+						//trigonometric direction
+						bamgmesh->IssmEdges[i*4+0]=edge4->i(i)+1;// back to M indexing
+						bamgmesh->IssmEdges[i*4+1]=edge4->j(i)+1;// back to M indexing
+					}
+					else{
+						bamgmesh->IssmEdges[i*4+0]=edge4->j(i)+1;// back to M indexing
+						bamgmesh->IssmEdges[i*4+1]=edge4->i(i)+1;// back to M indexing
+					}
+					found=true;
+					break;
+				}
+			}
+			ISSMASSERT(found);
+			bamgmesh->IssmEdges[i*4+2]=elemedge[2*i+0]+1; // back to M indexing
+			bamgmesh->IssmEdges[i*4+3]=elemedge[2*i+1]+1; // back to M indexing
+		}
+		//clean up
+		delete edge4;
+		xfree((void**)&elemedge);
+
+		/*IssmSegments*/
+		if(verbose>5) printf("      writing IssmSegments\n");
+		bamgmesh->IssmSegmentsSize[0]=NumIssmSegments;
+		bamgmesh->IssmSegmentsSize[1]=4;
+		bamgmesh->IssmSegments=(double*)xmalloc(4*NumIssmSegments*sizeof(double));
+		num=0;
+		for (i=0;i<nbe;i++){
+			if(edges[i].onGeometry){
+				//build segment
+				int i1=Number(edges[i][0]);
+				int i2=Number(edges[i][1]);
+				bool stop=false;
+				for(j=head_1[i1];j!=-1;j=next_1[j]){
+					for(k=0;k<3;k++){
+						if (Number(triangles[(int)j/3][k])==i1){
+							if (Number(triangles[(int)j/3][(int)((k+1)%3)])==i2){
+								bamgmesh->IssmSegments[num*4+0]=Number(edges[i][0])+1; //back to M indexing
+								bamgmesh->IssmSegments[num*4+1]=Number(edges[i][1])+1; //back to M indexing
+								bamgmesh->IssmSegments[num*4+2]=(int)j/3+1;            //back to M indexing
+								bamgmesh->IssmSegments[num*4+3]=edges[i].ref;
+								num+=1;
+								stop=true;
+								break;
+							}
+							if (Number(triangles[(int)j/3][(int)((k+2)%3)])==i2){
+								bamgmesh->IssmSegments[num*4+0]=Number(edges[i][1])+1; //back to M indexing
+								bamgmesh->IssmSegments[num*4+1]=Number(edges[i][0])+1; //back to M indexing
+								bamgmesh->IssmSegments[num*4+2]=(int)j/3+1;            //back to M indexing
+								bamgmesh->IssmSegments[num*4+3]=edges[i].ref;
+								num+=1;
+								stop=true;
+								break;
+							}
+						}
+					}
+					if(stop) break;
+				}
+				if (!stop){
+					ISSMERROR("Element holding segment [%i %i] not found...",i1+1,i2+1);
+				}
+			}
+		}
+
+		/*Triangles*/
+		if(verbose>5) printf("      writing Triangles\n");
+		k=nbInT-NbOfQuad*2;
+		num=0;
+		bamgmesh->TrianglesSize[0]=k;
+		bamgmesh->TrianglesSize[1]=4;
+		if (k){
+			bamgmesh->Triangles=(double*)xmalloc(4*k*sizeof(double));
+			for (i=0;i<nbt;i++){
+				Triangle &t=triangles[i];
+				//reft[i]=-1 for outside triangle
+				if (reft[i]>=0 && !( t.Hidden(0) || t.Hidden(1) || t.Hidden(2) )){
+					bamgmesh->Triangles[num*4+0]=Number(t[0])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+1]=Number(t[1])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+2]=Number(t[2])+1; //back to M indexing
+					bamgmesh->Triangles[num*4+3]=subdomains[reft[i]].ref;
+					num=num+1;
+				}
+			}
+		}
+
+		/*Quadrilaterals*/
+		if(verbose>5) printf("      writing Quadrilaterals\n");
+		bamgmesh->QuadrilateralsSize[0]=NbOfQuad;
+		bamgmesh->QuadrilateralsSize[1]=5;
+		if (NbOfQuad){
+			bamgmesh->Quadrilaterals=(double*)xmalloc(5*NbOfQuad*sizeof(double));
+			for (i=0;i<nbt;i++){
+				Triangle &t =triangles[i];
+				Triangle* ta;
+				MeshVertex *v0,*v1,*v2,*v3;
+				if (reft[i]<0) continue;
+				if ((ta=t.Quadrangle(v0,v1,v2,v3)) !=0 && &t<ta) { 
+					bamgmesh->Quadrilaterals[i*5+0]=Number(v0)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+1]=Number(v1)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+2]=Number(v2)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+3]=Number(v3)+1; //back to M indexing
+					bamgmesh->Quadrilaterals[i*5+4]=subdomains[reft[i]].ref;
+				}
+			}
+		}
+
+		/*SubDomains*/
+		if(verbose>5) printf("      writing SubDomains\n");
+		bamgmesh->SubDomainsSize[0]=NbSubDomains;
+		bamgmesh->SubDomainsSize[1]=4;
+		if (NbSubDomains){
+			bamgmesh->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
+			for (i=0;i<NbSubDomains;i++){
+				bamgmesh->SubDomains[i*4+0]=3;
+				bamgmesh->SubDomains[i*4+1]=reft[Number(subdomains[i].head)];
+				bamgmesh->SubDomains[i*4+2]=1;
+				bamgmesh->SubDomains[i*4+3]=subdomains[i].ref;
+			}
+		}
+
+		/*SubDomainsFromGeom*/
+		if(verbose>5) printf("      writing SubDomainsFromGeom\n");
+		bamgmesh->SubDomainsFromGeomSize[0]=Gh.NbSubDomains;
+		bamgmesh->SubDomainsFromGeomSize[1]=4;
+		if (Gh.NbSubDomains){
+			bamgmesh->SubDomainsFromGeom=(double*)xmalloc(4*Gh.NbSubDomains*sizeof(double));
+			for (i=0;i<Gh.NbSubDomains;i++){
+				bamgmesh->SubDomainsFromGeom[i*4+0]=2;
+				bamgmesh->SubDomainsFromGeom[i*4+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
+				bamgmesh->SubDomainsFromGeom[i*4+2]=subdomains[i].sens;
+				bamgmesh->SubDomainsFromGeom[i*4+3]=Gh.subdomains[i].ref;
+			}
+		}
+
+		/*VerticesOnGeomVertex*/
+		if(verbose>5) printf("      writing VerticesOnGeometricVertex\n");
+		bamgmesh->VerticesOnGeometricVertexSize[0]=NbVerticesOnGeomVertex;
+		bamgmesh->VerticesOnGeometricVertexSize[1]=2;
+		if (NbVerticesOnGeomVertex){
+			bamgmesh->VerticesOnGeometricVertex=(double*)xmalloc(2*NbVerticesOnGeomVertex*sizeof(double));
+			for (i=0;i<NbVerticesOnGeomVertex;i++){
+				VertexOnGeom &v=VerticesOnGeomVertex[i];
+				ISSMASSERT(v.OnGeomVertex());
+				bamgmesh->VerticesOnGeometricVertex[i*2+0]=Number((MeshVertex*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricVertex[i*2+1]=Gh.Number((GeometricalVertex*)v)+1; //back to Matlab indexing
+			}
+		}
+
+		/*VertexOnGeometricEdge*/
+		if(verbose>5) printf("      writing VerticesOnGeometricEdge\n");
+		bamgmesh->VerticesOnGeometricEdgeSize[0]=NbVerticesOnGeomEdge;
+		bamgmesh->VerticesOnGeometricEdgeSize[1]=3;
+		if (NbVerticesOnGeomEdge){
+			bamgmesh->VerticesOnGeometricEdge=(double*)xmalloc(3*NbVerticesOnGeomEdge*sizeof(double));
+			for (i=0;i<NbVerticesOnGeomEdge;i++){
+				const VertexOnGeom &v=VerticesOnGeomEdge[i];
+				if (!v.OnGeomEdge()){
+					ISSMERROR("A vertices supposed to be OnGeometricEdge is actually not");
+				}
+				bamgmesh->VerticesOnGeometricEdge[i*3+0]=Number((MeshVertex*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricEdge[i*3+1]=Gh.Number((const GeometricalEdge*)v)+1; //back to Matlab indexing
+				bamgmesh->VerticesOnGeometricEdge[i*3+2]=(double)v; //absisce
+			}
+		}
+
+		/*EdgesOnGeometricEdge*/
+		if(verbose>5) printf("      writing EdgesOnGeometricEdge\n");
+		k=0;
+		for (i=0;i<nbe;i++){
+			if (edges[i].onGeometry) k=k+1;
+		}
+		bamgmesh->EdgesOnGeometricEdgeSize[0]=k;
+		bamgmesh->EdgesOnGeometricEdgeSize[1]=2;
+		if (k){
+			bamgmesh->EdgesOnGeometricEdge=(double*)xmalloc(2*(int)k*sizeof(double));
+			int count=0;
+			for (i=0;i<nbe;i++){
+				if (edges[i].onGeometry){
+					bamgmesh->EdgesOnGeometricEdge[count*2+0]=(double)i+1; //back to Matlab indexing
+					bamgmesh->EdgesOnGeometricEdge[count*2+1]=(double)Gh.Number(edges[i].onGeometry)+1; //back to Matlab indexing
+					count=count+1;
+				}
+			}
+		}
+
+		/*Element Connectivity*/
+		if(verbose>5) printf("      writing Element connectivity\n");
+		bamgmesh->ElementConnectivitySize[0]=nbt-NbOutT;
+		bamgmesh->ElementConnectivitySize[1]=3;
+		bamgmesh->ElementConnectivity=(double*)xmalloc(3*(nbt-NbOutT)*sizeof(double));
+		for (i=0;i<3*(nbt-NbOutT);i++) bamgmesh->ElementConnectivity[i]=NAN;
+		num=0;
+		for (i=0;i<nbt;i++){
+			if (reft[i]>=0){
+				for (j=0;j<3;j++){
+					k=Number(triangles[i].TriangleAdj(j));
+					if (reft[k]>=0){
+						ISSMASSERT(3*num+j<3*(nbt-NbOutT));
+						bamgmesh->ElementConnectivity[3*num+j]=k+1; // back to Matlab indexing
+					}
+				}
+				num+=1;
+			}
+		}
+
+		/*ElementNodal Connectivity*/
+		if(verbose>5) printf("      writing Nodal element connectivity\n");
+		bamgmesh->NodalElementConnectivitySize[0]=nbv;
+		bamgmesh->NodalElementConnectivitySize[1]=connectivitymax_1;
+		bamgmesh->NodalElementConnectivity=(double*)xmalloc(connectivitymax_1*nbv*sizeof(double));
+		for (i=0;i<connectivitymax_1*nbv;i++) bamgmesh->NodalElementConnectivity[i]=NAN;
+		for (i=0;i<nbv;i++){
+			k=0;
+			for(j=head_1[i];j!=-1;j=next_1[j]){
+				ISSMASSERT(connectivitymax_1*i+k < connectivitymax_1*nbv);
+				bamgmesh->NodalElementConnectivity[connectivitymax_1*i+k]=floor(j/3)+1;
+				k++;
+			}
+		}
+
+		/*Nodal Connectivity*/
+		if(verbose>5) printf("      writing Nodal connectivity\n");
+		//chaining algorithm (again...)
+		int* head_2=NULL;
+		int* next_2=NULL;
+		int* connectivitysize_2=NULL;
+		int  connectivitymax_2=0;
+		i1=bamgmesh->IssmEdgesSize[0];
+		i2=bamgmesh->IssmEdgesSize[1];
+		head_2=(int*)xmalloc(nbv*sizeof(int));
+		next_2=(int*)xmalloc(2*i1*sizeof(int));
+		connectivitysize_2=(int*)xmalloc(nbv*sizeof(int));
+		//Initialization
+		for (i=0;i<nbv;i++) head_2[i]=-1;
+		for (i=0;i<nbv;i++) connectivitysize_2[i]=0;
+		k=0;
+		//Chains generation
+		for (i=0;i<i1;i++) {
+			for (j=0;j<2;j++){
+				int v=(int)bamgmesh->IssmEdges[i*i2+j]-1; //back to C indexing
+				if (k>2*i1-1 || k<0) ISSMERROR("Index exceed matrix dimensions (k=%i not in [0 %i]",k,2*i1-1);
+				next_2[k]=head_2[v];
+				if (v>nbv-1 || v<0)   ISSMERROR("Index exceed matrix dimensions (v=%i not in [0 %i])",v,nbv-1);
+				head_2[v]=k++;
+				connectivitysize_2[v]+=1;
+			}
+		}
+		//Get maximum connectivity
+		for (i=0;i<nbv;i++){
+			if (connectivitysize_2[i]>connectivitymax_2) connectivitymax_2=connectivitysize_2[i];
+		}
+		//Build output
+		bamgmesh->NodalConnectivitySize[0]=nbv;
+		bamgmesh->NodalConnectivitySize[1]=connectivitymax_2;
+		bamgmesh->NodalConnectivity=(double*)xmalloc(connectivitymax_2*nbv*sizeof(double));
+		for (i=0;i<connectivitymax_2*nbv;i++) bamgmesh->NodalConnectivity[i]=NAN;
+		for (i=0;i<nbv;i++){
+			k=0;
+			for(j=head_2[i];j!=-1;j=next_2[j]){
+				ISSMASSERT(connectivitymax_2*i+k < connectivitymax_2*nbv);
+				num=(int)bamgmesh->IssmEdges[int(j/2)*i2+0];
+				if (i+1==num){ //carefull, ElementEdge is in M indexing
+					//i is the first vertex of the edge, it is therefore connected to the second vertex
+					bamgmesh->NodalConnectivity[connectivitymax_2*i+k]=bamgmesh->IssmEdges[int(j/2)*i2+1];
+				}
+				else{
+					bamgmesh->NodalConnectivity[connectivitymax_2*i+k]=num;
+				}
+				k++;
+			}
+		}
+
+		/*Cracked vertices*/
+		if(verbose>5) printf("      writing Cracked vertices\n");
+		bamgmesh->CrackedVerticesSize[0]=NbCrackedVertices;
+		bamgmesh->CrackedVerticesSize[1]=2;
+		if (NbCrackedVertices){
+			bamgmesh->CrackedVertices=(double*)xmalloc(2*NbCrackedVertices*sizeof(double));
+			for (i=0;i<NbCrackedVertices;i++){
+				bamgmesh->CrackedVertices[i*2+0]=CrackedVertices[i*2+0]+1; //M indexing
+				bamgmesh->CrackedVertices[i*2+1]=CrackedVertices[i*2+1]+1; //M indexing
+			}
+		}
+
+		/*Cracked vertices*/
+		if(verbose>5) printf("      writing Cracked vertices\n");
+		bamgmesh->CrackedEdgesSize[0]=NbCrackedEdges;
+		bamgmesh->CrackedEdgesSize[1]=4;
+		if (NbCrackedEdges){
+			bamgmesh->CrackedEdges=(double*)xmalloc(2*NbCrackedEdges*sizeof(double));
+			for (i=0;i<NbCrackedEdges;i++){
+				bamgmesh->CrackedEdges[i*2+0]=0;//CrackedEdges[i]->+1; //M indexing
+				bamgmesh->CrackedEdges[i*2+1]=0;//CrackedEdges[i]-]->+1; //M indexing
+			}
+		}
+
+		//clean up
+		xfree((void**)&connectivitysize_1);
+		xfree((void**)&head_1);
+		xfree((void**)&next_1);
+		xfree((void**)&connectivitysize_2);
+		xfree((void**)&head_2);
+		xfree((void**)&next_2);
+		delete [] reft;
+		delete [] numt;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::ReadMetric{{{1*/
+	void Mesh::ReadMetric(const BamgOpts* bamgopts) {
+
+		/*Intermediary*/
+		int  i,j;
+
+		if(bamgopts->verbose>3) printf("      processing metric\n");
+		double hmin = Max(bamgopts->hmin,MinimalHmin());
+		double hmax = Min(bamgopts->hmax,MaximalHmax());
+		double coef = bamgopts->coeff;
+
+		//for now we only use j==3
+		j=3;
+
+		for (i=0;i<nbv;i++){
+			double h;
+			if (j == 1){
+				h=bamgopts->metric[i];
+				vertices[i].m=Metric(Max(hmin,Min(hmax, h*coef)));
+			}
+			else if (j==3){
+				//do not erase metric computed by hVertices
+				if (vertices[i].m.a11==1 && vertices[i].m.a21==0 && vertices[i].m.a22==1){
+					double a,b,c;	     
+					a=bamgopts->metric[i*3+0];
+					b=bamgopts->metric[i*3+1];
+					c=bamgopts->metric[i*3+2];
+					Metric M(a,b,c);
+					MatVVP2x2 Vp(M/coef);
+
+					Vp.Maxh(hmax);
+					Vp.Minh(hmin);
+					vertices[i].m = Vp;
+				}
+			}
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::WriteMetric{{{1*/
+	void Mesh::WriteMetric(BamgOpts* bamgopts) {
+		int i;
+		xfree((void**)&bamgopts->metric);
+		bamgopts->metric=(double*)xmalloc(3*nbv*sizeof(double));
+		for (i=0;i<nbv;i++){
+			bamgopts->metric[i*3+0]=vertices[i].m.a11;
+			bamgopts->metric[i*3+1]=vertices[i].m.a21;
+			bamgopts->metric[i*3+2]=vertices[i].m.a22;
+		}
+	}
+	/*}}}1*/
+
+	/*Methods*/
+	/*FUNCTION Mesh::AddGeometryMetric{{{1*/
+	void Mesh::AddGeometryMetric(BamgOpts* bamgopts){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/IntersectGeomMetric)*/
+
+		/*Get options*/
+		int    verbose=bamgopts->verbose;
+		double anisomax =bamgopts->anisomax;
+		double errg     =bamgopts->errg;
+
+		double ss[2]={0.00001,0.99999};
+		double errC = 2*sqrt(2*errg);
+		double hmax = Gh.MaximalHmax();
+		double hmin = Gh.MinimalHmin();
+
+		//check that hmax is positive
+		if (hmax<=0){
+			ISSMERROR("hmax<=0");
+		}
+
+		//errC cannot be higher than 1
+		if (errC>1) errC=1;
+
+		//Set all vertices to "on"
+		SetVertexFieldOn();
+
+		//loop over all the vertices on edges
+		for (int  i=0;i<nbe;i++){
+			for (int j=0;j<2;j++){
+
+				MeshVertex V;
+				VertexOnGeom GV;
+				Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
+
+				GeometricalEdge* eg = GV;
+				double s = GV;
+				R2 tg;
+				double  R1= eg->R1tg(s,tg);
+				double  ht=hmax;
+				// err relative to the length of the edge
+				if (R1>1.0e-20) {  
+					ht = Min(Max(errC/R1,hmin),hmax);
+				}
+				double hn=Min(hmax,ht*anisomax);
+
+				if (ht<=0 || hn<=0){
+					ISSMERROR("ht<=0 || hn<=0");
+				}
+				MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
+				Metric MVp(Vp);
+				edges[i][j].m.IntersectWith(MVp);
+			}
+		}
+		// the problem is for the vertex on vertex 
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::AddMetric{{{1*/
+	void Mesh::AddMetric(BamgOpts* bamgopts){
+		//  Hessiantype = 0 =>  H is computed using double P2 projection
+		//  Hessiantype = 1 =>  H is computed with green formula
+
+		/*Options*/
+		int Hessiantype=bamgopts->Hessiantype;
+
+		if (Hessiantype==0){
+			BuildMetric0(bamgopts);
+		}
+		else if (Hessiantype==1){
+			BuildMetric1(bamgopts);
+		}
+		else{
+			ISSMERROR("Hessiantype %i not supported yet (1->use Green formula, 0-> double P2 projection)",Hessiantype);
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::AddVertex{{{1*/
+	void Mesh::AddVertex( MeshVertex &s,Triangle* t, Icoor2* det3) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Add)*/
+		// -------------------------------------------
+		//             s2
+		//                                            !
+		//             /|\                            !
+		//            / | \                           !
+		//           /  |  \                          !
+		//    tt1   /   |   \ tt0                     !
+		//         /    |s   \                        !
+		//        /     .     \                       !
+		//       /  .      `   \                      !
+		//      / .           ` \                     !
+		//      ----------------                      !
+		//   s0       tt2       s1
+		//-------------------------------------------- 
+
+		//the three triangles tt
+		Triangle* tt[3];
+		//three vertices of t
+		MeshVertex &s0 = (*t)[0], &s1=(*t)[1], &s2=(*t)[2];
+		//three determinants
+		Icoor2 det3local[3];
+		// number of zero det3
+		register int nbzerodet =0; 
+		// izerodet = egde contening the vertex s
+		register int izerodet=-1,iedge; 
+		//determinant of t
+		Icoor2 detOld = t->det;
+
+		// infinitevertexpos = order of the infinite vertex (NULL)
+		// if no infinite vertex (NULL) infinitevertexpos=-1
+		// else if v_i is infinite, infinitevertexpos=i
+		int infinitevertexpos = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
+
+		//some checks
+		if (( infinitevertexpos <0 ) && (detOld <0) ||  ( infinitevertexpos >=0  ) && (detOld >0) ){
+			ISSMERROR("bug in Mesh::Add, bad configuration");
+		}
+
+		// if det3 does not exist, build it 
+		if (!det3) { 
+			//allocate
+			det3 = det3local;
+			//if no infinite vertex
+			if (infinitevertexpos<0 ) {
+				det3[0]=bamg::det(s ,s1,s2);
+				det3[1]=bamg::det(s0,s ,s2);
+				det3[2]=bamg::det(s0,s1,s );}
+			else { 
+				// one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
+				det3[0]= &s0 ? -1 : bamg::det(s ,s1,s2) ;
+				det3[1]= &s1 ? -1 : bamg::det(s0,s ,s2) ;
+				det3[2]= &s2 ? -1 : bamg::det(s0,s1,s ) ;
+			}
+		}
+
+		if (!det3[0]) izerodet=0,nbzerodet++;
+		if (!det3[1]) izerodet=1,nbzerodet++;
+		if (!det3[2]) izerodet=2,nbzerodet++;
+
+		//if nbzerodet>0, point s is on an egde or on a vertex 
+		if  (nbzerodet >0 ){ 
+			if (nbzerodet == 1) {
+				iedge = OppositeEdge[izerodet];
+				TriangleAdjacent ta = t->Adj(iedge);
+
+				// the point is on the edge 
+				// if the point is one the boundary 
+				// add the point in outside part 
+				if ( t->det >=0) { // inside triangle
+					if ((( Triangle *) ta)->det < 0 ) {
+						// add in outside triangle 
+						AddVertex(s,( Triangle *) ta);
+						return;
+					}
+				}
+			}
+			else {
+				//t->Echo();
+				printf("\nproblem while trying to add:\n");
+				s.Echo();
+				ISSMERROR("Bug in Mesh::Add points duplicated %i times",nbzerodet);
+			}
+		}
+
+		// remove de MarkUnSwap edge
+		t->SetUnMarkUnSwap(0);     
+		t->SetUnMarkUnSwap(1);     
+		t->SetUnMarkUnSwap(2);
+
+		tt[0]= t;
+		tt[1]= &triangles[nbt++];
+		tt[2]= &triangles[nbt++];
+
+		if (nbt>nbtx) {
+			ISSMERROR("Not ebough triangles");
+		}
+
+		*tt[1]=   *tt[2]= *t;
+		// gestion of the link
+		tt[0]->link=tt[1];
+		tt[1]->link=tt[2]; 
+
+		(* tt[0])(OppositeVertex[0])=&s;
+		(* tt[1])(OppositeVertex[1])=&s;
+		(* tt[2])(OppositeVertex[2])=&s;
+
+		tt[0]->det=det3[0];
+		tt[1]->det=det3[1];
+		tt[2]->det=det3[2];         
+
+		//  update adj des triangles externe 
+		tt[0]->SetAdjAdj(0);
+		tt[1]->SetAdjAdj(1);
+		tt[2]->SetAdjAdj(2);
+		//  update des adj des 3 triangle interne
+		const int i0 = 0;
+		const int i1= NextEdge[i0];
+		const int i2 = PreviousEdge[i0];
+
+		tt[i0]->SetAdj2(i2,tt[i2],i0);
+		tt[i1]->SetAdj2(i0,tt[i0],i1);
+		tt[i2]->SetAdj2(i1,tt[i1],i2);
+
+		tt[0]->SetTriangleContainingTheVertex();
+		tt[1]->SetTriangleContainingTheVertex();
+		tt[2]->SetTriangleContainingTheVertex();
+
+
+		// swap if the point s is on a edge
+		if(izerodet>=0) {
+			int rswap =tt[izerodet]->swap(iedge);
+
+			if (!rswap) {
+				ISSMERROR("swap the point s is on a edge");
+			}
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::BoundAnisotropy{{{1*/
+	void  Mesh::BoundAnisotropy(double anisomax,double hminaniso) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/BoundAnisotropy)*/
+
+		long int verbose=0;
+		double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
+
+		//display info
+		if (verbose > 1)  printf("   BoundAnisotropy by %g\n",anisomax);
+
+		double h1=1.e30,h2=1e-30;
+		double coef = 1./(anisomax*anisomax);
+		double hn1=1.e30,hn2=1e-30,rnx =1.e-30,rx=0;  
+
+		//loop over all vertices
+		for (int i=0;i<nbv;i++){
+			MatVVP2x2 Vp(vertices[i]);
+			double lmax=Vp.lmax();
+			Vp*=Min(lminaniso,lmax)/lmax;
+			Vp.BoundAniso2(coef);
+			vertices[i].m = Vp;
+
+			//info to be displayed
+			if (verbose>2){
+				h1 =Min(h1,Vp.lmin());
+				h2 =Max(h2,Vp.lmax());
+				hn1=Min(hn1,Vp.lmin());
+				hn2=Max(hn2,Vp.lmax());
+				rx =Max(rx,Vp.Aniso2());
+				rnx= Max(rnx,Vp.Aniso2());
+			}
+		}
+
+		//display info
+		if (verbose>2){
+			printf("      input:  Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(h2,-0.5),pow(h1,-0.5),pow(rx,0.5));
+			printf("      output: Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::BuildGeometryFromMesh{{{1*/
+	void Mesh::BuildGeometryFromMesh(BamgOpts* bamgopts){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshGeom.cpp/ConsGeometry)*/
+
+		/*Reconstruct Geometry from Mesh*/
+
+		/*Intermediary*/
+		int i,j,k,kk,it,jt;
+		int    verbose=0;
+		double cutoffradian=10*Pi/180;
+
+		/*Recover options*/
+		if (bamgopts){
+			verbose=bamgopts->verbose;
+			cutoffradian=bamgopts->MaxCornerAngle*Pi/180;
+		}
+
+		//display info
+		if (verbose>1) printf("   construction of the geometry from the 2d mesh\n");
+
+		//check that the mesh is not empty
+		if (nbt<=0 || nbv <=0 ) {
+			ISSMERROR("nbt or nbv is negative (Mesh empty?)");
+		}
+
+		//Gh is the geometry of the mesh (this), initialize MaxCornerAngle
+		if (cutoffradian>=0) Gh.MaxCornerAngle = cutoffradian;
+
+		/*Construction of the edges*/
+
+		//initialize st and edge4
+		SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
+		long*        st   = new long[nbt*3];
+
+		//initialize st as -1 (chaining algorithm)
+		for (i=0;i<nbt*3;i++) st[i]=-1;
+
+		//build edge4 (chain)
+		for (i=0;i<nbe;i++){
+			edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1]));
+		}
+		//check that there is no double edge
+		if (nbe !=  edge4->nb()){ 
+			ISSMERROR("Some Double edge in the mesh, the number is %i, nbe4=%i",nbe,edge4->nb()); 
+		}
+		//keep nbe in nbeold
+		long nbeold = nbe;
+
+		//Go through the triangles and ass the edges in edge4 if they are not there yet
+		for (i=0;i<nbt;i++){
+			//3 edges per triangle
+			for  (j=0;j<3;j++) {
+				//Add Edge to edge4 (k=numberofedges in edge4)
+				long k =edge4->SortAndAdd(Number(triangles[i][VerticesOfTriangularEdge[j][0]]), Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
+				long invisible = triangles[i].Hidden(j);
+
+				//if st[k] has not been changed yet, add 3*i+j (= vertex position in the index)
+				if(st[k]==-1) st[k]=3*i+j;
+
+				//else st[k]>=0 -> the edge already exist, check
+				else if(st[k]>=0) {
+					//check that it is not an edge on boundary (should not already exist)
+					if (triangles[i].TriangleAdj(j) || triangles[st[k]/3].TriangleAdj((int) (st[k]%3))){
+						ISSMERROR("problem in Geometry reconstruction: an edge on boundary is duplicated (double element?)");
+					}
+					//OK, the element is not on boundary, is belongs to 2 triangles -> build Adjacent triangles list
+					triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
+					if (invisible)  triangles[i].SetHidden(j);
+					// if k < nbe mark the edge as on Boundary (Locked)
+					if (k<nbe) {
+						triangles[i].SetLocked(j);
+					}
+					//set st[k] as negative so that the edge should not be called again
+					st[k]=-2-st[k]; 
+				}
+				//else (see 3 lines above), the edge has been called more than twice: return error
+				else {
+					printf("The edge (%i,%i) belongs to more than 2 triangles (%i)\n",Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]),k);
+					printf("Edge %i of triangle %i\n",j,i);
+					printf("Edge %i of triangle %i\n",(-st[k]+2)%3,(-st[k]+2)/3);
+					printf("Edge %i of triangle %i\n",triangles[(-st[k]+2)/3].NuEdgeTriangleAdj((int)((-st[k]+2)%3)),Number(triangles[(-st[k]+2)/3].TriangleAdj((int)((-st[k]+2)%3))));
+					ISSMERROR("An edge belongs to more than 2 triangles");
+				}	
+			}
+		}
+
+		//delete edge4
+		long nbedges = edge4->nb(); // the total number of edges 
+		delete edge4; edge4=NULL;
+
+		//display info
+		if(verbose>5) {
+			printf("         info on Mesh:\n");
+			printf("            - number of vertices    = %i \n",nbv); 
+			printf("            - number of triangles   = %i \n",nbt); 
+			printf("            - number of given edges = %i \n",nbe); 
+			printf("            - number of all edges   = %i \n",nbedges); 
+			printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-nbedges+nbv); 
+		}
+
+		// check consistency of edge[].adj and geometrical required  vertices
+		k=0; kk=0;
+		for (i=0;i<nbedges;i++){
+			//internal edge
+			if (st[i] <-1) {
+				//get triangle number back
+				it =  (-2-st[i])/3;
+				//get edge position back
+				j  =  (int) ((-2-st[i])%3);
+				Triangle &tt=*triangles[it].TriangleAdj(j);
+				if (triangles[it].color != tt.color|| i < nbeold) k++;
+			}
+			//boundary edge (alone)
+			else if (st[i] >=0) 
+			 kk++;
+		}
+
+		/*Constructions of edges*/
+
+		k += kk;
+		kk=0;
+		if (k) {
+			nbe = k;
+			Edge* edgessave=edges;
+			edges = new Edge[nbe];
+			k =0;
+
+			//display info
+			if(verbose>4) printf("   Construction of the edges %i\n",nbe);
+
+			for (i=0;i<nbedges;i++){ 
+				long  add= -1;
+
+				//internal edge (belongs to two triangles)
+				if (st[i] <-1){ 
+					it =  (-2-st[i])/3;
+					j  =  (int) ((-2-st[i])%3);
+					Triangle & tt = * triangles[it].TriangleAdj(j);
+					if (triangles[it].color !=  tt.color || i < nbeold) add=k++;
+				}
+				//boundary edge
+				else if (st[i] >=0){
+					it = st[i]/3;
+					j  = (int) (st[i]%3);
+					add=k++;
+				}
+				if (add>=0 && add < nbe){
+					edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
+					edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
+					edges[add].onGeometry=NULL; 
+					//if already existed
+					if (i<nbeold){
+						edges[add].ref=edgessave[i].ref; 		      
+						edges[add].onGeometry=edgessave[i].onGeometry; //  HACK to get required edges
+						printf("oh no...\n");
+					}
+					else
+					 edges[add].ref=Min(edges[add].v[0]->ref(),edges[add].v[1]->ref());
+				  }
+			}
+
+			//check that we have been through all edges
+			if (k!=nbe){
+				ISSMERROR("problem in edge construction process: k!=nbe (should not happen)");
+			}
+			//delete edgessave
+			if (edgessave) delete [] edgessave;
+		}
+
+		/*Color the vertices*/
+
+		//initialize color of all vertices as 0
+		for (i=0;i<nbv;i++) vertices[i].color =0;
+
+		//go through the edges and add a color to corresponding vertices
+		//(A vertex in 4 edges will have a color 4)
+		for (i=0;i<nbe;i++){
+		 for (j=0;j<2;j++) edges[i].v[j]->color++;
+		}
+
+		//change the color: if a vertex belongs to 2 edges -1, else -2
+		for (i=0;i<nbv;i++) {
+			vertices[i].color=(vertices[i].color ==2)? -1 : -2;
+		}
+
+		/*Build edges[i].adj: adjacency of each edge (if on the same curve)*/
+		for (i=0;i<nbe;i++){
+			for (j=0;j<2;j++){ 
+				//get current vertex
+				MeshVertex* v=edges[i].v[j];
+				//get vertex color (i0)
+				long i0=v->color;
+				long j0;
+
+				//if color<0 (first time), no adjacent edge
+				if(i0<0) edges[i].adj[j]=NULL;
+
+				//if color=-1 (corner),change the vertex color as 2*i+j (position of the vertex in edges)
+				if(i0==-1) v->color=i*2+j;
+
+				//if color>=0 (i and i0 edge are adjacent by the vertex v)
+				else if (i0>=0) {
+					//get position of v in edges back
+					j0 =  i0%2; //column in edges
+					i0 =  i0/2; //line in edges
+
+					//check that we have the correct vertex
+					if (v!=edges[i0 ].v[j0]){
+						ISSMERROR("v!=edges[i0 ].v[j0]: this should not happen as the vertex belongs to this edge");
+					}
+
+					//Add adjacence
+					edges[i ].adj[j ]=edges +i0;
+					edges[i0].adj[j0]=edges +i ;
+
+					//change color to -3
+					v->color = -3;
+				}
+			}
+		}
+
+		/*Reconstruct subdomains info*/
+
+		//check that NbSubDomains is empty
+		if (NbSubDomains){
+			ISSMERROR("NbSubDomains should be 0");
+		}
+		NbSubDomains=0;
+
+		//color the subdomains
+		long* colorT= new long[nbt];
+		Triangle *tt,*t;
+
+		//initialize the color of each triangle as -1
+		for (it=0;it<nbt;it++) colorT[it]=-1;
+
+		//loop over the triangles
+		for (it=0;it<nbt;it++){
+
+			//if the triangle has not been colored yet:
+			if (colorT[it]<0){
+
+				//color = number of subdomains
+				colorT[it]=NbSubDomains;
+
+				//color all the adjacent triangles of T that share a non marked edge
+				int level =1;
+				int kolor=triangles[it].color;
+				st[0]=it; // stack 
+				st[1]=0;
+				k=1;
+				while (level>0){
+					if( (j=st[level]++)<3 ){ 
+						t = &triangles[st[level-1]];
+						tt=t->TriangleAdj((int)j);
+
+						//color the adjacent triangle
+						if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor)) {
+							colorT[jt]=NbSubDomains;
+							st[++level]=jt;
+							st[++level]=0;
+							k++;
+						}
+					}
+					else level-=2;
+				}
+				NbSubDomains++;
+			}
+		}
+		if (verbose> 3) printf("      The Number of sub domain = %i\n",NbSubDomains); 
+
+		//build subdomains
+		long isd;
+		subdomains = new SubDomain[NbSubDomains];
+
+		//initialize subdomains[isd].head as 0
+		for (isd=0;isd<NbSubDomains;isd++) subdomains[isd].head =0;
+		  
+		k=0;
+		for (it=0;it<nbt;it++){
+			for (int j=0;j<3;j++){
+				tt=triangles[it].TriangleAdj(j);
+				if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head){
+					subdomains[isd].head = triangles+it;
+					subdomains[isd].ref =  triangles[it].color;
+					subdomains[isd].sens = j; // hack
+					subdomains[isd].edge = 0;
+					k++;
+				}
+			}
+		}
+		//check that we have been through all subdomains
+		if (k!= NbSubDomains){
+			ISSMERROR("k!= NbSubDomains");
+		}
+		//delete colorT and st
+		delete [] colorT;
+		delete [] st;
+
+		/*Reconstruct Geometry Gh*/
+
+		//build colorV -1 for all vertex and 0 for the vertices belonging to edges
+		long* colorV = new long[nbv];
+		for (i=0;i<nbv;i++) colorV[i]=-1;
+		for (i=0;i<nbe;i++){
+		 for ( j=0;j<2;j++) colorV[Number(edges[i][j])]=0;
+		}
+		//number the vertices belonging to edges
+		k=0;
+		for (i=0;i<nbv;i++){
+		 if(!colorV[i]) colorV[i]=k++;
+		}
+
+		//Build Gh
+		Gh.nbv=k;
+		Gh.nbe = nbe;
+		Gh.vertices = new GeometricalVertex[k];
+		Gh.edges = new GeometricalEdge[nbe];
+		Gh.NbSubDomains = NbSubDomains;
+		Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
+		if (verbose>3) printf("   number of vertices = %i\n   number of edges = %i\n",Gh.nbv,Gh.nbe);
+		NbVerticesOnGeomVertex = Gh.nbv;
+		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
+		NbVerticesOnGeomEdge =0;
+		VerticesOnGeomEdge =0;
+
+		//Build VertexOnGeom
+		for (i=0;i<nbv;i++){
+			if((j=colorV[i])>=0){
+				MeshVertex & v = Gh.vertices[j];
+				v = vertices[i];
+				v.color =0;
+				VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
+			}
+		}
+
+		//Buid pmin and pmax of Gh (extrema coordinates)
+		Gh.pmin =  Gh.vertices[0].r;
+		Gh.pmax =  Gh.vertices[0].r;
+		// recherche des extrema des vertices pmin,pmax
+		for (i=0;i<Gh.nbv;i++) {
+			Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
+			Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
+			Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
+			Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
+		}
+		R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
+		Gh.pmin -=  DD05;
+		Gh.pmax +=  DD05;
+
+		//Build Gh.coefIcoor
+		Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
+		if (Gh.coefIcoor<=0){
+			ISSMERROR("Gh.coefIcoor<=0 in infered Geometry (this should not happen)");
+		}
+
+		/*Build Gh.edges*/
+
+		//initialize len as 0
+		double * len = new double[Gh.nbv];
+		for(i=0;i<Gh.nbv;i++) len[i]=0;
+
+		//initialize edge4 again
+		edge4= new SetOfEdges4(nbe,nbv);  
+		double hmin = HUGE_VAL;
+		int kreq=0;
+		for (i=0;i<nbe;i++){
+
+			long i0 = Number(edges[i][0]);
+			long i1 = Number(edges[i][1]);
+			long j0 = colorV[i0];
+			long j1 = colorV[i1];
+
+			Gh.edges[i].v[0] = Gh.vertices +  j0;
+			Gh.edges[i].v[1] = Gh.vertices +  j1;
+
+			Gh.edges[i].flag = 0;
+
+			Gh.edges[i].tg[0]=R2();
+			Gh.edges[i].tg[1]=R2();
+
+			bool required= edges[i].onGeometry; 
+			if(required) kreq++;
+			edges[i].onGeometry =  Gh.edges + i;
+			if(required){
+				Gh.edges[i].v[0]->SetRequired();
+				Gh.edges[i].v[1]->SetRequired();
+				Gh.edges[i].SetRequired();
+			}
+
+			R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
+			double l12=Norme2(x12);        
+			hmin = Min(hmin,l12);
+
+			Gh.vertices[j1].color++;
+			Gh.vertices[j0].color++;
+
+			len[j0]+= l12;
+			len[j1] += l12;
+			hmin = Min(hmin,l12);
+			Gh.edges[i].ref  = edges[i].ref;
+
+			k = edge4->SortAndAdd(i0,i1);
+			if (k != i){
+				ISSMERROR("problem in Edge4 construction: k != i");
+			}
+		}
+
+		//Build metric for all vertices of Gh
+		for (i=0;i<Gh.nbv;i++){
+		 if (Gh.vertices[i].color > 0) 
+		  Gh.vertices[i].m=  Metric(len[i] /(double) Gh.vertices[i].color);
+		 else 
+		  Gh.vertices[i].m=  Metric(hmin);
+		}
+		//delete len
+		delete [] len;
+
+		//Build Gh.subdomains
+		for (i=0;i<NbSubDomains;i++){
+			it = Number(subdomains[i].head);
+			j = subdomains[i].sens;
+			long i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
+			long i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
+			k = edge4->SortAndFind(i0,i1);
+			if(k>=0){
+				subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
+				subdomains[i].edge = edges+k;
+				Gh.subdomains[i].edge = Gh.edges + k;
+				Gh.subdomains[i].sens  =  subdomains[i].sens;
+				Gh.subdomains[i].ref =  subdomains[i].ref;
+			}
+			else
+			 ISSMERROR("%i should be >=0");
+		  }
+
+		delete edge4;
+		delete [] colorV;
+
+		//unset adj
+		for (i=0;i<nbt;i++){
+			for ( j=0;j<3;j++){
+				triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
+			}
+		}
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::BuildMetric0 (double P2 projection){{{1*/
+	void Mesh::BuildMetric0(BamgOpts* bamgopts){
+
+		/*Options*/
+		double* s=NULL;
+		long    nbsol;
+		int     verbose;
+
+		int   i,j,k,iA,iB,iC;
+		int   iv;
+
+		/*Recover options*/
+		verbose=bamgopts->verbose;
+
+		/*Get and process fields*/
+		s=bamgopts->field;
+		nbsol=bamgopts->numfields;
+
+		//initialization of some variables
+		double* ss=(double*)s;
+		double  sA,sB,sC;
+		double*  detT = new double[nbt];
+		double*  sumareas = new double[nbv];
+		double*  alpha= new double[nbt*3];
+		double*  beta = new double[nbt*3];
+		double*  dx_elem    = new double[nbt];
+		double*  dy_elem    = new double[nbt];
+		double*  dx_vertex  = new double[nbv];
+		double*  dy_vertex  = new double[nbv];
+		double*  dxdx_elem  = new double[nbt];
+		double*  dxdy_elem  = new double[nbt];
+		double*  dydy_elem  = new double[nbt];
+		double*  dxdx_vertex= new double[nbv];
+		double*  dxdy_vertex= new double[nbv];
+		double*  dydy_vertex= new double[nbv];
+
+		//display infos
+		if(verbose>1) {
+			printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
+		}
+
+		//first, build the chains that will be used for the Hessian computation, as weel as the area of each element
+		int* head_s=NULL;
+		head_s=(int*)xmalloc(nbv*sizeof(int));
+		int* next_p=NULL;
+		next_p=(int*)xmalloc(3*nbt*sizeof(int));
+		int  p=0;
+		//initialization
+		for(i=0;i<nbv;i++){
+			sumareas[i]=0;
+			head_s[i]=-1;
+		}
+		for(i=0;i<nbt;i++){
+
+			//lopp over the real triangles (no boundary elements)
+			if(triangles[i].link){ 
+
+				//get current triangle t
+				const Triangle &t=triangles[i];
+
+				// coor of 3 vertices 
+				R2 A=t[0];
+				R2 B=t[1];
+				R2 C=t[2];
+
+				//compute triangle determinant (2*Area)
+				double dett = bamg::Area2(A,B,C);
+				detT[i]=dett;
+
+				/*The nodal functions are such that for a vertex A:
+				 *    N_A(x,y)=alphaA x + beta_A y +gamma_A
+				 *    N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
+				 * solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
+				 * leads to:
+				 *    N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
+				 * and this gives:
+				 *    alpha_A = (yB-yC)/(2*Area(T))*/
+				alpha[i*3+0]=(B.y-C.y)/dett;
+				alpha[i*3+1]=(C.y-A.y)/dett;
+				alpha[i*3+2]=(A.y-B.y)/dett;
+				beta[ i*3+0]=(C.x-B.x)/dett;
+				beta[ i*3+1]=(A.x-C.x)/dett;
+				beta[ i*3+2]=(B.x-A.x)/dett;
+
+				//compute chains
+				for(j=0;j<3;j++){
+					k=Number(triangles[i][j]);
+					next_p[p]=head_s[k];
+					head_s[k]=p++;
+
+					//add area to sumareas
+					sumareas[k]+=dett;
+				}
+
+			}
+		}
+
+		//for all Solutions
+		for (int nusol=0;nusol<nbsol;nusol++) {
+			double smin=ss[nusol],smax=ss[nusol];
+
+			//get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
+			for ( iv=0,k=0; iv<nbv; iv++){
+				smin=Min(smin,ss[iv*nbsol+nusol]);
+				smax=Max(smax,ss[iv*nbsol+nusol]);
+			}
+			double sdelta=smax-smin;
+			double absmax=Max(Abs(smin),Abs(smax));
+
+			//display info
+			if(verbose>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g\n",nusol,smin,smax,sdelta);
+
+			//skip constant field
+			if (sdelta < 1.0e-10*Max(absmax,1e-20)){
+				printf("      Solution %i is constant, skipping...\n",nusol);
+				continue;
+			}
+
+			//initialize the hessian and gradient matrices
+			for ( iv=0,k=0; iv<nbv; iv++) dxdx_vertex[iv]=dxdy_vertex[iv]=dydy_vertex[iv]=dx_vertex[iv]=dy_vertex[iv]=0;
+
+			//1: Compute gradient for each element (exact)
+			for (i=0;i<nbt;i++){
+				if(triangles[i].link){
+					// number of the 3 vertices
+					iA = Number(triangles[i][0]);
+					iB = Number(triangles[i][1]);
+					iC = Number(triangles[i][2]);
+
+					// value of the P1 fonction on 3 vertices 
+					sA = ss[iA*nbsol+nusol];
+					sB = ss[iB*nbsol+nusol];
+					sC = ss[iC*nbsol+nusol];
+
+					//gradient = (sum alpha_i s_i, sum_i beta_i s_i)
+					dx_elem[i]=sA*alpha[3*i+0]+sB*alpha[3*i+1]+sC*alpha[3*i+2];
+					dy_elem[i]=sA*beta[ 3*i+0]+sB*beta[ 3*i+1]+sC*beta[ 3*i+2];
+				}
+			}
+
+			//2: then compute a gradient for each vertex using a P2 projection
+			for(i=0;i<nbv;i++){
+				for(p=head_s[i];p!=-1;p=next_p[p]){
+					//Get triangle number
+					k=(long)(p/3);
+					dx_vertex[i]+=dx_elem[k]*detT[k]/sumareas[i];
+					dy_vertex[i]+=dy_elem[k]*detT[k]/sumareas[i];
+				}
+			}
+
+			//3: compute Hessian matrix on each element
+			for (i=0;i<nbt;i++){
+				if(triangles[i].link){
+					// number of the 3 vertices
+					iA = Number(triangles[i][0]);
+					iB = Number(triangles[i][1]);
+					iC = Number(triangles[i][2]);
+
+					//Hessian
+					dxdx_elem[i]=dx_vertex[iA]*alpha[3*i+0]+dx_vertex[iB]*alpha[3*i+1]+dx_vertex[iC]*alpha[3*i+2];
+					dxdy_elem[i]=dy_vertex[iA]*alpha[3*i+0]+dy_vertex[iB]*alpha[3*i+1]+dy_vertex[iC]*alpha[3*i+2];
+					dydy_elem[i]=dy_vertex[iA]*beta[3*i+0]+dy_vertex[iB]*beta[3*i+1]+dy_vertex[iC]*beta[3*i+2];
+				}
+			}
+
+			//4: finaly compute Hessian on each vertex using the second P2 projection
+			for(i=0;i<nbv;i++){
+				for(p=head_s[i];p!=-1;p=next_p[p]){
+					//Get triangle number
+					k=(long)(p/3);
+					dxdx_vertex[i]+=dxdx_elem[k]*detT[k]/sumareas[i];
+					dxdy_vertex[i]+=dxdy_elem[k]*detT[k]/sumareas[i];
+					dydy_vertex[i]+=dydy_elem[k]*detT[k]/sumareas[i];
+				}
+			}
+
+			/*Compute Metric from Hessian*/
+			for ( iv=0;iv<nbv;iv++){
+				vertices[iv].MetricFromHessian(dxdx_vertex[iv],dxdy_vertex[iv],dydy_vertex[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
+			}
+
+		}//for all solutions
+
+		//clean up
+		xfree((void**)&head_s);
+		xfree((void**)&next_p);
+		delete [] detT;
+		delete [] alpha;
+		delete [] beta;
+		delete [] sumareas;
+		delete [] dx_elem;
+		delete [] dy_elem;
+		delete [] dx_vertex;
+		delete [] dy_vertex;
+		delete [] dxdx_elem;
+		delete [] dxdy_elem;
+		delete [] dydy_elem;
+		delete [] dxdx_vertex;
+		delete [] dxdy_vertex;
+		delete [] dydy_vertex;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::BuildMetric1 (Green formula){{{1*/
+	void Mesh::BuildMetric1(BamgOpts* bamgopts){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/IntersectConsMetric)*/
+
+		/*Options*/
+		double* s=NULL;
+		long nbsol;
+		int NbJacobi;
+		int verbose;
+
+		/*Recover options*/
+		verbose=bamgopts->verbose;
+		NbJacobi=bamgopts->nbjacobi;
+
+		/*Get and process fields*/
+		s=bamgopts->field;
+		nbsol=bamgopts->numfields;
+
+		//initialization of some variables
+		long    i,k,iA,iB,iC,iv;
+		R2      O(0,0);
+		double* ss=(double*)s;
+		double  sA,sB,sC;
+		double*  detT = new double[nbt];
+		double*  Mmass= new double[nbv];
+		double*  Mmassxx= new double[nbv];
+		double*  dxdx= new double[nbv];
+		double*  dxdy= new double[nbv];
+		double*  dydy= new double[nbv];
+		double*  workT= new double[nbt];
+		double*  workV= new double[nbv];
+		int*    OnBoundary = new int[nbv];
+
+		//display infos
+		if(verbose>1) {
+			printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
+		}
+
+		//initialize Mmass, OnBoundary and Massxx by zero
+		for (iv=0;iv<nbv;iv++){
+			Mmass[iv]=0;
+			OnBoundary[iv]=0;
+			Mmassxx[iv]=0;
+		}
+
+		//Build detT Mmas Mmassxx workT and OnBoundary
+		for (i=0;i<nbt;i++){ 
+
+			//lopp over the real triangles (no boundary elements)
+			if(triangles[i].link){ 
+
+				//get current triangle t
+				const Triangle &t=triangles[i];
+
+				// coor of 3 vertices 
+				R2 A=t[0];
+				R2 B=t[1];
+				R2 C=t[2];
+
+				// number of the 3 vertices
+				iA = Number(t[0]);
+				iB = Number(t[1]);
+				iC = Number(t[2]);
+
+				//compute triangle determinant (2*Area)
+				double dett = bamg::Area2(A,B,C);
+				detT[i]=dett;
+				dett /= 6;
+
+				// construction of OnBoundary (flag=1 if on boundary, else 0)
+				int nbb=0;
+				for(int j=0;j<3;j++){
+					//get adjacent triangle
+					Triangle *ta=t.Adj(j);
+					//if there is no adjacent triangle, the edge of the triangle t is on boundary
+					if ( !ta || !ta->link){
+						//mark the two vertices of the edge as OnBoundary
+						OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1;
+						OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1;
+						nbb++;
+					}
+				}
+
+				//number of vertices on boundary for current triangle t
+				workT[i] = nbb;
+
+				//Build Mmass Mmass[i] = Mmass[i] + Area/3
+				Mmass[iA] += dett;
+				Mmass[iB] += dett;
+				Mmass[iC] += dett;
+
+				//Build Massxx = Mmass
+				Mmassxx[iA] += dett;
+				Mmassxx[iB] += dett;
+				Mmassxx[iC] += dett;
+			}
+
+			//else: the triangle is a boundary triangle -> workT=-1
+			else workT[i]=-1;
+		}
+
+		//for all Solution  
+		for (int nusol=0;nusol<nbsol;nusol++) {
+
+			double smin=ss[nusol],smax=ss[nusol];
+			double h1=1.e30,h2=1e-30,rx=0;
+			double hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
+
+			//get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
+			for ( iv=0,k=0; iv<nbv; iv++ ){
+				dxdx[iv]=dxdy[iv]=dydy[iv]=0;
+				smin=Min(smin,ss[iv*nbsol+nusol]);
+				smax=Max(smax,ss[iv*nbsol+nusol]);
+			}
+			double sdelta=smax-smin;
+			double absmax=Max(Abs(smin),Abs(smax));
+
+			//display info
+			if(verbose>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, number of fields = %i\n",nusol,smin,smax,sdelta,nbsol);
+
+			//skip constant field
+			if (sdelta < 1.0e-10*Max(absmax,1e-20) ){
+				if (verbose>2) printf("      Solution %i is constant, skipping...\n",nusol);
+				continue;
+			}
+
+			//pointer toward ss that is also a pointer toward s (solutions)
+			double* sf=ss; 
+
+				//initialize the hessian matrix
+				for ( iv=0,k=0; iv<nbv; iv++) dxdx[iv]=dxdy[iv]=dydy[iv]=0;
+
+				//loop over the triangles
+				for (i=0;i<nbt;i++){
+
+					//for real all triangles 
+					if(triangles[i].link){
+
+						// coor of 3 vertices 
+						R2 A=triangles[i][0];
+						R2 B=triangles[i][1];
+						R2 C=triangles[i][2];
+
+						//warning: the normal is internal and the size is the length of the edge
+						R2 nAB = Orthogonal(B-A);
+						R2 nBC = Orthogonal(C-B);
+						R2 nCA = Orthogonal(A-C);
+						//note that :  nAB + nBC + nCA == 0 
+
+						// number of the 3 vertices
+						iA = Number(triangles[i][0]);
+						iB = Number(triangles[i][1]);
+						iC = Number(triangles[i][2]);
+
+						// for the test of  boundary edge
+						// the 3 adj triangles 
+						Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
+						Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
+						Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
+
+						// value of the P1 fonction on 3 vertices 
+						sA = ss[iA*nbsol+nusol];
+						sB = ss[iB*nbsol+nusol];
+						sC = ss[iC*nbsol+nusol];
+
+						/*The nodal functions are such that for a vertex A:
+						  N_A(x,y)=alphaA x + beta_A y +gamma_A
+						  N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
+						  solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
+						  leads to:
+						  N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
+						  and this gives:
+						  alpha_A = (yB-yC)/(2*Area(T))
+						  beta_A = (xC-xB)/(2*Area(T))
+						  and therefore:
+						  grad N_A = nA / detT
+						  for an interpolation of a solution s:
+						  grad(s) = s * sum_{i=A,B,C} grad(N_i) */
+
+						R2 Grads=(nAB*sC+nBC*sA+nCA*sB)/detT[i];
+
+						//Use Green to compute Hessian Matrix
+
+						// if edge on boundary no contribution  => normal = 0
+						if ( !tBC || !tBC->link ) nBC=O;
+						if ( !tCA || !tCA->link ) nCA=O;
+						if ( !tAB || !tAB->link ) nAB=O;
+
+						// remark we forgot a 1/2 because
+						//       int_{edge} w_i = 1/2 if i is in edge 
+						//                         0  if not
+						// if we don't take the  boundary 
+						dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
+						dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
+						dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
+
+						//warning optimization (1) the division by 2 is done on the metric construction
+						dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
+						dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
+						dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; 
+
+						dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
+						dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
+						dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
+
+					} // for real all triangles 
+				}
+
+				long kk=0;
+				for ( iv=0,k=0 ; iv<nbv; iv++){
+					if(Mmassxx[iv]>0){
+						dxdx[iv] /= 2*Mmassxx[iv];
+						// warning optimization (1) on term dxdy[iv]*ci/2 
+						dxdy[iv] /= 4*Mmassxx[iv];
+						dydy[iv] /= 2*Mmassxx[iv];
+						// Compute the matrix with abs(eigen value)
+						Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
+						MatVVP2x2 Vp(M);
+						Vp.Abs();
+						M = Vp;
+						dxdx[iv] = M.a11;
+						dxdy[iv] = M.a21;
+						dydy[iv] = M.a22;
+					}
+					else kk++;
+				}
+
+				// correction of second derivative
+				// by a laplacien
+				double* d2[3] = {dxdx, dxdy, dydy};
+				double* dd;
+				for (int xy = 0;xy<3;xy++) {
+					dd = d2[xy];
+					// do leat 2 iteration for boundary problem
+					for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++){
+						for (i=0;i<nbt;i++) 
+						 if(triangles[i].link){// the real triangles 
+							 // number of the 3 vertices
+							 iA = Number(triangles[i][0]);
+							 iB = Number(triangles[i][1]);
+							 iC = Number(triangles[i][2]);
+							 double cc=3;
+							 if(ijacobi==0)
+							  cc = Max((double) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
+							 workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
+						 }
+						for (iv=0;iv<nbv;iv++) workV[iv]=0;
+
+						for (i=0;i<nbt;i++){ 
+							if(triangles[i].link){ // the real triangles 
+								// number of the 3 vertices
+								iA = Number(triangles[i][0]);
+								iB = Number(triangles[i][1]);
+								iC = Number(triangles[i][2]);
+								double cc =  workT[i]*detT[i];
+								workV[iA] += cc;
+								workV[iB] += cc;
+								workV[iC] += cc;
+							}
+						}
+
+						for (iv=0;iv<nbv;iv++){
+							if( ijacobi<NbJacobi || OnBoundary[iv]){
+								dd[iv] = workV[iv]/(Mmass[iv]*6);
+							}
+						}
+					}
+				}
+
+				/*Compute Metric from Hessian*/
+				for ( iv=0;iv<nbv;iv++){
+					vertices[iv].MetricFromHessian(dxdx[iv],dxdy[iv],dydy[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
+				}
+
+		}// end for all solution 
+
+		delete [] detT;
+		delete [] Mmass;
+		delete [] dxdx;
+		delete [] dxdy;
+		delete [] dydy;
+		delete []  workT;
+		delete [] workV;
+		delete [] Mmassxx;
+		delete []  OnBoundary;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::CrackMesh{{{1*/
+	void Mesh::CrackMesh(BamgOpts* bamgopts) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CrackMesh)*/
+
+		/*Intermediary*/
+		int i,j,k,num,count;
+		int i1,i2;
+		int j1,j2;
+
+		/*Options*/
+		int verbose=bamgopts->verbose;
+
+		//  computed the number of cracked edge
+		for (k=i=0;i<nbe;i++){
+			if(edges[i].onGeometry->Cracked()) k++;
+		}
+
+		//Return if no edge is cracked
+		if(k==0) return;
+		if (verbose>4) printf("      number of Cracked Edges = %i\n",k);
+
+		//Initialize Cracked edge
+		NbCrackedEdges=k;
+		CrackedEdges=new CrackedEdge[k];
+
+		//Compute number of Cracked Vertices
+		k=0;
+		NbCrackedVertices=0;
+
+		int* splitvertex=new int[nbv];
+		for (i=0;i<nbv;i++) splitvertex[i]=0;
+
+		for (i=0;i<nbe;i++){
+			if(edges[i].onGeometry->Cracked()){
+
+				//Fill edges fields of CrackedEdges
+				CrackedEdges[k  ].E =edges[i].onGeometry;
+				CrackedEdges[k++].e1=&edges[i];
+
+				//Get number of the two vertices on the edge
+				i1=Number(edges[i][0]);
+				i2=Number(edges[i][1]);
+				ISSMASSERT(i1>=0 && i1<nbv && i2>=0 && i2<nbv);
+				splitvertex[i1]++;
+				splitvertex[i2]++;
+
+				//If the vertex has already been flagged once, it is a cracked vertex (tip otherwise)
+				if (splitvertex[i1]==2) NbCrackedVertices++;
+				if (splitvertex[i2]==2) NbCrackedVertices++;
+
+				//The vertex cannot be marked more than twice
+				if (splitvertex[i1]==3 || splitvertex[i2]==3){
+					ISSMERROR("Crossing rifts not supported yet");
+				}
+			}
+		}
+		ISSMASSERT(k==NbCrackedEdges);
+
+		//Add new vertices
+		if (verbose>4) printf("      number of Cracked Vertices = %i\n",NbCrackedVertices);
+		if (NbCrackedVertices){
+			CrackedVertices=(long*)xmalloc(2*NbCrackedVertices*sizeof(double));
+			num=0;
+			for (i=0;i<nbv;i++){
+				if (splitvertex[i]==2){
+					CrackedVertices[num*2+0]=i;      //index of first vertex
+					CrackedVertices[num*2+1]=nbv+num;//index of new vertex
+					num++;
+				}
+			}
+			ISSMASSERT(num==NbCrackedVertices);
+		}
+		delete [] splitvertex;
+
+		//Now, find the triangles that hold a cracked edge
+		ReMakeTriangleContainingTheVertex();
+
+		long* Edgeflags=new long[NbCrackedEdges];
+		for(i=0;i<NbCrackedEdges;i++) Edgeflags[i]=0;
+
+		for(i=0;i<NbCrackedEdges;i++){
+			//Get the numbers of the 2 vertices of the crren cracked edge
+			i1=Number((*CrackedEdges[i].e1)[0]);
+			i2=Number((*CrackedEdges[i].e1)[1]);
+
+			//find a triangle holding the vertex i1 (first vertex of the ith cracked edge)
+			Triangle* tbegin=vertices[i1].t;
+			k=vertices[i1].vint;//local number of i in triangle tbegin
+			ISSMASSERT(Number((*tbegin)[k])==Number(vertices[i1]));
+
+			//Now, we are going to go through the adjacent triangle that hold i1 till
+			//we find one that has the cracked edge
+			TriangleAdjacent ta(tbegin,EdgesVertexTriangle[k][0]);
+			count=0;
+			do {
+				for(j=0;j<3;j++){
+					//Find the position of i1 in the triangle index
+					if (Number((*ta.t)[j])==i1){
+						j1=j;
+						break;
+					}
+				}
+				for(j=0;j<3;j++){
+					//Check wether i2 is also in the triangle index
+					if (Number((*ta.t)[j])==i2){
+						j2=j;
+						//Invert j1 and j2 if necessary
+						if ((j1+1)%3==j2){
+							int j3=j1;
+							j1=j2;
+							j2=j3;
+						}
+						if (Edgeflags[i]==0){
+							//first element
+							CrackedEdges[i].a=ta.t;
+							CrackedEdges[i].length=Norme2((*ta.t)[j1].r-(*ta.t)[j2].r);
+							CrackedEdges[i].normal=Orthogonal((*ta.t)[j1].r-(*ta.t)[j2].r);
+						}
+						else{
+							//Second element -> to renumber
+							CrackedEdges[i].b=ta.t;
+							CrackedEdges[i].length=Norme2((*ta.t)[j1].r-(*ta.t)[j2].r);
+							CrackedEdges[i].normal=Orthogonal((*ta.t)[j1].r-(*ta.t)[j2].r);
+						}
+						Edgeflags[i]++;
+						break;
+					}
+				}
+				//printf("%i -> %i %i %i, edge [%i->%i %i->%i]\n",element_renu[Number(ta.t)],Number((*ta.t)[0])+1,Number((*ta.t)[1])+1,Number((*ta.t)[2])+1,i1,j1,i2,j2);
+				ta = Next(ta).Adj(); 
+				if (count++>50) ISSMERROR("Maximum number of iteration exceeded");
+			}while ((tbegin != ta)); 
+		}
+
+		//Check EdgeFlag
+		for(i=0;i<NbCrackedEdges;i++){
+			if (Edgeflags[i]!=2){
+				ISSMERROR("A problem occured: at least one crack edge (number %i) does not belong to 2 elements",i+1);
+			}
+		}
+		delete [] Edgeflags;
+
+		//Reset MeshVertex to On
+		SetVertexFieldOn();
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::ForceBoundary{{{1*/
+		void Mesh::ForceBoundary() {
+			/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ForceBoundary)*/
+
+			long int verbose=2;
+			int k=0;
+			int nbfe=0,nbswp=0,Nbswap=0;
+
+			//display
+			if (verbose > 2) printf("   ForceBoundary  nb of edge: %i\n",nbe);
+
+			//check that there is no triangle with 0 determinant
+			for (int t = 0; t < nbt; t++){
+				if (!triangles[t].det) k++;
+			}
+			if (k!=0) {
+				ISSMERROR("there is %i triangles of mes = 0",k);
+			}
+
+			//Force Edges
+			TriangleAdjacent ta(0,0);
+			for (int i = 0; i < nbe; i++){
+
+				//Force edge i
+				nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
+				if (nbswp<0) k++;
+				else Nbswap += nbswp;
+
+				if (nbswp) nbfe++;
+				if ( nbswp < 0 && k < 5){
+					ISSMERROR("Missing Edge %i, v0=%i,v1=%i",i,Number(edges[i][0]),Number(edges[i][1]));
+				}
+			}
+
+			if (k!=0) {
+				ISSMERROR("There are %i lost edges, the boundary might be crossing",k);
+			}
+			for (int j=0;j<nbv;j++){
+				Nbswap +=  vertices[j].Optim(1,0);
+			}
+			if (verbose > 3) printf("      number of inforced edge = %i, number of swap= %i\n",nbfe,Nbswap); 
+		}
+	/*}}}1*/
+	/*FUNCTION Mesh::FindSubDomain{{{1*/
+	void Mesh::FindSubDomain(int OutSide) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FindSubDomain)*/
+
+		long int verbose=0;
+
+		if (verbose >2){
+			if (OutSide) printf("   Find all external sub-domain\n"); 
+			else printf("   Find all internal sub-domain\n");
+		  }
+		short * HeapArete = new short[nbt];
+		Triangle  **  HeapTriangle = new Triangle*  [nbt];
+		Triangle *t,*t1;
+		long k,it;
+
+		for (int itt=0;itt<nbt;itt++) 
+		 triangles[itt].link=0; // par defaut pas de couleur
+
+		long  NbSubDomTot =0;
+		for ( it=0;it<nbt;it++)  { 
+			if ( ! triangles[it].link  ) {
+				t = triangles + it;
+				NbSubDomTot++;; // new composante connexe
+				long i = 0; // niveau de la pile 
+				t->link = t ; // sd forme d'un triangle cicular link
+
+				HeapTriangle[i] =t ; 
+				HeapArete[i] = 3;
+
+				while (i >= 0) // boucle sur la pile
+				  { while ( HeapArete[i]--) // boucle sur les 3 aretes 
+					  { 
+						int na =  HeapArete[i];
+						Triangle * tc =  HeapTriangle[i]; // triangle courant
+						if( ! tc->Locked(na)) // arete non frontiere
+						  {
+							Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
+							if (ta->link == 0 ) // non deja chainer => on enpile
+							  { 
+								i++;
+								ta->link = t->link ;  // on chaine les triangles
+								t->link = ta ;  // d'un meme sous domaine          
+								HeapArete[i] = 3; // pour les 3 triangles adjacents
+								HeapTriangle[i] = ta;
+							  }}
+					  } // deplie fin de boucle sur les 3 adjacences
+					i--;
+				  }          
+			}      
+		}
+
+		// supression de tous les sous domaine infini <=>  contient le sommet NULL
+		it =0;
+		NbOutT = 0;
+		while (it<nbt) {
+			if (triangles[it].link) 
+			  { 
+				if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) )) 
+				  {
+					// infini triangle 
+					NbSubDomTot --;
+					t=&triangles[it];
+					NbOutT--;  // on fait un coup de trop. 
+					while  (t){
+						NbOutT++;
+						t1=t;
+						t=t->link;
+						t1->link=0;
+					}
+				  }
+			  }   
+			it++;} // end while (it<nbt)
+			if (nbt == NbOutT ||  !NbSubDomTot) {
+				ISSMERROR("The boundary is not close: all triangles are outside");
+			}
+
+			delete [] HeapArete;
+			delete [] HeapTriangle;
+
+
+			if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains ) 
+			  { // No geom sub domain
+				long i;
+				if (subdomains) delete [] subdomains;
+				subdomains = new SubDomain[ NbSubDomTot];
+				NbSubDomains=  NbSubDomTot;
+				for ( i=0;i<NbSubDomains;i++) {
+					subdomains[i].head=NULL;
+					subdomains[i].ref=i+1;
+				}
+				long * mark = new long[nbt];
+				for (it=0;it<nbt;it++)
+				 mark[it]=triangles[it].link ? -1 : -2;
+
+				it =0;
+				k = 0;
+				while (it<nbt) {
+					if (mark[it] == -1) {
+						t1 = & triangles[it];
+						t = t1->link;
+						mark[it]=k;
+						subdomains[k].head = t1;
+						do {
+							mark[Number(t)]=k;
+							t=t->link;
+						} while (t!=t1);
+						mark[it]=k++;}
+						//    else if(mark[it] == -2 ) triangles[it].Draw(999);
+						it++;} // end white (it<nbt)
+						if (k!=NbSubDomains){
+							ISSMERROR("k!=NbSubDomains");
+						}
+						if(OutSide) 
+						  {
+							//  to remove all the sub domain by parity adjacents
+							//  because in this case we have only the true boundary edge
+							// so teh boundary is manifold
+							long nbk = NbSubDomains;
+							while (nbk)
+							 for (it=0;it<nbt && nbk ;it++)
+							  for (int na=0;na<3 && nbk ;na++)
+								 {
+								  Triangle *ta = triangles[it].TriangleAdj(na);
+								  long kl = ta ? mark[Number(ta)] : -2;
+								  long kr = mark[it];
+								  if(kr !=kl) {
+									  if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
+										nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
+									  if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
+										nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
+									  if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
+										nbk--,subdomains[kl].ref=-1;
+									  if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
+										nbk--,subdomains[kr].ref=-1;
+								  }
+								 }
+							long  j=0;
+							for ( i=0;i<NbSubDomains;i++)
+							 if((-subdomains[i].ref) %2) { // good 
+								 if(i != j) 
+								  Exchange(subdomains[i],subdomains[j]);
+								 j++;}
+							 else{ 
+								 t= subdomains[i].head;
+								 while (t){
+									 NbOutT++;
+									 t1=t;
+									 t=t->link;
+									 t1->link=0;
+								 }//while (t)
+								}
+							if(verbose>4) printf("      Number of removes subdomains (OutSideMesh) = %i\n",NbSubDomains-j);
+							NbSubDomains=j;
+						  }
+
+						delete []  mark; 
+
+			  }
+			else
+			  { // find the head for all sub domaine
+				if (Gh.NbSubDomains != NbSubDomains && subdomains)
+				 delete [] subdomains, subdomains=0;
+				if (! subdomains  ) 
+				 subdomains = new SubDomain[ Gh.NbSubDomains];
+				NbSubDomains =Gh.NbSubDomains;
+				long err=0;
+				ReMakeTriangleContainingTheVertex();
+				long * mark = new long[nbt];
+				Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
+
+				for (it=0;it<nbt;it++)
+				 mark[it]=triangles[it].link ? -1 : -2;
+				long inew =0;
+				for (int i=0;i<NbSubDomains;i++) {
+					GeometricalEdge &eg = *Gh.subdomains[i].edge;
+					subdomains[i].ref = Gh.subdomains[i].ref;
+					int ssdlab = subdomains[i].ref;
+					// by carefull is not easy to find a edge create from a GeometricalEdge 
+					// see routine MakeGeometricalEdgeToEdge
+					Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
+					if (&e==NULL){
+						ISSMERROR("&e==NULL");
+					}
+					MeshVertex * v0 =  e(0),*v1 = e(1);
+					Triangle *t  = v0->t;
+					int sens = Gh.subdomains[i].sens;
+					// test if ge and e is in the same sens 
+					if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0) sens = -sens ;
+					subdomains[i].sens = sens;
+					subdomains[i].edge = &e;
+					if (!t || !sens){
+						ISSMERROR("!t || !sens");
+					}
+
+					TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
+
+					while (1) {
+						if ( v0 != ta.EdgeVertex(1) ){
+							ISSMERROR("v0 != ta.EdgeVertex(1)");
+						}
+						if (ta.EdgeVertex(0) == v1) { // ok we find the edge
+							if (sens>0)  
+							 subdomains[i].head=t=Adj(ta);
+							else 
+							 subdomains[i].head=t=ta;
+							if(t<triangles || t >= triangles+nbt || t->det < 0 || t->link == 0) {
+								ISSMERROR("bad definition of SubSomain %i",i);
+							}
+							long it = Number(t);
+							if (mark[it] >=0) {
+								break;
+							}
+							if(i != inew) 
+							 Exchange(subdomains[i],subdomains[inew]);
+							inew++;
+							Triangle *tt=t;
+							long kkk=0;
+							do 
+							  {
+								kkk++;
+								if (mark[Number(tt)]>=0){
+									ISSMERROR("mark[Number(tt)]>=0");
+								}
+								mark[Number(tt)]=i;
+								tt=tt->link;
+							  } while (tt!=t);
+							break;
+						}
+						ta = Previous(Adj(ta));         
+						if(t == (Triangle *) ta) {
+							ISSMERROR("bad definition of SubSomain %i",i);
+						}
+					}
+				}
+
+				if (inew < NbSubDomains) {
+					if (verbose>5) printf("WARNING: %i SubDomains are being removed\n",NbSubDomains-inew);
+					NbSubDomains=inew;}
+
+
+					for (it=0;it<nbt;it++)
+					 if ( mark[it] ==-1 ) 
+					  NbOutT++,triangles[it].link =0;
+					delete [] GeometricalEdgetoEdge;
+					delete [] mark;
+
+			  }
+			NbOutT=0;
+			for (it=0;it<nbt;it++) 
+			 if(!triangles[it].link)  NbOutT++;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::FindTriangleContaining{{{1*/
+	Triangle * Mesh::FindTriangleContaining(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FindTriangleContening)*/
+
+		Triangle * t=0;	
+		int j,jp,jn,jj;
+		int counter;
+
+		/*Get starting triangle. Take tsart if provided*/
+		if (tstart){
+			t=tstart;
+		}
+		/*Else find the closest Triangle using the quadtree*/
+		else {
+
+			/*Check that the quadtree does exist*/
+			if (!quadtree) ISSMERROR("no starting triangle provided and no quadtree available");
+
+			/*Call NearestVertex*/
+			MeshVertex *a = quadtree->NearestVertex(B.x,B.y) ;
+
+			/*Check output (Vertex a)*/
+			if (!a)    ISSMERROR("problem while trying to find nearest vertex from a given point. No output found");
+			if (!a->t) ISSMERROR("no triangle is associated to vertex number %i (another call to ReMakeTriangleContainingTheVertex is required)",Number(a)+1);
+			ISSMASSERT(a>=vertices && a<vertices+nbv);
+
+			/*Get starting triangle*/
+			t = a->t;
+			ISSMASSERT(t>=triangles && t<triangles+nbt);
+		}
+
+		Icoor2  detop ;
+
+		/*initialize number of test triangle*/
+		counter=0; 
+
+		/*The initial triangle might be outside*/
+		while (t->det < 0){ 
+
+			/*Get a real vertex from this triangle (k0)*/
+			int k0=(*t)(0)?(((*t)(1)?((*t)(2)?-1:2):1)):0;
+			ISSMASSERT(k0>=0);// k0 the NULL vertex
+			int k1=NextVertex[k0],k2=PreviousVertex[k0];
+			dete[k0]=det(B,(*t)[k1],(*t)[k2]);
+			dete[k1]=dete[k2]=-1;     
+			if (dete[k0] > 0) // outside B 
+			 return t; 
+			t = t->TriangleAdj(OppositeEdge[k0]);
+			counter++;
+			ISSMASSERT(counter<2);
+		}
+
+		jj=0;
+		detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
+
+		while(t->det>0) { 
+
+			/*Increase counter*/
+			if (++counter>=10000) ISSMERROR("Maximum number of iteration reached (threshold = %i).",counter);
+
+			j= OppositeVertex[jj];
+			dete[j] = detop;  //det(*b,*s1,*s2);
+			jn = NextVertex[j];
+			jp = PreviousVertex[j];
+			dete[jp]= det(*(*t)(j),*(*t)(jn),B);
+			dete[jn] = t->det-dete[j] -dete[jp];
+
+			// count the number k of  dete <0
+			int k=0,ii[3];
+			if (dete[0] < 0 ) ii[k++]=0; 
+			if (dete[1] < 0 ) ii[k++]=1;
+			if (dete[2] < 0 ) ii[k++]=2;
+			// 0 => ok
+			// 1 => go in way 1
+			// 2 => two way go in way 1 or 2 randomly
+
+			if (k==0) break;
+			if (k == 2 && BinaryRand()) Exchange(ii[0],ii[1]);
+			if ( k>=3){
+				ISSMERROR("k>=3");
+			}
+			TriangleAdjacent t1 = t->Adj(jj=ii[0]);
+			if ((t1.det() < 0 ) && (k == 2))
+			 t1 = t->Adj(jj=ii[1]);
+			t=t1;
+			j=t1;// for optimisation we now the -det[OppositeVertex[j]];
+			detop = -dete[OppositeVertex[jj]];
+			jj = j;
+		}
+
+		if (t->det<0) // outside triangle 
+		 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
+		//  NbOfTriangleSearchFind += counter;  
+		return t;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::GeomToTriangles0{{{1*/
+	void Mesh::GeomToTriangles0(long inbvx,BamgOpts* bamgopts){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/GeomToTriangles0)*/
+
+		/*Generate mesh from geometry*/
+
+		Gh.NbRef++;// add a ref to GH
+
+		int i,j,k;
+		int NbOfCurves=0,NbNewPoints,NbEdgeCurve;
+		double lcurve,lstep,s;
+		const int MaxSubEdge = 10;
+
+		R2 AB;
+		GeometricalVertex *a,*b;
+		MeshVertex *va,*vb;
+		GeometricalEdge *e;
+
+		/*Get options*/
+		int verbose=bamgopts->verbose;
+
+		//initialize this
+		if (verbose>3) printf("      Generating Boundary vertices\n");
+		PreInit(inbvx);
+		nbv=0;
+		NbVerticesOnGeomVertex=0;
+		NbVerticesOnGeomEdge=0;
+
+		//build background mesh flag (1 if background, else 0)
+		int  background=(&BTh != this);
+
+		//Compute number of vertices on geometrical vertex
+		for (i=0;i<Gh.nbv;i++){
+			if (Gh[i].Required() && Gh[i].IsThe()) NbVerticesOnGeomVertex++;
+		}
+
+		//initialize VerticesOnGeomVertex
+		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];  
+		if( NbVerticesOnGeomVertex >= nbvx) {
+			ISSMERROR("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx);
+		}
+
+		//Add all the geometrical vertices to the mesh
+		nbv=0;
+		for (i=0;i<Gh.nbv;i++){
+			/* Add vertex only if required and not duplicate 
+			 * (IsThe is a method of GeometricalVertex that checks
+			 * that we are taking into acount only one vertex is
+			 * 2 vertices are superimposed) */
+			if (Gh[i].Required() && Gh[i].IsThe()) {//Gh  vertices Required
+
+				//Add the vertex (provided that nbv<nbvx)
+				if (nbv<nbvx){
+					vertices[nbv]=Gh[i];
+				}
+				else{
+					ISSMERROR("Maximum number of vertices (nbvx = %i) too small",nbvx);
+				}
+				
+				//Add pointer from geometry (Gh) to vertex from mesh (Th)
+				Gh[i].to=vertices+nbv;
+
+				//Build VerticesOnGeomVertex for current point
+				VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
+
+				//nbv increment
+				nbv++;
+			}
+		}
+
+		//check that edges has been allocated
+		if (edges){
+			ISSMERROR("edges is empty");
+		}
+
+		/* Now we are going to create the first edges corresponding
+		 * to the one present in the geometry provided.
+		 * We proceed in 2 steps
+		 *  -step 1: we count all the edges
+		 *           we allocate the number of edges at the end of step 1
+		 *  -step 2: the edges are created */
+		for (int step=0;step<2;step++){
+
+			//initialize number of edges and number of edges max
+			long nbex=0;
+			nbe=0;
+			long NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
+			Gh.UnMarkEdges();	
+			NbOfCurves=0;
+
+			//go through the edges of the geometry
+			for (i=0;i<Gh.nbe;i++) {
+
+				//ei = current Geometrical edge
+				GeometricalEdge &ei=Gh.edges[i];   
+
+				for(int j=0;j<2;j++) {
+
+					/*The first time, no edge is marked but this might change during the loop*/
+					if (!ei.Mark() && ei[j].Required()){ 
+
+						long  nbvend=0;
+						Edge* PreviousNewEdge=NULL;
+
+						lstep = -1;
+
+						/*If Edge is required*/
+						if(ei.Required()){
+							//do not create internal points if required (take it as is)
+							if (j==0){
+								if(step==0) nbe++;
+								else{ 
+									e=&ei;
+									a=ei(0)->The();
+									b=ei(1)->The();
+
+									//check that edges has been allocated
+									if (!edges) ISSMERROR("edges has not been allocated...");
+									edges[nbe].v[0]=a->to;
+									edges[nbe].v[1]=b->to;;
+									edges[nbe].ref = e->ref;
+									edges[nbe].onGeometry = e;
+									edges[nbe].adj[0] = 0;
+									edges[nbe].adj[1] = 0;
+									nbe++;
+								}
+							}
+						}
+
+						/*If Edge is not required: on a curve*/
+						else {
+							for (int kstep=0;kstep<=step;kstep++){
+								//step=0, do nothing
+								//step=1, compute the length of the curve
+								//step=2  create the points and edge
+								PreviousNewEdge=0;
+								NbNewPoints=0;
+								NbEdgeCurve=0;
+								if (nbvend>=nbvx) ISSMERROR("maximum number of vertices too low! Check the domain outline or increase nbvx");
+								lcurve =0;
+								s = lstep;
+
+								// i = edge number, j=[0;1] vertex number in edge
+
+								k=j;            // k = vertex number in edge (0 or 1)
+								e=&ei;          // e = reference of current edge
+								a=ei(k)->The(); // a = pointer toward the kth vertex of the current edge
+								va = a->to;     // va = pointer toward vertex associated
+								e->SetMark();   // Mark edge
+
+								//if SameGeo We have go to the background geometry 
+								//to find the discretisation of the curve
+								for(;;){ 
+									k = 1-k;
+									b = (*e)(k)->The();// b = pointer toward the other vertex of the current edge
+									AB= b->r - a->r;   // AB = vector of the current edge
+									Metric MA = background ? BTh.MetricAt(a->r) :a->m ;  //Get metric associated to A
+									Metric MB =  background ? BTh.MetricAt(b->r) :b->m ; //Get metric associated to B
+									double ledge = (MA(AB) + MB(AB))/2;                   //Get edge length in metric
+
+									/* We are now creating the edges of the mesh from the
+									 * geometrical edge selected above.
+									 * The edge will be divided according to the metric
+									 * previously computed and cannot be divided more
+									 * than 10 times (MaxSubEdge). */
+
+									//By default, there is only one subedge that is the geometrical edge itself
+									int NbSubEdge = 1;
+
+									//initialize lSubEdge, holding the length of each subedge (cannot be higher than 10)
+									double lSubEdge[MaxSubEdge];
+
+									//Build Subedges according to the edge length
+									//if ledge < 1.5 (between one and 2), take the edge as is
+									if (ledge < 1.5) lSubEdge[0] = ledge;
+									//else, divide the edge
+									else {
+										//compute number of subedges (division of the edge)
+										NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
+										//A and B are the position of points on the edge
+										R2 A,B;
+										A=a->r;
+										Metric MAs=MA,MBs;
+										ledge=0; 
+										double x =0, xstep= 1./NbSubEdge;
+										for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
+											x += xstep;
+											B =  e->F(k ? x : 1-x);
+											MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
+											AB = A-B;
+											lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
+										}
+									}
+
+									double lcurveb = lcurve+ ledge ;
+
+									//Now, create corresponding points
+									while (lcurve<=s && s <= lcurveb && nbv < nbvend){
+
+										double ss = s-lcurve;
+
+										/*Find the SubEdge containing ss using Dichotomy*/
+
+										int kk0=-1,kk1=NbSubEdge-1,kkk;
+										double ll0=0,ll1=ledge,llk;
+										while (kk1-kk0>1){
+											if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
+											 kk1=kkk,ll1=llk;
+											else
+											 kk0=kkk,ll0=llk;
+										}
+										ISSMASSERT(kk1!=kk0);
+
+										double sbb = (ss-ll0  )/(ll1-ll0);
+										double bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
+
+										// new vertex on edge
+										vb = &vertices[nbv++];
+										vb->m = Metric(aa,a->m,bb,b->m);
+										vb->ReferenceNumber = e->ref;
+										vb->DirOfSearch =NoDirOfSearch;
+										double abcisse = k ? bb : aa;
+										vb->r =  e->F( abcisse );
+										VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);        
+
+										// to take into account the direction of the edge
+										s += lstep;
+										edges[nbe].v[0]=va;
+										edges[nbe].v[1]=vb;
+										edges[nbe].ref =e->ref;
+										edges[nbe].onGeometry = e;
+										edges[nbe].adj[0] = PreviousNewEdge;
+										if(PreviousNewEdge) PreviousNewEdge->adj[1]=&edges[nbe];
+										PreviousNewEdge=edges+nbe;
+										nbe++;
+										va = vb;
+									}
+									lcurve = lcurveb;
+									e->SetMark();
+									a=b;
+									if (b->Required() ) break;
+									int kprev=k;
+									k = e->DirAdj[kprev];// next vertices
+									e = e->Adj[kprev];
+									ISSMASSERT(e);
+								}// for(;;)
+								vb = b->to;
+								NbEdgeCurve = Max((long) (lcurve +0.5), (long) 1);
+								NbNewPoints = NbEdgeCurve-1;
+								if(!kstep){
+									NbVerticesOnGeomEdge0 += NbNewPoints;
+									NbOfCurves++;
+								}
+								nbvend=nbv+NbNewPoints; 
+								lstep = lcurve / NbEdgeCurve;
+							}// end of curve --
+							if (edges) { // last edges of the curves 
+								edges[nbe].v[0]=va;
+								edges[nbe].v[1]=vb;
+								edges[nbe].ref = e->ref;
+								edges[nbe].onGeometry = e;
+								edges[nbe].adj[0] = PreviousNewEdge;
+								edges[nbe].adj[1] = 0;
+								if(PreviousNewEdge) PreviousNewEdge->adj[1] = & edges[nbe];
+								nbe++;
+							}
+							else nbe += NbEdgeCurve;
+						} // end on  curve ---
+					}
+				}
+			} // for (i=0;i<nbe;i++)
+			if(!step) {
+				if (edges){
+					ISSMERROR("edges");
+				}
+				if (VerticesOnGeomEdge){
+					ISSMERROR("VerticesOnGeomEdge");
+				}
+				edges = new Edge[nbex=nbe];
+				if(NbVerticesOnGeomEdge0)
+				 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
+				if (!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0){
+					ISSMERROR("!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0");
+				}
+				// do the vertex on a geometrical vertex
+				NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
+			}
+			else if (NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0){
+				ISSMERROR("NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0");
+			}
+		}
+
+		//Insert points inside existing triangles
+		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
+		if (verbose>3) printf("      Creating initial Constrained Delaunay Triangulation...\n");
+		if (verbose>3) printf("         Inserting boundary points\n");
+		Insert();
+
+		//Force the boundary
+		if (verbose>3) printf("         Forcing boundaries\n");
+		ForceBoundary();
+
+		//Extract SubDomains
+		if (verbose>3) printf("         Extracting subdomains\n");
+		FindSubDomain();
+
+		if (verbose>3) printf("      Inserting internal points\n");
+		NewPoints(*this,bamgopts,0) ;
+		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::GeomToTriangles1{{{1*/
+	void Mesh::GeomToTriangles1(long inbvx,BamgOpts* bamgopts,int KeepVertices){ 
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/GeomToTriangles1)*/
+
+		/*Get options*/
+		int verbose=bamgopts->verbose;
+
+		Gh.NbRef++;// add a ref to Gh
+
+		/************************************************************************* 
+		 * method in 2 steps
+		 * 1 - compute the number of new edges to allocate
+		 * 2 - construct the edges
+		 * remark:
+		 * in this part we suppose to have a background mesh with the same geometry 
+		 * 
+		 * To construct the discretization of the new mesh we have to 
+		 * rediscretize the boundary of background Mesh 
+		 * because we have only the pointeur from the background mesh to the geometry.
+		 * We need the abcisse of the background mesh vertices on geometry
+		 * so a vertex is 
+		 * 0 on GeometricalVertex ;
+		 * 1 on GeometricalEdge + abcisse
+		 * 2 internal 
+		 *************************************************************************/
+
+		//Check that background mesh and current mesh do have the same geometry
+		ISSMASSERT(&BTh.Gh==&Gh);
+		BTh.NbRef++; // add a ref to BackGround Mesh
+
+		//Initialize new mesh
+		this->PreInit(inbvx);
+		BTh.SetVertexFieldOn();
+		int* bcurve = new int[Gh.NbOfCurves]; // 
+
+		/* There are 2 ways to make the loop 
+		* 1) on the geometry 
+		* 2) on the background mesh
+		*  if you do the loop on geometry, we don't have the pointeur on background,
+		*  and if you do the loop in background we have the pointeur on geometry
+		* so do the walk on  background */
+
+		NbVerticesOnGeomVertex=0;
+		NbVerticesOnGeomEdge=0;
+
+		/*STEP 1 copy of Required vertices*/
+
+		int i; 
+		for (i=0;i<Gh.nbv;i++) if (Gh[i].Required()) NbVerticesOnGeomVertex++;
+		if(NbVerticesOnGeomVertex >= nbvx) { ISSMERROR("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx);}
+
+		VerticesOnGeomVertex = new VertexOnGeom[  NbVerticesOnGeomVertex];
+		VertexOnBThVertex    = new VertexOnVertex[NbVerticesOnGeomVertex];
+
+		//At this point there is NO vertex but vertices should have been allocated by PreInit
+		ISSMASSERT(vertices);
+		for (i=0;i<Gh.nbv;i++){
+			if (Gh[i].Required()) {//Gh vertices Required
+				vertices[nbv]  =Gh[i];
+				vertices[nbv].i=I2(0,0);
+				Gh[i].to = vertices + nbv;// save Geom -> Th
+				VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
+				nbv++;
+			}
+			else Gh[i].to=0;
+		} 
+		for (i=0;i<BTh.NbVerticesOnGeomVertex;i++){ 
+			VertexOnGeom &vog=BTh.VerticesOnGeomVertex[i];
+			if (vog.IsRequiredVertex()){
+				GeometricalVertex* gv=vog;
+				MeshVertex *bv = vog;
+				ISSMASSERT(gv->to); // use of Geom -> Th
+				VertexOnBThVertex[NbVertexOnBThVertex++]=VertexOnVertex(gv->to,bv);
+				gv->to->m = bv->m; // for taking the metrix of the background mesh
+			}
+		}
+		ISSMASSERT(NbVertexOnBThVertex==NbVerticesOnGeomVertex);
+
+		/*STEP 2: reseed boundary edges*/
+
+		//  find the begining of the curve in BTh
+		Gh.UnMarkEdges();	
+		int bfind=0;
+		for (int i=0;i<Gh.NbOfCurves;i++) bcurve[i]=-1; 
+
+		/*Loop over the backgrounf mesh BTh edges*/
+		for (int iedge=0;iedge<BTh.nbe;iedge++){      
+			Edge &ei = BTh.edges[iedge];
+
+			/*Loop over the 2 vertices of the current edge*/
+			for(int je=0;je<2;je++){
+
+				/* If one of the vertex is required we are in a new curve*/
+				if (ei[je].onGeometry->IsRequiredVertex()){ 
+
+					/*Get curve number*/
+					int nc=ei.onGeometry->CurveNumber;
+					
+					//printf("Dealing with curve number %i\n",nc);
+					//printf("edge on geometry is same as GhCurve? %s\n",(ei.onGeometry==Gh.curves[nc].be || ei.onGeometry==Gh.curves[nc].ee)?"yes":"no");
+					//if(ei.onGeometry==Gh.curves[nc].be || ei.onGeometry==Gh.curves[nc].ee){
+					//	printf("Do we have the right extremity? curve first vertex -> %s\n",((GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].be)[Gh.curves[nc].kb])?"yes":"no");
+					//	printf("Do we have the right extremity? curve last  vertex -> %s\n",((GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].ee)[Gh.curves[nc].ke])?"yes":"no");
+					//}
+					//BUG FIX from original bamg
+					/*Check that we are on the same edge and right vertex (0 or 1) */
+					if(ei.onGeometry==Gh.curves[nc].be  && (GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].be)[Gh.curves[nc].kb]){
+						bcurve[nc]=iedge*2+je;
+						bfind++;	
+					}
+					else if ((ei.onGeometry==Gh.curves[nc].ee  && (GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].ee)[Gh.curves[nc].ke]) && bcurve[nc]==-1){
+						bcurve[nc]=iedge*2+je;
+						bfind++;	
+					}
+				}
+			}
+		} 
+		if (bfind!=Gh.NbOfCurves) ISSMERROR("problem generating number of curves (Gh.NbOfCurves=%i bfind=%i)",Gh.NbOfCurves,bfind);
+
+		// method in 2 + 1 step 
+		//  0.0) compute the length and the number of vertex to do allocation
+		//  1.0) recompute the length
+		//  1.1) compute the  vertex 
+
+		long nbex=0,NbVerticesOnGeomEdgex=0;
+		for (int step=0; step <2;step++){
+
+			long NbOfNewPoints=0;
+			long NbOfNewEdge=0;
+			long iedge;
+			Gh.UnMarkEdges();	
+			double L=0;
+
+			/*Go through all geometrical curve*/
+			for (int icurve=0;icurve<Gh.NbOfCurves;icurve++){ 
+
+				/*Get edge and vertex (index) of background mesh on this curve*/
+				iedge=bcurve[icurve]/2;
+				int jedge=bcurve[icurve]%2;
+
+				/*Skip if we are on a equi curve (duplicate)*/
+				if(!Gh.curves[icurve].master) continue; 
+
+				/*Get edge of Bth with index iedge*/
+				Edge &ei = BTh.edges[iedge];
+			
+				/*Initialize variables*/
+				double Lstep=0,Lcurve=0;    // step between two points   (phase==1) 
+				long NbCreatePointOnCurve=0;// Nb of new points on curve (phase==1) 
+
+				/*Do phase 0 to step*/
+				for(int phase=0;phase<=step;phase++){
+
+					/*Loop over all curves from icurve till the last curve*/
+					for(Curve *curve= Gh.curves+icurve;curve;curve= curve->next){
+
+						/*Get index of current curve*/
+						int icurveequi= Gh.Number(curve);
+
+						/*For phase 0, check that we are at the begining of the curve only*/
+						if(phase==0 &&  icurveequi!=icurve)  continue;
+
+						int   k0=jedge,k1;
+						Edge* pe=  BTh.edges+iedge;
+						int   iedgeequi=bcurve[icurveequi]/2;
+						int   jedgeequi=bcurve[icurveequi]%2;
+
+						int k0equi=jedgeequi,k1equi;		  
+						Edge * peequi= BTh.edges+iedgeequi;
+						GeometricalEdge *ongequi = peequi->onGeometry;
+
+						double sNew=Lstep;// abscisse of the new points (phase==1) 
+						L=0;// length of the curve
+						long i=0;// index of new points on the curve
+						register GeometricalVertex * GA0 = *(*peequi)[k0equi].onGeometry;
+						MeshVertex *A0;
+						A0 = GA0->to;  // the vertex in new mesh
+						MeshVertex *A1;
+						VertexOnGeom *GA1;
+						Edge* PreviousNewEdge = 0;
+
+						// New Curve phase 
+						ISSMASSERT(A0-vertices>=0 && A0-vertices<nbv);
+						if(ongequi->Required()){
+							GeometricalVertex *GA1 = *(*peequi)[1-k0equi].onGeometry;
+							A1 = GA1->to;  //
+						}       
+						else {
+							for(;;){
+								Edge &ee=*pe; 
+								Edge &eeequi=*peequi; 
+								k1 = 1-k0; // next vertex of the edge 
+								k1equi= 1 - k0equi;
+								ISSMASSERT(pe && ee.onGeometry);
+								ee.onGeometry->SetMark();
+								MeshVertex & v0=ee[0], & v1=ee[1];
+								R2 AB=(R2)v1-(R2)v0;
+								double L0=L,LAB;
+								LAB=LengthInterpole(v0.m,v1.m,AB);
+								L+= LAB;
+
+								if (phase){
+									// computation of the new points for the given curve
+									while ((i!=NbCreatePointOnCurve) && sNew<=L) { 
+
+										//some checks
+										ISSMASSERT(sNew>=L0);
+										ISSMASSERT(LAB);
+										ISSMASSERT(vertices && nbv<nbvx);
+										ISSMASSERT(edges && nbe<nbex);
+										ISSMASSERT(VerticesOnGeomEdge && NbVerticesOnGeomEdge<NbVerticesOnGeomEdgex);
+
+										// new vertex on edge
+										A1=vertices+nbv++;
+										GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
+										Edge* e = edges + nbe++;
+										double se= (sNew-L0)/LAB;
+										if (se<0 || se>=1.000000001){
+											ISSMERROR("Problem creating point on a boundary: se=%g should be in [0 1]",se);
+										}
+										se = abscisseInterpole(v0.m,v1.m,AB,se,1);
+										if (se<0 || se>1){
+											ISSMERROR("Problem creating point on a boundary: se=%g should be in [0 1]",se);
+										}
+										se = k1         ? se : 1. - se;
+										se = k1==k1equi ? se : 1. - se;
+										VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save 
+										ongequi=Gh.ProjectOnCurve(eeequi,se,*A1,*GA1); 
+										A1->ReferenceNumber = eeequi.ref;
+										A1->DirOfSearch =NoDirOfSearch;
+										e->onGeometry = ongequi;
+										e->v[0]=A0;
+										e->v[1]=A1;
+										e->ref = eeequi.ref;
+										e->adj[0]=PreviousNewEdge;
+
+										if (PreviousNewEdge) PreviousNewEdge->adj[1]=e;
+										PreviousNewEdge=e;
+										A0=A1;
+										sNew += Lstep;
+										if (++i== NbCreatePointOnCurve) break;
+									}
+								}
+
+								//some checks
+								ISSMASSERT(ee.onGeometry->CurveNumber==ei.onGeometry->CurveNumber);
+								if (ee[k1].onGeometry->IsRequiredVertex()) {
+									ISSMASSERT(eeequi[k1equi].onGeometry->IsRequiredVertex());
+									register GeometricalVertex * GA1 = *eeequi[k1equi].onGeometry;
+									A1=GA1->to;// the vertex in new mesh
+									ISSMASSERT(A1-vertices>=0 && A1-vertices<nbv);
+									break;
+								}
+								if (!ee.adj[k1]) {
+									ISSMERROR(" adj edge %i, nbe=%i, Gh.vertices=%i",BTh.Number(ee),nbe,Gh.vertices);
+								}
+								pe = ee.adj[k1]; // next edge
+								k0 = pe->Intersection(ee); 
+								peequi= eeequi.adj[k1equi];  // next edge
+								k0equi=peequi->Intersection(eeequi);            
+							}// for(;;) end of the curve
+						}
+
+
+						if (phase){ // construction of the last edge
+							Edge* e=edges + nbe++;
+							e->onGeometry  = ongequi;
+							e->v[0]=A0;
+							e->v[1]=A1;
+							e->ref = peequi->ref;
+							e->adj[0]=PreviousNewEdge;
+							e->adj[1]=0;
+							if (PreviousNewEdge) PreviousNewEdge->adj[1]=e;
+							PreviousNewEdge = e;
+
+							ISSMASSERT(i==NbCreatePointOnCurve);
+						}
+					} //  end loop on equi curve 
+
+					if (!phase)  { // 
+						long NbSegOnCurve = Max((long)(L+0.5),(long) 1);// nb of seg
+						Lstep = L/NbSegOnCurve; 
+						Lcurve = L;
+						NbCreatePointOnCurve = NbSegOnCurve-1;
+
+						for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next){
+							NbOfNewEdge += NbSegOnCurve;
+							NbOfNewPoints += NbCreatePointOnCurve;
+						}
+					}
+				}
+			}//  end of curve loop 
+
+			//Allocate memory
+			if(step==0){
+				if(nbv+NbOfNewPoints > nbvx) {
+					ISSMERROR("too many vertices on geometry: %i >= %i",nbv+NbOfNewPoints,nbvx);
+				}
+				edges = new Edge[NbOfNewEdge];
+				nbex = NbOfNewEdge;
+				if(NbOfNewPoints) {
+					VerticesOnGeomEdge    = new VertexOnGeom[NbOfNewPoints];
+					NbVertexOnBThEdge     = NbOfNewPoints;
+					VertexOnBThEdge       = new  VertexOnEdge[NbOfNewPoints];
+					NbVerticesOnGeomEdgex = NbOfNewPoints;
+				}
+				NbOfNewPoints =0;
+				NbOfNewEdge = 0;
+			}
+		}
+		ISSMASSERT(nbe!=0);
+		delete [] bcurve;
+
+		//Insert points inside existing triangles
+		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
+		if (verbose>3) printf("      Creating initial Constrained Delaunay Triangulation...\n");
+		if (verbose>3) printf("         Inserting boundary points\n");
+		Insert();
+
+		//Force the boundary
+		if (verbose>3) printf("         Forcing boundaries\n");
+		ForceBoundary();
+
+		//Extract SubDomains
+		if (verbose>3) printf("         Extracting subdomains\n");
+		FindSubDomain();
+
+		if (verbose>3) printf("      Inserting internal points\n");
+		NewPoints(BTh,bamgopts,KeepVertices) ;
+		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::Insert{{{1*/
+	void Mesh::Insert() {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Insert)*/
+
+		/*Insert points in the existing Geometry*/
+
+		//Intermediary
+		int i;
+
+		/*Get options*/
+		long int verbose=2;
+
+		//Display info
+		if (verbose>2) printf("   Insert initial %i vertices\n",nbv);
+
+		//Compute integer coordinates and determinants for the existing vertices (from Geometry)
+		SetIntCoor();
+
+		/*Now we want to build a list (ordre) of the vertices in a random
+		 * order. To do so, we use the following method:
+		 *
+		 * From an initial k0 in [0 nbv[ random (vertex number)
+		 * the next k (vertex number) is computed using a big
+		 * prime number (PN>>nbv) following:
+		 *
+		 * k_{i+1} = k_i + PN  [nbv]
+		 *
+		 * let's show that:
+		 *
+		 *   for all j in [0 nbv[, ∃! i in [0 nbv[ such that k_i=j
+		 *
+		 * Let's assume that there are 2 distinct j1 and j2 such that
+		 * k_j1 = k_j2
+		 *
+		 * This means that
+		 *  
+		 *  k0+j1*PN = k0+j2*PN [nbv]
+		 *  (j1-j2)*PN =0       [nbv]
+		 * since PN is a prime number larger than nbv, and nbv!=1
+		 *  j1-j2=0             [nbv]
+		 * BUT
+		 *  j1 and j2 are in [0 nbv[ which is impossible.
+		 *
+		 *  We hence have built a random list of nbv elements of
+		 *  [0 nbv[ all distincts*/
+		for (i=0;i<nbv;i++) ordre[i]= &vertices[i] ;
+		const long PrimeNumber= BigPrimeNumber(nbv) ;
+		int   k0=rand()%nbv; 
+		for (int is3=0; is3<nbv; is3++){
+			ordre[is3]= &vertices[k0=(k0+PrimeNumber)%nbv];
+		}
+
+		/*Modify ordre such that the first 3 vertices form a triangle*/
+
+		//get first vertex i such that [0,1,i] are not aligned
+		for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;){
+			//if i is higher than nbv, it means that all the determinants are 0,
+			//all vertices are aligned!
+			if  ( ++i >= nbv) {
+				ISSMERROR("all the vertices are aligned");
+			}
+		}
+		// exchange i et 2 in "ordre" so that
+		// the first 3 vertices are not aligned (real triangle)
+		Exchange(ordre[2], ordre[i]);
+
+		/*Take the first edge formed by the first two vertices and build
+		 * the initial simple mesh from this edge and 2 boundary triangles*/
+
+		MeshVertex *  v0=ordre[0], *v1=ordre[1];
+
+		nbt = 2;
+		triangles[0](0) = NULL; //infinite vertex
+		triangles[0](1) = v0;
+		triangles[0](2) = v1;
+		triangles[1](0) = NULL;//infinite vertex
+		triangles[1](2) = v0;
+		triangles[1](1) = v1;
+
+		//Build adjacence
+		const int e0 = OppositeEdge[0];
+		const int e1 = NextEdge[e0];
+		const int e2 = PreviousEdge[e0];
+		triangles[0].SetAdj2(e0, &triangles[1] ,e0);
+		triangles[0].SetAdj2(e1, &triangles[1] ,e2);
+		triangles[0].SetAdj2(e2, &triangles[1] ,e1);
+
+		triangles[0].det = -1;  //boundary triangle: det = -1
+		triangles[1].det = -1;  //boundary triangle: det = -1
+
+		triangles[0].SetTriangleContainingTheVertex();
+		triangles[1].SetTriangleContainingTheVertex();
+
+		triangles[0].link=&triangles[1];
+		triangles[1].link=&triangles[0];
+
+		//build quadtree
+		if (!quadtree)  quadtree = new QuadTree(this,0);
+		quadtree->Add(*v0);
+		quadtree->Add(*v1);
+
+		/*Now, add the vertices One by One*/
+
+		long NbSwap=0;
+		if (verbose>3) printf("   Begining of insertion process...\n");
+
+		for (int icount=2; icount<nbv; icount++) {
+
+			//Get new vertex
+			MeshVertex *newvertex=ordre[icount];
+
+			//Find the triangle in which newvertex is located
+			Icoor2 dete[3];
+			Triangle* tcvi = FindTriangleContaining(newvertex->i,dete); //(newvertex->i = integer coordinates)
+
+			//Add newvertex to the quadtree
+			quadtree->Add(*newvertex); 
+
+			//Add newvertex to the existing mesh
+			AddVertex(*newvertex,tcvi,dete);
+
+			//Make the mesh Delaunay around newvertex by swaping the edges
+			NbSwap += newvertex->Optim(1,0);
+		}
+
+		//Display info
+		if (verbose>3) {
+			printf("      NbSwap of insertion: %i\n",NbSwap);
+			printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
+		}
+
+#ifdef NBLOOPOPTIM
+
+		k0 = rand()%nbv ; 
+		for (int is4=0; is4<nbv; is4++) 
+		 ordre[is4]= &vertices[k0 = (k0 + PrimeNumber)% nbv];
+
+		for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++){
+			long  NbSwap = 0;
+			for (int is1=0; is1<nbv; is1++) 
+			 NbSwap += ordre[is1]->Optim(0,0);
+			if (verbose>3) {
+				printf("      Optim Loop: %i\n",Nbloop);
+				printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
+			}
+			if(!NbSwap) break;
+		}
+		ReMakeTriangleContainingTheVertex(); 
+		// because we break the TriangleContainingTheVertex
+#endif
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::InsertNewPoints{{{1*/
+	long Mesh::InsertNewPoints(long nbvold,long & NbTSwap) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/InsertNewPoints)*/
+
+		long int verbose=0;
+		double seuil= 1.414/2 ;// for two close point 
+		long i;
+		long NbSwap=0;
+		Icoor2 dete[3];
+
+		//number of new points
+		const long nbvnew=nbv-nbvold;
+
+		//display info if required
+		if (verbose>5) printf("      Try to Insert %i new points\n",nbvnew);
+
+		//return if no new points
+		if (!nbvnew) return 0; 
+
+		/*construction of a random order*/
+		const long PrimeNumber= BigPrimeNumber(nbv)  ;
+		//remainder of the division of rand() by nbvnew
+		long k3 = rand()%nbvnew;
+		//loop over the new points
+		for (int is3=0; is3<nbvnew; is3++){
+			register long j=nbvold +(k3 = (k3+PrimeNumber)%nbvnew);
+			register long i=nbvold+is3; 
+			ordre[i]= vertices + j;
+			ordre[i]->ReferenceNumber=i;
+		}
+
+		// for all the new point
+		long iv=nbvold;
+		for (i=nbvold;i<nbv;i++){
+			MeshVertex &vi=*ordre[i];
+			vi.i=toI2(vi.r);
+			vi.r=toR2(vi.i);
+			double hx,hy;
+			vi.m.Box(hx,hy);
+			Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
+			if (!quadtree->ToClose(vi,seuil,hi,hj)){
+				// a good new point 
+				MeshVertex &vj = vertices[iv];
+				long  j=vj.ReferenceNumber; 
+				if (&vj!=ordre[j]){
+					ISSMERROR("&vj!= ordre[j]");
+				}
+				if(i!=j){ 
+					Exchange(vi,vj);
+					Exchange(ordre[j],ordre[i]);
+				}
+				vj.ReferenceNumber=0; 
+				Triangle *tcvj=FindTriangleContaining(vj.i,dete);
+				if (tcvj && !tcvj->link){
+					tcvj->Echo();
+					ISSMERROR("problem inserting point in InsertNewPoints (tcvj=%p and tcvj->link=%i)",tcvj,tcvj->link);
+				}
+				quadtree->Add(vj);
+				AddVertex(vj,tcvj,dete);
+				NbSwap += vj.Optim(1);          
+				iv++;
+			}
+		} 
+		if (verbose>3) {
+			printf("         number of new points: %i\n",iv);
+			printf("         number of to close (?) points: %i\n",nbv-iv);
+			printf("         number of swap after: %i\n",NbSwap);
+		}
+		nbv = iv;
+
+		for (i=nbvold;i<nbv;i++) NbSwap += vertices[i].Optim(1);  
+		if (verbose>3) printf("   NbSwap=%i\n",NbSwap);
+
+		NbTSwap +=  NbSwap ;
+		return nbv-nbvold;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::MakeGeometricalEdgeToEdge{{{1*/
+	Edge** Mesh::MakeGeometricalEdgeToEdge() {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeGeometricalEdgeToEdge)*/
+
+		if (!Gh.nbe){
+			ISSMERROR("!Gh.nbe");
+		}
+		Edge **e= new (Edge* [Gh.nbe]);
+
+		long i;
+		for ( i=0;i<Gh.nbe ; i++)
+		 e[i]=NULL;
+		for ( i=0;i<nbe ; i++) 
+		  { 
+			Edge * ei = edges+i;
+			GeometricalEdge *onGeometry = ei->onGeometry; 
+			e[Gh.Number(onGeometry)] = ei;    
+		  }
+		for ( i=0;i<nbe ; i++) 
+		 for (int ii=0;ii<2;ii++) { 
+			 Edge * ei = edges+i;
+			 GeometricalEdge *onGeometry = ei->onGeometry;
+			 int j= ii;
+			 while (!(*onGeometry)[j].Required()) { 
+				 Adj(onGeometry,j); // next geom edge
+				 j=1-j;
+				 if (e[Gh.Number(onGeometry)])  break; // optimisation
+				 e[Gh.Number(onGeometry)] = ei; 
+			 }
+		 }
+
+		int kk=0;
+		for ( i=0;i<Gh.nbe ; i++){
+			if (!e[i]){
+				kk++;
+				if(kk<10) printf("BUG: the geometrical edge %i is on no edge curve\n",i);
+			}
+		}
+		if(kk) ISSMERROR("See above");
+
+		return e;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::MakeQuadrangles{{{1*/
+	void Mesh::MakeQuadrangles(double costheta){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeQuadrangles)*/
+
+		long int verbose=0;
+
+		if (verbose>2) printf("MakeQuadrangles costheta = %g\n",costheta);
+
+		if (costheta >1) {
+			if (verbose>5) printf("   do nothing: costheta > 1\n");
+		}
+
+
+			long nbqq = (nbt*3)/2;
+			DoubleAndInt *qq = new DoubleAndInt[nbqq];
+
+			long i,ij;
+			int j;
+			long k=0;
+			for (i=0;i<nbt;i++)
+			 for (j=0;j<3;j++)
+			  if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
+				qq[k++].i3j=i*3+j;
+			//  sort  qq
+			HeapSort(qq,k);
+
+			long kk=0;
+			for (ij=0;ij<k;ij++) { 
+				i=qq[ij].i3j/3;
+				j=(int) (qq[ij].i3j%3);
+				// optisamition no float computation  
+				if (triangles[i].QualityQuad(j,0) >=costheta) 
+				 triangles[i].SetHidden(j),kk++;
+			  }
+			NbOfQuad = kk;
+			if (verbose>2){
+				printf("   number of quadrilaterals    = %i\n",NbOfQuad);
+				printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
+				printf("   number of outside triangles = %i\n",NbOutT);
+			}
+			delete [] qq;
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::MakeQuadTree{{{1*/
+	void Mesh::MakeQuadTree() {  
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeQuadTree)*/
+
+		long int verbose=0;
+		if (  !quadtree )  quadtree = new QuadTree(this);
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::MaxSubDivision{{{1*/
+	void  Mesh::MaxSubDivision(double maxsubdiv) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/MaxSubDivision)*/
+
+		long int verbose=0;
+
+		const  double maxsubdiv2 = maxsubdiv*maxsubdiv;
+		if(verbose>1) printf("   Limit the subdivision of a edges in the new mesh by %g\n",maxsubdiv);
+		// for all the edges 
+		// if the len of the edge is to long 
+		long it,nbchange=0;    
+		double lmax=0;
+		for (it=0;it<nbt;it++){
+			Triangle &t=triangles[it];
+			for (int j=0;j<3;j++){
+				Triangle &tt = *t.TriangleAdj(j);
+				if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link)){
+					MeshVertex &v0 = t[VerticesOfTriangularEdge[j][0]];
+					MeshVertex &v1 = t[VerticesOfTriangularEdge[j][1]];
+					R2 AB= (R2) v1-(R2) v0;
+					Metric M = v0;
+					double l = M(AB,AB);
+					lmax = Max(lmax,l);
+					if(l> maxsubdiv2){
+					  R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
+						double lc = M(AC,AC);
+						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
+						D2xD2 Rt1(Rt.inv());
+						D2xD2 D(maxsubdiv2,0,0,lc);
+						D2xD2 MM = Rt1*D*Rt1.t();
+						v0.m =  M = Metric(MM.x.x,MM.y.x,MM.y.y);
+						nbchange++;
+					}
+					M = v1;
+					l = M(AB,AB);
+					lmax = Max(lmax,l);
+					if(l> maxsubdiv2){
+					  R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
+						double lc = M(AC,AC);
+						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
+						D2xD2 Rt1(Rt.inv());
+						D2xD2 D(maxsubdiv2,0,0,lc);
+						D2xD2  MM = Rt1*D*Rt1.t();
+						v1.m =  M = Metric(MM.x.x,MM.y.x,MM.y.y);
+						nbchange++;
+					}
+				}
+			}
+		}
+		if(verbose>3){
+			printf("      number of metric changes = %i, maximum number of subdivision of a edges before change = %g\n",nbchange,pow(lmax,0.5));
+		}
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::MetricAt{{{1*/
+	Metric Mesh::MetricAt(const R2 & A) const { 
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MetricAt)*/
+
+		I2 a = toI2(A);
+		Icoor2 deta[3];
+		Triangle * t =FindTriangleContaining(a,deta);
+		if (t->det <0) { // outside
+			double ba,bb;
+			TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
+			return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
+		else { // inside
+			double   aa[3];
+			double s = deta[0]+deta[1]+deta[2];
+			aa[0]=deta[0]/s;
+			aa[1]=deta[1]/s;
+			aa[2]=deta[2]/s;
+			return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
+		}
+	}
+	/*}}}1*/
+/*FUNCTION Mesh::NearestVertex{{{1*/
+MeshVertex* Mesh::NearestVertex(Icoor1 i,Icoor1 j) {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NearestVertex)*/
+	return  quadtree->NearestVertex(i,j); 
+} 
+/*}}}1*/
+	/*FUNCTION Mesh::NewPoints{{{1*/
+	void  Mesh::NewPoints(Mesh & Bh,BamgOpts* bamgopts,int KeepVertices){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NewPoints)*/
+
+		int i,j,k;
+		long NbTSwap=0;
+		long nbtold=nbt;
+		long nbvold=nbv;
+		long Headt=0;
+		long next_t;
+		long* first_np_or_next_t=new long[nbtx];
+		Triangle* t=NULL;
+
+		/*Recover options*/
+		int verbose=bamgopts->verbose;
+
+		/*First, insert old points if requested*/
+		if (KeepVertices && (&Bh != this) && (nbv+Bh.nbv< nbvx)){
+			if (verbose>5) printf("         Inserting initial mesh points\n");
+			for (i=0;i<Bh.nbv;i++){ 
+				MeshVertex &bv=Bh[i];
+				if (!bv.onGeometry){
+					vertices[nbv].r   = bv.r;
+					vertices[nbv++].m = bv.m;
+				}
+			}
+			Bh.ReMakeTriangleContainingTheVertex();     
+			InsertNewPoints(nbvold,NbTSwap)   ;            
+		}  
+		else Bh.ReMakeTriangleContainingTheVertex();     
+
+		// generation of the list of next Triangle 
+		for(i=0;i<nbt;i++) first_np_or_next_t[i]=-(i+1);
+		// the next traingle of i is -first_np_or_next_t[i]
+
+		// Big loop (most time consuming)
+		int iter=0;
+		if (verbose>5) printf("         Big loop\n");
+		do {
+			/*Update variables*/
+			iter++;
+			nbtold=nbt;
+			nbvold=nbv;
+
+			/*We test all triangles*/
+			i=Headt;
+			next_t=-first_np_or_next_t[i];
+			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]){
+
+				//check i
+				if (i<0 || i>=nbt ){
+					ISSMERROR("Index problem in NewPoints (i=%i not in [0 %i])",i,nbt-1);
+				}
+				//change first_np_or_next_t[i]
+				first_np_or_next_t[i] = iter; 
+
+				//Loop over the edges of t
+				for(j=0;j<3;j++){
+					TriangleAdjacent tj(t,j);
+					MeshVertex &vA = *tj.EdgeVertex(0);
+					MeshVertex &vB = *tj.EdgeVertex(1);
+
+					//if t is a boundary triangle, or tj locked, continue
+					if (!t->link)     continue;
+					if (t->det <0)    continue;
+					if (t->Locked(j)) continue;
+
+					TriangleAdjacent tadjj = t->Adj(j);	  
+					Triangle* ta=tadjj;
+
+					//if the adjacent triangle is a boundary triangle, continur
+					if (ta->det<0) continue;	  
+
+					R2 A=vA;
+					R2 B=vB;
+					k=Number(ta);
+
+					//if this edge has already been done, go to next edge of triangle
+					if(first_np_or_next_t[k]==iter) continue;
+
+					lIntTria.SplitEdge(Bh,A,B);
+					lIntTria.NewPoints(vertices,nbv,nbvx);
+				  } // end loop for each edge 
+			  }// for triangle   
+
+			if (!InsertNewPoints(nbvold,NbTSwap)) break;
+			for (i=nbtold;i<nbt;i++) first_np_or_next_t[i]=iter;
+			Headt = nbt; // empty list 
+
+			// for all the triangle containing the vertex i
+			for (i=nbvold;i<nbv;i++){ 
+				MeshVertex*          s  = vertices + i;
+				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
+				Triangle*        tbegin= (Triangle*) ta;
+				long kt;
+				do { 
+					kt = Number((Triangle*) ta);
+					if (first_np_or_next_t[kt]>0){
+						first_np_or_next_t[kt]=-Headt;
+						Headt=kt;
+					}
+					if (ta.EdgeVertex(0)!=s){
+						ISSMERROR("ta.EdgeVertex(0)!=s");
+					}
+					ta = Next(Adj(ta));
+				} while ( (tbegin != (Triangle*) ta)); 
+			}
+
+		} while (nbv!=nbvold);
+
+		delete []  first_np_or_next_t;
+
+		long NbSwapf =0,NbSwp;
+
+		NbSwp = NbSwapf;
+		for (i=0;i<nbv;i++)
+		 NbSwapf += vertices[i].Optim(0);
+		NbTSwap +=  NbSwapf ;
+	}
+	/*}}}1*/
+/*FUNCTION Mesh::PreInit{{{1*/
+void Mesh::PreInit(long inbvx) {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/PreInit)*/
+
+	long int verbose=0;
+
+	srand(19999999);
+	NbRef=0;
+	//  allocGeometry=0;
+	NbOfTriangleSearchFind =0;
+	NbOfSwapTriangle =0;
+	nbiv=0;
+	nbv=0;
+	nbvx=inbvx;
+	nbt=0;
+	NbOfQuad = 0;
+	nbtx=2*inbvx-2;
+	NbSubDomains=0;
+	NbVertexOnBThVertex=0;
+	NbVertexOnBThEdge=0;
+	VertexOnBThVertex=NULL;
+	VertexOnBThEdge=NULL;
+
+	NbCrackedVertices=0;
+	CrackedVertices  =NULL;  
+	NbCrackedEdges   =0;
+	CrackedEdges     =NULL;  
+	nbe = 0; 
+
+	if (inbvx) {
+		vertices=new MeshVertex[nbvx];
+		if (!vertices){
+			ISSMERROR("!vertices");
+		}
+		ordre=new (MeshVertex* [nbvx]);
+		if (!ordre){
+			ISSMERROR("!ordre");
+		}
+		triangles=new Triangle[nbtx];
+		if (!triangles){
+			ISSMERROR("!triangles");
+		}
+	}
+	else {
+		vertices=NULL;
+		ordre=NULL;
+		triangles=NULL;
+		nbtx=0;
+	} 
+
+	quadtree=NULL;
+	edges=NULL;
+	VerticesOnGeomVertex=NULL;
+	VerticesOnGeomEdge=NULL;
+	NbVerticesOnGeomVertex=0;
+	NbVerticesOnGeomEdge=0;
+	subdomains=NULL;
+	NbSubDomains=0;
+}
+/*}}}1*/
+	/*FUNCTION Mesh::ProjectOnCurve{{{1*/
+	GeometricalEdge*   Mesh::ProjectOnCurve( Edge & BhAB, MeshVertex &  vA, MeshVertex & vB,
+				double theta,MeshVertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshQuad.cpp/ProjectOnCurve)*/
+
+		void *pA=0,*pB=0;
+		double tA=0,tB=0;
+		R2 A=vA,B=vB;
+		MeshVertex * pvA=&vA, * pvB=&vB;
+		if (vA.vint == IsVertexOnVertex){
+			pA=vA.onBackgroundVertex;
+		}
+		else if (vA.vint == IsVertexOnEdge){
+			pA=vA.onBackgroundEdge->be;
+			tA=vA.onBackgroundEdge->abcisse;
+		}
+		else {
+			ISSMERROR("ProjectOnCurve On MeshVertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vA));
+		} 
+
+		if (vB.vint == IsVertexOnVertex){
+			pB=vB.onBackgroundVertex;
+		}
+		else if(vB.vint == IsVertexOnEdge){
+			pB=vB.onBackgroundEdge->be;
+			tB=vB.onBackgroundEdge->abcisse;
+		}
+		else {
+			ISSMERROR("ProjectOnCurve On MeshVertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vB));
+		} 
+		Edge * e = &BhAB;
+		if (!pA || !pB || !e){
+			ISSMERROR("!pA || !pB || !e");
+		}
+		// be carefull the back ground edge e is on same geom edge 
+		// of the initiale edge def by the 2 vertex A B;
+		//check Is a background Mesh;   
+		if (e<BTh.edges || e>=BTh.edges+BTh.nbe){
+			ISSMERROR("e<BTh.edges || e>=BTh.edges+BTh.nbe");
+		}
+		// walk on BTh edge 
+		//not finish ProjectOnCurve with BackGround Mesh);
+		// 1 first find a back ground edge contening the vertex A
+		// 2 walk n back gound boundary to find the final vertex B
+
+		if( vA.vint == IsVertexOnEdge) 
+		  { // find the start edge 
+			e = vA.onBackgroundEdge->be;	 
+
+		  } 
+		else if (vB.vint == IsVertexOnEdge) 
+		  {
+			theta = 1-theta;
+			Exchange(tA,tB);
+			Exchange(pA,pB);
+			Exchange(pvA,pvB);
+			Exchange(A,B);
+			e =  vB.onBackgroundEdge->be;
+
+		  } 
+		else{ // do the search by walking 
+			ISSMERROR("case not supported yet");
+		  }
+
+		// find the direction of walking with sens of edge and pA,PB;
+		R2 AB=B-A;
+
+		double cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
+		int kkk=0;
+		int sens = (cosE01AB>0) ? 1 : 0;
+
+		//   double l=0; // length of the edge AB
+		double abscisse = -1;
+
+		for (int cas=0;cas<2;cas++){
+			// 2 times algo:
+			//    1 for computing the length l
+			//    2 for find the vertex 
+			int  iii;
+			MeshVertex  *v0=pvA,*v1; 
+			Edge *neee,*eee;
+			double lg =0; // length of the curve 
+			double te0;
+			// we suppose take the curve's abcisse 
+			for ( eee=e,iii=sens,te0=tA;
+						eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
+						neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii ) { 
+
+				kkk=kkk+1;
+				if (kkk>=100){
+					ISSMERROR("kkk>=100");
+				}
+				if (!eee){
+					ISSMERROR("!eee");
+				}
+				double lg0 = lg;
+				double dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
+				lg += dp;
+				if (cas && abscisse <= lg) { // ok we find the geom edge 
+					double sss  =   (abscisse-lg0)/dp;
+					double thetab = te0*(1-sss)+ sss*iii;
+					if (thetab<0 || thetab>1){
+						ISSMERROR("thetab<0 || thetab>1");
+					}
+					BR = VertexOnEdge(&R,eee,thetab);
+					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
+				  }
+			  }
+			// we find the end 
+			if (v1 != pvB){
+				if (( void*) v1 == pB)
+				 tB = iii;
+
+				double lg0 = lg;
+				if (!eee){
+					ISSMERROR("!eee");
+				}
+				v1 = pvB;
+				double dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
+				lg += dp;	
+				abscisse = lg*theta;
+				if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
+				  { // ok we find the geom edge 
+					double sss  =   (abscisse-lg0)/dp;
+					double thetab = te0*(1-sss)+ sss*tB;
+					if (thetab<0 || thetab>1){
+						ISSMERROR("thetab<0 || thetab>1");
+					}
+					BR = VertexOnEdge(&R,eee,thetab);
+					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
+				  }
+			  }
+			abscisse = lg*theta;
+
+		  }
+		ISSMERROR("Big bug...");
+		return 0; // just for the compiler 
+	}                  
+	/*}}}1*/
+/*FUNCTION Mesh::ReconstructExistingMesh{{{1*/
+void Mesh::ReconstructExistingMesh(){
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FillHoleInMesh)*/
+
+	/*This routine reconstruct an existing mesh to make it CONVEX:
+	 * -all the holes are filled
+	 * -concave boundaries are filled
+	 * A convex mesh is required for a lot of operations. This is why every mesh
+	 * goes through this process.
+	 * This routine also generates mesh properties such as adjencies,...
+	 */
+
+	/*Intermediary*/
+	int verbose=0;
+
+	// generation of the integer coordinate
+
+	// find extrema coordinates of vertices pmin,pmax
+	long i;
+	if(verbose>2) printf("      Reconstruct mesh of %i vertices\n",nbv); 
+
+	//initialize ordre
+	ISSMASSERT(ordre);
+	for (i=0;i<nbv;i++) ordre[i]=0;
+
+	//Initialize NbSubDomains
+	NbSubDomains =0;
+
+	/* generation of triangles adjacency*/
+
+	//First add existing edges
+	long kk =0;
+	SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
+	for (i=0;i<nbe;i++){
+		kk=kk+(i==edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1])));
+	}
+	if (kk != nbe){ 
+		ISSMERROR("There are %i double edges in the mesh",kk-nbe);
+	}
+
+	//Add edges of all triangles in existing mesh
+	long* st = new long[nbt*3];
+	for (i=0;i<nbt*3;i++) st[i]=-1;
+	for (i=0;i<nbt;i++){
+		for (int j=0;j<3;j++){
+
+			//Add current triangle edge to edge4
+			long k =edge4->SortAndAdd(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
+
+			long invisible=triangles[i].Hidden(j);
+
+			//If the edge has not been added to st, add it
+			if(st[k]==-1) st[k]=3*i+j;
+
+			//If the edge already exists, add adjacency
+			else if(st[k]>=0) {
+				ISSMASSERT(!triangles[i].TriangleAdj(j));
+				ISSMASSERT(!triangles[st[k]/3].TriangleAdj((int) (st[k]%3)));
+
+				triangles[i].SetAdj2(j,triangles+st[k]/3,(int)(st[k]%3));
+				if (invisible) triangles[i].SetHidden(j);
+				if (k<nbe)     triangles[i].SetLocked(j);
+
+				//Make st[k] negative so that it will throw an error message if it is found again
+				st[k]=-2-st[k]; 
+			}
+
+			//An edge belongs to 2 triangles
+			else {
+				ISSMERROR("The edge (%i , %i) belongs to more than 2 triangles",Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
+			}
+		}
+	}
+
+	//Display info if required
+	if(verbose>5) {
+		printf("         info of Mesh:\n");
+		printf("            - number of vertices    = %i \n",nbv); 
+		printf("            - number of triangles   = %i \n",nbt); 
+		printf("            - number of given edges = %i \n",nbe); 
+		printf("            - number of all edges   = %i \n"  ,edge4->nb()); 
+		printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv); 
+	}
+
+	//check the consistency of edge[].adj and the geometrical required vertex
+	long k=0;
+	for (i=0;i<edge4->nb();i++){
+		if (st[i]>=0){ // edge alone 
+			if (i<nbe){
+				long i0=edge4->i(i);
+				ordre[i0] = vertices+i0;
+				long i1=edge4->j(i);
+				ordre[i1] = vertices+i1;
+			}
+			else {
+				k=k+1;
+				if (k<10) {
+					//print only 10 edges
+					printf("Lost boundary edges %i : %i %i\n",i,edge4->i(i),edge4->j(i));
+				}
+				else if (k==10){
+					printf("Other lost boundary edges not shown...\n");
+				}
+			}
+		}
+	}
+	if(k) {
+		ISSMERROR("%i boundary edges (from the geometry) are not defined as mesh edges",k);
+	}
+
+	/* mesh generation with boundary points*/
+	long nbvb=0;
+	for (i=0;i<nbv;i++){ 
+		vertices[i].t=0;
+		vertices[i].vint=0;
+		if (ordre[i]) ordre[nbvb++]=ordre[i];
+	}
+
+	Triangle* savetriangles=triangles;
+	long savenbt=nbt;
+	long savenbtx=nbtx;
+	SubDomain* savesubdomains=subdomains;
+	subdomains=0;
+
+	long  Nbtriafillhole=2*nbvb;
+	Triangle* triafillhole=new Triangle[Nbtriafillhole];
+	triangles = triafillhole;
+
+	nbt=2;
+	nbtx= Nbtriafillhole;
+
+	//Find a vertex that is not aligned with vertices 0 and 1
+	for (i=2;det(ordre[0]->i,ordre[1]->i,ordre[i]->i)==0;) 
+	 if  (++i>=nbvb) {
+		 ISSMERROR("ReconstructExistingMesh: All the vertices are aligned");
+	 }
+	//Move this vertex (i) to the 2d position in ordre
+	Exchange(ordre[2], ordre[i]);
+
+	/*Reconstruct mesh beginning with 2 triangles*/
+	MeshVertex *  v0=ordre[0], *v1=ordre[1];
+
+	triangles[0](0) = NULL; // Infinite vertex
+	triangles[0](1) = v0;
+	triangles[0](2) = v1;
+
+	triangles[1](0) = NULL;// Infinite vertex
+	triangles[1](2) = v0;
+	triangles[1](1) = v1;
+	const int e0 = OppositeEdge[0];
+	const int e1 = NextEdge[e0];
+	const int e2 = PreviousEdge[e0];
+	triangles[0].SetAdj2(e0, &triangles[1] ,e0);
+	triangles[0].SetAdj2(e1, &triangles[1] ,e2);
+	triangles[0].SetAdj2(e2, &triangles[1] ,e1);
+
+	triangles[0].det = -1;  // boundary triangles
+	triangles[1].det = -1;  // boundary triangles
+
+	triangles[0].SetTriangleContainingTheVertex();
+	triangles[1].SetTriangleContainingTheVertex();
+
+	triangles[0].link=&triangles[1];
+	triangles[1].link=&triangles[0];
+
+	if (!quadtree) delete quadtree; //ReInitialise;
+	quadtree = new QuadTree(this,0);
+	quadtree->Add(*v0);
+	quadtree->Add(*v1);
+
+	// vertices are added one by one
+	long NbSwap=0;
+	for (int icount=2; icount<nbvb; icount++) {
+		MeshVertex *vi  = ordre[icount];
+		Icoor2 dete[3];
+		Triangle *tcvi = FindTriangleContaining(vi->i,dete);
+		quadtree->Add(*vi); 
+		AddVertex(*vi,tcvi,dete);
+		NbSwap += vi->Optim(1,1);
+	}
+
+	//enforce the boundary 
+	TriangleAdjacent ta(0,0);
+	long nbloss = 0,knbe=0;
+	for ( i = 0; i < nbe; i++){
+		if (st[i] >=0){ //edge alone => on border
+			MeshVertex &a=edges[i][0], &b=edges[i][1];
+			if (a.t && b.t){
+				knbe++;
+				if (ForceEdge(a,b,ta)<0) nbloss++;
+			}
+		}
+	}
+	if(nbloss) {
+		ISSMERROR("we lost %i existing edges other %i",nbloss,knbe);
+	}
+
+	FindSubDomain(1);
+	// remove all the hole 
+	// remove all the good sub domain
+	long krm =0;
+	for (i=0;i<nbt;i++){
+		if (triangles[i].link){ // remove triangles
+			krm++;
+			for (int j=0;j<3;j++){
+				TriangleAdjacent ta =  triangles[i].Adj(j);
+				Triangle &tta = *(Triangle*)ta;
+				//if edge between remove and not remove 
+				if(! tta.link){ 
+					// change the link of ta;
+					int ja = ta;
+					MeshVertex *v0= ta.EdgeVertex(0);
+					MeshVertex *v1= ta.EdgeVertex(1);
+					long k =edge4->SortAndAdd(v0?Number(v0):nbv,v1? Number(v1):nbv);
+
+					ISSMASSERT(st[k]>=0);
+					tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
+					ta.SetLock();
+					st[k]=-2-st[k]; 
+				}
+			}
+		}
+	}
+	long NbTfillHoll =0;
+	for (i=0;i<nbt;i++){
+		if (triangles[i].link) {
+			triangles[i]=Triangle((MeshVertex *) NULL,(MeshVertex *) NULL,(MeshVertex *) NULL);
+			triangles[i].color=-1;
+		}
+		else{
+			triangles[i].color= savenbt+ NbTfillHoll++;
+		}
+	}
+	ISSMASSERT(savenbt+NbTfillHoll<=savenbtx);
+
+	// copy of the outside triangles in saveMesh 
+	for (i=0;i<nbt;i++){
+		if(triangles[i].color>=0) {
+			savetriangles[savenbt]=triangles[i];
+			savetriangles[savenbt].link=0;
+			savenbt++;
+		}
+	}
+	// gestion of the adj
+	k =0;
+	Triangle * tmax = triangles + nbt;
+	for (i=0;i<savenbt;i++) { 
+		Triangle & ti = savetriangles[i];
+		for (int j=0;j<3;j++){
+			Triangle * ta = ti.TriangleAdj(j);
+			int aa = ti.NuEdgeTriangleAdj(j);
+			int lck = ti.Locked(j);
+			if (!ta) k++; // bug 
+			else if ( ta >= triangles && ta < tmax){
+				ta= savetriangles + ta->color;
+				ti.SetAdj2(j,ta,aa);
+				if(lck) ti.SetLocked(j);
+			}
+		}
+	}
+
+	// restore triangles;
+	nbt=savenbt;
+	nbtx=savenbtx;
+	delete [] triangles;
+	delete [] subdomains;
+	triangles = savetriangles;
+	subdomains = savesubdomains;
+	if (k) {
+		ISSMERROR("number of triangles edges alone = %i",k);
+	}
+	FindSubDomain();
+
+	delete edge4;
+	delete [] st;
+	for (i=0;i<nbv;i++) quadtree->Add(vertices[i]);
+
+	SetVertexFieldOn();
+
+	/*Check requirements consistency*/
+	for (i=0;i<nbe;i++){
+ 	/*If the current mesh edge is on Geometry*/
+		if(edges[i].onGeometry){
+			for(int j=0;j<2;j++){
+				/*Go through the edges adjacent to current edge (if on the same curve)*/
+				if (!edges[i].adj[j]){
+					/*The edge is on Geometry and does not have 2 adjacent edges... (not on a closed curve)*/
+					/*Check that the 2 vertices are on geometry AND required*/
+					if(!edges[i][j].onGeometry->IsRequiredVertex()){
+						printf("ReconstructExistingMesh error message: problem with the edge number %i: [%i %i]\n",i+1,Number(edges[i][0])+1,Number(edges[i][1])+1);
+						printf("This edge is on geometrical edge number %i\n",Gh.Number(edges[i].onGeometry)+1);
+						if (edges[i][j].onGeometry->OnGeomVertex())
+						 printf("the vertex number %i of this edge is a geometric MeshVertex number %i\n",Number(edges[i][j])+1,Gh.Number(edges[i][j].onGeometry->gv)+1);
+						else if (edges[i][j].onGeometry->OnGeomEdge())
+						 printf("the vertex number %i of this edge is a geometric Edge number %i\n",Number(edges[i][j])+1,Gh.Number(edges[i][j].onGeometry->ge)+1);
+						else
+						 printf("Its pointer is %p\n",edges[i][j].onGeometry);
+
+						printf("This edge is on geometry and has no adjacent edge (open curve) and one of the tip is not required\n");
+						ISSMERROR("See above (might be cryptic...)");
+					}
+				}
+			}
+		}
+	}
+}
+/*}}}1*/
+	/*FUNCTION Mesh::ReNumberingTheTriangleBySubDomain{{{1*/
+	void Mesh::ReNumberingTheTriangleBySubDomain(bool justcompress){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ReNumberingTheTriangleBySubDomain)*/
+
+		long int verbose=0;
+		long *renu= new long[nbt];
+		register Triangle *t0,*t,*te=triangles+nbt;
+		register long k=0,it,i,j;
+
+		for ( it=0;it<nbt;it++) 
+		 renu[it]=-1; // outside triangle 
+		for ( i=0;i<NbSubDomains;i++)
+		  { 
+			t=t0=subdomains[i].head;
+			if (!t0){ // not empty sub domain
+				ISSMERROR("!t0");
+			}
+			do { 
+				long kt = Number(t);
+				if (kt<0 || kt >= nbt ){
+					ISSMERROR("kt<0 || kt >= nbt");
+				}
+				if (renu[kt]!=-1){
+					ISSMERROR("renu[kt]!=-1");
+				}
+				renu[kt]=k++;
+			}
+			while (t0 != (t=t->link));
+		  }
+		// take is same numbering if possible    
+		if(justcompress)
+		 for ( k=0,it=0;it<nbt;it++) 
+		  if(renu[it] >=0 ) 
+			renu[it]=k++;
+
+		// put the outside triangles at the end
+		for ( it=0;it<nbt;it++){
+			if (renu[it]==-1) renu[it]=k++;
+		}
+		if (k != nbt){
+			ISSMERROR("k != nbt");
+		}
+		// do the change on all the pointeur 
+		for ( it=0;it<nbt;it++)
+		 triangles[it].ReNumbering(triangles,te,renu);
+
+		for ( i=0;i<NbSubDomains;i++)
+		 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
+
+		// move the Triangles  without a copy of the array 
+		// be carefull not trivial code 
+		for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
+		 if (renu[it] >= 0) // a new sub cycle
+			{ 
+			 i=it;
+			 Triangle ti=triangles[i],tj;
+			 while ( (j=renu[i]) >= 0) 
+				{ // i is old, and j is new 
+				 renu[i] = -1; // mark 
+				 tj = triangles[j]; // save new
+				 triangles[j]= ti; // new <- old
+				 i=j;     // next 
+				 ti = tj;
+				}  
+			}
+		delete [] renu;
+		nt = nbt - NbOutT;
+
+	}
+	/*}}}1*/
+	/*FUNCTION Mesh::ReNumberingVertex{{{1*/
+	void Mesh::ReNumberingVertex(long * renu) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ReNumberingVertex)*/
+
+		// warning be carfull because pointer
+		// from on mesh to over mesh 
+		//  --  so do ReNumbering at the beginning
+		MeshVertex * ve = vertices+nbv;
+		long it,ie,i;
+
+		printf("renumbering triangles\n");
+		for ( it=0;it<nbt;it++) 
+		 triangles[it].ReNumbering(vertices,ve,renu);
+
+		printf("renumbering edges\n");
+		for ( ie=0;ie<nbe;ie++) 
+		 edges[ie].ReNumbering(vertices,ve,renu);
+
+		printf("renumbering vertices on geom\n");
+		for (i=0;i< NbVerticesOnGeomVertex;i++)
+		  {
+			MeshVertex *v = VerticesOnGeomVertex[i].mv;
+			if (v>=vertices && v < ve)
+			 VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
+		  }
+
+		printf("renumbering vertices on edge\n");
+		for (i=0;i< NbVerticesOnGeomEdge;i++)
+		  {
+			MeshVertex *v =VerticesOnGeomEdge[i].mv;
+			if (v>=vertices && v < ve)
+			 VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
+		  }
+
+		printf("renumbering vertices on Bth vertex\n");
+		for (i=0;i< NbVertexOnBThVertex;i++)
+		  {
+			MeshVertex *v=VertexOnBThVertex[i].v;
+			if (v>=vertices && v < ve)
+			 VertexOnBThVertex[i].v=vertices+renu[Number(v)];
+		  }
+
+		for (i=0;i< NbVertexOnBThEdge;i++)
+		  {
+			MeshVertex *v=VertexOnBThEdge[i].v;
+			if (v>=vertices && v < ve)
+			 VertexOnBThEdge[i].v=vertices+renu[Number(v)];
+		  }
+
+		// move the Vertices without a copy of the array 
+		// be carefull not trivial code 
+		long j;
+		for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
+		 if (renu[it] >= 0) // a new sub cycle
+			{ 
+			 i=it;
+			 MeshVertex ti=vertices[i],tj;
+			 while ( (j=renu[i]) >= 0){
+				 // i is old, and j is new 
+				 renu[i] = -1-renu[i]; // mark 
+				 tj = vertices[j];     // save new
+				 vertices[j]= ti;      // new <- old
+				 i=j;     // next 
+				 ti = tj;
+				}  
+			}
+		if (quadtree){
+			delete quadtree;
+			quadtree = new QuadTree(this);
+		}
+
+		for ( it=0;it<nbv;it++) renu[i]= -renu[i]-1;
+	}
+	/*}}}1*/
+/*FUNCTION Mesh::SetIntCoor{{{1*/
+void Mesh::SetIntCoor(const char * strfrom) {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SetIntCoor)*/
+
+	/*Set integer coordinate for existing vertices*/
+
+	//Get extrema coordinates of the existing vertices
+	pmin =  vertices[0].r;
+	pmax =  vertices[0].r;
+	long i;
+	for (i=0;i<nbv;i++) {
+		pmin.x = Min(pmin.x,vertices[i].r.x);
+		pmin.y = Min(pmin.y,vertices[i].r.y);
+		pmax.x = Max(pmax.x,vertices[i].r.x);
+		pmax.y = Max(pmax.y,vertices[i].r.y);
+	}
+	R2 DD = (pmax-pmin)*0.05;
+	pmin = pmin-DD;
+	pmax = pmax+DD; 
+
+	//Compute coefIcoor
+	coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
+	if (coefIcoor<=0){
+		ISSMERROR("coefIcoor should be positive, a problem in the geometry is likely");
+	}
+
+	// generation of integer coord  
+	for (i=0;i<nbv;i++) {
+		vertices[i].i = toI2(vertices[i].r);    
+	}
+
+	// computation of the det 
+	int number_of_errors=0;
+	for (i=0;i<nbt;i++) {
+		MeshVertex & v0 = triangles[i][0];
+		MeshVertex & v1 = triangles[i][1];
+		MeshVertex & v2 = triangles[i][2];
+
+		//If this is not a boundary triangle
+		if ( &v0 && &v1 &&  &v2 ){
+
+			/*Compute determinant*/
+			triangles[i].det= det(v0,v1,v2);
+
+			/*Check that determinant is positive*/
+			if (triangles[i].det <=0){
+
+				/*increase number_of_errors and print error only for the first 20 triangles*/
+				number_of_errors++;
+				if (number_of_errors<20){
+					printf("Area of Triangle %i < 0 (det=%i)\n",i+1,triangles[i].det);
+				}
+			}
+		}
+
+		//else, set as -1
+		else triangles[i].det=-1;
+	}
+
+	if (number_of_errors) ISSMERROR("Fatal error: some triangles have negative areas, see above");
+}
+/*}}}1*/
+/*FUNCTION Mesh::ShowRegulaty{{{1*/
+void  Mesh::ShowRegulaty() const {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr>*/
+
+	const  double  sqrt32=sqrt(3.)*0.5; 
+	const double  aireKh=sqrt32*0.5;
+	D2  Beq(1,0),Heq(0.5,sqrt32);
+	D2xD2 Br(D2xD2(Beq,Heq).t());
+	D2xD2 B1r(Br.inv());
+	double gammamn=1e100,hmin=1e100;
+	double gammamx=0,hmax=0;
+	double beta=1e100;
+	double beta0=0;
+	double  alpha2=0;
+	double area=0,Marea=0;
+	// double cf= double(coefIcoor);
+	// double cf2= 6.*cf*cf;
+	int nt=0;
+	for (int it=0;it<nbt;it++)
+	 if ( triangles[it].link) 
+		{
+		 nt++;
+		 Triangle &K=triangles[it];
+		 double  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
+		 area+= area3;
+		 D2xD2 B_Kt(K[0],K[1],K[2]);
+		 D2xD2 B_K(B_Kt.t());
+		 D2xD2 B1K = Br*B_K.inv();
+		 D2xD2 BK =  B_K*B1r;
+		 D2xD2 B1B1 = B1K.t()*B1K;
+		 Metric MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
+		 MatVVP2x2 VMK(MK);
+		 alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
+		 double betaK=0;
+
+		 for (int j=0;j<3;j++)
+			{
+			 double he= Norme2(R2(K[j],K[(j+1)%3]));
+			 hmin=Min(hmin,he);
+			 hmax=Max(hmax,he);
+			 MeshVertex & v=K[j];
+			 D2xD2 M((Metric)v);
+			 betaK += sqrt(M.det());
+
+			 D2xD2 BMB = BK.t()*M*BK;
+			 Metric M1(BMB.x.x,BMB.x.y,BMB.y.y);
+			 MatVVP2x2 VM1(M1);
+			 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
+			 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);		
+			}
+		 betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
+		 Marea+= betaK;
+		 beta=min(beta,betaK);
+		 beta0=max(beta0,betaK);
+		}   
+	area*=3; 
+	gammamn=sqrt(gammamn);
+	gammamx=sqrt(gammamx);    
+	printf("   Adaptmesh info:\n");
+	printf("      number of triangles = %i\n",nt);
+	printf("      hmin = %g, hmax=%g\n",hmin,hmax);
+	printf("      area = %g, M area = %g, M area/( |Khat| nt) = %g\n",area,Marea, Marea/(aireKh*nt));
+	printf("      infinite-regularity(?): min = %g, max = %g\n",gammamn,gammamx);
+	printf("      anisomax = %g, beta max = %g, min = %g\n",pow(alpha2,0.5),1./pow(beta/aireKh,0.5), 1./pow(beta0/aireKh,0.5));
+}
+/*}}}1*/
+/*FUNCTION Mesh::ShowHistogram{{{1*/
+void  Mesh::ShowHistogram() const {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ShowHistogram)*/
+
+	const long kmax=10;
+	const double llmin = 0.5,llmax=2;
+	const double lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
+	long histo[kmax+1];
+	long i,it,k, nbedges =0;
+	for (i=0;i<=kmax;i++) histo[i]=0;
+	for (it=0;it<nbt;it++)
+	 if ( triangles[it].link) 
+		{
+
+		 for (int j=0;j<3;j++)
+			{
+			 Triangle *ta = triangles[it].TriangleAdj(j);
+			 if ( !ta || !ta->link || Number(ta) >= it) 
+				{ 
+				 MeshVertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
+				 MeshVertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
+				 if ( !& vP || !&vQ) continue;
+				 R2 PQ = vQ.r - vP.r;
+				 double l = log(LengthInterpole(vP,vQ,PQ));
+				 nbedges++;
+				 k = (int) ((l - lmin)*delta);
+				 k = Min(Max(k,0L),kmax);
+				 histo[k]++;
+				}
+			}
+		}  
+	printf(" --- Histogram of the unit mesh,  nb of edges = %i\n",nbedges);
+	printf("      length of edge in   | %% of edge  | Nb of edges \n"); 
+	printf("      --------------------+-------------+-------------\n"); 
+	for   (i=0;i<=kmax;i++){ 
+		if (i==0) printf("      %10i",0);
+		else      printf("      %10g",exp(lmin+i/delta));
+		if (i==kmax) printf("          +inf   ");
+		else printf("      %10g",exp(lmin+(i+1)/delta));
+		printf("|  %10g |\n",((long)  ((10000.0 * histo[i])/ nbedges))/100.0);
+		printf("  %i\n",histo[i]);
+	}
+	printf("      --------------------+-------------+-------------\n"); 
+}
+/*}}}1*/
+/*FUNCTION Mesh::SmoothingVertex{{{1*/
+void Mesh::SmoothingVertex(int nbiter,double omega ) { 
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SmoothingVertex)*/
+
+	long int verbose=0;
+	//  if quatree exist remove it end reconstruct
+	if (quadtree) delete quadtree;
+	quadtree=0;
+	ReMakeTriangleContainingTheVertex();
+	Triangle vide; // a triangle to mark the boundary vertex
+	Triangle   ** tstart= new Triangle* [nbv];
+	long i,j,k;
+	//   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide 
+	if ( this == & BTh)
+	 for ( i=0;i<nbv;i++)
+	  tstart[i]=vertices[i].t;     
+	else 
+	 for ( i=0;i<nbv;i++)
+	  tstart[i]=0;
+	for ( j=0;j<NbVerticesOnGeomVertex;j++ ) 
+	 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
+	for ( k=0;k<NbVerticesOnGeomEdge;k++ ) 
+	 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
+	if(verbose>2) printf("   SmoothingVertex: nb Iteration = %i, Omega=%g\n",nbiter,omega);
+	for (k=0;k<nbiter;k++)
+	  {
+		long i,NbSwap =0;
+		double delta =0;
+		for ( i=0;i<nbv;i++)
+		 if (tstart[i] != &vide) // not a boundary vertex 
+		  delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
+		if (!NbOfQuad)
+		 for ( i=0;i<nbv;i++)
+		  if (tstart[i] != &vide) // not a boundary vertex 
+			NbSwap += vertices[i].Optim(1);
+		if (verbose>3) printf("      move max = %g, iteration = %i, nb of swap = %i\n",pow(delta,0.5),k,NbSwap);
+	  }
+
+	delete [] tstart;
+	if (quadtree) quadtree= new QuadTree(this);
+}
+/*}}}1*/
+/*FUNCTION Mesh::SmoothMetric{{{1*/
+void Mesh::SmoothMetric(double raisonmax) { 
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/SmoothMetric)*/
+
+	long int verbose=0;
+
+	if(raisonmax<1.1) return;
+	if(verbose > 1) printf("   Mesh::SmoothMetric raisonmax = %g\n",raisonmax);
+	ReMakeTriangleContainingTheVertex();
+	long i,j,kch,kk,ip;
+	long *first_np_or_next_t0 = new long[nbv];
+	long *first_np_or_next_t1 = new long[nbv];
+	long Head0 =0,Head1=-1;
+	double logseuil= log(raisonmax);
+
+	for(i=0;i<nbv-1;i++)
+	 first_np_or_next_t0[i]=i+1; 
+	first_np_or_next_t0[nbv-1]=-1;// end;
+	for(i=0;i<nbv;i++)
+	 first_np_or_next_t1[i]=-1;
+	kk=0;
+	while (Head0>=0&& kk++<100) {
+		kch=0;
+		for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1) {
+			//  pour tous les triangles autour du sommet s
+			register Triangle* t= vertices[i].t;
+			if (!t){
+				ISSMERROR("!t");
+			}
+			MeshVertex & vi = vertices[i];
+			TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
+			MeshVertex *pvj0 = ta.EdgeVertex(0);
+			while (1) {
+				ta=Previous(Adj(ta));
+				if (vertices+i != ta.EdgeVertex(1)){
+					ISSMERROR("vertices+i != ta.EdgeVertex(1)");
+				}
+				MeshVertex & vj = *(ta.EdgeVertex(0));
+				if ( &vj ) {
+					j= &vj-vertices;
+					if (j<0 || j >= nbv){
+						ISSMERROR("j<0 || j >= nbv");
+					}
+					R2 Aij = (R2) vj - (R2) vi;
+					double ll =  Norme2(Aij);
+					if (0) {  
+						double hi = ll/vi.m(Aij);
+						double hj = ll/vj.m(Aij);
+						if(hi < hj)
+						  {
+							double dh=(hj-hi)/ll;
+							if (dh>logseuil) {
+								vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
+								if(first_np_or_next_t1[j]<0)
+								 kch++,first_np_or_next_t1[j]=Head1,Head1=j;
+							}
+						  }
+					} 
+					else
+					  {
+						double li = vi.m(Aij);
+						if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
+						 if(first_np_or_next_t1[j]<0) // if the metrix change 
+						  kch++,first_np_or_next_t1[j]=Head1,Head1=j;
+					  }
+				}
+				if  ( &vj ==  pvj0 ) break;
+			}
+		}
+		Head0 = Head1;
+		Head1 = -1;
+		Exchange(first_np_or_next_t0,first_np_or_next_t1);
+	}
+	if(verbose>2) printf("      number of iterations = %i\n",kch); 
+	delete [] first_np_or_next_t0;
+	delete [] first_np_or_next_t1;
+}
+/*}}}1*/
+	/*FUNCTION Mesh::SplitElement{{{1*/
+	int  Mesh::SplitElement(int choice){
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshQuad.cpp/SplitElement)*/
+
+		long int verbose=0;
+
+		Direction NoDirOfSearch;
+		const  int withBackground = &BTh != this && &BTh;
+
+		ReNumberingTheTriangleBySubDomain();
+		//int nswap =0;
+		const long nfortria( choice ? 4 : 6);
+		if(withBackground) 
+		  {
+			BTh.SetVertexFieldOn();
+			SetVertexFieldOnBTh();
+		  }
+		else
+		 BTh.SetVertexFieldOn();
+
+		long newnbt=0,newnbv=0;
+		long * kedge = 0;
+		long newNbOfQuad=NbOfQuad;
+		long * ksplit= 0, * ksplitarray=0;
+		long kkk=0;
+		int ret =0;
+		if (nbvx<nbv+nbe) return 1;//   
+		// 1) create  the new points by spliting the internal edges 
+		// set the 
+		long nbvold = nbv;
+		long nbtold = nbt;
+		long NbOutTold  = NbOutT;
+		long  NbEdgeOnGeom=0;
+		long i;
+
+		nbt = nbt - NbOutT; // remove all the  the ouside triangles 
+		long nbtsave = nbt;
+		Triangle * lastT = triangles + nbt;
+		for (i=0;i<nbe;i++)
+		 if(edges[i].onGeometry) NbEdgeOnGeom++;
+		long newnbe=nbe+nbe;
+		//  long newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
+		long newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
+		// long newNbVertexOnBThVertex=NbVertexOnBThVertex;
+		long newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
+
+		// do allocation for pointeur to the geometry and background
+		VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
+		VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
+		if (NbVerticesOnGeomEdge)
+		 memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
+		if (NbVertexOnBThEdge)
+		 memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
+		Edge *newedges = new Edge [newnbe];
+		//  memcpy(newedges,edges,sizeof(Edge)*nbe);
+		SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
+		long k=nbv;
+		long kk=0;
+		long kvb = NbVertexOnBThEdge;
+		long kvg = NbVerticesOnGeomEdge;
+		long ie =0;
+		Edge ** edgesGtoB=0;
+		if (withBackground)
+		 edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
+		long ferr=0;
+		for (i=0;i<nbe;i++)
+		 newedges[ie].onGeometry=0;
+
+		for (i=0;i<nbe;i++)
+		  {
+			GeometricalEdge *ong =  edges[i].onGeometry;
+
+			newedges[ie]=edges[i];
+			newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
+			newedges[ie].adj[1]=newedges + ie +1;
+			R2 A = edges[i][0],B = edges[i][1];
+
+
+			kk += (i == edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1])));
+			if (ong) // a geometrical edges 
+			  { 
+				if (withBackground){
+					// walk on back ground mesh 
+					//  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge); 
+					// a faire -- difficile 
+					// the first PB is to now a background edge between the 2 vertices
+					if (!edgesGtoB){
+						ISSMERROR("!edgesGtoB");
+					}
+					ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].onGeometry)],
+								edges[i][0],edges[i][1],0.5,vertices[k],
+								newVertexOnBThEdge[kvb],
+								newVerticesOnGeomEdge[kvg++]);
+					vertices[k].ReferenceNumber= edges[i].ref;
+					vertices[k].DirOfSearch =   NoDirOfSearch;        
+					;
+					// get the Info on background mesh 
+					double s =        newVertexOnBThEdge[kvb];
+					MeshVertex &  bv0  = newVertexOnBThEdge[kvb][0];
+					MeshVertex &  bv1  = newVertexOnBThEdge[kvb][1];
+					// compute the metrix of the new points 
+					vertices[k].m =  Metric(1-s,bv0,s,bv1); 
+					kvb++;
+				  }
+				else 
+				  {
+					ong=Gh.ProjectOnCurve(edges[i],
+								0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
+					// vertices[k].i = toI2( vertices[k].r);
+					vertices[k].ReferenceNumber = edges[i].ref;
+					vertices[k].DirOfSearch = NoDirOfSearch;
+					vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	      
+				  }  
+			  }
+			else // straigth line edge ---
+			  { 
+				vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
+				vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
+				vertices[k].onGeometry = 0;
+			  }
+			//vertices[k].i = toI2( vertices[k].r);
+			R2 AB =  vertices[k].r;
+			R2 AA = (A+AB)*0.5;
+			R2 BB = (AB+B)*0.5;
+			vertices[k].ReferenceNumber = edges[i].ref;
+			vertices[k].DirOfSearch = NoDirOfSearch;
+
+			newedges[ie].onGeometry = Gh.Containing(AA,ong);
+			newedges[ie++].v[1]=vertices+k;
+
+			newedges[ie]=edges[i];
+			newedges[ie].adj[0]=newedges + ie -1;
+			newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
+			newedges[ie].onGeometry =  Gh.Containing(BB,ong);
+			newedges[ie++].v[0]=vertices+k;
+			k++;
+		  }
+		if (edgesGtoB) delete [] edgesGtoB;
+		edgesGtoB=0;
+
+		newnbv=k;
+		newNbVerticesOnGeomEdge=kvg;
+		if (newnbv> nbvx) goto Error;// bug 
+
+		nbv = k;
+
+
+		kedge = new long[3*nbt+1];
+		ksplitarray = new long[nbt+1];
+		ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
+
+		for (i=0;i<3*nbt;i++)
+		 kedge[i]=-1;
+
+		//  
+
+		for (i=0;i<nbt;i++) {
+			Triangle & t = triangles[i];
+			if (!t.link){
+				ISSMERROR("!t.link");
+			}
+			for(int j=0;j<3;j++)
+			  {
+				const TriangleAdjacent ta = t.Adj(j);
+				const Triangle & tt = ta;
+				if (&tt >= lastT)
+				 t.SetAdj2(j,0,0);// unset adj
+				const MeshVertex & v0 = t[VerticesOfTriangularEdge[j][0]];
+				const MeshVertex & v1 = t[VerticesOfTriangularEdge[j][1]];
+				long  ke =edge4->SortAndFind(Number(v0),Number(v1));
+				if (ke>0) 
+				  {
+					long ii = Number(tt);
+					int  jj = ta;
+					long ks = ke + nbvold;
+					kedge[3*i+j] = ks;
+					if (ii<nbt) // good triangle
+					 kedge[3*ii+jj] = ks;
+					MeshVertex &A=vertices[ks];
+					double aa,bb,cc,dd;
+					if ((dd=Area2(v0.r,v1.r,A.r)) >=0){
+						// warning PB roundoff error 
+						if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0 
+										||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0  
+										||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0)){
+							printf("%i not in triangle %i In= %i %g %g %g %g\n",ke + nbvold,i,!!t.link,aa,bb,cc,dd);
+							ISSMERROR("Number of triangles with P2 interpolation Problem");
+						}
+					}
+					else {
+						if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0 
+										||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0 
+										||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)){
+							printf("%i not in triangle %i In= %i %g %g %g %g\n",ke + nbvold,ii,!!tt.link,aa,bb,cc,dd);
+							ISSMERROR("Number of triangles with P2 interpolation Problem");
+						}
+					} 
+				  }
+			  }
+		}
+
+		for (i=0;i<nbt;i++){
+			ksplit[i]=1; // no split by default
+			const Triangle & t = triangles[ i];
+			int nbsplitedge =0;
+			int nbinvisible =0;
+			int invisibleedge=0;
+			int kkk[3];      
+			for (int j=0;j<3;j++)
+			  {
+				if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
+
+				const TriangleAdjacent ta = t.Adj(j);
+				const Triangle & tt = ta;
+
+
+				const MeshVertex & v0 = t[VerticesOfTriangularEdge[j][0]];
+				const MeshVertex & v1 = t[VerticesOfTriangularEdge[j][1]];
+				if ( kedge[3*i+j] < 0) 
+				  {
+					long  ke =edge4->SortAndFind(Number(v0),Number(v1));
+					if (ke<0) // new 
+					  {
+						if (&tt) // internal triangles all the boundary 
+						  { // new internal edges 
+							long ii = Number(tt);
+							int  jj = ta;
+
+							kedge[3*i+j]=k;// save the vertex number 
+							kedge[3*ii+jj]=k;
+							if (k<nbvx) 
+							  {
+								vertices[k].r = ((R2) v0+(R2) v1 )/2;
+								//vertices[k].i = toI2( vertices[k].r);
+								vertices[k].ReferenceNumber=0;
+								vertices[k].DirOfSearch =NoDirOfSearch;
+								vertices[k].m =  Metric(0.5,v0,0.5,v1);
+							  }
+							k++;
+							kkk[nbsplitedge++]=j;		      
+						  } // tt 
+						else
+						 ISSMERROR("Bug...");
+					  } // ke<0	       
+					else
+					  { // ke >=0
+						kedge[3*i+j]=nbvold+ke;
+						kkk[nbsplitedge++]=j;// previously splited
+					  }
+				  }
+				else 
+				 kkk[nbsplitedge++]=j;// previously splited
+
+			  } 
+			if (nbinvisible>=2){
+				ISSMERROR("nbinvisible>=2");
+			}
+			switch (nbsplitedge) {
+				case 0: ksplit[i]=10; newnbt++; break;   // nosplit
+				case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2 
+				case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3 
+				case 3:
+						  if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
+						  else   ksplit[i]=10*nfortria,newnbt+=nfortria;
+						  break;
+			} 
+			if (ksplit[i]<40){
+				ISSMERROR("ksplit[i]<40");
+			}
+		  }
+		//  now do the element split
+		newNbOfQuad = 4*NbOfQuad;
+		nbv = k;
+		kkk = nbt;
+		ksplit[-1] = nbt;
+		// look on  old true  triangles 
+
+		for (i=0;i<nbtsave;i++){
+			int  nbmkadj=0;
+			long mkadj [100];
+			mkadj[0]=i;
+			long kk=ksplit[i]/10;
+			int  ke=(int) (ksplit[i]%10);
+			if (kk>=7 || kk<=0){
+				ISSMERROR("kk>=7 || kk<=0");
+			}
+
+			// def the numbering   k (edge) i vertex 
+			int k0 = ke;
+			int k1 = NextEdge[k0];
+			int k2 = PreviousEdge[k0];
+			int i0 = OppositeVertex[k0];
+			int i1 = OppositeVertex[k1];
+			int i2 = OppositeVertex[k2];
+
+			Triangle &t0=triangles[i];
+			MeshVertex * v0=t0(i0);           
+			MeshVertex * v1=t0(i1);           
+			MeshVertex * v2=t0(i2);
+
+			if (nbmkadj>=10){
+				ISSMERROR("nbmkadj>=10");
+			}
+			// --------------------------
+			TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
+			// save the flag Hidden
+			int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
+			// un set all adj -- save Hidden flag --
+			t0.SetAdj2(0,0,hid[0]);
+			t0.SetAdj2(1,0,hid[1]);
+			t0.SetAdj2(2,0,hid[2]);
+			// --  remake 
+			switch  (kk) {
+				case 1: break;// nothing 
+				case 2: // 
+						  {
+							Triangle &t1=triangles[kkk++];
+							t1=t0;
+							if (kedge[3*i+i0]<0){
+								ISSMERROR("kedge[3*i+i0]<0");
+							}
+							MeshVertex * v3 = vertices + kedge[3*i+k0];
+
+							t0(i2) = v3;
+							t1(i1) = v3;
+							t0.SetAllFlag(k2,0);
+							t1.SetAllFlag(k1,0);
+						  } 
+						break; 
+				case 3: //
+						  {
+							Triangle &t1=triangles[kkk++];
+							Triangle &t2=triangles[kkk++];
+							t2=t1=t0;
+							if (kedge[3*i+k1]<0){
+								ISSMERROR("kedge[3*i+k1]<0");
+							}
+							if (kedge[3*i+k2]<0){
+								ISSMERROR("kedge[3*i+k2]<0");
+							}
+
+							MeshVertex * v01 = vertices + kedge[3*i+k2];
+							MeshVertex * v02 = vertices + kedge[3*i+k1]; 
+							t0(i1) = v01; 
+							t0(i2) = v02; 
+							t1(i2) = v02;
+							t1(i0) = v01; 
+							t2(i0) = v02; 
+							t0.SetAllFlag(k0,0);
+							t1.SetAllFlag(k1,0);
+							t1.SetAllFlag(k0,0);
+							t2.SetAllFlag(k2,0);
+						  } 
+						break;
+				case 4: // 
+				case 6: // split in 4 
+						  {
+							Triangle &t1=triangles[kkk++];
+							Triangle &t2=triangles[kkk++];
+							Triangle &t3=triangles[kkk++];
+							t3=t2=t1=t0;
+							if (kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0){
+								ISSMERROR("kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0");
+							}
+							MeshVertex * v12 = vertices + kedge[3*i+k0];
+							MeshVertex * v02 = vertices + kedge[3*i+k1]; 
+							MeshVertex * v01 = vertices + kedge[3*i+k2];
+							t0(i1) = v01;
+							t0(i2) = v02;
+							t0.SetAllFlag(k0,hid[k0]);
+
+							t1(i0) = v01;
+							t1(i2) = v12;
+							t0.SetAllFlag(k1,hid[k1]);
+
+							t2(i0) = v02;
+							t2(i1) = v12;
+							t2.SetAllFlag(k2,hid[k2]);
+
+							t3(i0) = v12;
+							t3(i1) = v02;
+							t3(i2) = v01;
+
+							t3.SetAllFlag(0,hid[0]);	   
+							t3.SetAllFlag(1,hid[1]);	   
+							t3.SetAllFlag(2,hid[2]);
+
+							if ( kk == 6)
+							  {
+
+								Triangle &t4=triangles[kkk++];
+								Triangle &t5=triangles[kkk++];
+
+								t4 = t3;
+								t5 = t3;
+
+								t0.SetHidden(k0);
+								t1.SetHidden(k1);
+								t2.SetHidden(k2);
+								t3.SetHidden(0);
+								t4.SetHidden(1);
+								t5.SetHidden(2);
+
+								if (nbv < nbvx ) 
+								  {
+									vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
+									vertices[nbv].ReferenceNumber =0;
+									vertices[nbv].DirOfSearch =NoDirOfSearch;
+									//vertices[nbv].i = toI2(vertices[nbv].r);
+									double a3[]={1./3.,1./3.,1./3.};
+									vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
+									MeshVertex * vc =  vertices +nbv++;
+									t3(i0) = vc;
+									t4(i1) = vc;
+									t5(i2) = vc;
+
+								  }
+								else
+								 goto Error; 
+							  }
+
+						  } 
+						break;         
+			}
+
+			// save all the new triangles
+			mkadj[nbmkadj++]=i;
+			long jj;
+			if (t0.link) 
+			 for (jj=nbt;jj<kkk;jj++)
+				{
+				 triangles[jj].link=t0.link;
+				 t0.link= triangles+jj;
+				 mkadj[nbmkadj++]=jj;
+				}
+			if (nbmkadj>13){// 13 = 6 + 4 +
+				ISSMERROR("nbmkadj>13");
+			}
+
+			if (kk==6)  newNbOfQuad+=3;
+			for (jj=ksplit[i-1];jj<kkk;jj++) nbt = kkk;
+			ksplit[i]= nbt; // save last adresse of the new triangles
+			kkk = nbt;
+		  }
+
+		for (i=0;i<nbv;i++) vertices[i].m = vertices[i].m*2.;
+
+		if(withBackground)
+		 for (i=0;i<BTh.nbv;i++)
+		  BTh.vertices[i].m =  BTh.vertices[i].m*2.;
+
+
+		ret = 2;
+		if (nbt>= nbtx) goto Error; // bug 
+		if (nbv>= nbvx) goto Error; // bug 
+		// generation of the new triangles 
+
+		SetIntCoor("In SplitElement"); 
+
+		ReMakeTriangleContainingTheVertex();
+		if(withBackground)
+		 BTh.ReMakeTriangleContainingTheVertex();
+
+		delete [] edges;
+		edges = newedges;
+		nbe = newnbe;
+		NbOfQuad = newNbOfQuad;
+
+		for (i=0;i<NbSubDomains;i++)
+		  { 
+			long k = subdomains[i].edge- edges;
+			subdomains[i].edge =  edges+2*k; // spilt all edge in 2 
+		  }
+
+		if (ksplitarray) delete [] ksplitarray;
+		if (kedge) delete [] kedge;
+		if (edge4) delete edge4;
+		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
+		VerticesOnGeomEdge= newVerticesOnGeomEdge;
+		if(VertexOnBThEdge) delete []  VertexOnBThEdge;
+		VertexOnBThEdge = newVertexOnBThEdge;
+		NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
+		NbVertexOnBThEdge=newNbVertexOnBThEdge;
+		//  ReMakeTriangleContainingTheVertex();
+
+		ReconstructExistingMesh();
+
+		if (verbose>2){
+			printf("   number of quadrilaterals    = %i\n",NbOfQuad);
+			printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
+			printf("   number of outside triangles = %i\n",NbOutT);
+		}
+
+		return 0; //ok
+
+Error:
+		nbv = nbvold;
+		nbt = nbtold;
+		NbOutT = NbOutTold;
+		// cleaning memory ---
+		delete newedges;
+		if (ksplitarray) delete [] ksplitarray;
+		if (kedge) delete [] kedge;
+		if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
+		if (edge4) delete edge4;
+		if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
+
+		return ret; // ok 
+	}
+	/*}}}1*/
+/*FUNCTION Mesh::SplitInternalEdgeWithBorderVertices{{{1*/
+long  Mesh::SplitInternalEdgeWithBorderVertices(){
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SplitInternalEdgeWithBorderVertices)*/
+
+	long NbSplitEdge=0;
+	SetVertexFieldOn();  
+	long it;
+	long nbvold=nbv;
+	long int verbose=2;
+	for (it=0;it<nbt;it++){
+		Triangle &t=triangles[it];
+		if (t.link)
+		 for (int j=0;j<3;j++)
+		  if(!t.Locked(j) && !t.Hidden(j)){
+			  Triangle &tt = *t.TriangleAdj(j);
+			  if ( &tt && tt.link && it < Number(tt)) 
+				 { // an internal edge 
+				  MeshVertex &v0 = t[VerticesOfTriangularEdge[j][0]];
+				  MeshVertex &v1 = t[VerticesOfTriangularEdge[j][1]];
+				  if (v0.onGeometry && v1.onGeometry){
+					  R2 P= ((R2) v0 + (R2) v1)*0.5;
+					  if ( nbv<nbvx) {
+						  vertices[nbv].r = P;
+						  vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
+						  vertices[nbv].ReferenceNumber=0;
+						  vertices[nbv].DirOfSearch = NoDirOfSearch ;
+					  }
+					  NbSplitEdge++;
+				  }
+				 }
+		  }
+	}
+	ReMakeTriangleContainingTheVertex();    
+	if (nbvold!=nbv){
+		long  iv = nbvold;
+		long NbSwap = 0;
+		Icoor2 dete[3];  
+		for (int i=nbvold;i<nbv;i++) {// for all the new point
+			MeshVertex & vi = vertices[i];
+			vi.i = toI2(vi.r);
+			vi.r = toR2(vi.i);
+
+			// a good new point 
+			vi.ReferenceNumber=0; 
+			vi.DirOfSearch =NoDirOfSearch;
+			Triangle *tcvi = FindTriangleContaining(vi.i,dete);
+			if (tcvi && !tcvi->link) {
+				printf("problem inserting point in SplitInternalEdgeWithBorderVertices (tcvj && !tcvj->link)\n");
+			}
+
+			quadtree->Add(vi);
+			if (!tcvi || tcvi->det<0){// internal
+				ISSMERROR("!tcvi || tcvi->det < 0");
+			}
+			AddVertex(vi,tcvi,dete);
+			NbSwap += vi.Optim(1);          
+			iv++;
+			//      }
+	}
+	if (verbose>3) {
+		printf("   number of points: %i\n",iv);
+		printf("   number of swap to  split internal edges with border vertices: %i\n",NbSwap);
+		nbv = iv;
+	}
+}
+if (NbSplitEdge>nbv-nbvold) printf("WARNING: not enough vertices  to split all internal edges, we lost %i edges...\n",NbSplitEdge - ( nbv-nbvold));
+if (verbose>2) printf("SplitInternalEdgeWithBorderVertices: Number of splited edge %i\n",NbSplitEdge);
+
+return  NbSplitEdge;
+}
+/*}}}1*/
+/*FUNCTION Mesh::TriangleReferenceList{{{1*/
+long  Mesh::TriangleReferenceList(long* reft) const {
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ConsRefTriangle)*/
+
+	long int verbose=0;
+	register Triangle *t0,*t;
+	register long k=0, num;   
+
+	//initialize all triangles as -1 (outside)
+	for (int it=0;it<nbt;it++) reft[it]=-1;
+
+	//loop over all subdomains
+	for (int i=0;i<NbSubDomains;i++){ 
+
+		//first triangle of the subdomain i
+		t=t0=subdomains[i].head;
+
+		//check that the subdomain is not empty
+		if (!t0){ ISSMERROR("At least one subdomain is empty");}
+
+		//loop
+		do{
+			k++;
+
+			//get current triangle number
+			num = Number(t);
+
+			//check that num is in [0 nbt[
+			if (num<0 || num>=nbt){ ISSMERROR("num<0 || num>=nbt");}
+
+			//reft of this triangle is the subdomain number
+			reft[num]=i;
+
+		} while (t0 != (t=t->link));
+		//stop when all triangles of subdomains have been tagged
+
+	}
+	return k;   
+}
+/*}}}1*/
+/*FUNCTION Mesh::TriangleIntNumbering{{{1*/
+void Mesh::TriangleIntNumbering(long* renumbering){
+
+	long num=0;
+	for (int i=0;i<nbt;i++){
+		if (triangles[i].det>0) renumbering[i]=num++;
+		else renumbering[i]=-1;
+	}
+	return;   
+}
+/*}}}1*/
+
+	/*Intermediary*/
+	/*FUNCTION CloseBoundaryEdge{{{1*/
+	TriangleAdjacent CloseBoundaryEdge(I2 A,Triangle *t, double &a,double &b) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CloseBoundaryEdge)*/
+
+		int k=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
+		int dir=0;
+		if (k<0){
+			ISSMERROR("k<0");
+		}
+		int kkk=0;  
+		Icoor2 IJ_IA,IJ_AJ;
+		TriangleAdjacent edge(t,OppositeEdge[k]);          
+		for (;;edge = dir >0 ? Next(Adj(Next(edge))) : Previous(Adj(Previous(edge)))) {  
+			kkk++;
+			if (kkk>=1000){
+				ISSMERROR("kkk>=1000");
+			}
+			MeshVertex  &vI =  *edge.EdgeVertex(0);
+			MeshVertex  &vJ =  *edge.EdgeVertex(1);
+			I2 I=vI, J=vJ, IJ= J-I;
+			IJ_IA = (IJ ,(A-I));
+			if (IJ_IA<0) {
+				if (dir>0) {a=1;b=0;return edge;}// change of signe => I
+				else {dir=-1;
+					continue;}};// go in direction i 
+					IJ_AJ = (IJ ,(J-A));
+					if (IJ_AJ<0) {
+						if(dir<0)  {a=0;b=1;return edge;}            
+						else {dir = 1;
+							continue;}}// go in direction j
+							double IJ2 = IJ_IA + IJ_AJ;
+							if (IJ2==0){
+								ISSMERROR("IJ2==0");
+							}
+							a= IJ_AJ/IJ2;
+							b= IJ_IA/IJ2;
+							return edge;
+		  } 
+	}
+	/*}}}1*/
+	/*FUNCTION CloseBoundaryEdgeV2{{{1*/
+	TriangleAdjacent CloseBoundaryEdgeV2(I2 C,Triangle *t, double &a,double &b) { 
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CloseBoundaryEdgeV2)*/
+		// walk around the vertex 
+		// version 2 for remove the probleme if we fill the hole
+		//int bug=1;
+		//  Triangle *torigine = t;
+		// restart:
+		//   int dir=0;
+		if (t->link != 0){
+			ISSMERROR("t->link != 0");
+		}
+		// to have a starting edges 
+		// try the 3 edge bourna-- in case of internal hole 
+		// and choice  the best 
+		// 
+		// the probleme is in case of  the fine and long internal hole
+		// for exemple neart the training edge of a wing
+		MeshVertex * s=0,*s1=0, *s0=0;
+		Icoor2 imax = MaxICoor22;
+		Icoor2 l0 = imax,l1 = imax;
+		double dd2 =  imax;// infinity
+		TriangleAdjacent er; 
+		int  cas=-2;
+		for (int j=0;j<3;j++)
+		  { 
+			TriangleAdjacent ta=t->FindBoundaryEdge(j);
+			if  (! (Triangle *) ta) continue;
+			s0 = ta.EdgeVertex(0);
+			s1 = ta.EdgeVertex(1);
+			I2 A = * s0;
+			I2 B = *ta.EdgeVertex(1);
+			I2 AB = B-A,AC=C-A,BC=B-C;
+			Icoor2  ACAC = (AC,AC), BCBC = (BC,BC);
+			Icoor2  AB2  =   Norme2_2(AB); //  ||AB||^2
+			Icoor2  ABAC  =   (AB,AC);         //  AB.AC|
+
+			double d2;
+			if ( ABAC < 0 )   // DIST A
+			  {
+				if ( (d2=(double) ACAC)  <  dd2) 
+				  {
+					er = ta;
+					l0 = ACAC;
+					l1 = BCBC;
+					cas = 0;
+					s = s0;
+				  }
+			  }
+			else if (ABAC > AB2)  // DIST B
+			  {
+				if ( (d2=(double) BCBC)  <  dd2) 
+				  {
+					dd2 = d2;
+					er = Adj(ta); // other direction
+					l0 = BCBC;
+					l1 = ACAC;
+					cas = 1;
+					s = s1;
+				  }
+			  }
+			else  // DIST AB
+			  { 
+
+				double det_2 =  (double) Det(AB,AC); 
+				det_2 *= det_2; // square of area*2 of triangle ABC
+				d2 = det_2/ (double) AB2; // hauteur^2 in C of of triangle ABC      
+
+				if (d2 < dd2) 
+				  {
+					dd2 = d2;
+					er = ta;
+					l0 = (AC,AC);
+					l1 = (BC,BC);
+					s = 0;
+					cas = -1;
+					b = ((double) ABAC/(double) AB2);
+					a = 1 - b;
+				  }
+			  }
+		  }
+		if (cas ==-2){
+			ISSMERROR("cas==-2");
+		}
+		// l1 = ||C s1||  , l0 = ||C s0||
+		// where s0,s1 are the vertex of the edge er
+
+		if ( s) 
+		  { 
+			t=er;
+			TriangleAdjacent edge(er); 
+
+			int kkk=0;  
+			int linkp = t->link == 0;
+
+			Triangle * tt=t=edge=Adj(Previous(edge));
+			do  {  // loop over vertex s
+				kkk++;
+				if (edge.EdgeVertex(0)!=s && kkk>=10000){
+					ISSMERROR("edge.EdgeVertex(0)!=s && kkk>=10000");
+				}
+
+				int link = tt->link == 0;
+				if ((link + linkp) == 1) 
+				  { // a boundary edge 
+					MeshVertex * st = edge.EdgeVertex(1);
+					I2 I=*st;
+					Icoor2  ll = Norme2_2 (C-I);
+					if (ll < l1) {  // the other vertex is neart 
+						s1=st;
+						l1=ll;
+						er = edge;
+						if(ll<l0) { // change of direction --
+							s1=s;
+							l1=l0;
+							s=st;
+							l0=ll;
+							t=tt;
+							edge=Adj(edge);
+							link=linkp;
+							er = edge;
+						}
+					}
+				  }
+
+				linkp=link;
+				edge=Adj(Previous(edge));
+				tt = edge;
+			} while (t!=tt);
+
+			if (!(Triangle *) er){
+				ISSMERROR("!(Triangle *) er");
+			}
+			I2 A((I2)*er.EdgeVertex(0));
+			I2 B((I2)*er.EdgeVertex(1));
+			I2 AB=B-A,AC=C-A,CB=B-C;
+			double aa =  (double) (AB,AC);
+			double bb =  (double) (AB,CB);
+			if (aa<0)       a=1,b=0;
+			else if(bb<0)   a=0,b=1;
+			else  
+			  {
+				a  = bb/(aa+bb);
+				b  = aa/(aa+bb);
+			  }
+		  }
+		return er;
+	} 
+	/*}}}1*/
+/*FUNCTION ForceEdge{{{1*/
+int ForceEdge(MeshVertex &a, MeshVertex & b,TriangleAdjacent & taret)  { 
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ForceEdge)*/
+
+	int NbSwap =0;
+	if (!a.t || !b.t){ // the 2 vertex is in a mesh
+		ISSMERROR("!a.t || !b.t");
+	}
+	int k=0;
+	taret=TriangleAdjacent(0,0); // erreur 
+
+	TriangleAdjacent tta(a.t,EdgesVertexTriangle[a.vint][0]);
+	MeshVertex   *v1, *v2 = tta.EdgeVertex(0),*vbegin =v2;
+	// we turn around a in the  direct sens  
+
+	Icoor2 det2 = v2 ? det(*v2,a,b): -1 , det1;
+	if(v2) // normal case 
+	 det2 = det(*v2,a,b);
+	else { // no chance infini vertex try the next
+		tta= Previous(Adj(tta));
+		v2 = tta.EdgeVertex(0);
+		vbegin =v2;
+		if (!v2){
+			ISSMERROR("!v2");
+		}
+		det2 = det(*v2,a,b);
+	}
+
+	while (v2 != &b) {
+		TriangleAdjacent tc = Previous(Adj(tta));    
+		v1 = v2; 
+		v2 = tc.EdgeVertex(0);
+		det1 = det2;
+		det2 =  v2 ? det(*v2,a,b): det2; 
+
+		if((det1 < 0) && (det2 >0)) { 
+			// try to force the edge 
+			MeshVertex * va = &a, *vb = &b;
+			tc = Previous(tc);
+			if (!v1 || !v2){
+				ISSMERROR("!v1 || !v2");
+			}
+			Icoor2 detss = 0,l=0,ks;
+			while ((ks=SwapForForcingEdge(  va,  vb, tc, detss, det1,det2,NbSwap)))
+			 if(l++ > 10000000) {
+				 ISSMERROR("Loop in forcing Egde, nb de swap=%i, nb of try swap (%i) too big",NbSwap,l);
+			 }
+			MeshVertex *aa = tc.EdgeVertex(0), *bb = tc.EdgeVertex(1);
+			if (( aa == &a ) && (bb == &b) ||  (bb ==  &a ) && (aa == &b)) {
+				tc.SetLock();
+				a.Optim(1,0);
+				b.Optim(1,0);
+				taret = tc;
+				return NbSwap;
+			}
+			else 
+			  {
+				taret = tc;
+				return -2; // error  boundary is crossing
+			  }
+		}
+		tta = tc;
+		k++;
+		if (k>=2000){
+			ISSMERROR("k>=2000");
+		}
+		if ( vbegin == v2 ) return -1;// error 
+	}
+
+	tta.SetLock();
+	taret=tta;
+	a.Optim(1,0);
+	b.Optim(1,0);
+	return NbSwap; 
+}
+/*}}}1*/
+/*FUNCTION swap{{{1*/
+void  swap(Triangle *t1,short a1, Triangle *t2,short a2, MeshVertex *s1,MeshVertex *s2,Icoor2 det1,Icoor2 det2){ 
+	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/swap)*/
+	// --------------------------------------------------------------
+	// short a2=aa[a];// les 2 numero de l arete dans les 2 triangles
+	//                               
+	//               sb                     sb    
+	//             / | \                   /   \                      !
+	//         as1/  |  \                 /a2   \                     !
+	//           /   |   \               /    t2 \                    !
+	//       s1 /t1  | t2 \s2  -->   s1 /___as2___\s2                 !
+	//          \  a1|a2  /             \   as1   /  
+	//           \   |   /               \ t1    /   
+	//            \  |  / as2             \   a1/    
+	//             \ | /                   \   /     
+	//              sa                       sa   
+	//  -------------------------------------------------------------
+	int as1 = NextEdge[a1];
+	int as2 = NextEdge[a2];
+	int ap1 = PreviousEdge[a1];
+	int ap2 = PreviousEdge[a2];
+	(*t1)(VerticesOfTriangularEdge[a1][1]) = s2 ; // avant sb
+	(*t2)(VerticesOfTriangularEdge[a2][1]) = s1  ; // avant sa
+	// mise a jour des 2 adjacences externes 
+	TriangleAdjacent taas1 = t1->Adj(as1),
+						  taas2 = t2->Adj(as2),
+						  tas1(t1,as1), tas2(t2,as2),
+						  ta1(t1,a1),ta2(t2,a2);
+	// externe haut gauche
+	taas1.SetAdj2(ta2, taas1.GetAllFlag_UnSwap());
+	// externe bas droite
+	taas2.SetAdj2(ta1, taas2.GetAllFlag_UnSwap());
+	// remove the Mark  UnMarkSwap 
+	t1->SetUnMarkUnSwap(ap1);
+	t2->SetUnMarkUnSwap(ap2);
+	// interne 
+	tas1.SetAdj2(tas2);
+
+	t1->det = det1;
+	t2->det = det2;
+
+	t1->SetTriangleContainingTheVertex();
+	t2->SetTriangleContainingTheVertex();
+} // end swap 
+/*}}}1*/
+	/*FUNCTION SwapForForcingEdge{{{1*/
+	int SwapForForcingEdge(MeshVertex   *  & pva ,MeshVertex  * &   pvb ,TriangleAdjacent & tt1,Icoor2 & dets1, Icoor2 & detsa,Icoor2 & detsb, int & NbSwap) {
+		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SwapForForcingEdge)*/
+		// l'arete ta coupe l'arete pva pvb
+		// de cas apres le swap sa coupe toujours
+		// on cherche l'arete suivante 
+		// on suppose que detsa >0 et detsb <0
+		// attention la routine echange pva et pvb 
+
+		if(tt1.Locked()) return 0; // frontiere croise 
+
+		TriangleAdjacent tt2 = Adj(tt1);
+		Triangle *t1=tt1,*t2=tt2;// les 2 triangles adjacent
+		short a1=tt1,a2=tt2;// les 2 numero de l arete dans les 2 triangles
+		if ( a1<0 || a1>=3 ){
+			ISSMERROR("a1<0 || a1>=3");
+		}
+
+		MeshVertex & sa= (* t1)[VerticesOfTriangularEdge[a1][0]];
+		MeshVertex & s1= (*t1)[OppositeVertex[a1]];
+		MeshVertex & s2= (*t2)[OppositeVertex[a2]];
+
+
+		Icoor2 dets2 = det(*pva,*pvb,s2);
+		Icoor2 det1=t1->det , det2=t2->det ;
+		Icoor2 detT = det1+det2;
+		if ((det1<=0 ) || (det2<=0)){
+			ISSMERROR("(det1<=0 ) || (det2<=0)");
+		}
+		if ( (detsa>=0) || (detsb<=0) ){ // [a,b] cut infinite line va,bb
+			ISSMERROR("(detsa>=0) || (detsb<=0)");
+		}
+		Icoor2 ndet1 = bamg::det(s1,sa,s2);
+		Icoor2 ndet2 = detT - ndet1;
+
+		int ToSwap =0; //pas de swap
+		if ((ndet1 >0) && (ndet2 >0)) 
+		  { // on peut swaper  
+			if ((dets1 <=0 && dets2 <=0) || (dets2 >=0 && detsb >=0))
+			 ToSwap =1; 
+			else // swap alleatoire 
+			 if (BinaryRand()) 
+			  ToSwap =2; 
+		  }
+		if (ToSwap) NbSwap++,
+		 bamg::swap(t1,a1,t2,a2,&s1,&s2,ndet1,ndet2);
+
+		int ret=1;
+
+		if (dets2 < 0) {// haut
+			dets1 = ToSwap ? dets1 : detsa ;
+			detsa = dets2; 
+			tt1 =  Previous(tt2) ;}
+		else if (dets2 > 0){// bas 
+			dets1 = ToSwap ? dets1 : detsb ;
+			detsb = dets2;
+			//xxxx tt1 = ToSwap ? tt1 : Next(tt2);
+			if(!ToSwap) tt1 =  Next(tt2);
+		}
+		else { // changement de sens 
+			ret = -1;
+			Exchange(pva,pvb);
+			Exchange(detsa,detsb);
+			Exchange(dets1,dets2);
+			Exchange(tt1,tt2);
+			dets1=-dets1;
+			dets2=-dets2;
+			detsa=-detsa;
+			detsb=-detsb;
+
+			if (ToSwap) 
+			 if (dets2 < 0) {// haut
+				 dets1 = (ToSwap ? dets1 : detsa) ;
+				 detsa = dets2; 
+				 tt1 =  Previous(tt2) ;}
+			 else if (dets2 > 0){// bas 
+				 dets1 = (ToSwap ? dets1 : detsb) ;
+				 detsb =  dets2;
+				 if(!ToSwap) tt1 =  Next(tt2);
+			 }
+			 else {// on a fin ???
+				 tt1 = Next(tt2);
+				 ret =0;}
+
+		}
+		return ret;
+	}
+	/*}}}1*/
+
+}
Index: /issm/trunk/src/c/objects/Bamg/Mesh.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Mesh.h	(revision 5095)
+++ /issm/trunk/src/c/objects/Bamg/Mesh.h	(revision 5095)
@@ -0,0 +1,203 @@
+#ifndef _TRIANGLES_H_
+#define _TRIANGLES_H_
+
+#include "./include.h"
+#include "./BamgOpts.h"
+#include "./BamgMesh.h"
+#include "./BamgGeom.h"
+#include "./Triangle.h"
+#include "./VertexOnGeom.h"
+#include "./VertexOnVertex.h"
+#include "./VertexOnEdge.h"
+#include "./ListofIntersectionTriangles.h"
+
+
+namespace bamg {
+
+	//classes
+	class Geometry;
+	class CrackedEdge;
+	class QuadTree;
+	class SubDomain;
+
+	class Mesh {
+		public:
+
+			Geometry & Gh;   // Geometry
+			Mesh & BTh; // Background Mesh Bth==*this =>no  background 
+			long NbRef;      // counter of ref on the this class if 0 we can delete
+			long nbvx,nbtx;  // nombre max  de sommets , de  triangles
+			long nt,nbv,nbt,nbiv,nbe; // nb of legal triangles, nb of vertex, of triangles, of initial vertices, of edges with reference,
+			long NbOfQuad;  // nb of quadrangle 
+			long NbSubDomains;
+			long NbOutT;    // Nb of oudeside triangle
+			long NbOfTriangleSearchFind;
+			long NbOfSwapTriangle;
+			MeshVertex* vertices;
+			long NbVerticesOnGeomVertex;
+			VertexOnGeom * VerticesOnGeomVertex;
+			long NbVerticesOnGeomEdge;
+			VertexOnGeom * VerticesOnGeomEdge;
+			long NbVertexOnBThVertex;
+			VertexOnVertex *VertexOnBThVertex;
+			long NbVertexOnBThEdge;
+			VertexOnEdge *VertexOnBThEdge;
+			long NbCrackedVertices;
+			long* CrackedVertices;
+			long NbCrackedEdges;
+			CrackedEdge* CrackedEdges;
+			R2 pmin,pmax;    // extrema
+			double coefIcoor; // coef to integer Icoor1;
+			Triangle* triangles;
+			Edge* edges; 
+			QuadTree* quadtree;
+			MeshVertex** ordre;
+			SubDomain* subdomains;
+			ListofIntersectionTriangles lIntTria;
+
+			//Constructors/Destructors
+			Mesh(BamgGeom* bamggeom,BamgMesh* bamgmesh,BamgOpts* bamgopts);
+			Mesh(double* index,double* x,double* y,int nods,int nels);
+			Mesh(Mesh &,Geometry * pGh=0,Mesh* pBTh=0,long nbvxx=0 ); //copy operator
+			Mesh(const Mesh &,const int *flag,const int *bb,BamgOpts* bamgopts); // truncature
+			Mesh(long nbvx,Mesh & BT,BamgOpts* bamgopts,int keepBackVertices=1) :Gh(BT.Gh),BTh(BT) {
+				try {GeomToTriangles1(nbvx,bamgopts,keepBackVertices);}
+				catch(...) { this->~Mesh(); throw; }
+			}
+			Mesh(long nbvx,Geometry & G,BamgOpts* bamgopts) :Gh(G),BTh(*this){
+				try { GeomToTriangles0(nbvx,bamgopts);}
+				catch(...) { this->~Mesh(); throw; }
+			}
+			~Mesh(); 
+
+			//Operators
+			const MeshVertex & operator[]  (long i) const { return vertices[i];};
+			MeshVertex & operator[](long i) { return vertices[i];};
+			const Triangle & operator()  (long i) const { return triangles[i];};
+			Triangle & operator()(long i) { return triangles[i];};
+
+			//Methods
+			void SetIntCoor(const char * from =0);
+			double MinimalHmin() {return 2.0/coefIcoor;}
+			double MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);}
+			I2 toI2(const R2 & P) const {
+				return  I2( (Icoor1) (coefIcoor*(P.x-pmin.x))
+							,(Icoor1) (coefIcoor*(P.y-pmin.y)) );}
+			R2 toR2(const I2 & P) const {
+				return  R2( (double) P.x/coefIcoor+pmin.x, (double) P.y/coefIcoor+pmin.y);
+			}
+			void AddVertex(MeshVertex & s,Triangle * t,Icoor2 *  =0) ;
+			void Insert();
+			void ForceBoundary();
+			void FindSubDomain(int OutSide=0);
+			long TriangleReferenceList(long*) const;
+			void TriangleIntNumbering(long* renumbering);
+			void ShowHistogram() const;
+			void CrackMesh(BamgOpts* bamgopts);
+			void ShowRegulaty() const;
+			void SmoothMetric(double raisonmax) ;
+			void BoundAnisotropy(double anisomax,double hminaniso= 1e-100) ;
+			void MaxSubDivision(double maxsubdiv);
+			Edge** MakeGeometricalEdgeToEdge();
+			long SplitInternalEdgeWithBorderVertices();
+			void MakeQuadrangles(double costheta);
+			int  SplitElement(int choice);
+			void MakeQuadTree();
+			void NewPoints(Mesh &,BamgOpts* bamgopts,int KeepVertices=1);
+			long InsertNewPoints(long nbvold,long & NbTSwap) ; 
+			void ReNumberingTheTriangleBySubDomain(bool justcompress=false);
+			void ReNumberingVertex(long * renu);
+			void SmoothingVertex(int =3,double=0.3);
+			Metric MetricAt (const R2 &) const;
+			GeometricalEdge* ProjectOnCurve( Edge & AB, MeshVertex &  A, MeshVertex & B,double theta, MeshVertex & R,VertexOnEdge & BR,VertexOnGeom & GR);
+			long Number(const Triangle & t) const  { return &t - triangles;}
+			long Number(const Triangle * t) const  { return t - triangles;}
+			long Number(const MeshVertex & t) const  { return &t - vertices;}
+			long Number(const MeshVertex * t) const  { return t - vertices;}
+			long Number(const Edge & t) const  { return &t - edges;}
+			long Number(const Edge * t) const  { return t - edges;}
+			long Number2(const Triangle * t) const  { return t - triangles; }
+			MeshVertex* NearestVertex(Icoor1 i,Icoor1 j) ;
+			Triangle* FindTriangleContaining(const I2 & ,Icoor2 [3],Triangle *tstart=0) const;
+			void ReadMesh(double* index,double* x,double* y,int nods,int nels);
+			void ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts);
+			void WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts);
+			void ReadMetric(const BamgOpts* bamgopts);
+			void WriteMetric(BamgOpts* bamgopts);
+			void AddMetric(BamgOpts* bamgopts);
+			void BuildMetric0(BamgOpts* bamgopts);
+			void BuildMetric1(BamgOpts* bamgopts);
+			void AddGeometryMetric(BamgOpts* bamgopts);
+			int  isCracked() const {return NbCrackedVertices != 0;}
+			void BuildGeometryFromMesh(BamgOpts* bamgopts=NULL);
+			void ReconstructExistingMesh();
+
+			//Inline methods
+			inline  void ReMakeTriangleContainingTheVertex(){
+				for (int i=0;i<nbv;i++) vertices[i].vint=0, vertices[i].t=NULL;
+				for (int i=0;i<nbt;i++) triangles[i].SetTriangleContainingTheVertex();
+			}
+			inline  void  UnMarkUnSwapTriangle(){
+				for (int i=0;i<nbt;i++)
+				 for(int j=0;j<3;j++)
+				  triangles[i].SetUnMarkUnSwap(j);
+			  }
+			inline  void  SetVertexFieldOn(){
+				for (int i=0;i<nbv;i++)                    vertices[i].onGeometry=NULL;
+				for (int j=0;j<NbVerticesOnGeomVertex;j++) VerticesOnGeomVertex[j].SetOn();
+				for (int k=0;k<NbVerticesOnGeomEdge;k++ )  VerticesOnGeomEdge[k].SetOn();
+			}	       
+			inline  void   SetVertexFieldOnBTh(){
+				for (int i=0;i<nbv;i++)                 vertices[i].onGeometry=NULL;
+				for (int j=0;j<NbVertexOnBThVertex;j++) VertexOnBThVertex[j].SetOnBTh();
+				for (int k=0;k<NbVertexOnBThEdge;k++ )  VertexOnBThEdge[k].SetOnBTh();
+			}
+
+		private:
+			void GeomToTriangles1(long nbvx,BamgOpts* bamgopts,int KeepVertices=1);// the real constructor mesh adaption
+			void GeomToTriangles0(long nbvx,BamgOpts* bamgopts);// the real constructor mesh generator
+			void PreInit(long);
+
+	};
+
+	/*Intermediary*/
+	TriangleAdjacent CloseBoundaryEdge(I2 ,Triangle *, double &,double &) ;
+	TriangleAdjacent CloseBoundaryEdgeV2(I2 A,Triangle *t, double &a,double &b);
+	void  swap(Triangle *t1,short a1,
+				Triangle *t2,short a2,
+				MeshVertex *s1,MeshVertex *s2,Icoor2 det1,Icoor2 det2);
+	int SwapForForcingEdge(MeshVertex   *  & pva ,MeshVertex  * &   pvb ,
+				TriangleAdjacent & tt1,Icoor2 & dets1,
+				Icoor2 & detsa,Icoor2 & detsb, int & nbswap);
+	int ForceEdge(MeshVertex &a, MeshVertex & b,TriangleAdjacent & taret) ;
+	inline TriangleAdjacent Previous(const TriangleAdjacent & ta){
+		return TriangleAdjacent(ta.t,PreviousEdge[ta.a]);
+	}
+	inline TriangleAdjacent Next(const TriangleAdjacent & ta){
+		return TriangleAdjacent(ta.t,NextEdge[ta.a]);
+	}
+	inline  TriangleAdjacent Adj(const TriangleAdjacent & a){
+		return  a.Adj();
+	}
+	inline void Adj(GeometricalEdge * & on,int &i){
+		int j=i;i=on->DirAdj[i];on=on->Adj[j];
+	}
+	inline double qualite(const MeshVertex &va,const MeshVertex &vb,const MeshVertex &vc){
+		double ret; 
+		I2 ia=va,ib=vb,ic=vc;
+		I2 ab=ib-ia,bc=ic-ib,ac=ic-ia;
+		Icoor2 deta=Det(ab,ac);
+		if (deta <=0) ret = -1;
+		else {
+			double a = sqrt((double) (ac,ac)),
+					 b = sqrt((double) (bc,bc)),
+					 c = sqrt((double) (ab,ab)),
+					 p = a+b+c;
+			double h= Max(Max(a,b),c),ro=deta/p;
+			ret = ro/h;
+		}
+		return ret;
+	}
+
+}
+#endif
Index: /issm/trunk/src/c/objects/Bamg/MeshVertex.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/MeshVertex.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/MeshVertex.cpp	(revision 5095)
@@ -10,5 +10,5 @@
 	/*Methods*/
 	/*FUNCTION MeshVertex::Smoothing{{{1*/
-	double  MeshVertex::Smoothing(Triangles &Th,const Triangles &BTh,Triangle* &tstart ,double omega){
+	double  MeshVertex::Smoothing(Mesh &Th,const Mesh &BTh,Triangle* &tstart ,double omega){
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Smoothing)*/
 
Index: /issm/trunk/src/c/objects/Bamg/MeshVertex.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/MeshVertex.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/MeshVertex.h	(revision 5095)
@@ -11,5 +11,5 @@
 	//classes
 	class Triangle;
-	class Triangles;
+	class Mesh;
 	class VertexOnGeom;
 	class VertexOnEdge;
@@ -28,6 +28,6 @@
 				long      color;
 				MeshVertex*   to;  // used in geometry MeshVertex to know the Mesh MeshVertex associated 
-				VertexOnGeom* onGeometry;        // if vint == 8; // set with Triangles::SetVertexFieldOn()
-				MeshVertex*       onBackgroundVertex;// if vint == 16 on Background vertex Triangles::SetVertexFieldOnBTh()
+				VertexOnGeom* onGeometry;        // if vint == 8; // set with Mesh::SetVertexFieldOn()
+				MeshVertex*       onBackgroundVertex;// if vint == 16 on Background vertex Mesh::SetVertexFieldOnBTh()
 				VertexOnEdge* onBackgroundEdge;  // if vint == 32 on Background edge
 			};
@@ -40,5 +40,5 @@
 
 			//methods (No constructor and no destructors...)
-			double Smoothing(Triangles & ,const Triangles & ,Triangle  * & ,double =1);
+			double Smoothing(Mesh & ,const Mesh & ,Triangle  * & ,double =1);
 			void   MetricFromHessian(const double Hxx,const double Hyx, const double Hyy, const double smin,const double smax,const double s,const double err,BamgOpts* bamgopts);
 			void   Echo();
@@ -47,5 +47,5 @@
 
 			//inline functions
-			inline void Set(const MeshVertex &rec,const Triangles & ,Triangles & ){*this=rec;}
+			inline void Set(const MeshVertex &rec,const Mesh & ,Mesh & ){*this=rec;}
 	};
 
Index: /issm/trunk/src/c/objects/Bamg/QuadTree.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/QuadTree.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/QuadTree.cpp	(revision 5095)
@@ -72,6 +72,6 @@
 
 	/*Constructors/Destructors*/
-	/*FUNCTION QuadTree::QuadTree(Triangles * t,long nbv){{{1*/
-	QuadTree::QuadTree(Triangles * t,long nbv) : 
+	/*FUNCTION QuadTree::QuadTree(Mesh * t,long nbv){{{1*/
+	QuadTree::QuadTree(Mesh * t,long nbv) : 
 		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, QuadTree.cpp/QuadTree)*/
 
Index: /issm/trunk/src/c/objects/Bamg/QuadTree.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/QuadTree.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/QuadTree.h	(revision 5095)
@@ -10,5 +10,5 @@
 	const long MaxISize = ( 1L << MaxDeep); 
 
-	class Triangles;
+	class Mesh;
 	class MeshVertex;
 
@@ -43,8 +43,8 @@
 			//fields
 			QuadTreeBox* root;
-			Triangles*   th;
+			Mesh*   th;
 			//functions
 			~QuadTree();
-			QuadTree(Triangles * t,long nbv=-1);
+			QuadTree(Mesh *t,long nbv=-1);
 			QuadTree();
 			long    NbQuadTreeBox,NbVertices;
Index: /issm/trunk/src/c/objects/Bamg/SubDomain.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/SubDomain.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/SubDomain.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "SubDomain.h"
-#include "Triangles.h"
+#include "Mesh.h"
 
 namespace bamg {
@@ -13,5 +13,5 @@
 	/*Methods*/
 	/*FUNCTION SubDomain::Set {{{1*/
-	void SubDomain::Set(const Triangles & Th ,long i,Triangles & ThNew){
+	void SubDomain::Set(const Mesh & Th ,long i,Mesh & ThNew){
 		*this = Th.subdomains[i];
 		if ( head-Th.triangles<0 || head-Th.triangles>=Th.nbt){
Index: /issm/trunk/src/c/objects/Bamg/SubDomain.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/SubDomain.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/SubDomain.h	(revision 5095)
@@ -9,5 +9,5 @@
 	//classes
 	class Triangle;
-	class Triangles;
+	class Mesh;
 
 	class SubDomain {
@@ -19,5 +19,5 @@
 
 			//Methods
-			void Set(const Triangles &,long,Triangles &);
+			void Set(const Mesh &,long,Mesh &);
 	};
 
Index: /issm/trunk/src/c/objects/Bamg/Triangle.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Triangle.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/Triangle.cpp	(revision 5095)
@@ -9,6 +9,6 @@
 
 	/*Constructors/Destructors*/
-	/*FUNCTION Triangle(Triangles *Th,long i,long j,long k) {{{1*/
-	Triangle::Triangle(Triangles *Th,long i,long j,long k) {
+	/*FUNCTION Triangle(Mesh *Th,long i,long j,long k) {{{1*/
+	Triangle::Triangle(Mesh *Th,long i,long j,long k) {
 		MeshVertex *v=Th->vertices;
 		long nbv = Th->nbv;
@@ -198,5 +198,5 @@
 	/*}}}*/
 	/*FUNCTION Triangle::Set {{{1*/
-	void Triangle::Set(const Triangle & rec,const Triangles & Th ,Triangles & ThNew){ 
+	void Triangle::Set(const Triangle & rec,const Mesh & Th ,Mesh & ThNew){ 
 		*this = rec;
 		if ( TriaVertices[0] ) TriaVertices[0] = ThNew.vertices +  Th.Number(TriaVertices[0]);
Index: /issm/trunk/src/c/objects/Bamg/Triangle.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Triangle.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/Triangle.h	(revision 5095)
@@ -8,5 +8,5 @@
 
 	//classes
-	class Triangles;
+	class Mesh;
 	class MeshVertex;
 	class Triangle;
@@ -30,5 +30,5 @@
 			//Constructors/Destructors
 			Triangle() {}
-			Triangle(Triangles *Th,long i,long j,long k);
+			Triangle(Mesh *Th,long i,long j,long k);
 			Triangle(MeshVertex *v0,MeshVertex *v1,MeshVertex *v2);
 
@@ -117,5 +117,5 @@
 			//Inline methods
 			double qualite() ;
-			void  Set(const Triangle &,const Triangles &,Triangles &);
+			void  Set(const Triangle &,const Mesh &,Mesh &);
 			int   In(MeshVertex *v) const { return TriaVertices[0]==v || TriaVertices[1]==v || TriaVertices[2]==v ;}
 
Index: /issm/trunk/src/c/objects/Bamg/TriangleAdjacent.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/TriangleAdjacent.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/TriangleAdjacent.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "TriangleAdjacent.h"
-#include "Triangles.h"
+#include "Mesh.h"
 
 namespace bamg {
Index: sm/trunk/src/c/objects/Bamg/Triangles.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Triangles.cpp	(revision 5094)
+++ 	(revision )
@@ -1,5868 +1,0 @@
-#include <cstdio>
-#include <cstring>
-#include <cmath>
-#include <ctime>
-
-#include "../objects.h"
-
-namespace bamg {
-
-	static const  Direction NoDirOfSearch=Direction();
-	long NbUnSwap =0;
-
-	/*Constructors/Destructors*/
-	/*FUNCTION Triangles::Triangles(BamgGeom* bamggeom,BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
-	Triangles::Triangles(BamgGeom* bamggeom,BamgMesh* bamgmesh, BamgOpts* bamgopts):Gh(*(new Geometry())),BTh(*this){ 
-
-		/*Initialize fields*/
-		PreInit(0);
-
-		/*Read Geometry if provided*/
-		if(bamggeom->Edges) {
-			Gh.ReadGeometry(bamggeom,bamgopts);
-			Gh.AfterRead();
-		}
-
-		/*Read background mesh*/
-		ReadMesh(bamgmesh,bamgopts);
-
-		/*Build Geometry if not provided*/
-		if(bamggeom->Edges==NULL) {
-			/*Recreate geometry if needed*/
-			printf("WARNING: mesh present but no geometry found. Reconstructing...\n");
-			BuildGeometryFromMesh(bamgopts);
-			Gh.AfterRead();
-		}
-
-		/*Set integer coordinates*/
-		SetIntCoor();
-
-		/*Fill holes and generate mesh properties*/
-		ReconstructExistingMesh();
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Triangles(double* index,double* x,double* y,int nods,int nels){{{1*/
-	Triangles::Triangles(double* index,double* x,double* y,int nods,int nels):Gh(*(new Geometry())),BTh(*this){
-
-		PreInit(0);
-		ReadMesh(index,x,y,nods,nels);
-		SetIntCoor();
-		ReconstructExistingMesh();
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
-	Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb,BamgOpts* bamgopts) : Gh(*(new Geometry())), BTh(*this) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
-
-		  int i,k,itadj;
-		  int kt=0;
-		  int * kk    = new int [Tho.nbv];
-		  long * reft = new long[Tho.nbt];
-		  long nbInT =    Tho.TriangleReferenceList(reft);
-		  long * refv = new long[Tho.nbv];
-
-		  for (i=0;i<Tho.nbv;i++)
-			kk[i]=-1;
-		  for (i=0;i<Tho.nbv;i++)
-			refv[i]=0;
-		  int nbNewBedge =0;
-		  //  int nbOldBedge =0;  
-		  for (i=0;i<Tho.nbt;i++)
-			if(  reft[i] >=0 && flag[i]) 
-			  {
-				const Triangle & t = Tho.triangles[i];
-				kt++;
-				kk[Tho.Number(t[0])]=1;
-				kk[Tho.Number(t[1])]=1;
-				kk[Tho.Number(t[2])]=1;
-				itadj=Tho.Number(t.TriangleAdj(0));
-				if (  reft[itadj] >=0 && !flag[itadj])
-				  { nbNewBedge++;
-					refv[Tho.Number(t[VerticesOfTriangularEdge[0][0]])]=bb[i];
-					refv[Tho.Number(t[VerticesOfTriangularEdge[0][1]])]=bb[i];
-				  }
-				itadj=Tho.Number(t.TriangleAdj(1));
-				if (  reft[itadj] >=0 && !flag[itadj])
-				  { nbNewBedge++;
-					refv[Tho.Number(t[VerticesOfTriangularEdge[1][0]])]=bb[i];
-					refv[Tho.Number(t[VerticesOfTriangularEdge[1][1]])]=bb[i];}
-					itadj=Tho.Number(t.TriangleAdj(2));
-					if (  reft[itadj] >=0 && !flag[itadj])
-					  { nbNewBedge++;
-						refv[Tho.Number(t[VerticesOfTriangularEdge[2][0]])]=bb[i];
-						refv[Tho.Number(t[VerticesOfTriangularEdge[2][1]])]=bb[i];}
-			  }
-		  k=0;
-		  for (i=0;i<Tho.nbv;i++){
-			  if (kk[i]>=0) kk[i]=k++;
-			}
-		  printf("   number of vertices %i, remove = %i\n",k,Tho.nbv - k);
-		  printf("   number of triangles %i, remove = %i\n",kt,nbInT-kt);
-		  printf("   number of New boundary edge %i\n",nbNewBedge);
-		  long inbvx =k;
-		  PreInit(inbvx);
-		  for (i=0;i<Tho.nbv;i++)
-			if (kk[i]>=0) 
-			  {
-				vertices[nbv] = Tho.vertices[i];
-				if (!vertices[nbv].ref())
-				 vertices[nbv].ReferenceNumber = refv[i];
-				nbv++;
-			  }
-		  if (inbvx != nbv){
-			  ISSMERROR("inbvx != nbv");
-		  }
-		  for (i=0;i<Tho.nbt;i++)
-			if(  reft[i] >=0 && flag[i]) 
-			  {
-				const Triangle & t = Tho.triangles[i];
-				int i0 = Tho.Number(t[0]);
-				int i1 = Tho.Number(t[1]);
-				int i2 = Tho.Number(t[2]);
-				if (i0<0 || i1<0 || i2<0){
-					ISSMERROR("i0<0 || i1<0 || i2< 0");
-				}
-				if (i0>=Tho.nbv || i1>=Tho.nbv || i2>=Tho.nbv){
-					ISSMERROR("i0>=Tho.nbv || i1>=Tho.nbv || i2>=Tho.nbv");
-				}
-				triangles[nbt] = Triangle(this,kk[i0],kk[i1],kk[i2]);
-				triangles[nbt].color = Tho.subdomains[reft[i]].ref; 
-				nbt++;           
-			  }
-		  if (kt!=nbt){
-			  ISSMERROR("kt!=nbt");
-		  }
-		  if (nbt==0 && nbv==0) {
-			  ISSMERROR("All triangles have been removed");
-		  }
-		  delete [] kk;
-		  delete [] reft;
-		  delete [] refv;
-		  //double cutoffradian = 10.0/180.0*Pi;
-		  BuildGeometryFromMesh(bamgopts);
-		  Gh.AfterRead(); 
-		  SetIntCoor();
-		  ReconstructExistingMesh();
-
-		  if (!NbSubDomains){
-			  ISSMERROR("NbSubDomains==0");
-		  }
-		  if (!subdomains[0].head || !subdomains[0].head->link){
-			  ISSMERROR("!subdomains[0].head || !subdomains[0].head->link");
-		  }
-
-	  }
-	/*}}}1*/
-	/*FUNCTION Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,long nbvxx) COPY{{{1*/
-	Triangles::Triangles(Triangles & Th,Geometry * pGh,Triangles * pBth,long nbvxx)
-	  : Gh(*(pGh?pGh:&Th.Gh)), BTh(*(pBth?pBth:this)) {
-		  /*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
-		  Gh.NbRef++;
-		  nbvxx = Max(nbvxx,Th.nbv); 
-		  long i;
-		  // do all the allocation to be sure all the pointer existe
-
-		  PreInit(nbvxx);// to make the allocation 
-		  // copy of triangles
-		  nt=Th.nt;
-		  nbv = Th.nbv;
-		  nbt = Th.nbt;
-		  nbiv = Th.nbiv;
-		  nbe = Th.nbe;
-		  NbSubDomains = Th.NbSubDomains;
-		  NbOutT = Th.NbOutT;
-		  NbOfQuad =  Th.NbOfQuad ;
-		  NbOfSwapTriangle =0;
-		  NbVerticesOnGeomVertex = Th.NbVerticesOnGeomVertex;
-		  if(NbVerticesOnGeomVertex)
-			VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
-		  NbVerticesOnGeomEdge = Th.NbVerticesOnGeomEdge;
-		  if (NbVerticesOnGeomEdge)
-			VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge] ;
-		  if (& BTh == & Th.BTh){ // same background 
-			  BTh.NbRef++;
-			  NbVertexOnBThVertex = Th.NbVertexOnBThVertex;
-			  if(NbVertexOnBThVertex)
-				VertexOnBThVertex = new VertexOnVertex[NbVertexOnBThVertex];
-			  NbVertexOnBThEdge = Th.NbVertexOnBThEdge;
-			  if(NbVertexOnBThEdge)
-				VertexOnBThEdge = new VertexOnEdge[NbVertexOnBThEdge];
-			 }
-		  else { // no add on background mesh 
-			  BTh.NbRef++;
-			  NbVertexOnBThVertex=0;
-			  VertexOnBThVertex=0;
-			  NbVertexOnBThEdge=0;
-			  VertexOnBThEdge=0;
-			 }
-
-
-		  if(nbe)
-			edges = new Edge[nbe];
-		  if(NbSubDomains)
-			subdomains = new SubDomain[NbSubDomains];
-		  pmin = Th.pmin;
-		  pmax = Th.pmax;
-		  coefIcoor = Th.coefIcoor;
-		  for(i=0;i<nbt;i++)
-			triangles[i].Set(Th.triangles[i],Th,*this);
-		  for(i=0;i<nbe;i++)
-			edges[i].Set(Th,i,*this);
-		  for(i=0;i<nbv;i++)
-			vertices[i].Set(Th.vertices[i],Th,*this);
-		  for(i=0;i<NbSubDomains;i++)  
-			subdomains[i].Set(Th,i,*this);
-		  for (i=0;i<NbVerticesOnGeomVertex;i++)
-			VerticesOnGeomVertex[i].Set(Th.VerticesOnGeomVertex[i],Th,*this);
-		  for (i=0;i<NbVerticesOnGeomEdge;i++)
-			VerticesOnGeomEdge[i].Set(Th.VerticesOnGeomEdge[i],Th,*this);
-		  quadtree=0;
-
-	  }
-	/*}}}1*/
-	/*FUNCTION Triangles::~Triangles(){{{1*/
-	Triangles::~Triangles() {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Triangles)*/
-
-		long int verbose=2;
-		//if(vertices)  delete [] vertices; //TEST  crash if not commented
-		if(edges)     delete [] edges;
-		if(triangles) delete [] triangles;
-		if(quadtree)  delete quadtree;
-		//if(ordre)     delete [] ordre; //TEST  crash if not commented
-		if( subdomains) delete []  subdomains;
-		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
-		if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
-		if (VertexOnBThVertex) delete [] VertexOnBThVertex;
-		if (VertexOnBThEdge) delete [] VertexOnBThEdge;
-
-		if (&Gh) {
-			if (Gh.NbRef>0) Gh.NbRef--;
-			else if (Gh.NbRef==0) delete &Gh;
-		}
-		if (&BTh && (&BTh != this)) {
-			if (BTh.NbRef>0) BTh.NbRef--;
-			else if (BTh.NbRef==0) delete &BTh;
-		}
-		PreInit(0); // set all to zero 
-	}
-	/*}}}1*/
-
-	/*IO*/
-	/*FUNCTION Triangles::ReadMesh(double* index,double* x,double* y,int nods,int nels){{{1*/
-	void Triangles::ReadMesh(double* index,double* x,double* y,int nods,int nels){
-
-		double Hmin = HUGE_VAL;// the infinie value 
-		long i1,i2,i3,iref;
-		long i,j;
-		Metric M1(1);
-		int verbose=0;
-
-		nbv=nods;
-		nbvx=nbv;
-		nbt=nels;
-		nbiv=nbvx;
-
-		//Vertices
-		if (verbose) printf("Reading vertices (%i)\n",nbv);
-		vertices=(MeshVertex*)xmalloc(nbv*sizeof(MeshVertex));
-		ordre=(MeshVertex**)xmalloc(nbv*sizeof(MeshVertex*));
-		for (i=0;i<nbv;i++){
-			vertices[i].r.x=x[i];
-			vertices[i].r.y=y[i];
-			vertices[i].ReferenceNumber=1;
-			vertices[i].DirOfSearch =NoDirOfSearch;
-			vertices[i].m=M1;
-			vertices[i].color=0;
-		}
-		nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
-
-		//Triangles
-		if (verbose) printf("Reading triangles (%i)\n",nbt);
-		triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
-		//other triangles will be added for each edge
-		for (i=0;i<nbt;i++){
-			Triangle & t = triangles[i];
-			i1=(long)index[i*3+0]-1; //for C indexing
-			i2=(long)index[i*3+1]-1; //for C indexing
-			i3=(long)index[i*3+2]-1; //for C indexing
-			t=Triangle(this,i1,i2,i3);
-			t.color=1;
-		}
-
-		/*Recreate geometry: */
-		if (verbose) printf("Building Geometry\n");
-		BuildGeometryFromMesh();
-		if (verbose) printf("Completing geometry\n");
-		Gh.AfterRead();
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){{{1*/
-	void Triangles::ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts){
-
-		int verbose;
-		double Hmin = HUGE_VAL;// the infinie value 
-		long i1,i2,i3,iref;
-		long i,j;
-		long ifgeom=0;
-		Metric M1(1);
-
-		verbose=bamgopts->verbose;
-
-		nbv=bamgmesh->VerticesSize[0];
-		nbvx=nbv;
-		nbt=bamgmesh->TrianglesSize[0];
-		nbiv=nbvx;
-
-		//Vertices
-		if(bamgmesh->Vertices){
-			if(verbose>5) printf("      processing Vertices\n");
-
-			vertices=(MeshVertex*)xmalloc(nbv*sizeof(MeshVertex));
-			ordre=(MeshVertex**)xmalloc(nbv*sizeof(MeshVertex*));
-
-			for (i=0;i<nbv;i++){
-				vertices[i].r.x=bamgmesh->Vertices[i*3+0];
-				vertices[i].r.y=bamgmesh->Vertices[i*3+1];
-				vertices[i].ReferenceNumber=(long)bamgmesh->Vertices[i*3+2];
-				vertices[i].DirOfSearch =NoDirOfSearch;
-				vertices[i].m=M1;
-				vertices[i].color=0;
-			}
-			nbtx=2*nbvx-2; // for filling The Holes and quadrilaterals 
-		}
-		else{
-			if(verbose>5) ISSMERROR("no Vertices found in the initial mesh");
-		}
-
-		//Triangles
-		if(bamgmesh->Triangles){
-			if(verbose>5) printf("      processing Triangles\n");
-			triangles =new Triangle[nbtx]; //we cannot allocate only nbt triangles since 
-			//other triangles will be added for each edge
-			for (i=0;i<nbt;i++){
-				Triangle & t = triangles[i];
-				i1=(long)bamgmesh->Triangles[i*4+0]-1; //for C indexing
-				i2=(long)bamgmesh->Triangles[i*4+1]-1; //for C indexing
-				i3=(long)bamgmesh->Triangles[i*4+2]-1; //for C indexing
-				t=Triangle(this,i1,i2,i3);
-				t.color=(long)bamgmesh->Triangles[i*4+3];
-			}
-		}
-		else{
-			if(verbose>5) ISSMERROR("no Triangles found in the initial mesh");
-		}
-
-		//Quadrilaterals
-		if(bamgmesh->Quadrilaterals){
-			if(verbose>5) printf("      processing Quadrilaterals\n");
-			long i1,i2,i3,i4,iref;
-			triangles =new Triangle[nbt];
-			for (i=0;i<bamgmesh->QuadrilateralsSize[0];i++){
-				//divide the quad into two triangles
-				Triangle & t1 = triangles[2*i];
-				Triangle & t2 = triangles[2*i+1];
-				i1=(long)bamgmesh->Quadrilaterals[i*5+0]-1; //for C indexing
-				i2=(long)bamgmesh->Quadrilaterals[i*5+1]-1; //for C indexing
-				i3=(long)bamgmesh->Quadrilaterals[i*5+2]-1; //for C indexing
-				i4=(long)bamgmesh->Quadrilaterals[i*5+3]-1; //for C indexing
-				t1=Triangle(this,i1,i2,i3);
-				t2=Triangle(this,i3,i4,i1);
-				t1.color=(long)bamgmesh->Quadrilaterals[i*5+4];
-				t2.color=(long)bamgmesh->Quadrilaterals[i*5+4];
-				t1.SetHidden(OppositeEdge[1]); // two times  because the adj was not created 
-				t2.SetHidden(OppositeEdge[1]); 
-			}
-		}
-
-		//VerticesOnGeometricEdge
-		if(bamgmesh->VerticesOnGeometricEdge){
-			if(verbose>5) printf("      processing VerticesOnGeometricEdge\n");
-			NbVerticesOnGeomEdge=bamgmesh->VerticesOnGeometricEdgeSize[0];
-			VerticesOnGeomEdge= new  VertexOnGeom[NbVerticesOnGeomEdge] ;
-			for (i=0;i<NbVerticesOnGeomEdge;i++){
-				long  i1,i2;
-				double s;
-				i1=(long)  bamgmesh->VerticesOnGeometricEdge[i*3+0]-1; //for C indexing
-				i2=(long)  bamgmesh->VerticesOnGeometricEdge[i*3+1]-1; //for C indexing
-				s =(double)bamgmesh->VerticesOnGeometricEdge[i*3+2];
-				VerticesOnGeomEdge[i]=VertexOnGeom(vertices[i1],Gh.edges[i2],s);
-			}
-		}
-
-		//VerticesOnGeometricVertex
-		if(bamgmesh->VerticesOnGeometricVertexSize[0]){
-			if(verbose>5) printf("      processing VerticesOnGeometricVertex\n");
-			NbVerticesOnGeomVertex=bamgmesh->VerticesOnGeometricVertexSize[0];
-			VerticesOnGeomVertex  = new  VertexOnGeom[NbVerticesOnGeomVertex] ;
-			for (i=0;i<NbVerticesOnGeomVertex;i++){
-				long  i1,i2;
-				i1=(long)bamgmesh->VerticesOnGeometricVertex[i*2+0]-1; //for C indexing
-				i2=(long)bamgmesh->VerticesOnGeometricVertex[i*2+1]-1; //for C indexing
-				VerticesOnGeomVertex[i]=VertexOnGeom(vertices[i1],Gh.vertices[i2]);
-			}
-		}
-
-		//Edges
-		if (bamgmesh->Edges){
-			int i1,i2;
-			double* len=NULL;
-
-			if(verbose>5) printf("      processing Edges\n");
-			nbe=bamgmesh->EdgesSize[0];
-			edges= new Edge[nbe];
-			//initialize length of each edge (used to provided metric)
-			len= new double[nbv];
-			for(i=0;i<nbv;i++) len[i]=0;
-
-			for (i=0;i<nbe;i++){
-				i1=(int)bamgmesh->Edges[i*3+0]-1; //-1 for C indexing
-				i2=(int)bamgmesh->Edges[i*3+1]-1; //-1 for C indexing
-				edges[i].ref=(long)bamgmesh->Edges[i*3+2];
-				edges[i].v[0]= vertices +i1;
-				edges[i].v[1]= vertices +i2;
-				edges[i].adj[0]=NULL;
-				edges[i].adj[1]=NULL;
-				R2 x12=vertices[i2].r-vertices[i1].r;
-				double l12=sqrt((x12,x12));
-
-				//prepare metric
-				vertices[i1].color++;
-				vertices[i2].color++;
-				len[i1]+=l12;
-				len[i2]+=l12;
-				Hmin = Min(Hmin,l12);
-			}
-
-			// definition  the default of the given mesh size 
-			for (i=0;i<nbv;i++){
-				if (vertices[i].color>0) 
-				 vertices[i].m=Metric(len[i]/(double)vertices[i].color);
-				else 
-				 vertices[i].m=Metric(Hmin);
-			}
-			delete [] len;
-
-			// construction of edges[].adj 
-			for (i=0;i<nbv;i++){ 
-				vertices[i].color=(vertices[i].color ==2) ?-1:-2;
-			}
-			for (i=0;i<nbe;i++){
-				for (j=0;j<2;j++) { 
-					MeshVertex *v=edges[i].v[j];
-					long i0=v->color,j0;
-					if(i0==-1){
-						v->color=i*2+j;
-					}
-					else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
-						j0 = i0%2;
-						i0 = i0/2;
-						ISSMASSERT(v==edges[i0 ].v[j0]);
-						edges[i ].adj[j ] =edges +i0;
-						edges[i0].adj[j0] =edges +i ;
-						v->color = -3;
-					}
-				}
-			}
-		}
-
-		//EdgeOnGeometricEdge
-		if(bamgmesh->EdgesOnGeometricEdge){
-			if(verbose>5) printf("      processing EdgesOnGeometricEdge\n");
-			int i1,i2,i,j;
-			i2=bamgmesh->EdgesOnGeometricEdgeSize[0];
-			for (i1=0;i1<i2;i1++) {
-				i=(int)bamgmesh->EdgesOnGeometricEdge[i1*2+0]-1; //C indexing
-				j=(int)bamgmesh->EdgesOnGeometricEdge[i1*2+1]-1; //C indexing
-				//Check value
-				if(!(i>=0 && j>=0 && i<nbe && j<Gh.nbe)) {
-					ISSMERROR("ReadMesh error: EdgesOnGeometricEdge edge provided (line %i: [%i %i]) is incorrect (must be positive, [0<i<nbe=%i 0<j<Gh.nbe=%i]",i1+1,i+1,j+1,nbe,Gh.nbe);
-				}
-				edges[i].onGeometry=Gh.edges+j;
-			}
-		}
-
-		//hVertices
-		if(bamgmesh->hVertices){
-			if(verbose>5) printf("      processing hVertices\n");
-			for (i=0;i< nbv;i++){
-				if (!isnan(bamgmesh->hVertices[i])){
-					vertices[i].m=Metric((double)bamgmesh->hVertices[i]);
-				}
-			}
-		}
-
-		//SubDomain
-		if(bamgmesh->SubDomains){
-			long i3,head,sens;
-			if(verbose>5) printf("      processing SubDomains\n");
-			NbSubDomains=bamgmesh->SubDomainsSize[0];
-			subdomains = new SubDomain [ NbSubDomains ];
-			for (i=0;i<NbSubDomains;i++) {
-				i3  =(int)bamgmesh->SubDomains[i*3+0];
-				head=(int)bamgmesh->SubDomains[i*3+1]-1;//C indexing
-				sens=(int)bamgmesh->SubDomains[i*3+2];
-				if (i3!=23) ISSMERROR("Bad Subdomain definition: first number should be 3");
-				if (head<0 || head>=nbt) ISSMERROR("Bad Subdomain definition: head should in [1 %i] (triangle number)",nbt);
-				subdomains[i].head = triangles+head;
-			}
-		}
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::WriteMesh {{{1*/
-	void Triangles::WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts){
-
-		/*Intermediary*/
-		int i,j,k,num,i1,i2;
-		long n;
-		int* head_1=NULL;
-		int* next_1=NULL;
-		int* connectivitysize_1=NULL;
-		int  connectivitymax_1=0;
-
-		/*Get options*/
-		int verbose=bamgopts->verbose;
-
-		/*Initialize output*/
-		BamgMeshInit(bamgmesh);
-
-		/*Build reft that holds the number the subdomain number of each triangle, and the real numbering of the elements*/
-		long* reft = new long[nbt];
-		long* numt = new long[nbt];
-		long nbInT = TriangleReferenceList(reft);
-		TriangleIntNumbering(numt);
-
-		/*Chaining algorithm used to generate connectivity tables and other outputs*/
-
-		//Memory Allocation
-		head_1=(int*)xmalloc(nbv*sizeof(int));
-		next_1=(int*)xmalloc(3*nbt*sizeof(int));
-		connectivitysize_1=(int*)xmalloc(nbv*sizeof(int));
-
-		//Initialization
-		for (i=0;i<nbv;i++) head_1[i]=-1;
-		for (i=0;i<nbv;i++) connectivitysize_1[i]=0;
-		k=0;
-		//Chains generation
-		for (i=0;i<nbt;i++) {
-			//Do not take into account outside triangles (reft<0)
-			if (reft[i]>=0){
-				for (j=0;j<3;j++){
-					int v=Number(triangles[i][j]); //jth vertex of the ith triangle
-					if (k>3*nbt-1 || k<0) ISSMERROR("k = %i, nbt = %i",k,nbt);
-					next_1[k]=head_1[v];
-					if (v>nbv-1 || v<0)   ISSMERROR("v = %i, nbv = %i",v,nbv);
-					head_1[v]=k++;
-					connectivitysize_1[v]+=1;
-				}
-			}
-		}
-		//Get maximum connectivity
-		connectivitymax_1=0;
-		for (i=0;i<nbv;i++){
-			if (connectivitysize_1[i]>connectivitymax_1) connectivitymax_1=connectivitysize_1[i];
-		}
-
-		/*OK, now build outputs*/
-
-		/*Vertices*/
-		if(verbose>5) printf("      writing Vertices\n");
-		bamgmesh->VerticesSize[0]=nbv;
-		bamgmesh->VerticesSize[1]=3;
-		if (nbv){
-			bamgmesh->Vertices=(double*)xmalloc(3*nbv*sizeof(double));
-			for (i=0;i<nbv;i++){
-				bamgmesh->Vertices[i*3+0]=vertices[i].r.x;
-				bamgmesh->Vertices[i*3+1]=vertices[i].r.y;
-				bamgmesh->Vertices[i*3+2]=vertices[i].ref();
-			}
-		}
-
-		/*Edges*/
-		if(verbose>5) printf("      writing Edges\n");
-		bamgmesh->EdgesSize[0]=nbe;
-		bamgmesh->EdgesSize[1]=3;
-		int NumIssmSegments=0;
-		if (nbe){
-			bamgmesh->Edges=(double*)xmalloc(3*nbe*sizeof(double));
-			for (i=0;i<nbe;i++){
-				bamgmesh->Edges[i*3+0]=Number(edges[i][0])+1; //back to M indexing
-				bamgmesh->Edges[i*3+1]=Number(edges[i][1])+1; //back to M indexing
-				bamgmesh->Edges[i*3+2]=edges[i].ref;
-				if(edges[i].onGeometry){
-					NumIssmSegments++;
-				}
-			}
-		}
-
-		/*Element edges*/
-		if(verbose>5) printf("      writing element edges\n");
-		SetOfEdges4* edge4=new SetOfEdges4(nbt*3,nbv);
-		double* elemedge=NULL;
-		elemedge=(double*)xmalloc(3*nbt*sizeof(double));
-		for (i=0;i<3*nbt;i++) elemedge[i]=NAN;
-		k=0;
-		for (i=0;i<nbt;i++){
-			//Do not take into account outside triangles (reft<0)
-			if (reft[i]>=0){
-				for  (j=0;j<3;j++) {
-					i1=Number(triangles[i][VerticesOfTriangularEdge[j][0]]);
-					i2=Number(triangles[i][VerticesOfTriangularEdge[j][1]]);
-					n =edge4->SortAndFind(i1,i2);
-					if (n==-1){
-						//first time
-						n=edge4->SortAndAdd(i1,i2);
-						elemedge[n*2+0]=double(k);
-					}
-					else{
-						//second time
-						elemedge[n*2+1]=double(k);
-					}
-				}
-				k++;
-			}
-		}
-		bamgmesh->IssmEdgesSize[0]=edge4->nb();
-		bamgmesh->IssmEdgesSize[1]=4;
-		bamgmesh->IssmEdges=(double*)xmalloc(4*edge4->nb()*sizeof(double));
-		for (i=0;i<edge4->nb();i++){
-			/*Invert first two vertices if necessary*/
-			bool found=false;
-			for (j=0;j<3;j++){
-				if (triangles[(int)elemedge[2*i+0]](j)==vertices+edge4->i(i)){
-					if (triangles[(int)elemedge[2*i+0]]((j+1)%3)==vertices+edge4->j(i)){
-						//trigonometric direction
-						bamgmesh->IssmEdges[i*4+0]=edge4->i(i)+1;// back to M indexing
-						bamgmesh->IssmEdges[i*4+1]=edge4->j(i)+1;// back to M indexing
-					}
-					else{
-						bamgmesh->IssmEdges[i*4+0]=edge4->j(i)+1;// back to M indexing
-						bamgmesh->IssmEdges[i*4+1]=edge4->i(i)+1;// back to M indexing
-					}
-					found=true;
-					break;
-				}
-			}
-			ISSMASSERT(found);
-			bamgmesh->IssmEdges[i*4+2]=elemedge[2*i+0]+1; // back to M indexing
-			bamgmesh->IssmEdges[i*4+3]=elemedge[2*i+1]+1; // back to M indexing
-		}
-		//clean up
-		delete edge4;
-		xfree((void**)&elemedge);
-
-		/*IssmSegments*/
-		if(verbose>5) printf("      writing IssmSegments\n");
-		bamgmesh->IssmSegmentsSize[0]=NumIssmSegments;
-		bamgmesh->IssmSegmentsSize[1]=4;
-		bamgmesh->IssmSegments=(double*)xmalloc(4*NumIssmSegments*sizeof(double));
-		num=0;
-		for (i=0;i<nbe;i++){
-			if(edges[i].onGeometry){
-				//build segment
-				int i1=Number(edges[i][0]);
-				int i2=Number(edges[i][1]);
-				bool stop=false;
-				for(j=head_1[i1];j!=-1;j=next_1[j]){
-					for(k=0;k<3;k++){
-						if (Number(triangles[(int)j/3][k])==i1){
-							if (Number(triangles[(int)j/3][(int)((k+1)%3)])==i2){
-								bamgmesh->IssmSegments[num*4+0]=Number(edges[i][0])+1; //back to M indexing
-								bamgmesh->IssmSegments[num*4+1]=Number(edges[i][1])+1; //back to M indexing
-								bamgmesh->IssmSegments[num*4+2]=(int)j/3+1;            //back to M indexing
-								bamgmesh->IssmSegments[num*4+3]=edges[i].ref;
-								num+=1;
-								stop=true;
-								break;
-							}
-							if (Number(triangles[(int)j/3][(int)((k+2)%3)])==i2){
-								bamgmesh->IssmSegments[num*4+0]=Number(edges[i][1])+1; //back to M indexing
-								bamgmesh->IssmSegments[num*4+1]=Number(edges[i][0])+1; //back to M indexing
-								bamgmesh->IssmSegments[num*4+2]=(int)j/3+1;            //back to M indexing
-								bamgmesh->IssmSegments[num*4+3]=edges[i].ref;
-								num+=1;
-								stop=true;
-								break;
-							}
-						}
-					}
-					if(stop) break;
-				}
-				if (!stop){
-					ISSMERROR("Element holding segment [%i %i] not found...",i1+1,i2+1);
-				}
-			}
-		}
-
-		/*Triangles*/
-		if(verbose>5) printf("      writing Triangles\n");
-		k=nbInT-NbOfQuad*2;
-		num=0;
-		bamgmesh->TrianglesSize[0]=k;
-		bamgmesh->TrianglesSize[1]=4;
-		if (k){
-			bamgmesh->Triangles=(double*)xmalloc(4*k*sizeof(double));
-			for (i=0;i<nbt;i++){
-				Triangle &t=triangles[i];
-				//reft[i]=-1 for outside triangle
-				if (reft[i]>=0 && !( t.Hidden(0) || t.Hidden(1) || t.Hidden(2) )){
-					bamgmesh->Triangles[num*4+0]=Number(t[0])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+1]=Number(t[1])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+2]=Number(t[2])+1; //back to M indexing
-					bamgmesh->Triangles[num*4+3]=subdomains[reft[i]].ref;
-					num=num+1;
-				}
-			}
-		}
-
-		/*Quadrilaterals*/
-		if(verbose>5) printf("      writing Quadrilaterals\n");
-		bamgmesh->QuadrilateralsSize[0]=NbOfQuad;
-		bamgmesh->QuadrilateralsSize[1]=5;
-		if (NbOfQuad){
-			bamgmesh->Quadrilaterals=(double*)xmalloc(5*NbOfQuad*sizeof(double));
-			for (i=0;i<nbt;i++){
-				Triangle &t =triangles[i];
-				Triangle* ta;
-				MeshVertex *v0,*v1,*v2,*v3;
-				if (reft[i]<0) continue;
-				if ((ta=t.Quadrangle(v0,v1,v2,v3)) !=0 && &t<ta) { 
-					bamgmesh->Quadrilaterals[i*5+0]=Number(v0)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+1]=Number(v1)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+2]=Number(v2)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+3]=Number(v3)+1; //back to M indexing
-					bamgmesh->Quadrilaterals[i*5+4]=subdomains[reft[i]].ref;
-				}
-			}
-		}
-
-		/*SubDomains*/
-		if(verbose>5) printf("      writing SubDomains\n");
-		bamgmesh->SubDomainsSize[0]=NbSubDomains;
-		bamgmesh->SubDomainsSize[1]=4;
-		if (NbSubDomains){
-			bamgmesh->SubDomains=(double*)xmalloc(4*NbSubDomains*sizeof(double));
-			for (i=0;i<NbSubDomains;i++){
-				bamgmesh->SubDomains[i*4+0]=3;
-				bamgmesh->SubDomains[i*4+1]=reft[Number(subdomains[i].head)];
-				bamgmesh->SubDomains[i*4+2]=1;
-				bamgmesh->SubDomains[i*4+3]=subdomains[i].ref;
-			}
-		}
-
-		/*SubDomainsFromGeom*/
-		if(verbose>5) printf("      writing SubDomainsFromGeom\n");
-		bamgmesh->SubDomainsFromGeomSize[0]=Gh.NbSubDomains;
-		bamgmesh->SubDomainsFromGeomSize[1]=4;
-		if (Gh.NbSubDomains){
-			bamgmesh->SubDomainsFromGeom=(double*)xmalloc(4*Gh.NbSubDomains*sizeof(double));
-			for (i=0;i<Gh.NbSubDomains;i++){
-				bamgmesh->SubDomainsFromGeom[i*4+0]=2;
-				bamgmesh->SubDomainsFromGeom[i*4+1]=Number(subdomains[i].edge)+1; //back to Matlab indexing
-				bamgmesh->SubDomainsFromGeom[i*4+2]=subdomains[i].sens;
-				bamgmesh->SubDomainsFromGeom[i*4+3]=Gh.subdomains[i].ref;
-			}
-		}
-
-		/*VerticesOnGeomVertex*/
-		if(verbose>5) printf("      writing VerticesOnGeometricVertex\n");
-		bamgmesh->VerticesOnGeometricVertexSize[0]=NbVerticesOnGeomVertex;
-		bamgmesh->VerticesOnGeometricVertexSize[1]=2;
-		if (NbVerticesOnGeomVertex){
-			bamgmesh->VerticesOnGeometricVertex=(double*)xmalloc(2*NbVerticesOnGeomVertex*sizeof(double));
-			for (i=0;i<NbVerticesOnGeomVertex;i++){
-				VertexOnGeom &v=VerticesOnGeomVertex[i];
-				ISSMASSERT(v.OnGeomVertex());
-				bamgmesh->VerticesOnGeometricVertex[i*2+0]=Number((MeshVertex*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricVertex[i*2+1]=Gh.Number((GeometricalVertex*)v)+1; //back to Matlab indexing
-			}
-		}
-
-		/*VertexOnGeometricEdge*/
-		if(verbose>5) printf("      writing VerticesOnGeometricEdge\n");
-		bamgmesh->VerticesOnGeometricEdgeSize[0]=NbVerticesOnGeomEdge;
-		bamgmesh->VerticesOnGeometricEdgeSize[1]=3;
-		if (NbVerticesOnGeomEdge){
-			bamgmesh->VerticesOnGeometricEdge=(double*)xmalloc(3*NbVerticesOnGeomEdge*sizeof(double));
-			for (i=0;i<NbVerticesOnGeomEdge;i++){
-				const VertexOnGeom &v=VerticesOnGeomEdge[i];
-				if (!v.OnGeomEdge()){
-					ISSMERROR("A vertices supposed to be OnGeometricEdge is actually not");
-				}
-				bamgmesh->VerticesOnGeometricEdge[i*3+0]=Number((MeshVertex*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricEdge[i*3+1]=Gh.Number((const GeometricalEdge*)v)+1; //back to Matlab indexing
-				bamgmesh->VerticesOnGeometricEdge[i*3+2]=(double)v; //absisce
-			}
-		}
-
-		/*EdgesOnGeometricEdge*/
-		if(verbose>5) printf("      writing EdgesOnGeometricEdge\n");
-		k=0;
-		for (i=0;i<nbe;i++){
-			if (edges[i].onGeometry) k=k+1;
-		}
-		bamgmesh->EdgesOnGeometricEdgeSize[0]=k;
-		bamgmesh->EdgesOnGeometricEdgeSize[1]=2;
-		if (k){
-			bamgmesh->EdgesOnGeometricEdge=(double*)xmalloc(2*(int)k*sizeof(double));
-			int count=0;
-			for (i=0;i<nbe;i++){
-				if (edges[i].onGeometry){
-					bamgmesh->EdgesOnGeometricEdge[count*2+0]=(double)i+1; //back to Matlab indexing
-					bamgmesh->EdgesOnGeometricEdge[count*2+1]=(double)Gh.Number(edges[i].onGeometry)+1; //back to Matlab indexing
-					count=count+1;
-				}
-			}
-		}
-
-		/*Element Connectivity*/
-		if(verbose>5) printf("      writing Element connectivity\n");
-		bamgmesh->ElementConnectivitySize[0]=nbt-NbOutT;
-		bamgmesh->ElementConnectivitySize[1]=3;
-		bamgmesh->ElementConnectivity=(double*)xmalloc(3*(nbt-NbOutT)*sizeof(double));
-		for (i=0;i<3*(nbt-NbOutT);i++) bamgmesh->ElementConnectivity[i]=NAN;
-		num=0;
-		for (i=0;i<nbt;i++){
-			if (reft[i]>=0){
-				for (j=0;j<3;j++){
-					k=Number(triangles[i].TriangleAdj(j));
-					if (reft[k]>=0){
-						ISSMASSERT(3*num+j<3*(nbt-NbOutT));
-						bamgmesh->ElementConnectivity[3*num+j]=k+1; // back to Matlab indexing
-					}
-				}
-				num+=1;
-			}
-		}
-
-		/*ElementNodal Connectivity*/
-		if(verbose>5) printf("      writing Nodal element connectivity\n");
-		bamgmesh->NodalElementConnectivitySize[0]=nbv;
-		bamgmesh->NodalElementConnectivitySize[1]=connectivitymax_1;
-		bamgmesh->NodalElementConnectivity=(double*)xmalloc(connectivitymax_1*nbv*sizeof(double));
-		for (i=0;i<connectivitymax_1*nbv;i++) bamgmesh->NodalElementConnectivity[i]=NAN;
-		for (i=0;i<nbv;i++){
-			k=0;
-			for(j=head_1[i];j!=-1;j=next_1[j]){
-				ISSMASSERT(connectivitymax_1*i+k < connectivitymax_1*nbv);
-				bamgmesh->NodalElementConnectivity[connectivitymax_1*i+k]=floor(j/3)+1;
-				k++;
-			}
-		}
-
-		/*Nodal Connectivity*/
-		if(verbose>5) printf("      writing Nodal connectivity\n");
-		//chaining algorithm (again...)
-		int* head_2=NULL;
-		int* next_2=NULL;
-		int* connectivitysize_2=NULL;
-		int  connectivitymax_2=0;
-		i1=bamgmesh->IssmEdgesSize[0];
-		i2=bamgmesh->IssmEdgesSize[1];
-		head_2=(int*)xmalloc(nbv*sizeof(int));
-		next_2=(int*)xmalloc(2*i1*sizeof(int));
-		connectivitysize_2=(int*)xmalloc(nbv*sizeof(int));
-		//Initialization
-		for (i=0;i<nbv;i++) head_2[i]=-1;
-		for (i=0;i<nbv;i++) connectivitysize_2[i]=0;
-		k=0;
-		//Chains generation
-		for (i=0;i<i1;i++) {
-			for (j=0;j<2;j++){
-				int v=(int)bamgmesh->IssmEdges[i*i2+j]-1; //back to C indexing
-				if (k>2*i1-1 || k<0) ISSMERROR("Index exceed matrix dimensions (k=%i not in [0 %i]",k,2*i1-1);
-				next_2[k]=head_2[v];
-				if (v>nbv-1 || v<0)   ISSMERROR("Index exceed matrix dimensions (v=%i not in [0 %i])",v,nbv-1);
-				head_2[v]=k++;
-				connectivitysize_2[v]+=1;
-			}
-		}
-		//Get maximum connectivity
-		for (i=0;i<nbv;i++){
-			if (connectivitysize_2[i]>connectivitymax_2) connectivitymax_2=connectivitysize_2[i];
-		}
-		//Build output
-		bamgmesh->NodalConnectivitySize[0]=nbv;
-		bamgmesh->NodalConnectivitySize[1]=connectivitymax_2;
-		bamgmesh->NodalConnectivity=(double*)xmalloc(connectivitymax_2*nbv*sizeof(double));
-		for (i=0;i<connectivitymax_2*nbv;i++) bamgmesh->NodalConnectivity[i]=NAN;
-		for (i=0;i<nbv;i++){
-			k=0;
-			for(j=head_2[i];j!=-1;j=next_2[j]){
-				ISSMASSERT(connectivitymax_2*i+k < connectivitymax_2*nbv);
-				num=(int)bamgmesh->IssmEdges[int(j/2)*i2+0];
-				if (i+1==num){ //carefull, ElementEdge is in M indexing
-					//i is the first vertex of the edge, it is therefore connected to the second vertex
-					bamgmesh->NodalConnectivity[connectivitymax_2*i+k]=bamgmesh->IssmEdges[int(j/2)*i2+1];
-				}
-				else{
-					bamgmesh->NodalConnectivity[connectivitymax_2*i+k]=num;
-				}
-				k++;
-			}
-		}
-
-		/*Cracked vertices*/
-		if(verbose>5) printf("      writing Cracked vertices\n");
-		bamgmesh->CrackedVerticesSize[0]=NbCrackedVertices;
-		bamgmesh->CrackedVerticesSize[1]=2;
-		if (NbCrackedVertices){
-			bamgmesh->CrackedVertices=(double*)xmalloc(2*NbCrackedVertices*sizeof(double));
-			for (i=0;i<NbCrackedVertices;i++){
-				bamgmesh->CrackedVertices[i*2+0]=CrackedVertices[i*2+0]+1; //M indexing
-				bamgmesh->CrackedVertices[i*2+1]=CrackedVertices[i*2+1]+1; //M indexing
-			}
-		}
-
-		/*Cracked vertices*/
-		if(verbose>5) printf("      writing Cracked vertices\n");
-		bamgmesh->CrackedEdgesSize[0]=NbCrackedEdges;
-		bamgmesh->CrackedEdgesSize[1]=4;
-		if (NbCrackedEdges){
-			bamgmesh->CrackedEdges=(double*)xmalloc(2*NbCrackedEdges*sizeof(double));
-			for (i=0;i<NbCrackedEdges;i++){
-				bamgmesh->CrackedEdges[i*2+0]=0;//CrackedEdges[i]->+1; //M indexing
-				bamgmesh->CrackedEdges[i*2+1]=0;//CrackedEdges[i]-]->+1; //M indexing
-			}
-		}
-
-		//clean up
-		xfree((void**)&connectivitysize_1);
-		xfree((void**)&head_1);
-		xfree((void**)&next_1);
-		xfree((void**)&connectivitysize_2);
-		xfree((void**)&head_2);
-		xfree((void**)&next_2);
-		delete [] reft;
-		delete [] numt;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReadMetric{{{1*/
-	void Triangles::ReadMetric(const BamgOpts* bamgopts) {
-
-		/*Intermediary*/
-		int  i,j;
-
-		if(bamgopts->verbose>3) printf("      processing metric\n");
-		double hmin = Max(bamgopts->hmin,MinimalHmin());
-		double hmax = Min(bamgopts->hmax,MaximalHmax());
-		double coef = bamgopts->coeff;
-
-		//for now we only use j==3
-		j=3;
-
-		for (i=0;i<nbv;i++){
-			double h;
-			if (j == 1){
-				h=bamgopts->metric[i];
-				vertices[i].m=Metric(Max(hmin,Min(hmax, h*coef)));
-			}
-			else if (j==3){
-				//do not erase metric computed by hVertices
-				if (vertices[i].m.a11==1 && vertices[i].m.a21==0 && vertices[i].m.a22==1){
-					double a,b,c;	     
-					a=bamgopts->metric[i*3+0];
-					b=bamgopts->metric[i*3+1];
-					c=bamgopts->metric[i*3+2];
-					Metric M(a,b,c);
-					MatVVP2x2 Vp(M/coef);
-
-					Vp.Maxh(hmax);
-					Vp.Minh(hmin);
-					vertices[i].m = Vp;
-				}
-			}
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::WriteMetric{{{1*/
-	void Triangles::WriteMetric(BamgOpts* bamgopts) {
-		int i;
-		xfree((void**)&bamgopts->metric);
-		bamgopts->metric=(double*)xmalloc(3*nbv*sizeof(double));
-		for (i=0;i<nbv;i++){
-			bamgopts->metric[i*3+0]=vertices[i].m.a11;
-			bamgopts->metric[i*3+1]=vertices[i].m.a21;
-			bamgopts->metric[i*3+2]=vertices[i].m.a22;
-		}
-	}
-	/*}}}1*/
-
-	/*Methods*/
-	/*FUNCTION Triangles::AddGeometryMetric{{{1*/
-	void Triangles::AddGeometryMetric(BamgOpts* bamgopts){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/IntersectGeomMetric)*/
-
-		/*Get options*/
-		int    verbose=bamgopts->verbose;
-		double anisomax =bamgopts->anisomax;
-		double errg     =bamgopts->errg;
-
-		double ss[2]={0.00001,0.99999};
-		double errC = 2*sqrt(2*errg);
-		double hmax = Gh.MaximalHmax();
-		double hmin = Gh.MinimalHmin();
-
-		//check that hmax is positive
-		if (hmax<=0){
-			ISSMERROR("hmax<=0");
-		}
-
-		//errC cannot be higher than 1
-		if (errC>1) errC=1;
-
-		//Set all vertices to "on"
-		SetVertexFieldOn();
-
-		//loop over all the vertices on edges
-		for (int  i=0;i<nbe;i++){
-			for (int j=0;j<2;j++){
-
-				MeshVertex V;
-				VertexOnGeom GV;
-				Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
-
-				GeometricalEdge* eg = GV;
-				double s = GV;
-				R2 tg;
-				double  R1= eg->R1tg(s,tg);
-				double  ht=hmax;
-				// err relative to the length of the edge
-				if (R1>1.0e-20) {  
-					ht = Min(Max(errC/R1,hmin),hmax);
-				}
-				double hn=Min(hmax,ht*anisomax);
-
-				if (ht<=0 || hn<=0){
-					ISSMERROR("ht<=0 || hn<=0");
-				}
-				MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
-				Metric MVp(Vp);
-				edges[i][j].m.IntersectWith(MVp);
-			}
-		}
-		// the problem is for the vertex on vertex 
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::AddMetric{{{1*/
-	void Triangles::AddMetric(BamgOpts* bamgopts){
-		//  Hessiantype = 0 =>  H is computed using double P2 projection
-		//  Hessiantype = 1 =>  H is computed with green formula
-
-		/*Options*/
-		int Hessiantype=bamgopts->Hessiantype;
-
-		if (Hessiantype==0){
-			BuildMetric0(bamgopts);
-		}
-		else if (Hessiantype==1){
-			BuildMetric1(bamgopts);
-		}
-		else{
-			ISSMERROR("Hessiantype %i not supported yet (1->use Green formula, 0-> double P2 projection)",Hessiantype);
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::AddVertex{{{1*/
-	void Triangles::AddVertex( MeshVertex &s,Triangle* t, Icoor2* det3) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Add)*/
-		// -------------------------------------------
-		//             s2
-		//                                            !
-		//             /|\                            !
-		//            / | \                           !
-		//           /  |  \                          !
-		//    tt1   /   |   \ tt0                     !
-		//         /    |s   \                        !
-		//        /     .     \                       !
-		//       /  .      `   \                      !
-		//      / .           ` \                     !
-		//      ----------------                      !
-		//   s0       tt2       s1
-		//-------------------------------------------- 
-
-		//the three triangles tt
-		Triangle* tt[3];
-		//three vertices of t
-		MeshVertex &s0 = (*t)[0], &s1=(*t)[1], &s2=(*t)[2];
-		//three determinants
-		Icoor2 det3local[3];
-		// number of zero det3
-		register int nbzerodet =0; 
-		// izerodet = egde contening the vertex s
-		register int izerodet=-1,iedge; 
-		//determinant of t
-		Icoor2 detOld = t->det;
-
-		// infinitevertexpos = order of the infinite vertex (NULL)
-		// if no infinite vertex (NULL) infinitevertexpos=-1
-		// else if v_i is infinite, infinitevertexpos=i
-		int infinitevertexpos = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
-
-		//some checks
-		if (( infinitevertexpos <0 ) && (detOld <0) ||  ( infinitevertexpos >=0  ) && (detOld >0) ){
-			ISSMERROR("bug in Triangles::Add, bad configuration");
-		}
-
-		// if det3 does not exist, build it 
-		if (!det3) { 
-			//allocate
-			det3 = det3local;
-			//if no infinite vertex
-			if (infinitevertexpos<0 ) {
-				det3[0]=bamg::det(s ,s1,s2);
-				det3[1]=bamg::det(s0,s ,s2);
-				det3[2]=bamg::det(s0,s1,s );}
-			else { 
-				// one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
-				det3[0]= &s0 ? -1 : bamg::det(s ,s1,s2) ;
-				det3[1]= &s1 ? -1 : bamg::det(s0,s ,s2) ;
-				det3[2]= &s2 ? -1 : bamg::det(s0,s1,s ) ;
-			}
-		}
-
-		if (!det3[0]) izerodet=0,nbzerodet++;
-		if (!det3[1]) izerodet=1,nbzerodet++;
-		if (!det3[2]) izerodet=2,nbzerodet++;
-
-		//if nbzerodet>0, point s is on an egde or on a vertex 
-		if  (nbzerodet >0 ){ 
-			if (nbzerodet == 1) {
-				iedge = OppositeEdge[izerodet];
-				TriangleAdjacent ta = t->Adj(iedge);
-
-				// the point is on the edge 
-				// if the point is one the boundary 
-				// add the point in outside part 
-				if ( t->det >=0) { // inside triangle
-					if ((( Triangle *) ta)->det < 0 ) {
-						// add in outside triangle 
-						AddVertex(s,( Triangle *) ta);
-						return;
-					}
-				}
-			}
-			else {
-				//t->Echo();
-				printf("\nproblem while trying to add:\n");
-				s.Echo();
-				ISSMERROR("Bug in Triangles::Add points duplicated %i times",nbzerodet);
-			}
-		}
-
-		// remove de MarkUnSwap edge
-		t->SetUnMarkUnSwap(0);     
-		t->SetUnMarkUnSwap(1);     
-		t->SetUnMarkUnSwap(2);
-
-		tt[0]= t;
-		tt[1]= &triangles[nbt++];
-		tt[2]= &triangles[nbt++];
-
-		if (nbt>nbtx) {
-			ISSMERROR("Not ebough triangles");
-		}
-
-		*tt[1]=   *tt[2]= *t;
-		// gestion of the link
-		tt[0]->link=tt[1];
-		tt[1]->link=tt[2]; 
-
-		(* tt[0])(OppositeVertex[0])=&s;
-		(* tt[1])(OppositeVertex[1])=&s;
-		(* tt[2])(OppositeVertex[2])=&s;
-
-		tt[0]->det=det3[0];
-		tt[1]->det=det3[1];
-		tt[2]->det=det3[2];         
-
-		//  update adj des triangles externe 
-		tt[0]->SetAdjAdj(0);
-		tt[1]->SetAdjAdj(1);
-		tt[2]->SetAdjAdj(2);
-		//  update des adj des 3 triangle interne
-		const int i0 = 0;
-		const int i1= NextEdge[i0];
-		const int i2 = PreviousEdge[i0];
-
-		tt[i0]->SetAdj2(i2,tt[i2],i0);
-		tt[i1]->SetAdj2(i0,tt[i0],i1);
-		tt[i2]->SetAdj2(i1,tt[i1],i2);
-
-		tt[0]->SetTriangleContainingTheVertex();
-		tt[1]->SetTriangleContainingTheVertex();
-		tt[2]->SetTriangleContainingTheVertex();
-
-
-		// swap if the point s is on a edge
-		if(izerodet>=0) {
-			int rswap =tt[izerodet]->swap(iedge);
-
-			if (!rswap) {
-				ISSMERROR("swap the point s is on a edge");
-			}
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::BoundAnisotropy{{{1*/
-	void  Triangles::BoundAnisotropy(double anisomax,double hminaniso) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/BoundAnisotropy)*/
-
-		long int verbose=0;
-		double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
-
-		//display info
-		if (verbose > 1)  printf("   BoundAnisotropy by %g\n",anisomax);
-
-		double h1=1.e30,h2=1e-30;
-		double coef = 1./(anisomax*anisomax);
-		double hn1=1.e30,hn2=1e-30,rnx =1.e-30,rx=0;  
-
-		//loop over all vertices
-		for (int i=0;i<nbv;i++){
-			MatVVP2x2 Vp(vertices[i]);
-			double lmax=Vp.lmax();
-			Vp*=Min(lminaniso,lmax)/lmax;
-			Vp.BoundAniso2(coef);
-			vertices[i].m = Vp;
-
-			//info to be displayed
-			if (verbose>2){
-				h1 =Min(h1,Vp.lmin());
-				h2 =Max(h2,Vp.lmax());
-				hn1=Min(hn1,Vp.lmin());
-				hn2=Max(hn2,Vp.lmax());
-				rx =Max(rx,Vp.Aniso2());
-				rnx= Max(rnx,Vp.Aniso2());
-			}
-		}
-
-		//display info
-		if (verbose>2){
-			printf("      input:  Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(h2,-0.5),pow(h1,-0.5),pow(rx,0.5));
-			printf("      output: Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::BuildGeometryFromMesh{{{1*/
-	void Triangles::BuildGeometryFromMesh(BamgOpts* bamgopts){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshGeom.cpp/ConsGeometry)*/
-
-		/*Reconstruct Geometry from Mesh*/
-
-		/*Intermediary*/
-		int i,j,k,kk,it,jt;
-		int    verbose=0;
-		double cutoffradian=10*Pi/180;
-
-		/*Recover options*/
-		if (bamgopts){
-			verbose=bamgopts->verbose;
-			cutoffradian=bamgopts->MaxCornerAngle*Pi/180;
-		}
-
-		//display info
-		if (verbose>1) printf("   construction of the geometry from the 2d mesh\n");
-
-		//check that the mesh is not empty
-		if (nbt<=0 || nbv <=0 ) {
-			ISSMERROR("nbt or nbv is negative (Mesh empty?)");
-		}
-
-		//Gh is the geometry of the mesh (this), initialize MaxCornerAngle
-		if (cutoffradian>=0) Gh.MaxCornerAngle = cutoffradian;
-
-		/*Construction of the edges*/
-
-		//initialize st and edge4
-		SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
-		long*        st   = new long[nbt*3];
-
-		//initialize st as -1 (chaining algorithm)
-		for (i=0;i<nbt*3;i++) st[i]=-1;
-
-		//build edge4 (chain)
-		for (i=0;i<nbe;i++){
-			edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1]));
-		}
-		//check that there is no double edge
-		if (nbe !=  edge4->nb()){ 
-			ISSMERROR("Some Double edge in the mesh, the number is %i, nbe4=%i",nbe,edge4->nb()); 
-		}
-		//keep nbe in nbeold
-		long nbeold = nbe;
-
-		//Go through the triangles and ass the edges in edge4 if they are not there yet
-		for (i=0;i<nbt;i++){
-			//3 edges per triangle
-			for  (j=0;j<3;j++) {
-				//Add Edge to edge4 (k=numberofedges in edge4)
-				long k =edge4->SortAndAdd(Number(triangles[i][VerticesOfTriangularEdge[j][0]]), Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
-				long invisible = triangles[i].Hidden(j);
-
-				//if st[k] has not been changed yet, add 3*i+j (= vertex position in the index)
-				if(st[k]==-1) st[k]=3*i+j;
-
-				//else st[k]>=0 -> the edge already exist, check
-				else if(st[k]>=0) {
-					//check that it is not an edge on boundary (should not already exist)
-					if (triangles[i].TriangleAdj(j) || triangles[st[k]/3].TriangleAdj((int) (st[k]%3))){
-						ISSMERROR("problem in Geometry reconstruction: an edge on boundary is duplicated (double element?)");
-					}
-					//OK, the element is not on boundary, is belongs to 2 triangles -> build Adjacent triangles list
-					triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
-					if (invisible)  triangles[i].SetHidden(j);
-					// if k < nbe mark the edge as on Boundary (Locked)
-					if (k<nbe) {
-						triangles[i].SetLocked(j);
-					}
-					//set st[k] as negative so that the edge should not be called again
-					st[k]=-2-st[k]; 
-				}
-				//else (see 3 lines above), the edge has been called more than twice: return error
-				else {
-					printf("The edge (%i,%i) belongs to more than 2 triangles (%i)\n",Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]),k);
-					printf("Edge %i of triangle %i\n",j,i);
-					printf("Edge %i of triangle %i\n",(-st[k]+2)%3,(-st[k]+2)/3);
-					printf("Edge %i of triangle %i\n",triangles[(-st[k]+2)/3].NuEdgeTriangleAdj((int)((-st[k]+2)%3)),Number(triangles[(-st[k]+2)/3].TriangleAdj((int)((-st[k]+2)%3))));
-					ISSMERROR("An edge belongs to more than 2 triangles");
-				}	
-			}
-		}
-
-		//delete edge4
-		long nbedges = edge4->nb(); // the total number of edges 
-		delete edge4; edge4=NULL;
-
-		//display info
-		if(verbose>5) {
-			printf("         info on Mesh:\n");
-			printf("            - number of vertices    = %i \n",nbv); 
-			printf("            - number of triangles   = %i \n",nbt); 
-			printf("            - number of given edges = %i \n",nbe); 
-			printf("            - number of all edges   = %i \n",nbedges); 
-			printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-nbedges+nbv); 
-		}
-
-		// check consistency of edge[].adj and geometrical required  vertices
-		k=0; kk=0;
-		for (i=0;i<nbedges;i++){
-			//internal edge
-			if (st[i] <-1) {
-				//get triangle number back
-				it =  (-2-st[i])/3;
-				//get edge position back
-				j  =  (int) ((-2-st[i])%3);
-				Triangle &tt=*triangles[it].TriangleAdj(j);
-				if (triangles[it].color != tt.color|| i < nbeold) k++;
-			}
-			//boundary edge (alone)
-			else if (st[i] >=0) 
-			 kk++;
-		}
-
-		/*Constructions of edges*/
-
-		k += kk;
-		kk=0;
-		if (k) {
-			nbe = k;
-			Edge* edgessave=edges;
-			edges = new Edge[nbe];
-			k =0;
-
-			//display info
-			if(verbose>4) printf("   Construction of the edges %i\n",nbe);
-
-			for (i=0;i<nbedges;i++){ 
-				long  add= -1;
-
-				//internal edge (belongs to two triangles)
-				if (st[i] <-1){ 
-					it =  (-2-st[i])/3;
-					j  =  (int) ((-2-st[i])%3);
-					Triangle & tt = * triangles[it].TriangleAdj(j);
-					if (triangles[it].color !=  tt.color || i < nbeold) add=k++;
-				}
-				//boundary edge
-				else if (st[i] >=0){
-					it = st[i]/3;
-					j  = (int) (st[i]%3);
-					add=k++;
-				}
-				if (add>=0 && add < nbe){
-					edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
-					edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
-					edges[add].onGeometry=NULL; 
-					//if already existed
-					if (i<nbeold){
-						edges[add].ref=edgessave[i].ref; 		      
-						edges[add].onGeometry=edgessave[i].onGeometry; //  HACK to get required edges
-						printf("oh no...\n");
-					}
-					else
-					 edges[add].ref=Min(edges[add].v[0]->ref(),edges[add].v[1]->ref());
-				  }
-			}
-
-			//check that we have been through all edges
-			if (k!=nbe){
-				ISSMERROR("problem in edge construction process: k!=nbe (should not happen)");
-			}
-			//delete edgessave
-			if (edgessave) delete [] edgessave;
-		}
-
-		/*Color the vertices*/
-
-		//initialize color of all vertices as 0
-		for (i=0;i<nbv;i++) vertices[i].color =0;
-
-		//go through the edges and add a color to corresponding vertices
-		//(A vertex in 4 edges will have a color 4)
-		for (i=0;i<nbe;i++){
-		 for (j=0;j<2;j++) edges[i].v[j]->color++;
-		}
-
-		//change the color: if a vertex belongs to 2 edges -1, else -2
-		for (i=0;i<nbv;i++) {
-			vertices[i].color=(vertices[i].color ==2)? -1 : -2;
-		}
-
-		/*Build edges[i].adj: adjacency of each edge (if on the same curve)*/
-		for (i=0;i<nbe;i++){
-			for (j=0;j<2;j++){ 
-				//get current vertex
-				MeshVertex* v=edges[i].v[j];
-				//get vertex color (i0)
-				long i0=v->color;
-				long j0;
-
-				//if color<0 (first time), no adjacent edge
-				if(i0<0) edges[i].adj[j]=NULL;
-
-				//if color=-1 (corner),change the vertex color as 2*i+j (position of the vertex in edges)
-				if(i0==-1) v->color=i*2+j;
-
-				//if color>=0 (i and i0 edge are adjacent by the vertex v)
-				else if (i0>=0) {
-					//get position of v in edges back
-					j0 =  i0%2; //column in edges
-					i0 =  i0/2; //line in edges
-
-					//check that we have the correct vertex
-					if (v!=edges[i0 ].v[j0]){
-						ISSMERROR("v!=edges[i0 ].v[j0]: this should not happen as the vertex belongs to this edge");
-					}
-
-					//Add adjacence
-					edges[i ].adj[j ]=edges +i0;
-					edges[i0].adj[j0]=edges +i ;
-
-					//change color to -3
-					v->color = -3;
-				}
-			}
-		}
-
-		/*Reconstruct subdomains info*/
-
-		//check that NbSubDomains is empty
-		if (NbSubDomains){
-			ISSMERROR("NbSubDomains should be 0");
-		}
-		NbSubDomains=0;
-
-		//color the subdomains
-		long* colorT= new long[nbt];
-		Triangle *tt,*t;
-
-		//initialize the color of each triangle as -1
-		for (it=0;it<nbt;it++) colorT[it]=-1;
-
-		//loop over the triangles
-		for (it=0;it<nbt;it++){
-
-			//if the triangle has not been colored yet:
-			if (colorT[it]<0){
-
-				//color = number of subdomains
-				colorT[it]=NbSubDomains;
-
-				//color all the adjacent triangles of T that share a non marked edge
-				int level =1;
-				int kolor=triangles[it].color;
-				st[0]=it; // stack 
-				st[1]=0;
-				k=1;
-				while (level>0){
-					if( (j=st[level]++)<3 ){ 
-						t = &triangles[st[level-1]];
-						tt=t->TriangleAdj((int)j);
-
-						//color the adjacent triangle
-						if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor)) {
-							colorT[jt]=NbSubDomains;
-							st[++level]=jt;
-							st[++level]=0;
-							k++;
-						}
-					}
-					else level-=2;
-				}
-				NbSubDomains++;
-			}
-		}
-		if (verbose> 3) printf("      The Number of sub domain = %i\n",NbSubDomains); 
-
-		//build subdomains
-		long isd;
-		subdomains = new SubDomain[NbSubDomains];
-
-		//initialize subdomains[isd].head as 0
-		for (isd=0;isd<NbSubDomains;isd++) subdomains[isd].head =0;
-		  
-		k=0;
-		for (it=0;it<nbt;it++){
-			for (int j=0;j<3;j++){
-				tt=triangles[it].TriangleAdj(j);
-				if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head){
-					subdomains[isd].head = triangles+it;
-					subdomains[isd].ref =  triangles[it].color;
-					subdomains[isd].sens = j; // hack
-					subdomains[isd].edge = 0;
-					k++;
-				}
-			}
-		}
-		//check that we have been through all subdomains
-		if (k!= NbSubDomains){
-			ISSMERROR("k!= NbSubDomains");
-		}
-		//delete colorT and st
-		delete [] colorT;
-		delete [] st;
-
-		/*Reconstruct Geometry Gh*/
-
-		//build colorV -1 for all vertex and 0 for the vertices belonging to edges
-		long* colorV = new long[nbv];
-		for (i=0;i<nbv;i++) colorV[i]=-1;
-		for (i=0;i<nbe;i++){
-		 for ( j=0;j<2;j++) colorV[Number(edges[i][j])]=0;
-		}
-		//number the vertices belonging to edges
-		k=0;
-		for (i=0;i<nbv;i++){
-		 if(!colorV[i]) colorV[i]=k++;
-		}
-
-		//Build Gh
-		Gh.nbv=k;
-		Gh.nbe = nbe;
-		Gh.vertices = new GeometricalVertex[k];
-		Gh.edges = new GeometricalEdge[nbe];
-		Gh.NbSubDomains = NbSubDomains;
-		Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
-		if (verbose>3) printf("   number of vertices = %i\n   number of edges = %i\n",Gh.nbv,Gh.nbe);
-		NbVerticesOnGeomVertex = Gh.nbv;
-		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
-		NbVerticesOnGeomEdge =0;
-		VerticesOnGeomEdge =0;
-
-		//Build VertexOnGeom
-		for (i=0;i<nbv;i++){
-			if((j=colorV[i])>=0){
-				MeshVertex & v = Gh.vertices[j];
-				v = vertices[i];
-				v.color =0;
-				VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
-			}
-		}
-
-		//Buid pmin and pmax of Gh (extrema coordinates)
-		Gh.pmin =  Gh.vertices[0].r;
-		Gh.pmax =  Gh.vertices[0].r;
-		// recherche des extrema des vertices pmin,pmax
-		for (i=0;i<Gh.nbv;i++) {
-			Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
-			Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
-			Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
-			Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
-		}
-		R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
-		Gh.pmin -=  DD05;
-		Gh.pmax +=  DD05;
-
-		//Build Gh.coefIcoor
-		Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
-		if (Gh.coefIcoor<=0){
-			ISSMERROR("Gh.coefIcoor<=0 in infered Geometry (this should not happen)");
-		}
-
-		/*Build Gh.edges*/
-
-		//initialize len as 0
-		double * len = new double[Gh.nbv];
-		for(i=0;i<Gh.nbv;i++) len[i]=0;
-
-		//initialize edge4 again
-		edge4= new SetOfEdges4(nbe,nbv);  
-		double hmin = HUGE_VAL;
-		int kreq=0;
-		for (i=0;i<nbe;i++){
-
-			long i0 = Number(edges[i][0]);
-			long i1 = Number(edges[i][1]);
-			long j0 = colorV[i0];
-			long j1 = colorV[i1];
-
-			Gh.edges[i].v[0] = Gh.vertices +  j0;
-			Gh.edges[i].v[1] = Gh.vertices +  j1;
-
-			Gh.edges[i].flag = 0;
-
-			Gh.edges[i].tg[0]=R2();
-			Gh.edges[i].tg[1]=R2();
-
-			bool required= edges[i].onGeometry; 
-			if(required) kreq++;
-			edges[i].onGeometry =  Gh.edges + i;
-			if(required){
-				Gh.edges[i].v[0]->SetRequired();
-				Gh.edges[i].v[1]->SetRequired();
-				Gh.edges[i].SetRequired();
-			}
-
-			R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
-			double l12=Norme2(x12);        
-			hmin = Min(hmin,l12);
-
-			Gh.vertices[j1].color++;
-			Gh.vertices[j0].color++;
-
-			len[j0]+= l12;
-			len[j1] += l12;
-			hmin = Min(hmin,l12);
-			Gh.edges[i].ref  = edges[i].ref;
-
-			k = edge4->SortAndAdd(i0,i1);
-			if (k != i){
-				ISSMERROR("problem in Edge4 construction: k != i");
-			}
-		}
-
-		//Build metric for all vertices of Gh
-		for (i=0;i<Gh.nbv;i++){
-		 if (Gh.vertices[i].color > 0) 
-		  Gh.vertices[i].m=  Metric(len[i] /(double) Gh.vertices[i].color);
-		 else 
-		  Gh.vertices[i].m=  Metric(hmin);
-		}
-		//delete len
-		delete [] len;
-
-		//Build Gh.subdomains
-		for (i=0;i<NbSubDomains;i++){
-			it = Number(subdomains[i].head);
-			j = subdomains[i].sens;
-			long i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
-			long i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
-			k = edge4->SortAndFind(i0,i1);
-			if(k>=0){
-				subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
-				subdomains[i].edge = edges+k;
-				Gh.subdomains[i].edge = Gh.edges + k;
-				Gh.subdomains[i].sens  =  subdomains[i].sens;
-				Gh.subdomains[i].ref =  subdomains[i].ref;
-			}
-			else
-			 ISSMERROR("%i should be >=0");
-		  }
-
-		delete edge4;
-		delete [] colorV;
-
-		//unset adj
-		for (i=0;i<nbt;i++){
-			for ( j=0;j<3;j++){
-				triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
-			}
-		}
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::BuildMetric0 (double P2 projection){{{1*/
-	void Triangles::BuildMetric0(BamgOpts* bamgopts){
-
-		/*Options*/
-		double* s=NULL;
-		long    nbsol;
-		int     verbose;
-
-		int   i,j,k,iA,iB,iC;
-		int   iv;
-
-		/*Recover options*/
-		verbose=bamgopts->verbose;
-
-		/*Get and process fields*/
-		s=bamgopts->field;
-		nbsol=bamgopts->numfields;
-
-		//initialization of some variables
-		double* ss=(double*)s;
-		double  sA,sB,sC;
-		double*  detT = new double[nbt];
-		double*  sumareas = new double[nbv];
-		double*  alpha= new double[nbt*3];
-		double*  beta = new double[nbt*3];
-		double*  dx_elem    = new double[nbt];
-		double*  dy_elem    = new double[nbt];
-		double*  dx_vertex  = new double[nbv];
-		double*  dy_vertex  = new double[nbv];
-		double*  dxdx_elem  = new double[nbt];
-		double*  dxdy_elem  = new double[nbt];
-		double*  dydy_elem  = new double[nbt];
-		double*  dxdx_vertex= new double[nbv];
-		double*  dxdy_vertex= new double[nbv];
-		double*  dydy_vertex= new double[nbv];
-
-		//display infos
-		if(verbose>1) {
-			printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
-		}
-
-		//first, build the chains that will be used for the Hessian computation, as weel as the area of each element
-		int* head_s=NULL;
-		head_s=(int*)xmalloc(nbv*sizeof(int));
-		int* next_p=NULL;
-		next_p=(int*)xmalloc(3*nbt*sizeof(int));
-		int  p=0;
-		//initialization
-		for(i=0;i<nbv;i++){
-			sumareas[i]=0;
-			head_s[i]=-1;
-		}
-		for(i=0;i<nbt;i++){
-
-			//lopp over the real triangles (no boundary elements)
-			if(triangles[i].link){ 
-
-				//get current triangle t
-				const Triangle &t=triangles[i];
-
-				// coor of 3 vertices 
-				R2 A=t[0];
-				R2 B=t[1];
-				R2 C=t[2];
-
-				//compute triangle determinant (2*Area)
-				double dett = bamg::Area2(A,B,C);
-				detT[i]=dett;
-
-				/*The nodal functions are such that for a vertex A:
-				 *    N_A(x,y)=alphaA x + beta_A y +gamma_A
-				 *    N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
-				 * solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
-				 * leads to:
-				 *    N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
-				 * and this gives:
-				 *    alpha_A = (yB-yC)/(2*Area(T))*/
-				alpha[i*3+0]=(B.y-C.y)/dett;
-				alpha[i*3+1]=(C.y-A.y)/dett;
-				alpha[i*3+2]=(A.y-B.y)/dett;
-				beta[ i*3+0]=(C.x-B.x)/dett;
-				beta[ i*3+1]=(A.x-C.x)/dett;
-				beta[ i*3+2]=(B.x-A.x)/dett;
-
-				//compute chains
-				for(j=0;j<3;j++){
-					k=Number(triangles[i][j]);
-					next_p[p]=head_s[k];
-					head_s[k]=p++;
-
-					//add area to sumareas
-					sumareas[k]+=dett;
-				}
-
-			}
-		}
-
-		//for all Solutions
-		for (int nusol=0;nusol<nbsol;nusol++) {
-			double smin=ss[nusol],smax=ss[nusol];
-
-			//get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
-			for ( iv=0,k=0; iv<nbv; iv++){
-				smin=Min(smin,ss[iv*nbsol+nusol]);
-				smax=Max(smax,ss[iv*nbsol+nusol]);
-			}
-			double sdelta=smax-smin;
-			double absmax=Max(Abs(smin),Abs(smax));
-
-			//display info
-			if(verbose>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g\n",nusol,smin,smax,sdelta);
-
-			//skip constant field
-			if (sdelta < 1.0e-10*Max(absmax,1e-20)){
-				printf("      Solution %i is constant, skipping...\n",nusol);
-				continue;
-			}
-
-			//initialize the hessian and gradient matrices
-			for ( iv=0,k=0; iv<nbv; iv++) dxdx_vertex[iv]=dxdy_vertex[iv]=dydy_vertex[iv]=dx_vertex[iv]=dy_vertex[iv]=0;
-
-			//1: Compute gradient for each element (exact)
-			for (i=0;i<nbt;i++){
-				if(triangles[i].link){
-					// number of the 3 vertices
-					iA = Number(triangles[i][0]);
-					iB = Number(triangles[i][1]);
-					iC = Number(triangles[i][2]);
-
-					// value of the P1 fonction on 3 vertices 
-					sA = ss[iA*nbsol+nusol];
-					sB = ss[iB*nbsol+nusol];
-					sC = ss[iC*nbsol+nusol];
-
-					//gradient = (sum alpha_i s_i, sum_i beta_i s_i)
-					dx_elem[i]=sA*alpha[3*i+0]+sB*alpha[3*i+1]+sC*alpha[3*i+2];
-					dy_elem[i]=sA*beta[ 3*i+0]+sB*beta[ 3*i+1]+sC*beta[ 3*i+2];
-				}
-			}
-
-			//2: then compute a gradient for each vertex using a P2 projection
-			for(i=0;i<nbv;i++){
-				for(p=head_s[i];p!=-1;p=next_p[p]){
-					//Get triangle number
-					k=(long)(p/3);
-					dx_vertex[i]+=dx_elem[k]*detT[k]/sumareas[i];
-					dy_vertex[i]+=dy_elem[k]*detT[k]/sumareas[i];
-				}
-			}
-
-			//3: compute Hessian matrix on each element
-			for (i=0;i<nbt;i++){
-				if(triangles[i].link){
-					// number of the 3 vertices
-					iA = Number(triangles[i][0]);
-					iB = Number(triangles[i][1]);
-					iC = Number(triangles[i][2]);
-
-					//Hessian
-					dxdx_elem[i]=dx_vertex[iA]*alpha[3*i+0]+dx_vertex[iB]*alpha[3*i+1]+dx_vertex[iC]*alpha[3*i+2];
-					dxdy_elem[i]=dy_vertex[iA]*alpha[3*i+0]+dy_vertex[iB]*alpha[3*i+1]+dy_vertex[iC]*alpha[3*i+2];
-					dydy_elem[i]=dy_vertex[iA]*beta[3*i+0]+dy_vertex[iB]*beta[3*i+1]+dy_vertex[iC]*beta[3*i+2];
-				}
-			}
-
-			//4: finaly compute Hessian on each vertex using the second P2 projection
-			for(i=0;i<nbv;i++){
-				for(p=head_s[i];p!=-1;p=next_p[p]){
-					//Get triangle number
-					k=(long)(p/3);
-					dxdx_vertex[i]+=dxdx_elem[k]*detT[k]/sumareas[i];
-					dxdy_vertex[i]+=dxdy_elem[k]*detT[k]/sumareas[i];
-					dydy_vertex[i]+=dydy_elem[k]*detT[k]/sumareas[i];
-				}
-			}
-
-			/*Compute Metric from Hessian*/
-			for ( iv=0;iv<nbv;iv++){
-				vertices[iv].MetricFromHessian(dxdx_vertex[iv],dxdy_vertex[iv],dydy_vertex[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
-			}
-
-		}//for all solutions
-
-		//clean up
-		xfree((void**)&head_s);
-		xfree((void**)&next_p);
-		delete [] detT;
-		delete [] alpha;
-		delete [] beta;
-		delete [] sumareas;
-		delete [] dx_elem;
-		delete [] dy_elem;
-		delete [] dx_vertex;
-		delete [] dy_vertex;
-		delete [] dxdx_elem;
-		delete [] dxdy_elem;
-		delete [] dydy_elem;
-		delete [] dxdx_vertex;
-		delete [] dxdy_vertex;
-		delete [] dydy_vertex;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::BuildMetric1 (Green formula){{{1*/
-	void Triangles::BuildMetric1(BamgOpts* bamgopts){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/IntersectConsMetric)*/
-
-		/*Options*/
-		double* s=NULL;
-		long nbsol;
-		int NbJacobi;
-		int verbose;
-
-		/*Recover options*/
-		verbose=bamgopts->verbose;
-		NbJacobi=bamgopts->nbjacobi;
-
-		/*Get and process fields*/
-		s=bamgopts->field;
-		nbsol=bamgopts->numfields;
-
-		//initialization of some variables
-		long    i,k,iA,iB,iC,iv;
-		R2      O(0,0);
-		double* ss=(double*)s;
-		double  sA,sB,sC;
-		double*  detT = new double[nbt];
-		double*  Mmass= new double[nbv];
-		double*  Mmassxx= new double[nbv];
-		double*  dxdx= new double[nbv];
-		double*  dxdy= new double[nbv];
-		double*  dydy= new double[nbv];
-		double*  workT= new double[nbt];
-		double*  workV= new double[nbv];
-		int*    OnBoundary = new int[nbv];
-
-		//display infos
-		if(verbose>1) {
-			printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
-		}
-
-		//initialize Mmass, OnBoundary and Massxx by zero
-		for (iv=0;iv<nbv;iv++){
-			Mmass[iv]=0;
-			OnBoundary[iv]=0;
-			Mmassxx[iv]=0;
-		}
-
-		//Build detT Mmas Mmassxx workT and OnBoundary
-		for (i=0;i<nbt;i++){ 
-
-			//lopp over the real triangles (no boundary elements)
-			if(triangles[i].link){ 
-
-				//get current triangle t
-				const Triangle &t=triangles[i];
-
-				// coor of 3 vertices 
-				R2 A=t[0];
-				R2 B=t[1];
-				R2 C=t[2];
-
-				// number of the 3 vertices
-				iA = Number(t[0]);
-				iB = Number(t[1]);
-				iC = Number(t[2]);
-
-				//compute triangle determinant (2*Area)
-				double dett = bamg::Area2(A,B,C);
-				detT[i]=dett;
-				dett /= 6;
-
-				// construction of OnBoundary (flag=1 if on boundary, else 0)
-				int nbb=0;
-				for(int j=0;j<3;j++){
-					//get adjacent triangle
-					Triangle *ta=t.Adj(j);
-					//if there is no adjacent triangle, the edge of the triangle t is on boundary
-					if ( !ta || !ta->link){
-						//mark the two vertices of the edge as OnBoundary
-						OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1;
-						OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1;
-						nbb++;
-					}
-				}
-
-				//number of vertices on boundary for current triangle t
-				workT[i] = nbb;
-
-				//Build Mmass Mmass[i] = Mmass[i] + Area/3
-				Mmass[iA] += dett;
-				Mmass[iB] += dett;
-				Mmass[iC] += dett;
-
-				//Build Massxx = Mmass
-				Mmassxx[iA] += dett;
-				Mmassxx[iB] += dett;
-				Mmassxx[iC] += dett;
-			}
-
-			//else: the triangle is a boundary triangle -> workT=-1
-			else workT[i]=-1;
-		}
-
-		//for all Solution  
-		for (int nusol=0;nusol<nbsol;nusol++) {
-
-			double smin=ss[nusol],smax=ss[nusol];
-			double h1=1.e30,h2=1e-30,rx=0;
-			double hn1=1.e30,hn2=1e-30,rnx =1.e-30;  
-
-			//get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
-			for ( iv=0,k=0; iv<nbv; iv++ ){
-				dxdx[iv]=dxdy[iv]=dydy[iv]=0;
-				smin=Min(smin,ss[iv*nbsol+nusol]);
-				smax=Max(smax,ss[iv*nbsol+nusol]);
-			}
-			double sdelta=smax-smin;
-			double absmax=Max(Abs(smin),Abs(smax));
-
-			//display info
-			if(verbose>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, number of fields = %i\n",nusol,smin,smax,sdelta,nbsol);
-
-			//skip constant field
-			if (sdelta < 1.0e-10*Max(absmax,1e-20) ){
-				if (verbose>2) printf("      Solution %i is constant, skipping...\n",nusol);
-				continue;
-			}
-
-			//pointer toward ss that is also a pointer toward s (solutions)
-			double* sf=ss; 
-
-				//initialize the hessian matrix
-				for ( iv=0,k=0; iv<nbv; iv++) dxdx[iv]=dxdy[iv]=dydy[iv]=0;
-
-				//loop over the triangles
-				for (i=0;i<nbt;i++){
-
-					//for real all triangles 
-					if(triangles[i].link){
-
-						// coor of 3 vertices 
-						R2 A=triangles[i][0];
-						R2 B=triangles[i][1];
-						R2 C=triangles[i][2];
-
-						//warning: the normal is internal and the size is the length of the edge
-						R2 nAB = Orthogonal(B-A);
-						R2 nBC = Orthogonal(C-B);
-						R2 nCA = Orthogonal(A-C);
-						//note that :  nAB + nBC + nCA == 0 
-
-						// number of the 3 vertices
-						iA = Number(triangles[i][0]);
-						iB = Number(triangles[i][1]);
-						iC = Number(triangles[i][2]);
-
-						// for the test of  boundary edge
-						// the 3 adj triangles 
-						Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
-						Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
-						Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
-
-						// value of the P1 fonction on 3 vertices 
-						sA = ss[iA*nbsol+nusol];
-						sB = ss[iB*nbsol+nusol];
-						sC = ss[iC*nbsol+nusol];
-
-						/*The nodal functions are such that for a vertex A:
-						  N_A(x,y)=alphaA x + beta_A y +gamma_A
-						  N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
-						  solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
-						  leads to:
-						  N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
-						  and this gives:
-						  alpha_A = (yB-yC)/(2*Area(T))
-						  beta_A = (xC-xB)/(2*Area(T))
-						  and therefore:
-						  grad N_A = nA / detT
-						  for an interpolation of a solution s:
-						  grad(s) = s * sum_{i=A,B,C} grad(N_i) */
-
-						R2 Grads=(nAB*sC+nBC*sA+nCA*sB)/detT[i];
-
-						//Use Green to compute Hessian Matrix
-
-						// if edge on boundary no contribution  => normal = 0
-						if ( !tBC || !tBC->link ) nBC=O;
-						if ( !tCA || !tCA->link ) nCA=O;
-						if ( !tAB || !tAB->link ) nAB=O;
-
-						// remark we forgot a 1/2 because
-						//       int_{edge} w_i = 1/2 if i is in edge 
-						//                         0  if not
-						// if we don't take the  boundary 
-						dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
-						dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
-						dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
-
-						//warning optimization (1) the division by 2 is done on the metric construction
-						dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
-						dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
-						dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; 
-
-						dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
-						dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
-						dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
-
-					} // for real all triangles 
-				}
-
-				long kk=0;
-				for ( iv=0,k=0 ; iv<nbv; iv++){
-					if(Mmassxx[iv]>0){
-						dxdx[iv] /= 2*Mmassxx[iv];
-						// warning optimization (1) on term dxdy[iv]*ci/2 
-						dxdy[iv] /= 4*Mmassxx[iv];
-						dydy[iv] /= 2*Mmassxx[iv];
-						// Compute the matrix with abs(eigen value)
-						Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
-						MatVVP2x2 Vp(M);
-						Vp.Abs();
-						M = Vp;
-						dxdx[iv] = M.a11;
-						dxdy[iv] = M.a21;
-						dydy[iv] = M.a22;
-					}
-					else kk++;
-				}
-
-				// correction of second derivative
-				// by a laplacien
-				double* d2[3] = {dxdx, dxdy, dydy};
-				double* dd;
-				for (int xy = 0;xy<3;xy++) {
-					dd = d2[xy];
-					// do leat 2 iteration for boundary problem
-					for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++){
-						for (i=0;i<nbt;i++) 
-						 if(triangles[i].link){// the real triangles 
-							 // number of the 3 vertices
-							 iA = Number(triangles[i][0]);
-							 iB = Number(triangles[i][1]);
-							 iC = Number(triangles[i][2]);
-							 double cc=3;
-							 if(ijacobi==0)
-							  cc = Max((double) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
-							 workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
-						 }
-						for (iv=0;iv<nbv;iv++) workV[iv]=0;
-
-						for (i=0;i<nbt;i++){ 
-							if(triangles[i].link){ // the real triangles 
-								// number of the 3 vertices
-								iA = Number(triangles[i][0]);
-								iB = Number(triangles[i][1]);
-								iC = Number(triangles[i][2]);
-								double cc =  workT[i]*detT[i];
-								workV[iA] += cc;
-								workV[iB] += cc;
-								workV[iC] += cc;
-							}
-						}
-
-						for (iv=0;iv<nbv;iv++){
-							if( ijacobi<NbJacobi || OnBoundary[iv]){
-								dd[iv] = workV[iv]/(Mmass[iv]*6);
-							}
-						}
-					}
-				}
-
-				/*Compute Metric from Hessian*/
-				for ( iv=0;iv<nbv;iv++){
-					vertices[iv].MetricFromHessian(dxdx[iv],dxdy[iv],dydy[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
-				}
-
-		}// end for all solution 
-
-		delete [] detT;
-		delete [] Mmass;
-		delete [] dxdx;
-		delete [] dxdy;
-		delete [] dydy;
-		delete []  workT;
-		delete [] workV;
-		delete [] Mmassxx;
-		delete []  OnBoundary;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::CrackMesh{{{1*/
-	void Triangles::CrackMesh(BamgOpts* bamgopts) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CrackMesh)*/
-
-		/*Intermediary*/
-		int i,j,k,num,count;
-		int i1,i2;
-		int j1,j2;
-
-		/*Options*/
-		int verbose=bamgopts->verbose;
-
-		//  computed the number of cracked edge
-		for (k=i=0;i<nbe;i++){
-			if(edges[i].onGeometry->Cracked()) k++;
-		}
-
-		//Return if no edge is cracked
-		if(k==0) return;
-		if (verbose>4) printf("      number of Cracked Edges = %i\n",k);
-
-		//Initialize Cracked edge
-		NbCrackedEdges=k;
-		CrackedEdges=new CrackedEdge[k];
-
-		//Compute number of Cracked Vertices
-		k=0;
-		NbCrackedVertices=0;
-
-		int* splitvertex=new int[nbv];
-		for (i=0;i<nbv;i++) splitvertex[i]=0;
-
-		for (i=0;i<nbe;i++){
-			if(edges[i].onGeometry->Cracked()){
-
-				//Fill edges fields of CrackedEdges
-				CrackedEdges[k  ].E =edges[i].onGeometry;
-				CrackedEdges[k++].e1=&edges[i];
-
-				//Get number of the two vertices on the edge
-				i1=Number(edges[i][0]);
-				i2=Number(edges[i][1]);
-				ISSMASSERT(i1>=0 && i1<nbv && i2>=0 && i2<nbv);
-				splitvertex[i1]++;
-				splitvertex[i2]++;
-
-				//If the vertex has already been flagged once, it is a cracked vertex (tip otherwise)
-				if (splitvertex[i1]==2) NbCrackedVertices++;
-				if (splitvertex[i2]==2) NbCrackedVertices++;
-
-				//The vertex cannot be marked more than twice
-				if (splitvertex[i1]==3 || splitvertex[i2]==3){
-					ISSMERROR("Crossing rifts not supported yet");
-				}
-			}
-		}
-		ISSMASSERT(k==NbCrackedEdges);
-
-		//Add new vertices
-		if (verbose>4) printf("      number of Cracked Vertices = %i\n",NbCrackedVertices);
-		if (NbCrackedVertices){
-			CrackedVertices=(long*)xmalloc(2*NbCrackedVertices*sizeof(double));
-			num=0;
-			for (i=0;i<nbv;i++){
-				if (splitvertex[i]==2){
-					CrackedVertices[num*2+0]=i;      //index of first vertex
-					CrackedVertices[num*2+1]=nbv+num;//index of new vertex
-					num++;
-				}
-			}
-			ISSMASSERT(num==NbCrackedVertices);
-		}
-		delete [] splitvertex;
-
-		//Now, find the triangles that hold a cracked edge
-		ReMakeTriangleContainingTheVertex();
-
-		long* Edgeflags=new long[NbCrackedEdges];
-		for(i=0;i<NbCrackedEdges;i++) Edgeflags[i]=0;
-
-		for(i=0;i<NbCrackedEdges;i++){
-			//Get the numbers of the 2 vertices of the crren cracked edge
-			i1=Number((*CrackedEdges[i].e1)[0]);
-			i2=Number((*CrackedEdges[i].e1)[1]);
-
-			//find a triangle holding the vertex i1 (first vertex of the ith cracked edge)
-			Triangle* tbegin=vertices[i1].t;
-			k=vertices[i1].vint;//local number of i in triangle tbegin
-			ISSMASSERT(Number((*tbegin)[k])==Number(vertices[i1]));
-
-			//Now, we are going to go through the adjacent triangle that hold i1 till
-			//we find one that has the cracked edge
-			TriangleAdjacent ta(tbegin,EdgesVertexTriangle[k][0]);
-			count=0;
-			do {
-				for(j=0;j<3;j++){
-					//Find the position of i1 in the triangle index
-					if (Number((*ta.t)[j])==i1){
-						j1=j;
-						break;
-					}
-				}
-				for(j=0;j<3;j++){
-					//Check wether i2 is also in the triangle index
-					if (Number((*ta.t)[j])==i2){
-						j2=j;
-						//Invert j1 and j2 if necessary
-						if ((j1+1)%3==j2){
-							int j3=j1;
-							j1=j2;
-							j2=j3;
-						}
-						if (Edgeflags[i]==0){
-							//first element
-							CrackedEdges[i].a=ta.t;
-							CrackedEdges[i].length=Norme2((*ta.t)[j1].r-(*ta.t)[j2].r);
-							CrackedEdges[i].normal=Orthogonal((*ta.t)[j1].r-(*ta.t)[j2].r);
-						}
-						else{
-							//Second element -> to renumber
-							CrackedEdges[i].b=ta.t;
-							CrackedEdges[i].length=Norme2((*ta.t)[j1].r-(*ta.t)[j2].r);
-							CrackedEdges[i].normal=Orthogonal((*ta.t)[j1].r-(*ta.t)[j2].r);
-						}
-						Edgeflags[i]++;
-						break;
-					}
-				}
-				//printf("%i -> %i %i %i, edge [%i->%i %i->%i]\n",element_renu[Number(ta.t)],Number((*ta.t)[0])+1,Number((*ta.t)[1])+1,Number((*ta.t)[2])+1,i1,j1,i2,j2);
-				ta = Next(ta).Adj(); 
-				if (count++>50) ISSMERROR("Maximum number of iteration exceeded");
-			}while ((tbegin != ta)); 
-		}
-
-		//Check EdgeFlag
-		for(i=0;i<NbCrackedEdges;i++){
-			if (Edgeflags[i]!=2){
-				ISSMERROR("A problem occured: at least one crack edge (number %i) does not belong to 2 elements",i+1);
-			}
-		}
-		delete [] Edgeflags;
-
-		//Reset MeshVertex to On
-		SetVertexFieldOn();
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ForceBoundary{{{1*/
-		void Triangles::ForceBoundary() {
-			/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ForceBoundary)*/
-
-			long int verbose=2;
-			int k=0;
-			int nbfe=0,nbswp=0,Nbswap=0;
-
-			//display
-			if (verbose > 2) printf("   ForceBoundary  nb of edge: %i\n",nbe);
-
-			//check that there is no triangle with 0 determinant
-			for (int t = 0; t < nbt; t++){
-				if (!triangles[t].det) k++;
-			}
-			if (k!=0) {
-				ISSMERROR("there is %i triangles of mes = 0",k);
-			}
-
-			//Force Edges
-			TriangleAdjacent ta(0,0);
-			for (int i = 0; i < nbe; i++){
-
-				//Force edge i
-				nbswp =  ForceEdge(edges[i][0],edges[i][1],ta);
-				if (nbswp<0) k++;
-				else Nbswap += nbswp;
-
-				if (nbswp) nbfe++;
-				if ( nbswp < 0 && k < 5){
-					ISSMERROR("Missing Edge %i, v0=%i,v1=%i",i,Number(edges[i][0]),Number(edges[i][1]));
-				}
-			}
-
-			if (k!=0) {
-				ISSMERROR("There are %i lost edges, the boundary might be crossing",k);
-			}
-			for (int j=0;j<nbv;j++){
-				Nbswap +=  vertices[j].Optim(1,0);
-			}
-			if (verbose > 3) printf("      number of inforced edge = %i, number of swap= %i\n",nbfe,Nbswap); 
-		}
-	/*}}}1*/
-	/*FUNCTION Triangles::FindSubDomain{{{1*/
-	void Triangles::FindSubDomain(int OutSide) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FindSubDomain)*/
-
-		long int verbose=0;
-
-		if (verbose >2){
-			if (OutSide) printf("   Find all external sub-domain\n"); 
-			else printf("   Find all internal sub-domain\n");
-		  }
-		short * HeapArete = new short[nbt];
-		Triangle  **  HeapTriangle = new Triangle*  [nbt];
-		Triangle *t,*t1;
-		long k,it;
-
-		for (int itt=0;itt<nbt;itt++) 
-		 triangles[itt].link=0; // par defaut pas de couleur
-
-		long  NbSubDomTot =0;
-		for ( it=0;it<nbt;it++)  { 
-			if ( ! triangles[it].link  ) {
-				t = triangles + it;
-				NbSubDomTot++;; // new composante connexe
-				long i = 0; // niveau de la pile 
-				t->link = t ; // sd forme d'un triangle cicular link
-
-				HeapTriangle[i] =t ; 
-				HeapArete[i] = 3;
-
-				while (i >= 0) // boucle sur la pile
-				  { while ( HeapArete[i]--) // boucle sur les 3 aretes 
-					  { 
-						int na =  HeapArete[i];
-						Triangle * tc =  HeapTriangle[i]; // triangle courant
-						if( ! tc->Locked(na)) // arete non frontiere
-						  {
-							Triangle * ta = tc->TriangleAdj(na) ; // næ triangle adjacent
-							if (ta->link == 0 ) // non deja chainer => on enpile
-							  { 
-								i++;
-								ta->link = t->link ;  // on chaine les triangles
-								t->link = ta ;  // d'un meme sous domaine          
-								HeapArete[i] = 3; // pour les 3 triangles adjacents
-								HeapTriangle[i] = ta;
-							  }}
-					  } // deplie fin de boucle sur les 3 adjacences
-					i--;
-				  }          
-			}      
-		}
-
-		// supression de tous les sous domaine infini <=>  contient le sommet NULL
-		it =0;
-		NbOutT = 0;
-		while (it<nbt) {
-			if (triangles[it].link) 
-			  { 
-				if (!( triangles[it](0) &&  triangles[it](1) &&  triangles[it](2) )) 
-				  {
-					// infini triangle 
-					NbSubDomTot --;
-					t=&triangles[it];
-					NbOutT--;  // on fait un coup de trop. 
-					while  (t){
-						NbOutT++;
-						t1=t;
-						t=t->link;
-						t1->link=0;
-					}
-				  }
-			  }   
-			it++;} // end while (it<nbt)
-			if (nbt == NbOutT ||  !NbSubDomTot) {
-				ISSMERROR("The boundary is not close: all triangles are outside");
-			}
-
-			delete [] HeapArete;
-			delete [] HeapTriangle;
-
-
-			if (OutSide|| !Gh.subdomains || !Gh.NbSubDomains ) 
-			  { // No geom sub domain
-				long i;
-				if (subdomains) delete [] subdomains;
-				subdomains = new SubDomain[ NbSubDomTot];
-				NbSubDomains=  NbSubDomTot;
-				for ( i=0;i<NbSubDomains;i++) {
-					subdomains[i].head=NULL;
-					subdomains[i].ref=i+1;
-				}
-				long * mark = new long[nbt];
-				for (it=0;it<nbt;it++)
-				 mark[it]=triangles[it].link ? -1 : -2;
-
-				it =0;
-				k = 0;
-				while (it<nbt) {
-					if (mark[it] == -1) {
-						t1 = & triangles[it];
-						t = t1->link;
-						mark[it]=k;
-						subdomains[k].head = t1;
-						do {
-							mark[Number(t)]=k;
-							t=t->link;
-						} while (t!=t1);
-						mark[it]=k++;}
-						//    else if(mark[it] == -2 ) triangles[it].Draw(999);
-						it++;} // end white (it<nbt)
-						if (k!=NbSubDomains){
-							ISSMERROR("k!=NbSubDomains");
-						}
-						if(OutSide) 
-						  {
-							//  to remove all the sub domain by parity adjacents
-							//  because in this case we have only the true boundary edge
-							// so teh boundary is manifold
-							long nbk = NbSubDomains;
-							while (nbk)
-							 for (it=0;it<nbt && nbk ;it++)
-							  for (int na=0;na<3 && nbk ;na++)
-								 {
-								  Triangle *ta = triangles[it].TriangleAdj(na);
-								  long kl = ta ? mark[Number(ta)] : -2;
-								  long kr = mark[it];
-								  if(kr !=kl) {
-									  if (kl >=0 && subdomains[kl].ref <0 && kr >=0 && subdomains[kr].ref>=0)
-										nbk--,subdomains[kr].ref=subdomains[kl].ref-1;
-									  if (kr >=0 && subdomains[kr].ref <0 && kl >=0 && subdomains[kl].ref>=0)
-										nbk--,subdomains[kl].ref=subdomains[kr].ref-1;
-									  if(kr<0 && kl >=0 && subdomains[kl].ref>=0)
-										nbk--,subdomains[kl].ref=-1;
-									  if(kl<0 && kr >=0 && subdomains[kr].ref>=0)
-										nbk--,subdomains[kr].ref=-1;
-								  }
-								 }
-							long  j=0;
-							for ( i=0;i<NbSubDomains;i++)
-							 if((-subdomains[i].ref) %2) { // good 
-								 if(i != j) 
-								  Exchange(subdomains[i],subdomains[j]);
-								 j++;}
-							 else{ 
-								 t= subdomains[i].head;
-								 while (t){
-									 NbOutT++;
-									 t1=t;
-									 t=t->link;
-									 t1->link=0;
-								 }//while (t)
-								}
-							if(verbose>4) printf("      Number of removes subdomains (OutSideMesh) = %i\n",NbSubDomains-j);
-							NbSubDomains=j;
-						  }
-
-						delete []  mark; 
-
-			  }
-			else
-			  { // find the head for all sub domaine
-				if (Gh.NbSubDomains != NbSubDomains && subdomains)
-				 delete [] subdomains, subdomains=0;
-				if (! subdomains  ) 
-				 subdomains = new SubDomain[ Gh.NbSubDomains];
-				NbSubDomains =Gh.NbSubDomains;
-				long err=0;
-				ReMakeTriangleContainingTheVertex();
-				long * mark = new long[nbt];
-				Edge **GeometricalEdgetoEdge = MakeGeometricalEdgeToEdge();
-
-				for (it=0;it<nbt;it++)
-				 mark[it]=triangles[it].link ? -1 : -2;
-				long inew =0;
-				for (int i=0;i<NbSubDomains;i++) {
-					GeometricalEdge &eg = *Gh.subdomains[i].edge;
-					subdomains[i].ref = Gh.subdomains[i].ref;
-					int ssdlab = subdomains[i].ref;
-					// by carefull is not easy to find a edge create from a GeometricalEdge 
-					// see routine MakeGeometricalEdgeToEdge
-					Edge &e = *GeometricalEdgetoEdge[Gh.Number(eg)];
-					if (&e==NULL){
-						ISSMERROR("&e==NULL");
-					}
-					MeshVertex * v0 =  e(0),*v1 = e(1);
-					Triangle *t  = v0->t;
-					int sens = Gh.subdomains[i].sens;
-					// test if ge and e is in the same sens 
-					if (((eg[0].r-eg[1].r),(e[0].r-e[1].r))<0) sens = -sens ;
-					subdomains[i].sens = sens;
-					subdomains[i].edge = &e;
-					if (!t || !sens){
-						ISSMERROR("!t || !sens");
-					}
-
-					TriangleAdjacent  ta(t,EdgesVertexTriangle[v0->vint][0]);// previous edges
-
-					while (1) {
-						if ( v0 != ta.EdgeVertex(1) ){
-							ISSMERROR("v0 != ta.EdgeVertex(1)");
-						}
-						if (ta.EdgeVertex(0) == v1) { // ok we find the edge
-							if (sens>0)  
-							 subdomains[i].head=t=Adj(ta);
-							else 
-							 subdomains[i].head=t=ta;
-							if(t<triangles || t >= triangles+nbt || t->det < 0 || t->link == 0) {
-								ISSMERROR("bad definition of SubSomain %i",i);
-							}
-							long it = Number(t);
-							if (mark[it] >=0) {
-								break;
-							}
-							if(i != inew) 
-							 Exchange(subdomains[i],subdomains[inew]);
-							inew++;
-							Triangle *tt=t;
-							long kkk=0;
-							do 
-							  {
-								kkk++;
-								if (mark[Number(tt)]>=0){
-									ISSMERROR("mark[Number(tt)]>=0");
-								}
-								mark[Number(tt)]=i;
-								tt=tt->link;
-							  } while (tt!=t);
-							break;
-						}
-						ta = Previous(Adj(ta));         
-						if(t == (Triangle *) ta) {
-							ISSMERROR("bad definition of SubSomain %i",i);
-						}
-					}
-				}
-
-				if (inew < NbSubDomains) {
-					if (verbose>5) printf("WARNING: %i SubDomains are being removed\n",NbSubDomains-inew);
-					NbSubDomains=inew;}
-
-
-					for (it=0;it<nbt;it++)
-					 if ( mark[it] ==-1 ) 
-					  NbOutT++,triangles[it].link =0;
-					delete [] GeometricalEdgetoEdge;
-					delete [] mark;
-
-			  }
-			NbOutT=0;
-			for (it=0;it<nbt;it++) 
-			 if(!triangles[it].link)  NbOutT++;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::FindTriangleContaining{{{1*/
-	Triangle * Triangles::FindTriangleContaining(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FindTriangleContening)*/
-
-		Triangle * t=0;	
-		int j,jp,jn,jj;
-		int counter;
-
-		/*Get starting triangle. Take tsart if provided*/
-		if (tstart){
-			t=tstart;
-		}
-		/*Else find the closest Triangle using the quadtree*/
-		else {
-
-			/*Check that the quadtree does exist*/
-			if (!quadtree) ISSMERROR("no starting triangle provided and no quadtree available");
-
-			/*Call NearestVertex*/
-			MeshVertex *a = quadtree->NearestVertex(B.x,B.y) ;
-
-			/*Check output (Vertex a)*/
-			if (!a)    ISSMERROR("problem while trying to find nearest vertex from a given point. No output found");
-			if (!a->t) ISSMERROR("no triangle is associated to vertex number %i (another call to ReMakeTriangleContainingTheVertex is required)",Number(a)+1);
-			ISSMASSERT(a>=vertices && a<vertices+nbv);
-
-			/*Get starting triangle*/
-			t = a->t;
-			ISSMASSERT(t>=triangles && t<triangles+nbt);
-		}
-
-		Icoor2  detop ;
-
-		/*initialize number of test triangle*/
-		counter=0; 
-
-		/*The initial triangle might be outside*/
-		while (t->det < 0){ 
-
-			/*Get a real vertex from this triangle (k0)*/
-			int k0=(*t)(0)?(((*t)(1)?((*t)(2)?-1:2):1)):0;
-			ISSMASSERT(k0>=0);// k0 the NULL vertex
-			int k1=NextVertex[k0],k2=PreviousVertex[k0];
-			dete[k0]=det(B,(*t)[k1],(*t)[k2]);
-			dete[k1]=dete[k2]=-1;     
-			if (dete[k0] > 0) // outside B 
-			 return t; 
-			t = t->TriangleAdj(OppositeEdge[k0]);
-			counter++;
-			ISSMASSERT(counter<2);
-		}
-
-		jj=0;
-		detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
-
-		while(t->det>0) { 
-
-			/*Increase counter*/
-			if (++counter>=10000) ISSMERROR("Maximum number of iteration reached (threshold = %i).",counter);
-
-			j= OppositeVertex[jj];
-			dete[j] = detop;  //det(*b,*s1,*s2);
-			jn = NextVertex[j];
-			jp = PreviousVertex[j];
-			dete[jp]= det(*(*t)(j),*(*t)(jn),B);
-			dete[jn] = t->det-dete[j] -dete[jp];
-
-			// count the number k of  dete <0
-			int k=0,ii[3];
-			if (dete[0] < 0 ) ii[k++]=0; 
-			if (dete[1] < 0 ) ii[k++]=1;
-			if (dete[2] < 0 ) ii[k++]=2;
-			// 0 => ok
-			// 1 => go in way 1
-			// 2 => two way go in way 1 or 2 randomly
-
-			if (k==0) break;
-			if (k == 2 && BinaryRand()) Exchange(ii[0],ii[1]);
-			if ( k>=3){
-				ISSMERROR("k>=3");
-			}
-			TriangleAdjacent t1 = t->Adj(jj=ii[0]);
-			if ((t1.det() < 0 ) && (k == 2))
-			 t1 = t->Adj(jj=ii[1]);
-			t=t1;
-			j=t1;// for optimisation we now the -det[OppositeVertex[j]];
-			detop = -dete[OppositeVertex[jj]];
-			jj = j;
-		}
-
-		if (t->det<0) // outside triangle 
-		 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
-		//  NbOfTriangleSearchFind += counter;  
-		return t;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::GeomToTriangles0{{{1*/
-	void Triangles::GeomToTriangles0(long inbvx,BamgOpts* bamgopts){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/GeomToTriangles0)*/
-
-		/*Generate mesh from geometry*/
-
-		Gh.NbRef++;// add a ref to GH
-
-		int i,j,k;
-		int NbOfCurves=0,NbNewPoints,NbEdgeCurve;
-		double lcurve,lstep,s;
-		const int MaxSubEdge = 10;
-
-		R2 AB;
-		GeometricalVertex *a,*b;
-		MeshVertex *va,*vb;
-		GeometricalEdge *e;
-
-		/*Get options*/
-		int verbose=bamgopts->verbose;
-
-		//initialize this
-		if (verbose>3) printf("      Generating Boundary vertices\n");
-		PreInit(inbvx);
-		nbv=0;
-		NbVerticesOnGeomVertex=0;
-		NbVerticesOnGeomEdge=0;
-
-		//build background mesh flag (1 if background, else 0)
-		int  background=(&BTh != this);
-
-		//Compute number of vertices on geometrical vertex
-		for (i=0;i<Gh.nbv;i++){
-			if (Gh[i].Required() && Gh[i].IsThe()) NbVerticesOnGeomVertex++;
-		}
-
-		//initialize VerticesOnGeomVertex
-		VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];  
-		if( NbVerticesOnGeomVertex >= nbvx) {
-			ISSMERROR("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx);
-		}
-
-		//Add all the geometrical vertices to the mesh
-		nbv=0;
-		for (i=0;i<Gh.nbv;i++){
-			/* Add vertex only if required and not duplicate 
-			 * (IsThe is a method of GeometricalVertex that checks
-			 * that we are taking into acount only one vertex is
-			 * 2 vertices are superimposed) */
-			if (Gh[i].Required() && Gh[i].IsThe()) {//Gh  vertices Required
-
-				//Add the vertex (provided that nbv<nbvx)
-				if (nbv<nbvx){
-					vertices[nbv]=Gh[i];
-				}
-				else{
-					ISSMERROR("Maximum number of vertices (nbvx = %i) too small",nbvx);
-				}
-				
-				//Add pointer from geometry (Gh) to vertex from mesh (Th)
-				Gh[i].to=vertices+nbv;
-
-				//Build VerticesOnGeomVertex for current point
-				VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
-
-				//nbv increment
-				nbv++;
-			}
-		}
-
-		//check that edges has been allocated
-		if (edges){
-			ISSMERROR("edges is empty");
-		}
-
-		/* Now we are going to create the first edges corresponding
-		 * to the one present in the geometry provided.
-		 * We proceed in 2 steps
-		 *  -step 1: we count all the edges
-		 *           we allocate the number of edges at the end of step 1
-		 *  -step 2: the edges are created */
-		for (int step=0;step<2;step++){
-
-			//initialize number of edges and number of edges max
-			long nbex=0;
-			nbe=0;
-			long NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
-			Gh.UnMarkEdges();	
-			NbOfCurves=0;
-
-			//go through the edges of the geometry
-			for (i=0;i<Gh.nbe;i++) {
-
-				//ei = current Geometrical edge
-				GeometricalEdge &ei=Gh.edges[i];   
-
-				for(int j=0;j<2;j++) {
-
-					/*The first time, no edge is marked but this might change during the loop*/
-					if (!ei.Mark() && ei[j].Required()){ 
-
-						long  nbvend=0;
-						Edge* PreviousNewEdge=NULL;
-
-						lstep = -1;
-
-						/*If Edge is required*/
-						if(ei.Required()){
-							//do not create internal points if required (take it as is)
-							if (j==0){
-								if(step==0) nbe++;
-								else{ 
-									e=&ei;
-									a=ei(0)->The();
-									b=ei(1)->The();
-
-									//check that edges has been allocated
-									if (!edges) ISSMERROR("edges has not been allocated...");
-									edges[nbe].v[0]=a->to;
-									edges[nbe].v[1]=b->to;;
-									edges[nbe].ref = e->ref;
-									edges[nbe].onGeometry = e;
-									edges[nbe].adj[0] = 0;
-									edges[nbe].adj[1] = 0;
-									nbe++;
-								}
-							}
-						}
-
-						/*If Edge is not required: on a curve*/
-						else {
-							for (int kstep=0;kstep<=step;kstep++){
-								//step=0, do nothing
-								//step=1, compute the length of the curve
-								//step=2  create the points and edge
-								PreviousNewEdge=0;
-								NbNewPoints=0;
-								NbEdgeCurve=0;
-								if (nbvend>=nbvx) ISSMERROR("maximum number of vertices too low! Check the domain outline or increase nbvx");
-								lcurve =0;
-								s = lstep;
-
-								// i = edge number, j=[0;1] vertex number in edge
-
-								k=j;            // k = vertex number in edge (0 or 1)
-								e=&ei;          // e = reference of current edge
-								a=ei(k)->The(); // a = pointer toward the kth vertex of the current edge
-								va = a->to;     // va = pointer toward vertex associated
-								e->SetMark();   // Mark edge
-
-								//if SameGeo We have go to the background geometry 
-								//to find the discretisation of the curve
-								for(;;){ 
-									k = 1-k;
-									b = (*e)(k)->The();// b = pointer toward the other vertex of the current edge
-									AB= b->r - a->r;   // AB = vector of the current edge
-									Metric MA = background ? BTh.MetricAt(a->r) :a->m ;  //Get metric associated to A
-									Metric MB =  background ? BTh.MetricAt(b->r) :b->m ; //Get metric associated to B
-									double ledge = (MA(AB) + MB(AB))/2;                   //Get edge length in metric
-
-									/* We are now creating the edges of the mesh from the
-									 * geometrical edge selected above.
-									 * The edge will be divided according to the metric
-									 * previously computed and cannot be divided more
-									 * than 10 times (MaxSubEdge). */
-
-									//By default, there is only one subedge that is the geometrical edge itself
-									int NbSubEdge = 1;
-
-									//initialize lSubEdge, holding the length of each subedge (cannot be higher than 10)
-									double lSubEdge[MaxSubEdge];
-
-									//Build Subedges according to the edge length
-									//if ledge < 1.5 (between one and 2), take the edge as is
-									if (ledge < 1.5) lSubEdge[0] = ledge;
-									//else, divide the edge
-									else {
-										//compute number of subedges (division of the edge)
-										NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
-										//A and B are the position of points on the edge
-										R2 A,B;
-										A=a->r;
-										Metric MAs=MA,MBs;
-										ledge=0; 
-										double x =0, xstep= 1./NbSubEdge;
-										for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
-											x += xstep;
-											B =  e->F(k ? x : 1-x);
-											MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
-											AB = A-B;
-											lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
-										}
-									}
-
-									double lcurveb = lcurve+ ledge ;
-
-									//Now, create corresponding points
-									while (lcurve<=s && s <= lcurveb && nbv < nbvend){
-
-										double ss = s-lcurve;
-
-										/*Find the SubEdge containing ss using Dichotomy*/
-
-										int kk0=-1,kk1=NbSubEdge-1,kkk;
-										double ll0=0,ll1=ledge,llk;
-										while (kk1-kk0>1){
-											if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
-											 kk1=kkk,ll1=llk;
-											else
-											 kk0=kkk,ll0=llk;
-										}
-										ISSMASSERT(kk1!=kk0);
-
-										double sbb = (ss-ll0  )/(ll1-ll0);
-										double bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
-
-										// new vertex on edge
-										vb = &vertices[nbv++];
-										vb->m = Metric(aa,a->m,bb,b->m);
-										vb->ReferenceNumber = e->ref;
-										vb->DirOfSearch =NoDirOfSearch;
-										double abcisse = k ? bb : aa;
-										vb->r =  e->F( abcisse );
-										VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);        
-
-										// to take into account the direction of the edge
-										s += lstep;
-										edges[nbe].v[0]=va;
-										edges[nbe].v[1]=vb;
-										edges[nbe].ref =e->ref;
-										edges[nbe].onGeometry = e;
-										edges[nbe].adj[0] = PreviousNewEdge;
-										if(PreviousNewEdge) PreviousNewEdge->adj[1]=&edges[nbe];
-										PreviousNewEdge=edges+nbe;
-										nbe++;
-										va = vb;
-									}
-									lcurve = lcurveb;
-									e->SetMark();
-									a=b;
-									if (b->Required() ) break;
-									int kprev=k;
-									k = e->DirAdj[kprev];// next vertices
-									e = e->Adj[kprev];
-									ISSMASSERT(e);
-								}// for(;;)
-								vb = b->to;
-								NbEdgeCurve = Max((long) (lcurve +0.5), (long) 1);
-								NbNewPoints = NbEdgeCurve-1;
-								if(!kstep){
-									NbVerticesOnGeomEdge0 += NbNewPoints;
-									NbOfCurves++;
-								}
-								nbvend=nbv+NbNewPoints; 
-								lstep = lcurve / NbEdgeCurve;
-							}// end of curve --
-							if (edges) { // last edges of the curves 
-								edges[nbe].v[0]=va;
-								edges[nbe].v[1]=vb;
-								edges[nbe].ref = e->ref;
-								edges[nbe].onGeometry = e;
-								edges[nbe].adj[0] = PreviousNewEdge;
-								edges[nbe].adj[1] = 0;
-								if(PreviousNewEdge) PreviousNewEdge->adj[1] = & edges[nbe];
-								nbe++;
-							}
-							else nbe += NbEdgeCurve;
-						} // end on  curve ---
-					}
-				}
-			} // for (i=0;i<nbe;i++)
-			if(!step) {
-				if (edges){
-					ISSMERROR("edges");
-				}
-				if (VerticesOnGeomEdge){
-					ISSMERROR("VerticesOnGeomEdge");
-				}
-				edges = new Edge[nbex=nbe];
-				if(NbVerticesOnGeomEdge0)
-				 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
-				if (!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0){
-					ISSMERROR("!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0");
-				}
-				// do the vertex on a geometrical vertex
-				NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
-			}
-			else if (NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0){
-				ISSMERROR("NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0");
-			}
-		}
-
-		//Insert points inside existing triangles
-		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
-		if (verbose>3) printf("      Creating initial Constrained Delaunay Triangulation...\n");
-		if (verbose>3) printf("         Inserting boundary points\n");
-		Insert();
-
-		//Force the boundary
-		if (verbose>3) printf("         Forcing boundaries\n");
-		ForceBoundary();
-
-		//Extract SubDomains
-		if (verbose>3) printf("         Extracting subdomains\n");
-		FindSubDomain();
-
-		if (verbose>3) printf("      Inserting internal points\n");
-		NewPoints(*this,bamgopts,0) ;
-		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::GeomToTriangles1{{{1*/
-	void Triangles::GeomToTriangles1(long inbvx,BamgOpts* bamgopts,int KeepVertices){ 
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/GeomToTriangles1)*/
-
-		/*Get options*/
-		int verbose=bamgopts->verbose;
-
-		Gh.NbRef++;// add a ref to Gh
-
-		/************************************************************************* 
-		 * method in 2 steps
-		 * 1 - compute the number of new edges to allocate
-		 * 2 - construct the edges
-		 * remark:
-		 * in this part we suppose to have a background mesh with the same geometry 
-		 * 
-		 * To construct the discretization of the new mesh we have to 
-		 * rediscretize the boundary of background Mesh 
-		 * because we have only the pointeur from the background mesh to the geometry.
-		 * We need the abcisse of the background mesh vertices on geometry
-		 * so a vertex is 
-		 * 0 on GeometricalVertex ;
-		 * 1 on GeometricalEdge + abcisse
-		 * 2 internal 
-		 *************************************************************************/
-
-		//Check that background mesh and current mesh do have the same geometry
-		ISSMASSERT(&BTh.Gh==&Gh);
-		BTh.NbRef++; // add a ref to BackGround Mesh
-
-		//Initialize new mesh
-		this->PreInit(inbvx);
-		BTh.SetVertexFieldOn();
-		int* bcurve = new int[Gh.NbOfCurves]; // 
-
-		/* There are 2 ways to make the loop 
-		* 1) on the geometry 
-		* 2) on the background mesh
-		*  if you do the loop on geometry, we don't have the pointeur on background,
-		*  and if you do the loop in background we have the pointeur on geometry
-		* so do the walk on  background */
-
-		NbVerticesOnGeomVertex=0;
-		NbVerticesOnGeomEdge=0;
-
-		/*STEP 1 copy of Required vertices*/
-
-		int i; 
-		for (i=0;i<Gh.nbv;i++) if (Gh[i].Required()) NbVerticesOnGeomVertex++;
-		if(NbVerticesOnGeomVertex >= nbvx) { ISSMERROR("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx);}
-
-		VerticesOnGeomVertex = new VertexOnGeom[  NbVerticesOnGeomVertex];
-		VertexOnBThVertex    = new VertexOnVertex[NbVerticesOnGeomVertex];
-
-		//At this point there is NO vertex but vertices should have been allocated by PreInit
-		ISSMASSERT(vertices);
-		for (i=0;i<Gh.nbv;i++){
-			if (Gh[i].Required()) {//Gh vertices Required
-				vertices[nbv]  =Gh[i];
-				vertices[nbv].i=I2(0,0);
-				Gh[i].to = vertices + nbv;// save Geom -> Th
-				VerticesOnGeomVertex[nbv]= VertexOnGeom(vertices[nbv],Gh[i]);
-				nbv++;
-			}
-			else Gh[i].to=0;
-		} 
-		for (i=0;i<BTh.NbVerticesOnGeomVertex;i++){ 
-			VertexOnGeom &vog=BTh.VerticesOnGeomVertex[i];
-			if (vog.IsRequiredVertex()){
-				GeometricalVertex* gv=vog;
-				MeshVertex *bv = vog;
-				ISSMASSERT(gv->to); // use of Geom -> Th
-				VertexOnBThVertex[NbVertexOnBThVertex++]=VertexOnVertex(gv->to,bv);
-				gv->to->m = bv->m; // for taking the metrix of the background mesh
-			}
-		}
-		ISSMASSERT(NbVertexOnBThVertex==NbVerticesOnGeomVertex);
-
-		/*STEP 2: reseed boundary edges*/
-
-		//  find the begining of the curve in BTh
-		Gh.UnMarkEdges();	
-		int bfind=0;
-		for (int i=0;i<Gh.NbOfCurves;i++) bcurve[i]=-1; 
-
-		/*Loop over the backgrounf mesh BTh edges*/
-		for (int iedge=0;iedge<BTh.nbe;iedge++){      
-			Edge &ei = BTh.edges[iedge];
-
-			/*Loop over the 2 vertices of the current edge*/
-			for(int je=0;je<2;je++){
-
-				/* If one of the vertex is required we are in a new curve*/
-				if (ei[je].onGeometry->IsRequiredVertex()){ 
-
-					/*Get curve number*/
-					int nc=ei.onGeometry->CurveNumber;
-					
-					//printf("Dealing with curve number %i\n",nc);
-					//printf("edge on geometry is same as GhCurve? %s\n",(ei.onGeometry==Gh.curves[nc].be || ei.onGeometry==Gh.curves[nc].ee)?"yes":"no");
-					//if(ei.onGeometry==Gh.curves[nc].be || ei.onGeometry==Gh.curves[nc].ee){
-					//	printf("Do we have the right extremity? curve first vertex -> %s\n",((GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].be)[Gh.curves[nc].kb])?"yes":"no");
-					//	printf("Do we have the right extremity? curve last  vertex -> %s\n",((GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].ee)[Gh.curves[nc].ke])?"yes":"no");
-					//}
-					//BUG FIX from original bamg
-					/*Check that we are on the same edge and right vertex (0 or 1) */
-					if(ei.onGeometry==Gh.curves[nc].be  && (GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].be)[Gh.curves[nc].kb]){
-						bcurve[nc]=iedge*2+je;
-						bfind++;	
-					}
-					else if ((ei.onGeometry==Gh.curves[nc].ee  && (GeometricalVertex *)*ei[je].onGeometry==&(*Gh.curves[nc].ee)[Gh.curves[nc].ke]) && bcurve[nc]==-1){
-						bcurve[nc]=iedge*2+je;
-						bfind++;	
-					}
-				}
-			}
-		} 
-		if (bfind!=Gh.NbOfCurves) ISSMERROR("problem generating number of curves (Gh.NbOfCurves=%i bfind=%i)",Gh.NbOfCurves,bfind);
-
-		// method in 2 + 1 step 
-		//  0.0) compute the length and the number of vertex to do allocation
-		//  1.0) recompute the length
-		//  1.1) compute the  vertex 
-
-		long nbex=0,NbVerticesOnGeomEdgex=0;
-		for (int step=0; step <2;step++){
-
-			long NbOfNewPoints=0;
-			long NbOfNewEdge=0;
-			long iedge;
-			Gh.UnMarkEdges();	
-			double L=0;
-
-			/*Go through all geometrical curve*/
-			for (int icurve=0;icurve<Gh.NbOfCurves;icurve++){ 
-
-				/*Get edge and vertex (index) of background mesh on this curve*/
-				iedge=bcurve[icurve]/2;
-				int jedge=bcurve[icurve]%2;
-
-				/*Skip if we are on a equi curve (duplicate)*/
-				if(!Gh.curves[icurve].master) continue; 
-
-				/*Get edge of Bth with index iedge*/
-				Edge &ei = BTh.edges[iedge];
-			
-				/*Initialize variables*/
-				double Lstep=0,Lcurve=0;    // step between two points   (phase==1) 
-				long NbCreatePointOnCurve=0;// Nb of new points on curve (phase==1) 
-
-				/*Do phase 0 to step*/
-				for(int phase=0;phase<=step;phase++){
-
-					/*Loop over all curves from icurve till the last curve*/
-					for(Curve *curve= Gh.curves+icurve;curve;curve= curve->next){
-
-						/*Get index of current curve*/
-						int icurveequi= Gh.Number(curve);
-
-						/*For phase 0, check that we are at the begining of the curve only*/
-						if(phase==0 &&  icurveequi!=icurve)  continue;
-
-						int   k0=jedge,k1;
-						Edge* pe=  BTh.edges+iedge;
-						int   iedgeequi=bcurve[icurveequi]/2;
-						int   jedgeequi=bcurve[icurveequi]%2;
-
-						int k0equi=jedgeequi,k1equi;		  
-						Edge * peequi= BTh.edges+iedgeequi;
-						GeometricalEdge *ongequi = peequi->onGeometry;
-
-						double sNew=Lstep;// abscisse of the new points (phase==1) 
-						L=0;// length of the curve
-						long i=0;// index of new points on the curve
-						register GeometricalVertex * GA0 = *(*peequi)[k0equi].onGeometry;
-						MeshVertex *A0;
-						A0 = GA0->to;  // the vertex in new mesh
-						MeshVertex *A1;
-						VertexOnGeom *GA1;
-						Edge* PreviousNewEdge = 0;
-
-						// New Curve phase 
-						ISSMASSERT(A0-vertices>=0 && A0-vertices<nbv);
-						if(ongequi->Required()){
-							GeometricalVertex *GA1 = *(*peequi)[1-k0equi].onGeometry;
-							A1 = GA1->to;  //
-						}       
-						else {
-							for(;;){
-								Edge &ee=*pe; 
-								Edge &eeequi=*peequi; 
-								k1 = 1-k0; // next vertex of the edge 
-								k1equi= 1 - k0equi;
-								ISSMASSERT(pe && ee.onGeometry);
-								ee.onGeometry->SetMark();
-								MeshVertex & v0=ee[0], & v1=ee[1];
-								R2 AB=(R2)v1-(R2)v0;
-								double L0=L,LAB;
-								LAB=LengthInterpole(v0.m,v1.m,AB);
-								L+= LAB;
-
-								if (phase){
-									// computation of the new points for the given curve
-									while ((i!=NbCreatePointOnCurve) && sNew<=L) { 
-
-										//some checks
-										ISSMASSERT(sNew>=L0);
-										ISSMASSERT(LAB);
-										ISSMASSERT(vertices && nbv<nbvx);
-										ISSMASSERT(edges && nbe<nbex);
-										ISSMASSERT(VerticesOnGeomEdge && NbVerticesOnGeomEdge<NbVerticesOnGeomEdgex);
-
-										// new vertex on edge
-										A1=vertices+nbv++;
-										GA1=VerticesOnGeomEdge+NbVerticesOnGeomEdge;
-										Edge* e = edges + nbe++;
-										double se= (sNew-L0)/LAB;
-										if (se<0 || se>=1.000000001){
-											ISSMERROR("Problem creating point on a boundary: se=%g should be in [0 1]",se);
-										}
-										se = abscisseInterpole(v0.m,v1.m,AB,se,1);
-										if (se<0 || se>1){
-											ISSMERROR("Problem creating point on a boundary: se=%g should be in [0 1]",se);
-										}
-										se = k1         ? se : 1. - se;
-										se = k1==k1equi ? se : 1. - se;
-										VertexOnBThEdge[NbVerticesOnGeomEdge++] = VertexOnEdge(A1,&eeequi,se); // save 
-										ongequi=Gh.ProjectOnCurve(eeequi,se,*A1,*GA1); 
-										A1->ReferenceNumber = eeequi.ref;
-										A1->DirOfSearch =NoDirOfSearch;
-										e->onGeometry = ongequi;
-										e->v[0]=A0;
-										e->v[1]=A1;
-										e->ref = eeequi.ref;
-										e->adj[0]=PreviousNewEdge;
-
-										if (PreviousNewEdge) PreviousNewEdge->adj[1]=e;
-										PreviousNewEdge=e;
-										A0=A1;
-										sNew += Lstep;
-										if (++i== NbCreatePointOnCurve) break;
-									}
-								}
-
-								//some checks
-								ISSMASSERT(ee.onGeometry->CurveNumber==ei.onGeometry->CurveNumber);
-								if (ee[k1].onGeometry->IsRequiredVertex()) {
-									ISSMASSERT(eeequi[k1equi].onGeometry->IsRequiredVertex());
-									register GeometricalVertex * GA1 = *eeequi[k1equi].onGeometry;
-									A1=GA1->to;// the vertex in new mesh
-									ISSMASSERT(A1-vertices>=0 && A1-vertices<nbv);
-									break;
-								}
-								if (!ee.adj[k1]) {
-									ISSMERROR(" adj edge %i, nbe=%i, Gh.vertices=%i",BTh.Number(ee),nbe,Gh.vertices);
-								}
-								pe = ee.adj[k1]; // next edge
-								k0 = pe->Intersection(ee); 
-								peequi= eeequi.adj[k1equi];  // next edge
-								k0equi=peequi->Intersection(eeequi);            
-							}// for(;;) end of the curve
-						}
-
-
-						if (phase){ // construction of the last edge
-							Edge* e=edges + nbe++;
-							e->onGeometry  = ongequi;
-							e->v[0]=A0;
-							e->v[1]=A1;
-							e->ref = peequi->ref;
-							e->adj[0]=PreviousNewEdge;
-							e->adj[1]=0;
-							if (PreviousNewEdge) PreviousNewEdge->adj[1]=e;
-							PreviousNewEdge = e;
-
-							ISSMASSERT(i==NbCreatePointOnCurve);
-						}
-					} //  end loop on equi curve 
-
-					if (!phase)  { // 
-						long NbSegOnCurve = Max((long)(L+0.5),(long) 1);// nb of seg
-						Lstep = L/NbSegOnCurve; 
-						Lcurve = L;
-						NbCreatePointOnCurve = NbSegOnCurve-1;
-
-						for(Curve * curve= Gh.curves+icurve;curve;curve= curve->next){
-							NbOfNewEdge += NbSegOnCurve;
-							NbOfNewPoints += NbCreatePointOnCurve;
-						}
-					}
-				}
-			}//  end of curve loop 
-
-			//Allocate memory
-			if(step==0){
-				if(nbv+NbOfNewPoints > nbvx) {
-					ISSMERROR("too many vertices on geometry: %i >= %i",nbv+NbOfNewPoints,nbvx);
-				}
-				edges = new Edge[NbOfNewEdge];
-				nbex = NbOfNewEdge;
-				if(NbOfNewPoints) {
-					VerticesOnGeomEdge    = new VertexOnGeom[NbOfNewPoints];
-					NbVertexOnBThEdge     = NbOfNewPoints;
-					VertexOnBThEdge       = new  VertexOnEdge[NbOfNewPoints];
-					NbVerticesOnGeomEdgex = NbOfNewPoints;
-				}
-				NbOfNewPoints =0;
-				NbOfNewEdge = 0;
-			}
-		}
-		ISSMASSERT(nbe!=0);
-		delete [] bcurve;
-
-		//Insert points inside existing triangles
-		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
-		if (verbose>3) printf("      Creating initial Constrained Delaunay Triangulation...\n");
-		if (verbose>3) printf("         Inserting boundary points\n");
-		Insert();
-
-		//Force the boundary
-		if (verbose>3) printf("         Forcing boundaries\n");
-		ForceBoundary();
-
-		//Extract SubDomains
-		if (verbose>3) printf("         Extracting subdomains\n");
-		FindSubDomain();
-
-		if (verbose>3) printf("      Inserting internal points\n");
-		NewPoints(BTh,bamgopts,KeepVertices) ;
-		if (verbose>4) printf("      -- current number of vertices = %i\n",nbv);
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::Insert{{{1*/
-	void Triangles::Insert() {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/Insert)*/
-
-		/*Insert points in the existing Geometry*/
-
-		//Intermediary
-		int i;
-
-		/*Get options*/
-		long int verbose=2;
-
-		//Display info
-		if (verbose>2) printf("   Insert initial %i vertices\n",nbv);
-
-		//Compute integer coordinates and determinants for the existing vertices (from Geometry)
-		SetIntCoor();
-
-		/*Now we want to build a list (ordre) of the vertices in a random
-		 * order. To do so, we use the following method:
-		 *
-		 * From an initial k0 in [0 nbv[ random (vertex number)
-		 * the next k (vertex number) is computed using a big
-		 * prime number (PN>>nbv) following:
-		 *
-		 * k_{i+1} = k_i + PN  [nbv]
-		 *
-		 * let's show that:
-		 *
-		 *   for all j in [0 nbv[, ∃! i in [0 nbv[ such that k_i=j
-		 *
-		 * Let's assume that there are 2 distinct j1 and j2 such that
-		 * k_j1 = k_j2
-		 *
-		 * This means that
-		 *  
-		 *  k0+j1*PN = k0+j2*PN [nbv]
-		 *  (j1-j2)*PN =0       [nbv]
-		 * since PN is a prime number larger than nbv, and nbv!=1
-		 *  j1-j2=0             [nbv]
-		 * BUT
-		 *  j1 and j2 are in [0 nbv[ which is impossible.
-		 *
-		 *  We hence have built a random list of nbv elements of
-		 *  [0 nbv[ all distincts*/
-		for (i=0;i<nbv;i++) ordre[i]= &vertices[i] ;
-		const long PrimeNumber= BigPrimeNumber(nbv) ;
-		int   k0=rand()%nbv; 
-		for (int is3=0; is3<nbv; is3++){
-			ordre[is3]= &vertices[k0=(k0+PrimeNumber)%nbv];
-		}
-
-		/*Modify ordre such that the first 3 vertices form a triangle*/
-
-		//get first vertex i such that [0,1,i] are not aligned
-		for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;){
-			//if i is higher than nbv, it means that all the determinants are 0,
-			//all vertices are aligned!
-			if  ( ++i >= nbv) {
-				ISSMERROR("all the vertices are aligned");
-			}
-		}
-		// exchange i et 2 in "ordre" so that
-		// the first 3 vertices are not aligned (real triangle)
-		Exchange(ordre[2], ordre[i]);
-
-		/*Take the first edge formed by the first two vertices and build
-		 * the initial simple mesh from this edge and 2 boundary triangles*/
-
-		MeshVertex *  v0=ordre[0], *v1=ordre[1];
-
-		nbt = 2;
-		triangles[0](0) = NULL; //infinite vertex
-		triangles[0](1) = v0;
-		triangles[0](2) = v1;
-		triangles[1](0) = NULL;//infinite vertex
-		triangles[1](2) = v0;
-		triangles[1](1) = v1;
-
-		//Build adjacence
-		const int e0 = OppositeEdge[0];
-		const int e1 = NextEdge[e0];
-		const int e2 = PreviousEdge[e0];
-		triangles[0].SetAdj2(e0, &triangles[1] ,e0);
-		triangles[0].SetAdj2(e1, &triangles[1] ,e2);
-		triangles[0].SetAdj2(e2, &triangles[1] ,e1);
-
-		triangles[0].det = -1;  //boundary triangle: det = -1
-		triangles[1].det = -1;  //boundary triangle: det = -1
-
-		triangles[0].SetTriangleContainingTheVertex();
-		triangles[1].SetTriangleContainingTheVertex();
-
-		triangles[0].link=&triangles[1];
-		triangles[1].link=&triangles[0];
-
-		//build quadtree
-		if (!quadtree)  quadtree = new QuadTree(this,0);
-		quadtree->Add(*v0);
-		quadtree->Add(*v1);
-
-		/*Now, add the vertices One by One*/
-
-		long NbSwap=0;
-		if (verbose>3) printf("   Begining of insertion process...\n");
-
-		for (int icount=2; icount<nbv; icount++) {
-
-			//Get new vertex
-			MeshVertex *newvertex=ordre[icount];
-
-			//Find the triangle in which newvertex is located
-			Icoor2 dete[3];
-			Triangle* tcvi = FindTriangleContaining(newvertex->i,dete); //(newvertex->i = integer coordinates)
-
-			//Add newvertex to the quadtree
-			quadtree->Add(*newvertex); 
-
-			//Add newvertex to the existing mesh
-			AddVertex(*newvertex,tcvi,dete);
-
-			//Make the mesh Delaunay around newvertex by swaping the edges
-			NbSwap += newvertex->Optim(1,0);
-		}
-
-		//Display info
-		if (verbose>3) {
-			printf("      NbSwap of insertion: %i\n",NbSwap);
-			printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
-		}
-
-#ifdef NBLOOPOPTIM
-
-		k0 = rand()%nbv ; 
-		for (int is4=0; is4<nbv; is4++) 
-		 ordre[is4]= &vertices[k0 = (k0 + PrimeNumber)% nbv];
-
-		for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++){
-			long  NbSwap = 0;
-			for (int is1=0; is1<nbv; is1++) 
-			 NbSwap += ordre[is1]->Optim(0,0);
-			if (verbose>3) {
-				printf("      Optim Loop: %i\n",Nbloop);
-				printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
-			}
-			if(!NbSwap) break;
-		}
-		ReMakeTriangleContainingTheVertex(); 
-		// because we break the TriangleContainingTheVertex
-#endif
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::InsertNewPoints{{{1*/
-	long Triangles::InsertNewPoints(long nbvold,long & NbTSwap) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/InsertNewPoints)*/
-
-		long int verbose=0;
-		double seuil= 1.414/2 ;// for two close point 
-		long i;
-		long NbSwap=0;
-		Icoor2 dete[3];
-
-		//number of new points
-		const long nbvnew=nbv-nbvold;
-
-		//display info if required
-		if (verbose>5) printf("      Try to Insert %i new points\n",nbvnew);
-
-		//return if no new points
-		if (!nbvnew) return 0; 
-
-		/*construction of a random order*/
-		const long PrimeNumber= BigPrimeNumber(nbv)  ;
-		//remainder of the division of rand() by nbvnew
-		long k3 = rand()%nbvnew;
-		//loop over the new points
-		for (int is3=0; is3<nbvnew; is3++){
-			register long j=nbvold +(k3 = (k3+PrimeNumber)%nbvnew);
-			register long i=nbvold+is3; 
-			ordre[i]= vertices + j;
-			ordre[i]->ReferenceNumber=i;
-		}
-
-		// for all the new point
-		long iv=nbvold;
-		for (i=nbvold;i<nbv;i++){
-			MeshVertex &vi=*ordre[i];
-			vi.i=toI2(vi.r);
-			vi.r=toR2(vi.i);
-			double hx,hy;
-			vi.m.Box(hx,hy);
-			Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
-			if (!quadtree->ToClose(vi,seuil,hi,hj)){
-				// a good new point 
-				MeshVertex &vj = vertices[iv];
-				long  j=vj.ReferenceNumber; 
-				if (&vj!=ordre[j]){
-					ISSMERROR("&vj!= ordre[j]");
-				}
-				if(i!=j){ 
-					Exchange(vi,vj);
-					Exchange(ordre[j],ordre[i]);
-				}
-				vj.ReferenceNumber=0; 
-				Triangle *tcvj=FindTriangleContaining(vj.i,dete);
-				if (tcvj && !tcvj->link){
-					tcvj->Echo();
-					ISSMERROR("problem inserting point in InsertNewPoints (tcvj=%p and tcvj->link=%i)",tcvj,tcvj->link);
-				}
-				quadtree->Add(vj);
-				AddVertex(vj,tcvj,dete);
-				NbSwap += vj.Optim(1);          
-				iv++;
-			}
-		} 
-		if (verbose>3) {
-			printf("         number of new points: %i\n",iv);
-			printf("         number of to close (?) points: %i\n",nbv-iv);
-			printf("         number of swap after: %i\n",NbSwap);
-		}
-		nbv = iv;
-
-		for (i=nbvold;i<nbv;i++) NbSwap += vertices[i].Optim(1);  
-		if (verbose>3) printf("   NbSwap=%i\n",NbSwap);
-
-		NbTSwap +=  NbSwap ;
-		return nbv-nbvold;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
-	Edge** Triangles::MakeGeometricalEdgeToEdge() {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeGeometricalEdgeToEdge)*/
-
-		if (!Gh.nbe){
-			ISSMERROR("!Gh.nbe");
-		}
-		Edge **e= new (Edge* [Gh.nbe]);
-
-		long i;
-		for ( i=0;i<Gh.nbe ; i++)
-		 e[i]=NULL;
-		for ( i=0;i<nbe ; i++) 
-		  { 
-			Edge * ei = edges+i;
-			GeometricalEdge *onGeometry = ei->onGeometry; 
-			e[Gh.Number(onGeometry)] = ei;    
-		  }
-		for ( i=0;i<nbe ; i++) 
-		 for (int ii=0;ii<2;ii++) { 
-			 Edge * ei = edges+i;
-			 GeometricalEdge *onGeometry = ei->onGeometry;
-			 int j= ii;
-			 while (!(*onGeometry)[j].Required()) { 
-				 Adj(onGeometry,j); // next geom edge
-				 j=1-j;
-				 if (e[Gh.Number(onGeometry)])  break; // optimisation
-				 e[Gh.Number(onGeometry)] = ei; 
-			 }
-		 }
-
-		int kk=0;
-		for ( i=0;i<Gh.nbe ; i++){
-			if (!e[i]){
-				kk++;
-				if(kk<10) printf("BUG: the geometrical edge %i is on no edge curve\n",i);
-			}
-		}
-		if(kk) ISSMERROR("See above");
-
-		return e;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeQuadrangles{{{1*/
-	void Triangles::MakeQuadrangles(double costheta){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeQuadrangles)*/
-
-		long int verbose=0;
-
-		if (verbose>2) printf("MakeQuadrangles costheta = %g\n",costheta);
-
-		if (costheta >1) {
-			if (verbose>5) printf("   do nothing: costheta > 1\n");
-		}
-
-
-			long nbqq = (nbt*3)/2;
-			DoubleAndInt *qq = new DoubleAndInt[nbqq];
-
-			long i,ij;
-			int j;
-			long k=0;
-			for (i=0;i<nbt;i++)
-			 for (j=0;j<3;j++)
-			  if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
-				qq[k++].i3j=i*3+j;
-			//  sort  qq
-			HeapSort(qq,k);
-
-			long kk=0;
-			for (ij=0;ij<k;ij++) { 
-				i=qq[ij].i3j/3;
-				j=(int) (qq[ij].i3j%3);
-				// optisamition no float computation  
-				if (triangles[i].QualityQuad(j,0) >=costheta) 
-				 triangles[i].SetHidden(j),kk++;
-			  }
-			NbOfQuad = kk;
-			if (verbose>2){
-				printf("   number of quadrilaterals    = %i\n",NbOfQuad);
-				printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
-				printf("   number of outside triangles = %i\n",NbOutT);
-			}
-			delete [] qq;
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MakeQuadTree{{{1*/
-	void Triangles::MakeQuadTree() {  
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MakeQuadTree)*/
-
-		long int verbose=0;
-		if (  !quadtree )  quadtree = new QuadTree(this);
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MaxSubDivision{{{1*/
-	void  Triangles::MaxSubDivision(double maxsubdiv) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/MaxSubDivision)*/
-
-		long int verbose=0;
-
-		const  double maxsubdiv2 = maxsubdiv*maxsubdiv;
-		if(verbose>1) printf("   Limit the subdivision of a edges in the new mesh by %g\n",maxsubdiv);
-		// for all the edges 
-		// if the len of the edge is to long 
-		long it,nbchange=0;    
-		double lmax=0;
-		for (it=0;it<nbt;it++){
-			Triangle &t=triangles[it];
-			for (int j=0;j<3;j++){
-				Triangle &tt = *t.TriangleAdj(j);
-				if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link)){
-					MeshVertex &v0 = t[VerticesOfTriangularEdge[j][0]];
-					MeshVertex &v1 = t[VerticesOfTriangularEdge[j][1]];
-					R2 AB= (R2) v1-(R2) v0;
-					Metric M = v0;
-					double l = M(AB,AB);
-					lmax = Max(lmax,l);
-					if(l> maxsubdiv2){
-					  R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
-						double lc = M(AC,AC);
-						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
-						D2xD2 Rt1(Rt.inv());
-						D2xD2 D(maxsubdiv2,0,0,lc);
-						D2xD2 MM = Rt1*D*Rt1.t();
-						v0.m =  M = Metric(MM.x.x,MM.y.x,MM.y.y);
-						nbchange++;
-					}
-					M = v1;
-					l = M(AB,AB);
-					lmax = Max(lmax,l);
-					if(l> maxsubdiv2){
-					  R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
-						double lc = M(AC,AC);
-						D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
-						D2xD2 Rt1(Rt.inv());
-						D2xD2 D(maxsubdiv2,0,0,lc);
-						D2xD2  MM = Rt1*D*Rt1.t();
-						v1.m =  M = Metric(MM.x.x,MM.y.x,MM.y.y);
-						nbchange++;
-					}
-				}
-			}
-		}
-		if(verbose>3){
-			printf("      number of metric changes = %i, maximum number of subdivision of a edges before change = %g\n",nbchange,pow(lmax,0.5));
-		}
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::MetricAt{{{1*/
-	Metric Triangles::MetricAt(const R2 & A) const { 
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/MetricAt)*/
-
-		I2 a = toI2(A);
-		Icoor2 deta[3];
-		Triangle * t =FindTriangleContaining(a,deta);
-		if (t->det <0) { // outside
-			double ba,bb;
-			TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
-			return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
-		else { // inside
-			double   aa[3];
-			double s = deta[0]+deta[1]+deta[2];
-			aa[0]=deta[0]/s;
-			aa[1]=deta[1]/s;
-			aa[2]=deta[2]/s;
-			return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
-		}
-	}
-	/*}}}1*/
-/*FUNCTION Triangles::NearestVertex{{{1*/
-MeshVertex* Triangles::NearestVertex(Icoor1 i,Icoor1 j) {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NearestVertex)*/
-	return  quadtree->NearestVertex(i,j); 
-} 
-/*}}}1*/
-	/*FUNCTION Triangles::NewPoints{{{1*/
-	void  Triangles::NewPoints(Triangles & Bh,BamgOpts* bamgopts,int KeepVertices){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/NewPoints)*/
-
-		int i,j,k;
-		long NbTSwap=0;
-		long nbtold=nbt;
-		long nbvold=nbv;
-		long Headt=0;
-		long next_t;
-		long* first_np_or_next_t=new long[nbtx];
-		Triangle* t=NULL;
-
-		/*Recover options*/
-		int verbose=bamgopts->verbose;
-
-		/*First, insert old points if requested*/
-		if (KeepVertices && (&Bh != this) && (nbv+Bh.nbv< nbvx)){
-			if (verbose>5) printf("         Inserting initial mesh points\n");
-			for (i=0;i<Bh.nbv;i++){ 
-				MeshVertex &bv=Bh[i];
-				if (!bv.onGeometry){
-					vertices[nbv].r   = bv.r;
-					vertices[nbv++].m = bv.m;
-				}
-			}
-			Bh.ReMakeTriangleContainingTheVertex();     
-			InsertNewPoints(nbvold,NbTSwap)   ;            
-		}  
-		else Bh.ReMakeTriangleContainingTheVertex();     
-
-		// generation of the list of next Triangle 
-		for(i=0;i<nbt;i++) first_np_or_next_t[i]=-(i+1);
-		// the next traingle of i is -first_np_or_next_t[i]
-
-		// Big loop (most time consuming)
-		int iter=0;
-		if (verbose>5) printf("         Big loop\n");
-		do {
-			/*Update variables*/
-			iter++;
-			nbtold=nbt;
-			nbvold=nbv;
-
-			/*We test all triangles*/
-			i=Headt;
-			next_t=-first_np_or_next_t[i];
-			for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i]){
-
-				//check i
-				if (i<0 || i>=nbt ){
-					ISSMERROR("Index problem in NewPoints (i=%i not in [0 %i])",i,nbt-1);
-				}
-				//change first_np_or_next_t[i]
-				first_np_or_next_t[i] = iter; 
-
-				//Loop over the edges of t
-				for(j=0;j<3;j++){
-					TriangleAdjacent tj(t,j);
-					MeshVertex &vA = *tj.EdgeVertex(0);
-					MeshVertex &vB = *tj.EdgeVertex(1);
-
-					//if t is a boundary triangle, or tj locked, continue
-					if (!t->link)     continue;
-					if (t->det <0)    continue;
-					if (t->Locked(j)) continue;
-
-					TriangleAdjacent tadjj = t->Adj(j);	  
-					Triangle* ta=tadjj;
-
-					//if the adjacent triangle is a boundary triangle, continur
-					if (ta->det<0) continue;	  
-
-					R2 A=vA;
-					R2 B=vB;
-					k=Number(ta);
-
-					//if this edge has already been done, go to next edge of triangle
-					if(first_np_or_next_t[k]==iter) continue;
-
-					lIntTria.SplitEdge(Bh,A,B);
-					lIntTria.NewPoints(vertices,nbv,nbvx);
-				  } // end loop for each edge 
-			  }// for triangle   
-
-			if (!InsertNewPoints(nbvold,NbTSwap)) break;
-			for (i=nbtold;i<nbt;i++) first_np_or_next_t[i]=iter;
-			Headt = nbt; // empty list 
-
-			// for all the triangle containing the vertex i
-			for (i=nbvold;i<nbv;i++){ 
-				MeshVertex*          s  = vertices + i;
-				TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
-				Triangle*        tbegin= (Triangle*) ta;
-				long kt;
-				do { 
-					kt = Number((Triangle*) ta);
-					if (first_np_or_next_t[kt]>0){
-						first_np_or_next_t[kt]=-Headt;
-						Headt=kt;
-					}
-					if (ta.EdgeVertex(0)!=s){
-						ISSMERROR("ta.EdgeVertex(0)!=s");
-					}
-					ta = Next(Adj(ta));
-				} while ( (tbegin != (Triangle*) ta)); 
-			}
-
-		} while (nbv!=nbvold);
-
-		delete []  first_np_or_next_t;
-
-		long NbSwapf =0,NbSwp;
-
-		NbSwp = NbSwapf;
-		for (i=0;i<nbv;i++)
-		 NbSwapf += vertices[i].Optim(0);
-		NbTSwap +=  NbSwapf ;
-	}
-	/*}}}1*/
-/*FUNCTION Triangles::PreInit{{{1*/
-void Triangles::PreInit(long inbvx) {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/PreInit)*/
-
-	long int verbose=0;
-
-	srand(19999999);
-	NbRef=0;
-	//  allocGeometry=0;
-	NbOfTriangleSearchFind =0;
-	NbOfSwapTriangle =0;
-	nbiv=0;
-	nbv=0;
-	nbvx=inbvx;
-	nbt=0;
-	NbOfQuad = 0;
-	nbtx=2*inbvx-2;
-	NbSubDomains=0;
-	NbVertexOnBThVertex=0;
-	NbVertexOnBThEdge=0;
-	VertexOnBThVertex=NULL;
-	VertexOnBThEdge=NULL;
-
-	NbCrackedVertices=0;
-	CrackedVertices  =NULL;  
-	NbCrackedEdges   =0;
-	CrackedEdges     =NULL;  
-	nbe = 0; 
-
-	if (inbvx) {
-		vertices=new MeshVertex[nbvx];
-		if (!vertices){
-			ISSMERROR("!vertices");
-		}
-		ordre=new (MeshVertex* [nbvx]);
-		if (!ordre){
-			ISSMERROR("!ordre");
-		}
-		triangles=new Triangle[nbtx];
-		if (!triangles){
-			ISSMERROR("!triangles");
-		}
-	}
-	else {
-		vertices=NULL;
-		ordre=NULL;
-		triangles=NULL;
-		nbtx=0;
-	} 
-
-	quadtree=NULL;
-	edges=NULL;
-	VerticesOnGeomVertex=NULL;
-	VerticesOnGeomEdge=NULL;
-	NbVerticesOnGeomVertex=0;
-	NbVerticesOnGeomEdge=0;
-	subdomains=NULL;
-	NbSubDomains=0;
-}
-/*}}}1*/
-	/*FUNCTION Triangles::ProjectOnCurve{{{1*/
-	GeometricalEdge*   Triangles::ProjectOnCurve( Edge & BhAB, MeshVertex &  vA, MeshVertex & vB,
-				double theta,MeshVertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshQuad.cpp/ProjectOnCurve)*/
-
-		void *pA=0,*pB=0;
-		double tA=0,tB=0;
-		R2 A=vA,B=vB;
-		MeshVertex * pvA=&vA, * pvB=&vB;
-		if (vA.vint == IsVertexOnVertex){
-			pA=vA.onBackgroundVertex;
-		}
-		else if (vA.vint == IsVertexOnEdge){
-			pA=vA.onBackgroundEdge->be;
-			tA=vA.onBackgroundEdge->abcisse;
-		}
-		else {
-			ISSMERROR("ProjectOnCurve On MeshVertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vA));
-		} 
-
-		if (vB.vint == IsVertexOnVertex){
-			pB=vB.onBackgroundVertex;
-		}
-		else if(vB.vint == IsVertexOnEdge){
-			pB=vB.onBackgroundEdge->be;
-			tB=vB.onBackgroundEdge->abcisse;
-		}
-		else {
-			ISSMERROR("ProjectOnCurve On MeshVertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vB));
-		} 
-		Edge * e = &BhAB;
-		if (!pA || !pB || !e){
-			ISSMERROR("!pA || !pB || !e");
-		}
-		// be carefull the back ground edge e is on same geom edge 
-		// of the initiale edge def by the 2 vertex A B;
-		//check Is a background Mesh;   
-		if (e<BTh.edges || e>=BTh.edges+BTh.nbe){
-			ISSMERROR("e<BTh.edges || e>=BTh.edges+BTh.nbe");
-		}
-		// walk on BTh edge 
-		//not finish ProjectOnCurve with BackGround Mesh);
-		// 1 first find a back ground edge contening the vertex A
-		// 2 walk n back gound boundary to find the final vertex B
-
-		if( vA.vint == IsVertexOnEdge) 
-		  { // find the start edge 
-			e = vA.onBackgroundEdge->be;	 
-
-		  } 
-		else if (vB.vint == IsVertexOnEdge) 
-		  {
-			theta = 1-theta;
-			Exchange(tA,tB);
-			Exchange(pA,pB);
-			Exchange(pvA,pvB);
-			Exchange(A,B);
-			e =  vB.onBackgroundEdge->be;
-
-		  } 
-		else{ // do the search by walking 
-			ISSMERROR("case not supported yet");
-		  }
-
-		// find the direction of walking with sens of edge and pA,PB;
-		R2 AB=B-A;
-
-		double cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
-		int kkk=0;
-		int sens = (cosE01AB>0) ? 1 : 0;
-
-		//   double l=0; // length of the edge AB
-		double abscisse = -1;
-
-		for (int cas=0;cas<2;cas++){
-			// 2 times algo:
-			//    1 for computing the length l
-			//    2 for find the vertex 
-			int  iii;
-			MeshVertex  *v0=pvA,*v1; 
-			Edge *neee,*eee;
-			double lg =0; // length of the curve 
-			double te0;
-			// we suppose take the curve's abcisse 
-			for ( eee=e,iii=sens,te0=tA;
-						eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
-						neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii ) { 
-
-				kkk=kkk+1;
-				if (kkk>=100){
-					ISSMERROR("kkk>=100");
-				}
-				if (!eee){
-					ISSMERROR("!eee");
-				}
-				double lg0 = lg;
-				double dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
-				lg += dp;
-				if (cas && abscisse <= lg) { // ok we find the geom edge 
-					double sss  =   (abscisse-lg0)/dp;
-					double thetab = te0*(1-sss)+ sss*iii;
-					if (thetab<0 || thetab>1){
-						ISSMERROR("thetab<0 || thetab>1");
-					}
-					BR = VertexOnEdge(&R,eee,thetab);
-					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
-				  }
-			  }
-			// we find the end 
-			if (v1 != pvB){
-				if (( void*) v1 == pB)
-				 tB = iii;
-
-				double lg0 = lg;
-				if (!eee){
-					ISSMERROR("!eee");
-				}
-				v1 = pvB;
-				double dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
-				lg += dp;	
-				abscisse = lg*theta;
-				if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
-				  { // ok we find the geom edge 
-					double sss  =   (abscisse-lg0)/dp;
-					double thetab = te0*(1-sss)+ sss*tB;
-					if (thetab<0 || thetab>1){
-						ISSMERROR("thetab<0 || thetab>1");
-					}
-					BR = VertexOnEdge(&R,eee,thetab);
-					return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
-				  }
-			  }
-			abscisse = lg*theta;
-
-		  }
-		ISSMERROR("Big bug...");
-		return 0; // just for the compiler 
-	}                  
-	/*}}}1*/
-/*FUNCTION Triangles::ReconstructExistingMesh{{{1*/
-void Triangles::ReconstructExistingMesh(){
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/FillHoleInMesh)*/
-
-	/*This routine reconstruct an existing mesh to make it CONVEX:
-	 * -all the holes are filled
-	 * -concave boundaries are filled
-	 * A convex mesh is required for a lot of operations. This is why every mesh
-	 * goes through this process.
-	 * This routine also generates mesh properties such as adjencies,...
-	 */
-
-	/*Intermediary*/
-	int verbose=0;
-
-	// generation of the integer coordinate
-
-	// find extrema coordinates of vertices pmin,pmax
-	long i;
-	if(verbose>2) printf("      Reconstruct mesh of %i vertices\n",nbv); 
-
-	//initialize ordre
-	ISSMASSERT(ordre);
-	for (i=0;i<nbv;i++) ordre[i]=0;
-
-	//Initialize NbSubDomains
-	NbSubDomains =0;
-
-	/* generation of triangles adjacency*/
-
-	//First add existing edges
-	long kk =0;
-	SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
-	for (i=0;i<nbe;i++){
-		kk=kk+(i==edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1])));
-	}
-	if (kk != nbe){ 
-		ISSMERROR("There are %i double edges in the mesh",kk-nbe);
-	}
-
-	//Add edges of all triangles in existing mesh
-	long* st = new long[nbt*3];
-	for (i=0;i<nbt*3;i++) st[i]=-1;
-	for (i=0;i<nbt;i++){
-		for (int j=0;j<3;j++){
-
-			//Add current triangle edge to edge4
-			long k =edge4->SortAndAdd(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
-
-			long invisible=triangles[i].Hidden(j);
-
-			//If the edge has not been added to st, add it
-			if(st[k]==-1) st[k]=3*i+j;
-
-			//If the edge already exists, add adjacency
-			else if(st[k]>=0) {
-				ISSMASSERT(!triangles[i].TriangleAdj(j));
-				ISSMASSERT(!triangles[st[k]/3].TriangleAdj((int) (st[k]%3)));
-
-				triangles[i].SetAdj2(j,triangles+st[k]/3,(int)(st[k]%3));
-				if (invisible) triangles[i].SetHidden(j);
-				if (k<nbe)     triangles[i].SetLocked(j);
-
-				//Make st[k] negative so that it will throw an error message if it is found again
-				st[k]=-2-st[k]; 
-			}
-
-			//An edge belongs to 2 triangles
-			else {
-				ISSMERROR("The edge (%i , %i) belongs to more than 2 triangles",Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
-			}
-		}
-	}
-
-	//Display info if required
-	if(verbose>5) {
-		printf("         info of Mesh:\n");
-		printf("            - number of vertices    = %i \n",nbv); 
-		printf("            - number of triangles   = %i \n",nbt); 
-		printf("            - number of given edges = %i \n",nbe); 
-		printf("            - number of all edges   = %i \n"  ,edge4->nb()); 
-		printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv); 
-	}
-
-	//check the consistency of edge[].adj and the geometrical required vertex
-	long k=0;
-	for (i=0;i<edge4->nb();i++){
-		if (st[i]>=0){ // edge alone 
-			if (i<nbe){
-				long i0=edge4->i(i);
-				ordre[i0] = vertices+i0;
-				long i1=edge4->j(i);
-				ordre[i1] = vertices+i1;
-			}
-			else {
-				k=k+1;
-				if (k<10) {
-					//print only 10 edges
-					printf("Lost boundary edges %i : %i %i\n",i,edge4->i(i),edge4->j(i));
-				}
-				else if (k==10){
-					printf("Other lost boundary edges not shown...\n");
-				}
-			}
-		}
-	}
-	if(k) {
-		ISSMERROR("%i boundary edges (from the geometry) are not defined as mesh edges",k);
-	}
-
-	/* mesh generation with boundary points*/
-	long nbvb=0;
-	for (i=0;i<nbv;i++){ 
-		vertices[i].t=0;
-		vertices[i].vint=0;
-		if (ordre[i]) ordre[nbvb++]=ordre[i];
-	}
-
-	Triangle* savetriangles=triangles;
-	long savenbt=nbt;
-	long savenbtx=nbtx;
-	SubDomain* savesubdomains=subdomains;
-	subdomains=0;
-
-	long  Nbtriafillhole=2*nbvb;
-	Triangle* triafillhole=new Triangle[Nbtriafillhole];
-	triangles = triafillhole;
-
-	nbt=2;
-	nbtx= Nbtriafillhole;
-
-	//Find a vertex that is not aligned with vertices 0 and 1
-	for (i=2;det(ordre[0]->i,ordre[1]->i,ordre[i]->i)==0;) 
-	 if  (++i>=nbvb) {
-		 ISSMERROR("ReconstructExistingMesh: All the vertices are aligned");
-	 }
-	//Move this vertex (i) to the 2d position in ordre
-	Exchange(ordre[2], ordre[i]);
-
-	/*Reconstruct mesh beginning with 2 triangles*/
-	MeshVertex *  v0=ordre[0], *v1=ordre[1];
-
-	triangles[0](0) = NULL; // Infinite vertex
-	triangles[0](1) = v0;
-	triangles[0](2) = v1;
-
-	triangles[1](0) = NULL;// Infinite vertex
-	triangles[1](2) = v0;
-	triangles[1](1) = v1;
-	const int e0 = OppositeEdge[0];
-	const int e1 = NextEdge[e0];
-	const int e2 = PreviousEdge[e0];
-	triangles[0].SetAdj2(e0, &triangles[1] ,e0);
-	triangles[0].SetAdj2(e1, &triangles[1] ,e2);
-	triangles[0].SetAdj2(e2, &triangles[1] ,e1);
-
-	triangles[0].det = -1;  // boundary triangles
-	triangles[1].det = -1;  // boundary triangles
-
-	triangles[0].SetTriangleContainingTheVertex();
-	triangles[1].SetTriangleContainingTheVertex();
-
-	triangles[0].link=&triangles[1];
-	triangles[1].link=&triangles[0];
-
-	if (!quadtree) delete quadtree; //ReInitialise;
-	quadtree = new QuadTree(this,0);
-	quadtree->Add(*v0);
-	quadtree->Add(*v1);
-
-	// vertices are added one by one
-	long NbSwap=0;
-	for (int icount=2; icount<nbvb; icount++) {
-		MeshVertex *vi  = ordre[icount];
-		Icoor2 dete[3];
-		Triangle *tcvi = FindTriangleContaining(vi->i,dete);
-		quadtree->Add(*vi); 
-		AddVertex(*vi,tcvi,dete);
-		NbSwap += vi->Optim(1,1);
-	}
-
-	//enforce the boundary 
-	TriangleAdjacent ta(0,0);
-	long nbloss = 0,knbe=0;
-	for ( i = 0; i < nbe; i++){
-		if (st[i] >=0){ //edge alone => on border
-			MeshVertex &a=edges[i][0], &b=edges[i][1];
-			if (a.t && b.t){
-				knbe++;
-				if (ForceEdge(a,b,ta)<0) nbloss++;
-			}
-		}
-	}
-	if(nbloss) {
-		ISSMERROR("we lost %i existing edges other %i",nbloss,knbe);
-	}
-
-	FindSubDomain(1);
-	// remove all the hole 
-	// remove all the good sub domain
-	long krm =0;
-	for (i=0;i<nbt;i++){
-		if (triangles[i].link){ // remove triangles
-			krm++;
-			for (int j=0;j<3;j++){
-				TriangleAdjacent ta =  triangles[i].Adj(j);
-				Triangle &tta = *(Triangle*)ta;
-				//if edge between remove and not remove 
-				if(! tta.link){ 
-					// change the link of ta;
-					int ja = ta;
-					MeshVertex *v0= ta.EdgeVertex(0);
-					MeshVertex *v1= ta.EdgeVertex(1);
-					long k =edge4->SortAndAdd(v0?Number(v0):nbv,v1? Number(v1):nbv);
-
-					ISSMASSERT(st[k]>=0);
-					tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
-					ta.SetLock();
-					st[k]=-2-st[k]; 
-				}
-			}
-		}
-	}
-	long NbTfillHoll =0;
-	for (i=0;i<nbt;i++){
-		if (triangles[i].link) {
-			triangles[i]=Triangle((MeshVertex *) NULL,(MeshVertex *) NULL,(MeshVertex *) NULL);
-			triangles[i].color=-1;
-		}
-		else{
-			triangles[i].color= savenbt+ NbTfillHoll++;
-		}
-	}
-	ISSMASSERT(savenbt+NbTfillHoll<=savenbtx);
-
-	// copy of the outside triangles in saveTriangles 
-	for (i=0;i<nbt;i++){
-		if(triangles[i].color>=0) {
-			savetriangles[savenbt]=triangles[i];
-			savetriangles[savenbt].link=0;
-			savenbt++;
-		}
-	}
-	// gestion of the adj
-	k =0;
-	Triangle * tmax = triangles + nbt;
-	for (i=0;i<savenbt;i++) { 
-		Triangle & ti = savetriangles[i];
-		for (int j=0;j<3;j++){
-			Triangle * ta = ti.TriangleAdj(j);
-			int aa = ti.NuEdgeTriangleAdj(j);
-			int lck = ti.Locked(j);
-			if (!ta) k++; // bug 
-			else if ( ta >= triangles && ta < tmax){
-				ta= savetriangles + ta->color;
-				ti.SetAdj2(j,ta,aa);
-				if(lck) ti.SetLocked(j);
-			}
-		}
-	}
-
-	// restore triangles;
-	nbt=savenbt;
-	nbtx=savenbtx;
-	delete [] triangles;
-	delete [] subdomains;
-	triangles = savetriangles;
-	subdomains = savesubdomains;
-	if (k) {
-		ISSMERROR("number of triangles edges alone = %i",k);
-	}
-	FindSubDomain();
-
-	delete edge4;
-	delete [] st;
-	for (i=0;i<nbv;i++) quadtree->Add(vertices[i]);
-
-	SetVertexFieldOn();
-
-	/*Check requirements consistency*/
-	for (i=0;i<nbe;i++){
- 	/*If the current mesh edge is on Geometry*/
-		if(edges[i].onGeometry){
-			for(int j=0;j<2;j++){
-				/*Go through the edges adjacent to current edge (if on the same curve)*/
-				if (!edges[i].adj[j]){
-					/*The edge is on Geometry and does not have 2 adjacent edges... (not on a closed curve)*/
-					/*Check that the 2 vertices are on geometry AND required*/
-					if(!edges[i][j].onGeometry->IsRequiredVertex()){
-						printf("ReconstructExistingMesh error message: problem with the edge number %i: [%i %i]\n",i+1,Number(edges[i][0])+1,Number(edges[i][1])+1);
-						printf("This edge is on geometrical edge number %i\n",Gh.Number(edges[i].onGeometry)+1);
-						if (edges[i][j].onGeometry->OnGeomVertex())
-						 printf("the vertex number %i of this edge is a geometric MeshVertex number %i\n",Number(edges[i][j])+1,Gh.Number(edges[i][j].onGeometry->gv)+1);
-						else if (edges[i][j].onGeometry->OnGeomEdge())
-						 printf("the vertex number %i of this edge is a geometric Edge number %i\n",Number(edges[i][j])+1,Gh.Number(edges[i][j].onGeometry->ge)+1);
-						else
-						 printf("Its pointer is %p\n",edges[i][j].onGeometry);
-
-						printf("This edge is on geometry and has no adjacent edge (open curve) and one of the tip is not required\n");
-						ISSMERROR("See above (might be cryptic...)");
-					}
-				}
-			}
-		}
-	}
-}
-/*}}}1*/
-	/*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
-	void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ReNumberingTheTriangleBySubDomain)*/
-
-		long int verbose=0;
-		long *renu= new long[nbt];
-		register Triangle *t0,*t,*te=triangles+nbt;
-		register long k=0,it,i,j;
-
-		for ( it=0;it<nbt;it++) 
-		 renu[it]=-1; // outside triangle 
-		for ( i=0;i<NbSubDomains;i++)
-		  { 
-			t=t0=subdomains[i].head;
-			if (!t0){ // not empty sub domain
-				ISSMERROR("!t0");
-			}
-			do { 
-				long kt = Number(t);
-				if (kt<0 || kt >= nbt ){
-					ISSMERROR("kt<0 || kt >= nbt");
-				}
-				if (renu[kt]!=-1){
-					ISSMERROR("renu[kt]!=-1");
-				}
-				renu[kt]=k++;
-			}
-			while (t0 != (t=t->link));
-		  }
-		// take is same numbering if possible    
-		if(justcompress)
-		 for ( k=0,it=0;it<nbt;it++) 
-		  if(renu[it] >=0 ) 
-			renu[it]=k++;
-
-		// put the outside triangles at the end
-		for ( it=0;it<nbt;it++){
-			if (renu[it]==-1) renu[it]=k++;
-		}
-		if (k != nbt){
-			ISSMERROR("k != nbt");
-		}
-		// do the change on all the pointeur 
-		for ( it=0;it<nbt;it++)
-		 triangles[it].ReNumbering(triangles,te,renu);
-
-		for ( i=0;i<NbSubDomains;i++)
-		 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
-
-		// move the Triangles  without a copy of the array 
-		// be carefull not trivial code 
-		for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
-		 if (renu[it] >= 0) // a new sub cycle
-			{ 
-			 i=it;
-			 Triangle ti=triangles[i],tj;
-			 while ( (j=renu[i]) >= 0) 
-				{ // i is old, and j is new 
-				 renu[i] = -1; // mark 
-				 tj = triangles[j]; // save new
-				 triangles[j]= ti; // new <- old
-				 i=j;     // next 
-				 ti = tj;
-				}  
-			}
-		delete [] renu;
-		nt = nbt - NbOutT;
-
-	}
-	/*}}}1*/
-	/*FUNCTION Triangles::ReNumberingVertex{{{1*/
-	void Triangles::ReNumberingVertex(long * renu) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ReNumberingVertex)*/
-
-		// warning be carfull because pointer
-		// from on mesh to over mesh 
-		//  --  so do ReNumbering at the beginning
-		MeshVertex * ve = vertices+nbv;
-		long it,ie,i;
-
-		printf("renumbering triangles\n");
-		for ( it=0;it<nbt;it++) 
-		 triangles[it].ReNumbering(vertices,ve,renu);
-
-		printf("renumbering edges\n");
-		for ( ie=0;ie<nbe;ie++) 
-		 edges[ie].ReNumbering(vertices,ve,renu);
-
-		printf("renumbering vertices on geom\n");
-		for (i=0;i< NbVerticesOnGeomVertex;i++)
-		  {
-			MeshVertex *v = VerticesOnGeomVertex[i].mv;
-			if (v>=vertices && v < ve)
-			 VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
-		  }
-
-		printf("renumbering vertices on edge\n");
-		for (i=0;i< NbVerticesOnGeomEdge;i++)
-		  {
-			MeshVertex *v =VerticesOnGeomEdge[i].mv;
-			if (v>=vertices && v < ve)
-			 VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
-		  }
-
-		printf("renumbering vertices on Bth vertex\n");
-		for (i=0;i< NbVertexOnBThVertex;i++)
-		  {
-			MeshVertex *v=VertexOnBThVertex[i].v;
-			if (v>=vertices && v < ve)
-			 VertexOnBThVertex[i].v=vertices+renu[Number(v)];
-		  }
-
-		for (i=0;i< NbVertexOnBThEdge;i++)
-		  {
-			MeshVertex *v=VertexOnBThEdge[i].v;
-			if (v>=vertices && v < ve)
-			 VertexOnBThEdge[i].v=vertices+renu[Number(v)];
-		  }
-
-		// move the Vertices without a copy of the array 
-		// be carefull not trivial code 
-		long j;
-		for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
-		 if (renu[it] >= 0) // a new sub cycle
-			{ 
-			 i=it;
-			 MeshVertex ti=vertices[i],tj;
-			 while ( (j=renu[i]) >= 0){
-				 // i is old, and j is new 
-				 renu[i] = -1-renu[i]; // mark 
-				 tj = vertices[j];     // save new
-				 vertices[j]= ti;      // new <- old
-				 i=j;     // next 
-				 ti = tj;
-				}  
-			}
-		if (quadtree){
-			delete quadtree;
-			quadtree = new QuadTree(this);
-		}
-
-		for ( it=0;it<nbv;it++) renu[i]= -renu[i]-1;
-	}
-	/*}}}1*/
-/*FUNCTION Triangles::SetIntCoor{{{1*/
-void Triangles::SetIntCoor(const char * strfrom) {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SetIntCoor)*/
-
-	/*Set integer coordinate for existing vertices*/
-
-	//Get extrema coordinates of the existing vertices
-	pmin =  vertices[0].r;
-	pmax =  vertices[0].r;
-	long i;
-	for (i=0;i<nbv;i++) {
-		pmin.x = Min(pmin.x,vertices[i].r.x);
-		pmin.y = Min(pmin.y,vertices[i].r.y);
-		pmax.x = Max(pmax.x,vertices[i].r.x);
-		pmax.y = Max(pmax.y,vertices[i].r.y);
-	}
-	R2 DD = (pmax-pmin)*0.05;
-	pmin = pmin-DD;
-	pmax = pmax+DD; 
-
-	//Compute coefIcoor
-	coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
-	if (coefIcoor<=0){
-		ISSMERROR("coefIcoor should be positive, a problem in the geometry is likely");
-	}
-
-	// generation of integer coord  
-	for (i=0;i<nbv;i++) {
-		vertices[i].i = toI2(vertices[i].r);    
-	}
-
-	// computation of the det 
-	int number_of_errors=0;
-	for (i=0;i<nbt;i++) {
-		MeshVertex & v0 = triangles[i][0];
-		MeshVertex & v1 = triangles[i][1];
-		MeshVertex & v2 = triangles[i][2];
-
-		//If this is not a boundary triangle
-		if ( &v0 && &v1 &&  &v2 ){
-
-			/*Compute determinant*/
-			triangles[i].det= det(v0,v1,v2);
-
-			/*Check that determinant is positive*/
-			if (triangles[i].det <=0){
-
-				/*increase number_of_errors and print error only for the first 20 triangles*/
-				number_of_errors++;
-				if (number_of_errors<20){
-					printf("Area of Triangle %i < 0 (det=%i)\n",i+1,triangles[i].det);
-				}
-			}
-		}
-
-		//else, set as -1
-		else triangles[i].det=-1;
-	}
-
-	if (number_of_errors) ISSMERROR("Fatal error: some triangles have negative areas, see above");
-}
-/*}}}1*/
-/*FUNCTION Triangles::ShowRegulaty{{{1*/
-void  Triangles::ShowRegulaty() const {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr>*/
-
-	const  double  sqrt32=sqrt(3.)*0.5; 
-	const double  aireKh=sqrt32*0.5;
-	D2  Beq(1,0),Heq(0.5,sqrt32);
-	D2xD2 Br(D2xD2(Beq,Heq).t());
-	D2xD2 B1r(Br.inv());
-	double gammamn=1e100,hmin=1e100;
-	double gammamx=0,hmax=0;
-	double beta=1e100;
-	double beta0=0;
-	double  alpha2=0;
-	double area=0,Marea=0;
-	// double cf= double(coefIcoor);
-	// double cf2= 6.*cf*cf;
-	int nt=0;
-	for (int it=0;it<nbt;it++)
-	 if ( triangles[it].link) 
-		{
-		 nt++;
-		 Triangle &K=triangles[it];
-		 double  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
-		 area+= area3;
-		 D2xD2 B_Kt(K[0],K[1],K[2]);
-		 D2xD2 B_K(B_Kt.t());
-		 D2xD2 B1K = Br*B_K.inv();
-		 D2xD2 BK =  B_K*B1r;
-		 D2xD2 B1B1 = B1K.t()*B1K;
-		 Metric MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
-		 MatVVP2x2 VMK(MK);
-		 alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
-		 double betaK=0;
-
-		 for (int j=0;j<3;j++)
-			{
-			 double he= Norme2(R2(K[j],K[(j+1)%3]));
-			 hmin=Min(hmin,he);
-			 hmax=Max(hmax,he);
-			 MeshVertex & v=K[j];
-			 D2xD2 M((Metric)v);
-			 betaK += sqrt(M.det());
-
-			 D2xD2 BMB = BK.t()*M*BK;
-			 Metric M1(BMB.x.x,BMB.x.y,BMB.y.y);
-			 MatVVP2x2 VM1(M1);
-			 gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
-			 gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);		
-			}
-		 betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
-		 Marea+= betaK;
-		 beta=min(beta,betaK);
-		 beta0=max(beta0,betaK);
-		}   
-	area*=3; 
-	gammamn=sqrt(gammamn);
-	gammamx=sqrt(gammamx);    
-	printf("   Adaptmesh info:\n");
-	printf("      number of triangles = %i\n",nt);
-	printf("      hmin = %g, hmax=%g\n",hmin,hmax);
-	printf("      area = %g, M area = %g, M area/( |Khat| nt) = %g\n",area,Marea, Marea/(aireKh*nt));
-	printf("      infinite-regularity(?): min = %g, max = %g\n",gammamn,gammamx);
-	printf("      anisomax = %g, beta max = %g, min = %g\n",pow(alpha2,0.5),1./pow(beta/aireKh,0.5), 1./pow(beta0/aireKh,0.5));
-}
-/*}}}1*/
-/*FUNCTION Triangles::ShowHistogram{{{1*/
-void  Triangles::ShowHistogram() const {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ShowHistogram)*/
-
-	const long kmax=10;
-	const double llmin = 0.5,llmax=2;
-	const double lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
-	long histo[kmax+1];
-	long i,it,k, nbedges =0;
-	for (i=0;i<=kmax;i++) histo[i]=0;
-	for (it=0;it<nbt;it++)
-	 if ( triangles[it].link) 
-		{
-
-		 for (int j=0;j<3;j++)
-			{
-			 Triangle *ta = triangles[it].TriangleAdj(j);
-			 if ( !ta || !ta->link || Number(ta) >= it) 
-				{ 
-				 MeshVertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
-				 MeshVertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
-				 if ( !& vP || !&vQ) continue;
-				 R2 PQ = vQ.r - vP.r;
-				 double l = log(LengthInterpole(vP,vQ,PQ));
-				 nbedges++;
-				 k = (int) ((l - lmin)*delta);
-				 k = Min(Max(k,0L),kmax);
-				 histo[k]++;
-				}
-			}
-		}  
-	printf(" --- Histogram of the unit mesh,  nb of edges = %i\n",nbedges);
-	printf("      length of edge in   | %% of edge  | Nb of edges \n"); 
-	printf("      --------------------+-------------+-------------\n"); 
-	for   (i=0;i<=kmax;i++){ 
-		if (i==0) printf("      %10i",0);
-		else      printf("      %10g",exp(lmin+i/delta));
-		if (i==kmax) printf("          +inf   ");
-		else printf("      %10g",exp(lmin+(i+1)/delta));
-		printf("|  %10g |\n",((long)  ((10000.0 * histo[i])/ nbedges))/100.0);
-		printf("  %i\n",histo[i]);
-	}
-	printf("      --------------------+-------------+-------------\n"); 
-}
-/*}}}1*/
-/*FUNCTION Triangles::SmoothingVertex{{{1*/
-void Triangles::SmoothingVertex(int nbiter,double omega ) { 
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SmoothingVertex)*/
-
-	long int verbose=0;
-	//  if quatree exist remove it end reconstruct
-	if (quadtree) delete quadtree;
-	quadtree=0;
-	ReMakeTriangleContainingTheVertex();
-	Triangle vide; // a triangle to mark the boundary vertex
-	Triangle   ** tstart= new Triangle* [nbv];
-	long i,j,k;
-	//   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide 
-	if ( this == & BTh)
-	 for ( i=0;i<nbv;i++)
-	  tstart[i]=vertices[i].t;     
-	else 
-	 for ( i=0;i<nbv;i++)
-	  tstart[i]=0;
-	for ( j=0;j<NbVerticesOnGeomVertex;j++ ) 
-	 tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
-	for ( k=0;k<NbVerticesOnGeomEdge;k++ ) 
-	 tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
-	if(verbose>2) printf("   SmoothingVertex: nb Iteration = %i, Omega=%g\n",nbiter,omega);
-	for (k=0;k<nbiter;k++)
-	  {
-		long i,NbSwap =0;
-		double delta =0;
-		for ( i=0;i<nbv;i++)
-		 if (tstart[i] != &vide) // not a boundary vertex 
-		  delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
-		if (!NbOfQuad)
-		 for ( i=0;i<nbv;i++)
-		  if (tstart[i] != &vide) // not a boundary vertex 
-			NbSwap += vertices[i].Optim(1);
-		if (verbose>3) printf("      move max = %g, iteration = %i, nb of swap = %i\n",pow(delta,0.5),k,NbSwap);
-	  }
-
-	delete [] tstart;
-	if (quadtree) quadtree= new QuadTree(this);
-}
-/*}}}1*/
-/*FUNCTION Triangles::SmoothMetric{{{1*/
-void Triangles::SmoothMetric(double raisonmax) { 
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Metric.cpp/SmoothMetric)*/
-
-	long int verbose=0;
-
-	if(raisonmax<1.1) return;
-	if(verbose > 1) printf("   Triangles::SmoothMetric raisonmax = %g\n",raisonmax);
-	ReMakeTriangleContainingTheVertex();
-	long i,j,kch,kk,ip;
-	long *first_np_or_next_t0 = new long[nbv];
-	long *first_np_or_next_t1 = new long[nbv];
-	long Head0 =0,Head1=-1;
-	double logseuil= log(raisonmax);
-
-	for(i=0;i<nbv-1;i++)
-	 first_np_or_next_t0[i]=i+1; 
-	first_np_or_next_t0[nbv-1]=-1;// end;
-	for(i=0;i<nbv;i++)
-	 first_np_or_next_t1[i]=-1;
-	kk=0;
-	while (Head0>=0&& kk++<100) {
-		kch=0;
-		for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1) {
-			//  pour tous les triangles autour du sommet s
-			register Triangle* t= vertices[i].t;
-			if (!t){
-				ISSMERROR("!t");
-			}
-			MeshVertex & vi = vertices[i];
-			TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
-			MeshVertex *pvj0 = ta.EdgeVertex(0);
-			while (1) {
-				ta=Previous(Adj(ta));
-				if (vertices+i != ta.EdgeVertex(1)){
-					ISSMERROR("vertices+i != ta.EdgeVertex(1)");
-				}
-				MeshVertex & vj = *(ta.EdgeVertex(0));
-				if ( &vj ) {
-					j= &vj-vertices;
-					if (j<0 || j >= nbv){
-						ISSMERROR("j<0 || j >= nbv");
-					}
-					R2 Aij = (R2) vj - (R2) vi;
-					double ll =  Norme2(Aij);
-					if (0) {  
-						double hi = ll/vi.m(Aij);
-						double hj = ll/vj.m(Aij);
-						if(hi < hj)
-						  {
-							double dh=(hj-hi)/ll;
-							if (dh>logseuil) {
-								vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
-								if(first_np_or_next_t1[j]<0)
-								 kch++,first_np_or_next_t1[j]=Head1,Head1=j;
-							}
-						  }
-					} 
-					else
-					  {
-						double li = vi.m(Aij);
-						if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
-						 if(first_np_or_next_t1[j]<0) // if the metrix change 
-						  kch++,first_np_or_next_t1[j]=Head1,Head1=j;
-					  }
-				}
-				if  ( &vj ==  pvj0 ) break;
-			}
-		}
-		Head0 = Head1;
-		Head1 = -1;
-		Exchange(first_np_or_next_t0,first_np_or_next_t1);
-	}
-	if(verbose>2) printf("      number of iterations = %i\n",kch); 
-	delete [] first_np_or_next_t0;
-	delete [] first_np_or_next_t1;
-}
-/*}}}1*/
-	/*FUNCTION Triangles::SplitElement{{{1*/
-	int  Triangles::SplitElement(int choice){
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, MeshQuad.cpp/SplitElement)*/
-
-		long int verbose=0;
-
-		Direction NoDirOfSearch;
-		const  int withBackground = &BTh != this && &BTh;
-
-		ReNumberingTheTriangleBySubDomain();
-		//int nswap =0;
-		const long nfortria( choice ? 4 : 6);
-		if(withBackground) 
-		  {
-			BTh.SetVertexFieldOn();
-			SetVertexFieldOnBTh();
-		  }
-		else
-		 BTh.SetVertexFieldOn();
-
-		long newnbt=0,newnbv=0;
-		long * kedge = 0;
-		long newNbOfQuad=NbOfQuad;
-		long * ksplit= 0, * ksplitarray=0;
-		long kkk=0;
-		int ret =0;
-		if (nbvx<nbv+nbe) return 1;//   
-		// 1) create  the new points by spliting the internal edges 
-		// set the 
-		long nbvold = nbv;
-		long nbtold = nbt;
-		long NbOutTold  = NbOutT;
-		long  NbEdgeOnGeom=0;
-		long i;
-
-		nbt = nbt - NbOutT; // remove all the  the ouside triangles 
-		long nbtsave = nbt;
-		Triangle * lastT = triangles + nbt;
-		for (i=0;i<nbe;i++)
-		 if(edges[i].onGeometry) NbEdgeOnGeom++;
-		long newnbe=nbe+nbe;
-		//  long newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
-		long newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
-		// long newNbVertexOnBThVertex=NbVertexOnBThVertex;
-		long newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
-
-		// do allocation for pointeur to the geometry and background
-		VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
-		VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
-		if (NbVerticesOnGeomEdge)
-		 memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
-		if (NbVertexOnBThEdge)
-		 memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
-		Edge *newedges = new Edge [newnbe];
-		//  memcpy(newedges,edges,sizeof(Edge)*nbe);
-		SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
-		long k=nbv;
-		long kk=0;
-		long kvb = NbVertexOnBThEdge;
-		long kvg = NbVerticesOnGeomEdge;
-		long ie =0;
-		Edge ** edgesGtoB=0;
-		if (withBackground)
-		 edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
-		long ferr=0;
-		for (i=0;i<nbe;i++)
-		 newedges[ie].onGeometry=0;
-
-		for (i=0;i<nbe;i++)
-		  {
-			GeometricalEdge *ong =  edges[i].onGeometry;
-
-			newedges[ie]=edges[i];
-			newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
-			newedges[ie].adj[1]=newedges + ie +1;
-			R2 A = edges[i][0],B = edges[i][1];
-
-
-			kk += (i == edge4->SortAndAdd(Number(edges[i][0]),Number(edges[i][1])));
-			if (ong) // a geometrical edges 
-			  { 
-				if (withBackground){
-					// walk on back ground mesh 
-					//  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge); 
-					// a faire -- difficile 
-					// the first PB is to now a background edge between the 2 vertices
-					if (!edgesGtoB){
-						ISSMERROR("!edgesGtoB");
-					}
-					ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].onGeometry)],
-								edges[i][0],edges[i][1],0.5,vertices[k],
-								newVertexOnBThEdge[kvb],
-								newVerticesOnGeomEdge[kvg++]);
-					vertices[k].ReferenceNumber= edges[i].ref;
-					vertices[k].DirOfSearch =   NoDirOfSearch;        
-					;
-					// get the Info on background mesh 
-					double s =        newVertexOnBThEdge[kvb];
-					MeshVertex &  bv0  = newVertexOnBThEdge[kvb][0];
-					MeshVertex &  bv1  = newVertexOnBThEdge[kvb][1];
-					// compute the metrix of the new points 
-					vertices[k].m =  Metric(1-s,bv0,s,bv1); 
-					kvb++;
-				  }
-				else 
-				  {
-					ong=Gh.ProjectOnCurve(edges[i],
-								0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
-					// vertices[k].i = toI2( vertices[k].r);
-					vertices[k].ReferenceNumber = edges[i].ref;
-					vertices[k].DirOfSearch = NoDirOfSearch;
-					vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	      
-				  }  
-			  }
-			else // straigth line edge ---
-			  { 
-				vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
-				vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
-				vertices[k].onGeometry = 0;
-			  }
-			//vertices[k].i = toI2( vertices[k].r);
-			R2 AB =  vertices[k].r;
-			R2 AA = (A+AB)*0.5;
-			R2 BB = (AB+B)*0.5;
-			vertices[k].ReferenceNumber = edges[i].ref;
-			vertices[k].DirOfSearch = NoDirOfSearch;
-
-			newedges[ie].onGeometry = Gh.Containing(AA,ong);
-			newedges[ie++].v[1]=vertices+k;
-
-			newedges[ie]=edges[i];
-			newedges[ie].adj[0]=newedges + ie -1;
-			newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
-			newedges[ie].onGeometry =  Gh.Containing(BB,ong);
-			newedges[ie++].v[0]=vertices+k;
-			k++;
-		  }
-		if (edgesGtoB) delete [] edgesGtoB;
-		edgesGtoB=0;
-
-		newnbv=k;
-		newNbVerticesOnGeomEdge=kvg;
-		if (newnbv> nbvx) goto Error;// bug 
-
-		nbv = k;
-
-
-		kedge = new long[3*nbt+1];
-		ksplitarray = new long[nbt+1];
-		ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
-
-		for (i=0;i<3*nbt;i++)
-		 kedge[i]=-1;
-
-		//  
-
-		for (i=0;i<nbt;i++) {
-			Triangle & t = triangles[i];
-			if (!t.link){
-				ISSMERROR("!t.link");
-			}
-			for(int j=0;j<3;j++)
-			  {
-				const TriangleAdjacent ta = t.Adj(j);
-				const Triangle & tt = ta;
-				if (&tt >= lastT)
-				 t.SetAdj2(j,0,0);// unset adj
-				const MeshVertex & v0 = t[VerticesOfTriangularEdge[j][0]];
-				const MeshVertex & v1 = t[VerticesOfTriangularEdge[j][1]];
-				long  ke =edge4->SortAndFind(Number(v0),Number(v1));
-				if (ke>0) 
-				  {
-					long ii = Number(tt);
-					int  jj = ta;
-					long ks = ke + nbvold;
-					kedge[3*i+j] = ks;
-					if (ii<nbt) // good triangle
-					 kedge[3*ii+jj] = ks;
-					MeshVertex &A=vertices[ks];
-					double aa,bb,cc,dd;
-					if ((dd=Area2(v0.r,v1.r,A.r)) >=0){
-						// warning PB roundoff error 
-						if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0 
-										||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0  
-										||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0)){
-							printf("%i not in triangle %i In= %i %g %g %g %g\n",ke + nbvold,i,!!t.link,aa,bb,cc,dd);
-							ISSMERROR("Number of triangles with P2 interpolation Problem");
-						}
-					}
-					else {
-						if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0 
-										||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0 
-										||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)){
-							printf("%i not in triangle %i In= %i %g %g %g %g\n",ke + nbvold,ii,!!tt.link,aa,bb,cc,dd);
-							ISSMERROR("Number of triangles with P2 interpolation Problem");
-						}
-					} 
-				  }
-			  }
-		}
-
-		for (i=0;i<nbt;i++){
-			ksplit[i]=1; // no split by default
-			const Triangle & t = triangles[ i];
-			int nbsplitedge =0;
-			int nbinvisible =0;
-			int invisibleedge=0;
-			int kkk[3];      
-			for (int j=0;j<3;j++)
-			  {
-				if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
-
-				const TriangleAdjacent ta = t.Adj(j);
-				const Triangle & tt = ta;
-
-
-				const MeshVertex & v0 = t[VerticesOfTriangularEdge[j][0]];
-				const MeshVertex & v1 = t[VerticesOfTriangularEdge[j][1]];
-				if ( kedge[3*i+j] < 0) 
-				  {
-					long  ke =edge4->SortAndFind(Number(v0),Number(v1));
-					if (ke<0) // new 
-					  {
-						if (&tt) // internal triangles all the boundary 
-						  { // new internal edges 
-							long ii = Number(tt);
-							int  jj = ta;
-
-							kedge[3*i+j]=k;// save the vertex number 
-							kedge[3*ii+jj]=k;
-							if (k<nbvx) 
-							  {
-								vertices[k].r = ((R2) v0+(R2) v1 )/2;
-								//vertices[k].i = toI2( vertices[k].r);
-								vertices[k].ReferenceNumber=0;
-								vertices[k].DirOfSearch =NoDirOfSearch;
-								vertices[k].m =  Metric(0.5,v0,0.5,v1);
-							  }
-							k++;
-							kkk[nbsplitedge++]=j;		      
-						  } // tt 
-						else
-						 ISSMERROR("Bug...");
-					  } // ke<0	       
-					else
-					  { // ke >=0
-						kedge[3*i+j]=nbvold+ke;
-						kkk[nbsplitedge++]=j;// previously splited
-					  }
-				  }
-				else 
-				 kkk[nbsplitedge++]=j;// previously splited
-
-			  } 
-			if (nbinvisible>=2){
-				ISSMERROR("nbinvisible>=2");
-			}
-			switch (nbsplitedge) {
-				case 0: ksplit[i]=10; newnbt++; break;   // nosplit
-				case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2 
-				case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3 
-				case 3:
-						  if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
-						  else   ksplit[i]=10*nfortria,newnbt+=nfortria;
-						  break;
-			} 
-			if (ksplit[i]<40){
-				ISSMERROR("ksplit[i]<40");
-			}
-		  }
-		//  now do the element split
-		newNbOfQuad = 4*NbOfQuad;
-		nbv = k;
-		kkk = nbt;
-		ksplit[-1] = nbt;
-		// look on  old true  triangles 
-
-		for (i=0;i<nbtsave;i++){
-			int  nbmkadj=0;
-			long mkadj [100];
-			mkadj[0]=i;
-			long kk=ksplit[i]/10;
-			int  ke=(int) (ksplit[i]%10);
-			if (kk>=7 || kk<=0){
-				ISSMERROR("kk>=7 || kk<=0");
-			}
-
-			// def the numbering   k (edge) i vertex 
-			int k0 = ke;
-			int k1 = NextEdge[k0];
-			int k2 = PreviousEdge[k0];
-			int i0 = OppositeVertex[k0];
-			int i1 = OppositeVertex[k1];
-			int i2 = OppositeVertex[k2];
-
-			Triangle &t0=triangles[i];
-			MeshVertex * v0=t0(i0);           
-			MeshVertex * v1=t0(i1);           
-			MeshVertex * v2=t0(i2);
-
-			if (nbmkadj>=10){
-				ISSMERROR("nbmkadj>=10");
-			}
-			// --------------------------
-			TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
-			// save the flag Hidden
-			int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
-			// un set all adj -- save Hidden flag --
-			t0.SetAdj2(0,0,hid[0]);
-			t0.SetAdj2(1,0,hid[1]);
-			t0.SetAdj2(2,0,hid[2]);
-			// --  remake 
-			switch  (kk) {
-				case 1: break;// nothing 
-				case 2: // 
-						  {
-							Triangle &t1=triangles[kkk++];
-							t1=t0;
-							if (kedge[3*i+i0]<0){
-								ISSMERROR("kedge[3*i+i0]<0");
-							}
-							MeshVertex * v3 = vertices + kedge[3*i+k0];
-
-							t0(i2) = v3;
-							t1(i1) = v3;
-							t0.SetAllFlag(k2,0);
-							t1.SetAllFlag(k1,0);
-						  } 
-						break; 
-				case 3: //
-						  {
-							Triangle &t1=triangles[kkk++];
-							Triangle &t2=triangles[kkk++];
-							t2=t1=t0;
-							if (kedge[3*i+k1]<0){
-								ISSMERROR("kedge[3*i+k1]<0");
-							}
-							if (kedge[3*i+k2]<0){
-								ISSMERROR("kedge[3*i+k2]<0");
-							}
-
-							MeshVertex * v01 = vertices + kedge[3*i+k2];
-							MeshVertex * v02 = vertices + kedge[3*i+k1]; 
-							t0(i1) = v01; 
-							t0(i2) = v02; 
-							t1(i2) = v02;
-							t1(i0) = v01; 
-							t2(i0) = v02; 
-							t0.SetAllFlag(k0,0);
-							t1.SetAllFlag(k1,0);
-							t1.SetAllFlag(k0,0);
-							t2.SetAllFlag(k2,0);
-						  } 
-						break;
-				case 4: // 
-				case 6: // split in 4 
-						  {
-							Triangle &t1=triangles[kkk++];
-							Triangle &t2=triangles[kkk++];
-							Triangle &t3=triangles[kkk++];
-							t3=t2=t1=t0;
-							if (kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0){
-								ISSMERROR("kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0");
-							}
-							MeshVertex * v12 = vertices + kedge[3*i+k0];
-							MeshVertex * v02 = vertices + kedge[3*i+k1]; 
-							MeshVertex * v01 = vertices + kedge[3*i+k2];
-							t0(i1) = v01;
-							t0(i2) = v02;
-							t0.SetAllFlag(k0,hid[k0]);
-
-							t1(i0) = v01;
-							t1(i2) = v12;
-							t0.SetAllFlag(k1,hid[k1]);
-
-							t2(i0) = v02;
-							t2(i1) = v12;
-							t2.SetAllFlag(k2,hid[k2]);
-
-							t3(i0) = v12;
-							t3(i1) = v02;
-							t3(i2) = v01;
-
-							t3.SetAllFlag(0,hid[0]);	   
-							t3.SetAllFlag(1,hid[1]);	   
-							t3.SetAllFlag(2,hid[2]);
-
-							if ( kk == 6)
-							  {
-
-								Triangle &t4=triangles[kkk++];
-								Triangle &t5=triangles[kkk++];
-
-								t4 = t3;
-								t5 = t3;
-
-								t0.SetHidden(k0);
-								t1.SetHidden(k1);
-								t2.SetHidden(k2);
-								t3.SetHidden(0);
-								t4.SetHidden(1);
-								t5.SetHidden(2);
-
-								if (nbv < nbvx ) 
-								  {
-									vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
-									vertices[nbv].ReferenceNumber =0;
-									vertices[nbv].DirOfSearch =NoDirOfSearch;
-									//vertices[nbv].i = toI2(vertices[nbv].r);
-									double a3[]={1./3.,1./3.,1./3.};
-									vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
-									MeshVertex * vc =  vertices +nbv++;
-									t3(i0) = vc;
-									t4(i1) = vc;
-									t5(i2) = vc;
-
-								  }
-								else
-								 goto Error; 
-							  }
-
-						  } 
-						break;         
-			}
-
-			// save all the new triangles
-			mkadj[nbmkadj++]=i;
-			long jj;
-			if (t0.link) 
-			 for (jj=nbt;jj<kkk;jj++)
-				{
-				 triangles[jj].link=t0.link;
-				 t0.link= triangles+jj;
-				 mkadj[nbmkadj++]=jj;
-				}
-			if (nbmkadj>13){// 13 = 6 + 4 +
-				ISSMERROR("nbmkadj>13");
-			}
-
-			if (kk==6)  newNbOfQuad+=3;
-			for (jj=ksplit[i-1];jj<kkk;jj++) nbt = kkk;
-			ksplit[i]= nbt; // save last adresse of the new triangles
-			kkk = nbt;
-		  }
-
-		for (i=0;i<nbv;i++) vertices[i].m = vertices[i].m*2.;
-
-		if(withBackground)
-		 for (i=0;i<BTh.nbv;i++)
-		  BTh.vertices[i].m =  BTh.vertices[i].m*2.;
-
-
-		ret = 2;
-		if (nbt>= nbtx) goto Error; // bug 
-		if (nbv>= nbvx) goto Error; // bug 
-		// generation of the new triangles 
-
-		SetIntCoor("In SplitElement"); 
-
-		ReMakeTriangleContainingTheVertex();
-		if(withBackground)
-		 BTh.ReMakeTriangleContainingTheVertex();
-
-		delete [] edges;
-		edges = newedges;
-		nbe = newnbe;
-		NbOfQuad = newNbOfQuad;
-
-		for (i=0;i<NbSubDomains;i++)
-		  { 
-			long k = subdomains[i].edge- edges;
-			subdomains[i].edge =  edges+2*k; // spilt all edge in 2 
-		  }
-
-		if (ksplitarray) delete [] ksplitarray;
-		if (kedge) delete [] kedge;
-		if (edge4) delete edge4;
-		if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
-		VerticesOnGeomEdge= newVerticesOnGeomEdge;
-		if(VertexOnBThEdge) delete []  VertexOnBThEdge;
-		VertexOnBThEdge = newVertexOnBThEdge;
-		NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
-		NbVertexOnBThEdge=newNbVertexOnBThEdge;
-		//  ReMakeTriangleContainingTheVertex();
-
-		ReconstructExistingMesh();
-
-		if (verbose>2){
-			printf("   number of quadrilaterals    = %i\n",NbOfQuad);
-			printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
-			printf("   number of outside triangles = %i\n",NbOutT);
-		}
-
-		return 0; //ok
-
-Error:
-		nbv = nbvold;
-		nbt = nbtold;
-		NbOutT = NbOutTold;
-		// cleaning memory ---
-		delete newedges;
-		if (ksplitarray) delete [] ksplitarray;
-		if (kedge) delete [] kedge;
-		if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
-		if (edge4) delete edge4;
-		if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
-
-		return ret; // ok 
-	}
-	/*}}}1*/
-/*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
-long  Triangles::SplitInternalEdgeWithBorderVertices(){
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SplitInternalEdgeWithBorderVertices)*/
-
-	long NbSplitEdge=0;
-	SetVertexFieldOn();  
-	long it;
-	long nbvold=nbv;
-	long int verbose=2;
-	for (it=0;it<nbt;it++){
-		Triangle &t=triangles[it];
-		if (t.link)
-		 for (int j=0;j<3;j++)
-		  if(!t.Locked(j) && !t.Hidden(j)){
-			  Triangle &tt = *t.TriangleAdj(j);
-			  if ( &tt && tt.link && it < Number(tt)) 
-				 { // an internal edge 
-				  MeshVertex &v0 = t[VerticesOfTriangularEdge[j][0]];
-				  MeshVertex &v1 = t[VerticesOfTriangularEdge[j][1]];
-				  if (v0.onGeometry && v1.onGeometry){
-					  R2 P= ((R2) v0 + (R2) v1)*0.5;
-					  if ( nbv<nbvx) {
-						  vertices[nbv].r = P;
-						  vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
-						  vertices[nbv].ReferenceNumber=0;
-						  vertices[nbv].DirOfSearch = NoDirOfSearch ;
-					  }
-					  NbSplitEdge++;
-				  }
-				 }
-		  }
-	}
-	ReMakeTriangleContainingTheVertex();    
-	if (nbvold!=nbv){
-		long  iv = nbvold;
-		long NbSwap = 0;
-		Icoor2 dete[3];  
-		for (int i=nbvold;i<nbv;i++) {// for all the new point
-			MeshVertex & vi = vertices[i];
-			vi.i = toI2(vi.r);
-			vi.r = toR2(vi.i);
-
-			// a good new point 
-			vi.ReferenceNumber=0; 
-			vi.DirOfSearch =NoDirOfSearch;
-			Triangle *tcvi = FindTriangleContaining(vi.i,dete);
-			if (tcvi && !tcvi->link) {
-				printf("problem inserting point in SplitInternalEdgeWithBorderVertices (tcvj && !tcvj->link)\n");
-			}
-
-			quadtree->Add(vi);
-			if (!tcvi || tcvi->det<0){// internal
-				ISSMERROR("!tcvi || tcvi->det < 0");
-			}
-			AddVertex(vi,tcvi,dete);
-			NbSwap += vi.Optim(1);          
-			iv++;
-			//      }
-	}
-	if (verbose>3) {
-		printf("   number of points: %i\n",iv);
-		printf("   number of swap to  split internal edges with border vertices: %i\n",NbSwap);
-		nbv = iv;
-	}
-}
-if (NbSplitEdge>nbv-nbvold) printf("WARNING: not enough vertices  to split all internal edges, we lost %i edges...\n",NbSplitEdge - ( nbv-nbvold));
-if (verbose>2) printf("SplitInternalEdgeWithBorderVertices: Number of splited edge %i\n",NbSplitEdge);
-
-return  NbSplitEdge;
-}
-/*}}}1*/
-/*FUNCTION Triangles::TriangleReferenceList{{{1*/
-long  Triangles::TriangleReferenceList(long* reft) const {
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ConsRefTriangle)*/
-
-	long int verbose=0;
-	register Triangle *t0,*t;
-	register long k=0, num;   
-
-	//initialize all triangles as -1 (outside)
-	for (int it=0;it<nbt;it++) reft[it]=-1;
-
-	//loop over all subdomains
-	for (int i=0;i<NbSubDomains;i++){ 
-
-		//first triangle of the subdomain i
-		t=t0=subdomains[i].head;
-
-		//check that the subdomain is not empty
-		if (!t0){ ISSMERROR("At least one subdomain is empty");}
-
-		//loop
-		do{
-			k++;
-
-			//get current triangle number
-			num = Number(t);
-
-			//check that num is in [0 nbt[
-			if (num<0 || num>=nbt){ ISSMERROR("num<0 || num>=nbt");}
-
-			//reft of this triangle is the subdomain number
-			reft[num]=i;
-
-		} while (t0 != (t=t->link));
-		//stop when all triangles of subdomains have been tagged
-
-	}
-	return k;   
-}
-/*}}}1*/
-/*FUNCTION Triangles::TriangleIntNumbering{{{1*/
-void Triangles::TriangleIntNumbering(long* renumbering){
-
-	long num=0;
-	for (int i=0;i<nbt;i++){
-		if (triangles[i].det>0) renumbering[i]=num++;
-		else renumbering[i]=-1;
-	}
-	return;   
-}
-/*}}}1*/
-
-	/*Intermediary*/
-	/*FUNCTION CloseBoundaryEdge{{{1*/
-	TriangleAdjacent CloseBoundaryEdge(I2 A,Triangle *t, double &a,double &b) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CloseBoundaryEdge)*/
-
-		int k=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
-		int dir=0;
-		if (k<0){
-			ISSMERROR("k<0");
-		}
-		int kkk=0;  
-		Icoor2 IJ_IA,IJ_AJ;
-		TriangleAdjacent edge(t,OppositeEdge[k]);          
-		for (;;edge = dir >0 ? Next(Adj(Next(edge))) : Previous(Adj(Previous(edge)))) {  
-			kkk++;
-			if (kkk>=1000){
-				ISSMERROR("kkk>=1000");
-			}
-			MeshVertex  &vI =  *edge.EdgeVertex(0);
-			MeshVertex  &vJ =  *edge.EdgeVertex(1);
-			I2 I=vI, J=vJ, IJ= J-I;
-			IJ_IA = (IJ ,(A-I));
-			if (IJ_IA<0) {
-				if (dir>0) {a=1;b=0;return edge;}// change of signe => I
-				else {dir=-1;
-					continue;}};// go in direction i 
-					IJ_AJ = (IJ ,(J-A));
-					if (IJ_AJ<0) {
-						if(dir<0)  {a=0;b=1;return edge;}            
-						else {dir = 1;
-							continue;}}// go in direction j
-							double IJ2 = IJ_IA + IJ_AJ;
-							if (IJ2==0){
-								ISSMERROR("IJ2==0");
-							}
-							a= IJ_AJ/IJ2;
-							b= IJ_IA/IJ2;
-							return edge;
-		  } 
-	}
-	/*}}}1*/
-	/*FUNCTION CloseBoundaryEdgeV2{{{1*/
-	TriangleAdjacent CloseBoundaryEdgeV2(I2 C,Triangle *t, double &a,double &b) { 
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/CloseBoundaryEdgeV2)*/
-		// walk around the vertex 
-		// version 2 for remove the probleme if we fill the hole
-		//int bug=1;
-		//  Triangle *torigine = t;
-		// restart:
-		//   int dir=0;
-		if (t->link != 0){
-			ISSMERROR("t->link != 0");
-		}
-		// to have a starting edges 
-		// try the 3 edge bourna-- in case of internal hole 
-		// and choice  the best 
-		// 
-		// the probleme is in case of  the fine and long internal hole
-		// for exemple neart the training edge of a wing
-		MeshVertex * s=0,*s1=0, *s0=0;
-		Icoor2 imax = MaxICoor22;
-		Icoor2 l0 = imax,l1 = imax;
-		double dd2 =  imax;// infinity
-		TriangleAdjacent er; 
-		int  cas=-2;
-		for (int j=0;j<3;j++)
-		  { 
-			TriangleAdjacent ta=t->FindBoundaryEdge(j);
-			if  (! (Triangle *) ta) continue;
-			s0 = ta.EdgeVertex(0);
-			s1 = ta.EdgeVertex(1);
-			I2 A = * s0;
-			I2 B = *ta.EdgeVertex(1);
-			I2 AB = B-A,AC=C-A,BC=B-C;
-			Icoor2  ACAC = (AC,AC), BCBC = (BC,BC);
-			Icoor2  AB2  =   Norme2_2(AB); //  ||AB||^2
-			Icoor2  ABAC  =   (AB,AC);         //  AB.AC|
-
-			double d2;
-			if ( ABAC < 0 )   // DIST A
-			  {
-				if ( (d2=(double) ACAC)  <  dd2) 
-				  {
-					er = ta;
-					l0 = ACAC;
-					l1 = BCBC;
-					cas = 0;
-					s = s0;
-				  }
-			  }
-			else if (ABAC > AB2)  // DIST B
-			  {
-				if ( (d2=(double) BCBC)  <  dd2) 
-				  {
-					dd2 = d2;
-					er = Adj(ta); // other direction
-					l0 = BCBC;
-					l1 = ACAC;
-					cas = 1;
-					s = s1;
-				  }
-			  }
-			else  // DIST AB
-			  { 
-
-				double det_2 =  (double) Det(AB,AC); 
-				det_2 *= det_2; // square of area*2 of triangle ABC
-				d2 = det_2/ (double) AB2; // hauteur^2 in C of of triangle ABC      
-
-				if (d2 < dd2) 
-				  {
-					dd2 = d2;
-					er = ta;
-					l0 = (AC,AC);
-					l1 = (BC,BC);
-					s = 0;
-					cas = -1;
-					b = ((double) ABAC/(double) AB2);
-					a = 1 - b;
-				  }
-			  }
-		  }
-		if (cas ==-2){
-			ISSMERROR("cas==-2");
-		}
-		// l1 = ||C s1||  , l0 = ||C s0||
-		// where s0,s1 are the vertex of the edge er
-
-		if ( s) 
-		  { 
-			t=er;
-			TriangleAdjacent edge(er); 
-
-			int kkk=0;  
-			int linkp = t->link == 0;
-
-			Triangle * tt=t=edge=Adj(Previous(edge));
-			do  {  // loop over vertex s
-				kkk++;
-				if (edge.EdgeVertex(0)!=s && kkk>=10000){
-					ISSMERROR("edge.EdgeVertex(0)!=s && kkk>=10000");
-				}
-
-				int link = tt->link == 0;
-				if ((link + linkp) == 1) 
-				  { // a boundary edge 
-					MeshVertex * st = edge.EdgeVertex(1);
-					I2 I=*st;
-					Icoor2  ll = Norme2_2 (C-I);
-					if (ll < l1) {  // the other vertex is neart 
-						s1=st;
-						l1=ll;
-						er = edge;
-						if(ll<l0) { // change of direction --
-							s1=s;
-							l1=l0;
-							s=st;
-							l0=ll;
-							t=tt;
-							edge=Adj(edge);
-							link=linkp;
-							er = edge;
-						}
-					}
-				  }
-
-				linkp=link;
-				edge=Adj(Previous(edge));
-				tt = edge;
-			} while (t!=tt);
-
-			if (!(Triangle *) er){
-				ISSMERROR("!(Triangle *) er");
-			}
-			I2 A((I2)*er.EdgeVertex(0));
-			I2 B((I2)*er.EdgeVertex(1));
-			I2 AB=B-A,AC=C-A,CB=B-C;
-			double aa =  (double) (AB,AC);
-			double bb =  (double) (AB,CB);
-			if (aa<0)       a=1,b=0;
-			else if(bb<0)   a=0,b=1;
-			else  
-			  {
-				a  = bb/(aa+bb);
-				b  = aa/(aa+bb);
-			  }
-		  }
-		return er;
-	} 
-	/*}}}1*/
-/*FUNCTION ForceEdge{{{1*/
-int ForceEdge(MeshVertex &a, MeshVertex & b,TriangleAdjacent & taret)  { 
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/ForceEdge)*/
-
-	int NbSwap =0;
-	if (!a.t || !b.t){ // the 2 vertex is in a mesh
-		ISSMERROR("!a.t || !b.t");
-	}
-	int k=0;
-	taret=TriangleAdjacent(0,0); // erreur 
-
-	TriangleAdjacent tta(a.t,EdgesVertexTriangle[a.vint][0]);
-	MeshVertex   *v1, *v2 = tta.EdgeVertex(0),*vbegin =v2;
-	// we turn around a in the  direct sens  
-
-	Icoor2 det2 = v2 ? det(*v2,a,b): -1 , det1;
-	if(v2) // normal case 
-	 det2 = det(*v2,a,b);
-	else { // no chance infini vertex try the next
-		tta= Previous(Adj(tta));
-		v2 = tta.EdgeVertex(0);
-		vbegin =v2;
-		if (!v2){
-			ISSMERROR("!v2");
-		}
-		det2 = det(*v2,a,b);
-	}
-
-	while (v2 != &b) {
-		TriangleAdjacent tc = Previous(Adj(tta));    
-		v1 = v2; 
-		v2 = tc.EdgeVertex(0);
-		det1 = det2;
-		det2 =  v2 ? det(*v2,a,b): det2; 
-
-		if((det1 < 0) && (det2 >0)) { 
-			// try to force the edge 
-			MeshVertex * va = &a, *vb = &b;
-			tc = Previous(tc);
-			if (!v1 || !v2){
-				ISSMERROR("!v1 || !v2");
-			}
-			Icoor2 detss = 0,l=0,ks;
-			while ((ks=SwapForForcingEdge(  va,  vb, tc, detss, det1,det2,NbSwap)))
-			 if(l++ > 10000000) {
-				 ISSMERROR("Loop in forcing Egde, nb de swap=%i, nb of try swap (%i) too big",NbSwap,l);
-			 }
-			MeshVertex *aa = tc.EdgeVertex(0), *bb = tc.EdgeVertex(1);
-			if (( aa == &a ) && (bb == &b) ||  (bb ==  &a ) && (aa == &b)) {
-				tc.SetLock();
-				a.Optim(1,0);
-				b.Optim(1,0);
-				taret = tc;
-				return NbSwap;
-			}
-			else 
-			  {
-				taret = tc;
-				return -2; // error  boundary is crossing
-			  }
-		}
-		tta = tc;
-		k++;
-		if (k>=2000){
-			ISSMERROR("k>=2000");
-		}
-		if ( vbegin == v2 ) return -1;// error 
-	}
-
-	tta.SetLock();
-	taret=tta;
-	a.Optim(1,0);
-	b.Optim(1,0);
-	return NbSwap; 
-}
-/*}}}1*/
-/*FUNCTION swap{{{1*/
-void  swap(Triangle *t1,short a1, Triangle *t2,short a2, MeshVertex *s1,MeshVertex *s2,Icoor2 det1,Icoor2 det2){ 
-	/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/swap)*/
-	// --------------------------------------------------------------
-	// short a2=aa[a];// les 2 numero de l arete dans les 2 triangles
-	//                               
-	//               sb                     sb    
-	//             / | \                   /   \                      !
-	//         as1/  |  \                 /a2   \                     !
-	//           /   |   \               /    t2 \                    !
-	//       s1 /t1  | t2 \s2  -->   s1 /___as2___\s2                 !
-	//          \  a1|a2  /             \   as1   /  
-	//           \   |   /               \ t1    /   
-	//            \  |  / as2             \   a1/    
-	//             \ | /                   \   /     
-	//              sa                       sa   
-	//  -------------------------------------------------------------
-	int as1 = NextEdge[a1];
-	int as2 = NextEdge[a2];
-	int ap1 = PreviousEdge[a1];
-	int ap2 = PreviousEdge[a2];
-	(*t1)(VerticesOfTriangularEdge[a1][1]) = s2 ; // avant sb
-	(*t2)(VerticesOfTriangularEdge[a2][1]) = s1  ; // avant sa
-	// mise a jour des 2 adjacences externes 
-	TriangleAdjacent taas1 = t1->Adj(as1),
-						  taas2 = t2->Adj(as2),
-						  tas1(t1,as1), tas2(t2,as2),
-						  ta1(t1,a1),ta2(t2,a2);
-	// externe haut gauche
-	taas1.SetAdj2(ta2, taas1.GetAllFlag_UnSwap());
-	// externe bas droite
-	taas2.SetAdj2(ta1, taas2.GetAllFlag_UnSwap());
-	// remove the Mark  UnMarkSwap 
-	t1->SetUnMarkUnSwap(ap1);
-	t2->SetUnMarkUnSwap(ap2);
-	// interne 
-	tas1.SetAdj2(tas2);
-
-	t1->det = det1;
-	t2->det = det2;
-
-	t1->SetTriangleContainingTheVertex();
-	t2->SetTriangleContainingTheVertex();
-} // end swap 
-/*}}}1*/
-	/*FUNCTION SwapForForcingEdge{{{1*/
-	int SwapForForcingEdge(MeshVertex   *  & pva ,MeshVertex  * &   pvb ,TriangleAdjacent & tt1,Icoor2 & dets1, Icoor2 & detsa,Icoor2 & detsb, int & NbSwap) {
-		/*Original code from Frederic Hecht <hecht@ann.jussieu.fr> (BAMG v1.01, Mesh2.cpp/SwapForForcingEdge)*/
-		// l'arete ta coupe l'arete pva pvb
-		// de cas apres le swap sa coupe toujours
-		// on cherche l'arete suivante 
-		// on suppose que detsa >0 et detsb <0
-		// attention la routine echange pva et pvb 
-
-		if(tt1.Locked()) return 0; // frontiere croise 
-
-		TriangleAdjacent tt2 = Adj(tt1);
-		Triangle *t1=tt1,*t2=tt2;// les 2 triangles adjacent
-		short a1=tt1,a2=tt2;// les 2 numero de l arete dans les 2 triangles
-		if ( a1<0 || a1>=3 ){
-			ISSMERROR("a1<0 || a1>=3");
-		}
-
-		MeshVertex & sa= (* t1)[VerticesOfTriangularEdge[a1][0]];
-		MeshVertex & s1= (*t1)[OppositeVertex[a1]];
-		MeshVertex & s2= (*t2)[OppositeVertex[a2]];
-
-
-		Icoor2 dets2 = det(*pva,*pvb,s2);
-		Icoor2 det1=t1->det , det2=t2->det ;
-		Icoor2 detT = det1+det2;
-		if ((det1<=0 ) || (det2<=0)){
-			ISSMERROR("(det1<=0 ) || (det2<=0)");
-		}
-		if ( (detsa>=0) || (detsb<=0) ){ // [a,b] cut infinite line va,bb
-			ISSMERROR("(detsa>=0) || (detsb<=0)");
-		}
-		Icoor2 ndet1 = bamg::det(s1,sa,s2);
-		Icoor2 ndet2 = detT - ndet1;
-
-		int ToSwap =0; //pas de swap
-		if ((ndet1 >0) && (ndet2 >0)) 
-		  { // on peut swaper  
-			if ((dets1 <=0 && dets2 <=0) || (dets2 >=0 && detsb >=0))
-			 ToSwap =1; 
-			else // swap alleatoire 
-			 if (BinaryRand()) 
-			  ToSwap =2; 
-		  }
-		if (ToSwap) NbSwap++,
-		 bamg::swap(t1,a1,t2,a2,&s1,&s2,ndet1,ndet2);
-
-		int ret=1;
-
-		if (dets2 < 0) {// haut
-			dets1 = ToSwap ? dets1 : detsa ;
-			detsa = dets2; 
-			tt1 =  Previous(tt2) ;}
-		else if (dets2 > 0){// bas 
-			dets1 = ToSwap ? dets1 : detsb ;
-			detsb = dets2;
-			//xxxx tt1 = ToSwap ? tt1 : Next(tt2);
-			if(!ToSwap) tt1 =  Next(tt2);
-		}
-		else { // changement de sens 
-			ret = -1;
-			Exchange(pva,pvb);
-			Exchange(detsa,detsb);
-			Exchange(dets1,dets2);
-			Exchange(tt1,tt2);
-			dets1=-dets1;
-			dets2=-dets2;
-			detsa=-detsa;
-			detsb=-detsb;
-
-			if (ToSwap) 
-			 if (dets2 < 0) {// haut
-				 dets1 = (ToSwap ? dets1 : detsa) ;
-				 detsa = dets2; 
-				 tt1 =  Previous(tt2) ;}
-			 else if (dets2 > 0){// bas 
-				 dets1 = (ToSwap ? dets1 : detsb) ;
-				 detsb =  dets2;
-				 if(!ToSwap) tt1 =  Next(tt2);
-			 }
-			 else {// on a fin ???
-				 tt1 = Next(tt2);
-				 ret =0;}
-
-		}
-		return ret;
-	}
-	/*}}}1*/
-
-}
Index: sm/trunk/src/c/objects/Bamg/Triangles.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/Triangles.h	(revision 5094)
+++ 	(revision )
@@ -1,203 +1,0 @@
-#ifndef _TRIANGLES_H_
-#define _TRIANGLES_H_
-
-#include "./include.h"
-#include "./BamgOpts.h"
-#include "./BamgMesh.h"
-#include "./BamgGeom.h"
-#include "./Triangle.h"
-#include "./VertexOnGeom.h"
-#include "./VertexOnVertex.h"
-#include "./VertexOnEdge.h"
-#include "./ListofIntersectionTriangles.h"
-
-
-namespace bamg {
-
-	//classes
-	class Geometry;
-	class CrackedEdge;
-	class QuadTree;
-	class SubDomain;
-
-	class Triangles {
-		public:
-
-			Geometry & Gh;   // Geometry
-			Triangles & BTh; // Background Mesh Bth==*this =>no  background 
-			long NbRef;      // counter of ref on the this class if 0 we can delete
-			long nbvx,nbtx;  // nombre max  de sommets , de  triangles
-			long nt,nbv,nbt,nbiv,nbe; // nb of legal triangles, nb of vertex, of triangles, of initial vertices, of edges with reference,
-			long NbOfQuad;  // nb of quadrangle 
-			long NbSubDomains;
-			long NbOutT;    // Nb of oudeside triangle
-			long NbOfTriangleSearchFind;
-			long NbOfSwapTriangle;
-			MeshVertex* vertices;
-			long NbVerticesOnGeomVertex;
-			VertexOnGeom * VerticesOnGeomVertex;
-			long NbVerticesOnGeomEdge;
-			VertexOnGeom * VerticesOnGeomEdge;
-			long NbVertexOnBThVertex;
-			VertexOnVertex *VertexOnBThVertex;
-			long NbVertexOnBThEdge;
-			VertexOnEdge *VertexOnBThEdge;
-			long NbCrackedVertices;
-			long* CrackedVertices;
-			long NbCrackedEdges;
-			CrackedEdge* CrackedEdges;
-			R2 pmin,pmax;    // extrema
-			double coefIcoor; // coef to integer Icoor1;
-			Triangle* triangles;
-			Edge* edges; 
-			QuadTree* quadtree;
-			MeshVertex** ordre;
-			SubDomain* subdomains;
-			ListofIntersectionTriangles lIntTria;
-
-			//Constructors/Destructors
-			Triangles(BamgGeom* bamggeom,BamgMesh* bamgmesh,BamgOpts* bamgopts);
-			Triangles(double* index,double* x,double* y,int nods,int nels);
-			Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,long nbvxx=0 ); //copy operator
-			Triangles(const Triangles &,const int *flag,const int *bb,BamgOpts* bamgopts); // truncature
-			Triangles(long nbvx,Triangles & BT,BamgOpts* bamgopts,int keepBackVertices=1) :Gh(BT.Gh),BTh(BT) {
-				try {GeomToTriangles1(nbvx,bamgopts,keepBackVertices);}
-				catch(...) { this->~Triangles(); throw; }
-			}
-			Triangles(long nbvx,Geometry & G,BamgOpts* bamgopts) :Gh(G),BTh(*this){
-				try { GeomToTriangles0(nbvx,bamgopts);}
-				catch(...) { this->~Triangles(); throw; }
-			}
-			~Triangles(); 
-
-			//Operators
-			const MeshVertex & operator[]  (long i) const { return vertices[i];};
-			MeshVertex & operator[](long i) { return vertices[i];};
-			const Triangle & operator()  (long i) const { return triangles[i];};
-			Triangle & operator()(long i) { return triangles[i];};
-
-			//Methods
-			void SetIntCoor(const char * from =0);
-			double MinimalHmin() {return 2.0/coefIcoor;}
-			double MaximalHmax() {return Max(pmax.x-pmin.x,pmax.y-pmin.y);}
-			I2 toI2(const R2 & P) const {
-				return  I2( (Icoor1) (coefIcoor*(P.x-pmin.x))
-							,(Icoor1) (coefIcoor*(P.y-pmin.y)) );}
-			R2 toR2(const I2 & P) const {
-				return  R2( (double) P.x/coefIcoor+pmin.x, (double) P.y/coefIcoor+pmin.y);
-			}
-			void AddVertex(MeshVertex & s,Triangle * t,Icoor2 *  =0) ;
-			void Insert();
-			void ForceBoundary();
-			void FindSubDomain(int OutSide=0);
-			long TriangleReferenceList(long*) const;
-			void TriangleIntNumbering(long* renumbering);
-			void ShowHistogram() const;
-			void CrackMesh(BamgOpts* bamgopts);
-			void ShowRegulaty() const;
-			void SmoothMetric(double raisonmax) ;
-			void BoundAnisotropy(double anisomax,double hminaniso= 1e-100) ;
-			void MaxSubDivision(double maxsubdiv);
-			Edge** MakeGeometricalEdgeToEdge();
-			long SplitInternalEdgeWithBorderVertices();
-			void MakeQuadrangles(double costheta);
-			int  SplitElement(int choice);
-			void MakeQuadTree();
-			void NewPoints(Triangles &,BamgOpts* bamgopts,int KeepVertices=1);
-			long InsertNewPoints(long nbvold,long & NbTSwap) ; 
-			void ReNumberingTheTriangleBySubDomain(bool justcompress=false);
-			void ReNumberingVertex(long * renu);
-			void SmoothingVertex(int =3,double=0.3);
-			Metric MetricAt (const R2 &) const;
-			GeometricalEdge* ProjectOnCurve( Edge & AB, MeshVertex &  A, MeshVertex & B,double theta, MeshVertex & R,VertexOnEdge & BR,VertexOnGeom & GR);
-			long Number(const Triangle & t) const  { return &t - triangles;}
-			long Number(const Triangle * t) const  { return t - triangles;}
-			long Number(const MeshVertex & t) const  { return &t - vertices;}
-			long Number(const MeshVertex * t) const  { return t - vertices;}
-			long Number(const Edge & t) const  { return &t - edges;}
-			long Number(const Edge * t) const  { return t - edges;}
-			long Number2(const Triangle * t) const  { return t - triangles; }
-			MeshVertex* NearestVertex(Icoor1 i,Icoor1 j) ;
-			Triangle* FindTriangleContaining(const I2 & ,Icoor2 [3],Triangle *tstart=0) const;
-			void ReadMesh(double* index,double* x,double* y,int nods,int nels);
-			void ReadMesh(BamgMesh* bamgmesh, BamgOpts* bamgopts);
-			void WriteMesh(BamgMesh* bamgmesh,BamgOpts* bamgopts);
-			void ReadMetric(const BamgOpts* bamgopts);
-			void WriteMetric(BamgOpts* bamgopts);
-			void AddMetric(BamgOpts* bamgopts);
-			void BuildMetric0(BamgOpts* bamgopts);
-			void BuildMetric1(BamgOpts* bamgopts);
-			void AddGeometryMetric(BamgOpts* bamgopts);
-			int  isCracked() const {return NbCrackedVertices != 0;}
-			void BuildGeometryFromMesh(BamgOpts* bamgopts=NULL);
-			void ReconstructExistingMesh();
-
-			//Inline methods
-			inline  void ReMakeTriangleContainingTheVertex(){
-				for (int i=0;i<nbv;i++) vertices[i].vint=0, vertices[i].t=NULL;
-				for (int i=0;i<nbt;i++) triangles[i].SetTriangleContainingTheVertex();
-			}
-			inline  void  UnMarkUnSwapTriangle(){
-				for (int i=0;i<nbt;i++)
-				 for(int j=0;j<3;j++)
-				  triangles[i].SetUnMarkUnSwap(j);
-			  }
-			inline  void  SetVertexFieldOn(){
-				for (int i=0;i<nbv;i++)                    vertices[i].onGeometry=NULL;
-				for (int j=0;j<NbVerticesOnGeomVertex;j++) VerticesOnGeomVertex[j].SetOn();
-				for (int k=0;k<NbVerticesOnGeomEdge;k++ )  VerticesOnGeomEdge[k].SetOn();
-			}	       
-			inline  void   SetVertexFieldOnBTh(){
-				for (int i=0;i<nbv;i++)                 vertices[i].onGeometry=NULL;
-				for (int j=0;j<NbVertexOnBThVertex;j++) VertexOnBThVertex[j].SetOnBTh();
-				for (int k=0;k<NbVertexOnBThEdge;k++ )  VertexOnBThEdge[k].SetOnBTh();
-			}
-
-		private:
-			void GeomToTriangles1(long nbvx,BamgOpts* bamgopts,int KeepVertices=1);// the real constructor mesh adaption
-			void GeomToTriangles0(long nbvx,BamgOpts* bamgopts);// the real constructor mesh generator
-			void PreInit(long);
-
-	};
-
-	/*Intermediary*/
-	TriangleAdjacent CloseBoundaryEdge(I2 ,Triangle *, double &,double &) ;
-	TriangleAdjacent CloseBoundaryEdgeV2(I2 A,Triangle *t, double &a,double &b);
-	void  swap(Triangle *t1,short a1,
-				Triangle *t2,short a2,
-				MeshVertex *s1,MeshVertex *s2,Icoor2 det1,Icoor2 det2);
-	int SwapForForcingEdge(MeshVertex   *  & pva ,MeshVertex  * &   pvb ,
-				TriangleAdjacent & tt1,Icoor2 & dets1,
-				Icoor2 & detsa,Icoor2 & detsb, int & nbswap);
-	int ForceEdge(MeshVertex &a, MeshVertex & b,TriangleAdjacent & taret) ;
-	inline TriangleAdjacent Previous(const TriangleAdjacent & ta){
-		return TriangleAdjacent(ta.t,PreviousEdge[ta.a]);
-	}
-	inline TriangleAdjacent Next(const TriangleAdjacent & ta){
-		return TriangleAdjacent(ta.t,NextEdge[ta.a]);
-	}
-	inline  TriangleAdjacent Adj(const TriangleAdjacent & a){
-		return  a.Adj();
-	}
-	inline void Adj(GeometricalEdge * & on,int &i){
-		int j=i;i=on->DirAdj[i];on=on->Adj[j];
-	}
-	inline double qualite(const MeshVertex &va,const MeshVertex &vb,const MeshVertex &vc){
-		double ret; 
-		I2 ia=va,ib=vb,ic=vc;
-		I2 ab=ib-ia,bc=ic-ib,ac=ic-ia;
-		Icoor2 deta=Det(ab,ac);
-		if (deta <=0) ret = -1;
-		else {
-			double a = sqrt((double) (ac,ac)),
-					 b = sqrt((double) (bc,bc)),
-					 c = sqrt((double) (ab,ab)),
-					 p = a+b+c;
-			double h= Max(Max(a,b),c),ro=deta/p;
-			ret = ro/h;
-		}
-		return ret;
-	}
-
-}
-#endif
Index: /issm/trunk/src/c/objects/Bamg/VertexOnEdge.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnEdge.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnEdge.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "VertexOnEdge.h"
-#include "Triangles.h"
+#include "Mesh.h"
 
 namespace bamg {
@@ -13,5 +13,5 @@
 	/*Methods*/
 	/*FUNCTION VertexOnEdge::Set {{{1*/
-	void VertexOnEdge::Set(const Triangles & Th ,long i,Triangles & ThNew){
+	void VertexOnEdge::Set(const Mesh & Th ,long i,Mesh & ThNew){
 		*this = Th.VertexOnBThEdge[i];  
 		v = ThNew.vertices + Th.Number(v);
Index: /issm/trunk/src/c/objects/Bamg/VertexOnEdge.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnEdge.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnEdge.h	(revision 5095)
@@ -8,5 +8,5 @@
 
 	//classes
-	class Triangles;
+	class Mesh;
 	class MeshVertex;
 
@@ -30,5 +30,5 @@
 			//Methods
 			void SetOnBTh(){v->onBackgroundEdge=this;v->vint=IsVertexOnEdge;}  
-			void Set(const Triangles &,long,Triangles &);  
+			void Set(const Mesh &,long,Mesh &);  
 	};
 
Index: /issm/trunk/src/c/objects/Bamg/VertexOnGeom.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnGeom.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnGeom.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "VertexOnGeom.h"
-#include "Triangles.h"
+#include "Mesh.h"
 #include "Geometry.h"
 
@@ -14,5 +14,5 @@
 	/*Methods*/
 	/*FUNCTION VertexOnGeom::Set {{{1*/
-	void VertexOnGeom::Set(const VertexOnGeom & rec,const Triangles & Th ,Triangles & ThNew){
+	void VertexOnGeom::Set(const VertexOnGeom & rec,const Mesh & Th ,Mesh & ThNew){
 		*this = rec;  
 		mv = ThNew.vertices + Th.Number(mv);
Index: /issm/trunk/src/c/objects/Bamg/VertexOnGeom.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnGeom.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnGeom.h	(revision 5095)
@@ -8,5 +8,5 @@
 
 	//classes
-	class Triangles;
+	class Mesh;
 	class MeshVertex;
 	class GeometricalEdge;
@@ -41,5 +41,5 @@
 
 			//Inline methods
-			void Set(const VertexOnGeom&,const Triangles &,Triangles &);  
+			void Set(const VertexOnGeom&,const Mesh &,Mesh &);  
 
 	};
Index: /issm/trunk/src/c/objects/Bamg/VertexOnVertex.cpp
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnVertex.cpp	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnVertex.cpp	(revision 5095)
@@ -5,5 +5,5 @@
 
 #include "VertexOnVertex.h"
-#include "Triangles.h"
+#include "Mesh.h"
 
 namespace bamg {
@@ -13,5 +13,5 @@
 	/*Methods*/
 	/*FUNCTION VertexOnVertex::Set{{{1*/
-	void VertexOnVertex::Set(const Triangles &Th ,long i,Triangles &ThNew) { 
+	void VertexOnVertex::Set(const Mesh &Th ,long i,Mesh &ThNew) { 
 		*this = Th.VertexOnBThVertex[i];  
 		v     = ThNew.vertices + Th.Number(v);
Index: /issm/trunk/src/c/objects/Bamg/VertexOnVertex.h
===================================================================
--- /issm/trunk/src/c/objects/Bamg/VertexOnVertex.h	(revision 5094)
+++ /issm/trunk/src/c/objects/Bamg/VertexOnVertex.h	(revision 5095)
@@ -8,5 +8,5 @@
 
 	//classes
-	class Triangles;
+	class Mesh;
 
 	class VertexOnVertex {
@@ -22,5 +22,5 @@
 			//Methods
 			void SetOnBTh(){v->onBackgroundVertex=bv;v->vint=IsVertexOnVertex;}
-			void Set(const Triangles &,long,Triangles &);
+			void Set(const Mesh &,long,Mesh &);
 	};
 
Index: /issm/trunk/src/c/objects/objects.h
===================================================================
--- /issm/trunk/src/c/objects/objects.h	(revision 5094)
+++ /issm/trunk/src/c/objects/objects.h	(revision 5095)
@@ -113,5 +113,5 @@
 #include "./Bamg/VertexOnEdge.h"
 #include "./Bamg/CrackedEdge.h"
-#include "./Bamg/Triangles.h"
+#include "./Bamg/Mesh.h"
 #include "./Bamg/Geometry.h"
 #include "./Bamg/QuadTree.h"
