Changeset 2877


Ignore:
Timestamp:
01/20/10 16:10:17 (15 years ago)
Author:
Mathieu Morlighem
Message:

Added some comments and changed variable names

Location:
issm/trunk/src/c/Bamgx
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/Bamgx/Bamgx.cpp

    r2865 r2877  
    8484                //build metric if not given in input
    8585                if (verbosity>1) printf("   Generating Metric...\n");
    86                 for(i=0;i<Gh.nbv;i++)
    87                   {
     86                for(i=0;i<Gh.nbv;i++){
    8887                        MetricAnIso M=Gh[i];
    8988                        MatVVP2x2 Vp(M/coef);
     
    9190                        Vp.Minh(hmax);
    9291                        Gh.vertices[i].m = Vp;
    93                   }
     92                }
    9493
    9594                //generate mesh
  • issm/trunk/src/c/Bamgx/Mesh2.h

    r2870 r2877  
    219219                int cas;
    220220                friend class Geometry;
    221                 GeometricalVertex * link; //  link all the same GeometricalVertex circular (Crack)
     221                GeometricalVertex* link; //  link all the same GeometricalVertex circular (Crack)
    222222                public:
    223223                int Corner() const {return cas&4;}
     
    228228                GeometricalVertex() :cas(0), link(this) {};
    229229
    230                 GeometricalVertex * The() {
     230                GeometricalVertex* The() {
    231231                        if (!link){
    232232                                throw ErrorException(__FUNCT__,exprintf("!link"));
    233233                        }
    234234                        return link;
    235                 }// return a unique vertices
     235                }// return a unique vertex
    236236
    237237                int IsThe() const { return link == this;} 
     
    249249                        //   if tg[0] =0 => no continuite
    250250                        GeometricalEdge * Adj [2];
    251                         int SensAdj[2];
     251                        int DirAdj[2];
    252252                        //  private:
    253253                        int flag ;
     
    656656
    657657                        int static counter; // to kown the number of mesh in memory
    658                         int OnDisk;       // true if on disk
    659658                        Geometry & Gh;   // Geometry
    660659                        Triangles & BTh; // Background Mesh Bth==*this =>no  background
     
    713712                        Triangles(BamgMesh* bamgmesh,BamgOpts* bamgopts);
    714713
    715                         Triangles(Int4 nbvx,Triangles & BT,int keepBackVertices=1)
    716                           :Gh(BT.Gh),BTh(BT) {
    717                                   try {GeomToTriangles1(nbvx,keepBackVertices);}
    718                                   catch(...) { this->~Triangles(); throw; } }
    719 
    720                                   Triangles(Int4 nbvx,Geometry & G)
    721                                          :Gh(G),BTh(*this){
    722                                                  try { GeomToTriangles0(nbvx);}
    723                                                  catch(...) { this->~Triangles(); throw; } }
    724                                                  Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,Int4 nbvxx=0 ); // COPY OPERATEUR
    725                                                  Triangles(const Triangles &,const int *flag,const int *bb); // truncature
     714                        Triangles(Int4 nbvx,Triangles & BT,int keepBackVertices=1) :Gh(BT.Gh),BTh(BT) {
     715                                try {GeomToTriangles1(nbvx,keepBackVertices);}
     716                                catch(...) { this->~Triangles(); throw; }
     717                        }
     718
     719                        Triangles(Int4 nbvx,Geometry & G) :Gh(G),BTh(*this){
     720                                try { GeomToTriangles0(nbvx);}
     721                                catch(...) { this->~Triangles(); throw; }
     722                        }
     723
     724                        Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,Int4 nbvxx=0 ); // COPY OPERATEUR
     725                        Triangles(const Triangles &,const int *flag,const int *bb); // truncature
    726726
    727727                                                 void SetIntCoor(const char * from =0);
     
    746746                                                 void ForceBoundary();
    747747                                                 void Heap();
    748                                                  void FindSubDomain(int );
     748                                                 void FindSubDomain(int OutSide=0);
    749749                                                 Int4  ConsRefTriangle(Int4 *) const;
    750750                                                 void ShowHistogram() const;
     
    820820        class Geometry {
    821821                public:
    822                         int OnDisk;
    823822                        Int4 NbRef; // counter of ref on the this class if 0 we can delete
    824823
     
    832831                        Int4 NbOfCurves;
    833832                        int empty(){return (nbv ==0) && (nbt==0) && (nbe==0) && (NbSubDomains==0); }
    834                         GeometricalVertex * vertices;   // data of vertices des sommets
     833                        GeometricalVertex* vertices;
    835834                        Triangle * triangles;
    836835                        GeometricalEdge * edges;
     
    859858                        Geometry() {EmptyGeometry();}// empty Geometry
    860859                        void AfterRead();
    861                         Geometry(BamgGeom* bamggeom, BamgOpts* bamgopts) {EmptyGeometry();OnDisk=1;ReadGeometry(bamggeom,bamgopts);AfterRead();}
     860                        Geometry(BamgGeom* bamggeom, BamgOpts* bamgopts) {EmptyGeometry();ReadGeometry(bamggeom,bamgopts);AfterRead();}
    862861
    863862                        const GeometricalVertex & operator[]  (Int4 i) const { return vertices[i];};
     
    11431142
    11441143        inline void Adj(GeometricalEdge * & on,int &i)
    1145           {int j=i;i=on->SensAdj[i];on=on->Adj[j];}
     1144          {int j=i;i=on->DirAdj[i];on=on->Adj[j];}
    11461145
    11471146        inline Real4 qualite(const Vertex &va,const Vertex &vb,const Vertex &vc)
  • issm/trunk/src/c/Bamgx/QuadTree.h

    r2862 r2877  
    99        const IntQuad MaxISize = ( 1L << MaxDeep);
    1010
    11 
    1211        class Triangles;
    1312        class Vertex;
     
    1514        class QuadTree {
    1615                public:
    17 
    1816                        class QuadTreeBox {
    1917                                public:
    20 
    2118                                        long n; // if n < 4 => Vertex else =>  QuadTreeBox;
    2219                                        union {
     
    2421                                                Vertex * v[4];
    2522                                        };
    26 
    27 
    28                         }; // end class QuadTreeBox  /////////////////
    29 
     23                        }; // end class
    3024                        class StorageQuadTreeBox {
    3125                                public:
     
    4135                                                return len*sizeof(QuadTreeBox)+sizeof(StorageQuadTreeBox)+ (n?n->SizeOf():0);
    4236                                        }
    43                         }; // end class  StorageQuadTreeBox
    44 
     37                        }; // end class
    4538                        StorageQuadTreeBox * sb;
    46 
    47 
    4839                        long  lenStorageQuadTreeBox;
    4940
    5041                public:
    51                         QuadTreeBox * root;
    52                         Triangles *th;
     42                        QuadTreeBox* root;
     43                        Triangles* th;
    5344                        long NbQuadTreeBox,NbVertices;
    5445                        long NbQuadTreeBoxSearch,NbVerticesSearch;
    55                         Vertex * NearestVertex(Icoor1 i,Icoor1 j);
    56                         Vertex *  NearestVertexWithNormal(Icoor1 i,Icoor1 j); // new version 
    57                         Vertex * ToClose(Vertex & ,Real8 ,Icoor1,Icoor1);
     46                        Vertex* NearestVertex(Icoor1 i,Icoor1 j);
     47                        Vertex*  NearestVertexWithNormal(Icoor1 i,Icoor1 j);
     48                        Vertex* ToClose(Vertex & ,Real8 ,Icoor1,Icoor1);
    5849                        long SizeOf() const {return sizeof(QuadTree)+sb->SizeOf();}
    59 
    60 
    6150                        void  Add( Vertex & w);
    62 
    6351                        QuadTreeBox* NewQuadTreeBox(){
    64                                 if(! (sb->bc<sb->be))
    65                                  sb=new StorageQuadTreeBox(lenStorageQuadTreeBox,sb);
    66 
     52                                if(! (sb->bc<sb->be)) sb=new StorageQuadTreeBox(lenStorageQuadTreeBox,sb);
    6753                                if (!sb || (sb->bc->n != 0)){
    6854                                        throw ErrorException(__FUNCT__,exprintf("!sb || (sb->bc->n != 0)"));
  • issm/trunk/src/c/Bamgx/objects/Geometry.cpp

    r2865 r2877  
    314314                                edges[i].tg[0]=zero2;
    315315                                edges[i].tg[1]=zero2;
    316                                 edges[i].SensAdj[0] = edges[i].SensAdj[1] = -1;
     316                                edges[i].DirAdj[0] = edges[i].DirAdj[1] = -1;
    317317                                edges[i].Adj[0] = edges[i].Adj[1] = 0;
    318318                                edges[i].flag = 0;
     
    483483
    484484        /*Methods*/
    485         /*FUNCTION  Geometry::EmptyGeometry(){{{1*/
    486         void Geometry::EmptyGeometry() {
    487                 OnDisk=0;
    488                 NbRef=0;
    489                 name =0;
    490                 quadtree=0;
    491                 curves=0;
    492                 // edgescomponante=0;
    493                 triangles=0;
    494                 edges=0;
    495                 vertices=0;
    496                 NbSubDomains=0;
    497                 //  nbtf=0;
    498                 //  BeginOfCurve=0; 
    499                 nbiv=nbv=nbvx=0;
    500                 nbe=nbt=nbtx=0;
    501                 NbOfCurves=0;
    502                 //  BeginOfCurve=0;
    503                 subdomains=0;
    504                 MaximalAngleOfCorner = 10*Pi/180;
    505         }
    506         /*}}}1*/
    507         /*FUNCTION  Geometry::Contening{{{1*/
    508         GeometricalEdge* Geometry::Contening(const R2 P,  GeometricalEdge * start) const {
    509                 GeometricalEdge* on =start,* pon=0;
    510                 // walk with the cos on geometry
    511                 int k=0;
    512                 while(pon != on){ 
    513                         k++;
    514                         pon = on;
    515                         if (k>=100){
    516                                 throw ErrorException(__FUNCT__,exprintf("k>=100"));
    517                         }
    518                         R2 A= (*on)[0];
    519                         R2 B= (*on)[1];
    520                         R2 AB = B-A;
    521                         R2 AP = P-A;
    522                         R2 BP = P-B;
    523                         if ( (AB,AP) < 0)
    524                          on = on->Adj[0];
    525                         else if ( (AB,BP)  > 0)
    526                          on = on->Adj[1];
    527                         else
    528                          return on;
    529                   }
    530                 return on;
    531         }
    532         /*}}}1*/
    533         /*FUNCTION  Geometry::Geometry::ProjectOnCurve {{{1*/
    534         GeometricalEdge* Geometry::ProjectOnCurve(const Edge & e,Real8 s,Vertex &V,VertexOnGeom &GV ) const {
    535                 Real8 save_s=s;
    536                 int NbTry=0;
    537 retry:   
    538                 s=save_s;
    539                 GeometricalEdge* on = e.on;
    540                 if (!on){
    541                         throw ErrorException(__FUNCT__,exprintf("!on"));
    542                 }
    543                 if (!e[0].on ||  !e[1].on){
    544                         throw ErrorException(__FUNCT__,exprintf("!e[0].on ||  !e[1].on"));
    545                 }
    546                 const Vertex &v0=e[0],&v1=e[1];
    547                 V.m = Metric(1.0-s, v0,s, v1);
    548                 const int mxe =100;
    549                 GeometricalEdge *ge[mxe+1];
    550                 int    sensge[mxe+1];
    551                 Real8  lge[mxe+1];
    552                 int bge=mxe/2,tge=bge;
    553                 ge[bge] = e.on;
    554                 sensge[bge]=1;
    555 
    556                 R2 V0 = v0,V1=v1,V01=V1-V0;
    557                 VertexOnGeom  vg0= *v0.on,  vg1=*v1.on;
    558 
    559                 //    GeometricalEdge * eg0 = e.on,* eg1 = e.on, *eg=NULL;
    560                 GeometricalEdge * eg0=on, *eg1=on;
    561                 R2 Ag=(R2) (*on)[0],Bg=(R2)(*on)[1],AB=Bg-Ag;
    562                 int OppositeSens = (V01,AB) < 0;
    563                 int sens0=0,sens1=1;
    564                 if (OppositeSens)
    565                  s=1-s,Exchange(vg0,vg1),Exchange(V0,V1);
    566                 while (eg0 != (GeometricalEdge*) vg0  &&  (*eg0)(sens0) != (GeometricalVertex*) vg0){
    567                         if (bge<=0) {
    568                                 //          int kkk;
    569                                 if(NbTry) {
    570                                         printf("Fatal Error: on the class triangles before call Geometry::ProjectOnCurve\n");
    571                                         printf("That bug might come from:\n");
    572                                         printf(" 1)  a mesh edge  contening more than %i geometrical edges\n",mxe/2);
    573                                         printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
    574                                         printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
    575                                         throw ErrorException(__FUNCT__,exprintf("see above"));
    576                                   }
    577                                 NbTry++;
    578                                 goto retry;}
    579                                 GeometricalEdge* tmpge = eg0;
    580                                 ge[--bge] =eg0 = eg0->Adj[sens0];
    581                                 if (bge<0 || bge>mxe){
    582                                         throw ErrorException(__FUNCT__,exprintf("bge<0 || bge>mxe"));
    583                                 }
    584                                 sens0 = 1-( sensge[bge] = tmpge->SensAdj[sens0]);
    585                   }
    586                 while (eg1 != (GeometricalEdge*) vg1  &&  (*eg1)(sens1) != (GeometricalVertex*) vg1) {
    587                         if(tge>=mxe ) {
    588                                 printf("WARNING: on the class triangles before call Geometry::ProjectOnCurve is having issues (isn't it Eric?)\n");
    589                                 NbTry++;
    590                                 if (NbTry<2) goto retry;
    591                                 printf("Fatal Error: on the class triangles before call Geometry::ProjectOnCurve\n");
    592                                 printf("That bug might come from:\n");
    593                                 printf(" 1)  a mesh edge  contening more than %i geometrical edges\n",mxe/2);
    594                                 printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
    595                                 printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
    596                                 throw ErrorException(__FUNCT__,exprintf("see above"));
    597                         }
    598 
    599                         GeometricalEdge* tmpge = eg1;
    600                         ge[++tge] =eg1 = eg1->Adj[sens1];
    601                         sensge[tge]= sens1 = 1-tmpge->SensAdj[sens1];
    602                         if (tge<0 || tge>mxe){
    603                                 throw ErrorException(__FUNCT__,exprintf("(tge<0 || tge>mxe)"));
    604                         }
    605                   }
    606 
    607 
    608                 if ( (*eg0)(sens0) == (GeometricalVertex*) vg0 )
    609                  vg0 = VertexOnGeom( *(Vertex *) vg0,*eg0,sens0);
    610 
    611                 if ( (*eg1)(sens1) == (GeometricalVertex*) vg1)
    612                  vg1 = VertexOnGeom( *(Vertex *) vg1,*eg1,sens1);
    613 
    614                 Real8 sg;
    615                 if (eg0 == eg1) {
    616                         register Real8 s0= vg0,s1=vg1;
    617                         sg =  s0 * (1.0-s) +  s * s1;
    618                         on=eg0;}
    619                 else {
    620                         R2 AA=V0,BB;
    621                         Real8 s0,s1;
    622                         int i=bge;
    623                         Real8 ll=0;
    624                         for(i=bge;i<tge;i++){
    625                                 if ( i<0 || i>mxe){
    626                                         throw ErrorException(__FUNCT__,exprintf("i<0 || i>mxe"));
    627                                 }
    628                                 BB =  (*ge[i])[sensge[i]];
    629                                 lge[i]=ll += Norme2(AA-BB);
    630                                 AA=BB ;}
    631                                 lge[tge]=ll+=Norme2(AA-V1);
    632                                 // search the geometrical edge
    633                                 if (s>1.0){
    634                                         throw ErrorException(__FUNCT__,exprintf("s>1.0"));
    635                                 }
    636                                 Real8 ls= s*ll;
    637                                 on =0;
    638                                 s0 = vg0;
    639                                 s1= sensge[bge];
    640                                 Real8 l0=0,l1;
    641                                 i=bge;
    642                                 while (  (l1=lge[i]) < ls ) {
    643                                         if (i<0 || i>mxe){
    644                                                 throw ErrorException(__FUNCT__,exprintf("i<0 || i>mxe"));
    645                                         }
    646                                         i++,s0=1-(s1=sensge[i]),l0=l1;}
    647                                         on=ge[i];
    648                                         if (i==tge)
    649                                          s1=vg1;
    650 
    651                                         s=(ls-l0)/(l1-l0);
    652                                         sg =  s0 * (1.0-s) +  s * s1;   
    653                 }
    654                 if (!on){
    655                         throw ErrorException(__FUNCT__,exprintf("!on"));
    656                 }
    657                 V.r= on->F(sg);
    658                 GV=VertexOnGeom(V,*on,sg);
    659                 return on;
    660         }
    661         /*}}}1*/
    662485        /*FUNCTION  Geometry::AfterRead(){{{1*/
    663         void Geometry::AfterRead() {
     486        void Geometry::AfterRead(){
    664487                long int verbosity=0;
    665488
    666                 Int4 i,k=0;        ;
    667                 int jj; // jj in [0,1]
    668                 Int4 * hv = new Int4 [ nbv];
    669                 Int4 * ev = new Int4 [ 2 * nbe ];
    670                 float  * eangle = new float[ nbe ];
    671                 double eps = 1e-20;
     489                Int4 i,j,k;
     490                int jj;
     491                Int4* hv=new Int4[nbv];
     492                Int4* ev=new Int4[2*nbe];
     493                float* eangle=new float[nbe];
     494                double eps=1e-20;
    672495                QuadTree quadtree; // to find same vertices
    673                 Vertex * v0 = vertices;
    674                 GeometricalVertex  * v0g = (GeometricalVertex  *) (void *) v0;   
    675 
    676                 for (i=0;i<nbv;i++)
    677                  vertices[i].link = vertices +i;
    678                 for (i=0;i<nbv;i++)
    679                   {
    680                         vertices[i].i = toI2(vertices[i].r); // set integer coordinate
    681                         Vertex *v= quadtree.NearestVertex(vertices[i].i.x,vertices[i].i.y);
    682                         if( v && Norme1(v->r - vertices[i]) < eps )
    683                           { // link v & vertices[i]
    684                                 // vieille ruse pour recuperer j
    685                                 GeometricalVertex * vg = (GeometricalVertex  *) (void *) v;
    686                                 int j = vg-v0g;
     496                Vertex* v0=vertices;
     497                GeometricalVertex* v0g=(GeometricalVertex*) (void*)v0;   
     498
     499                k=0;
     500                //link all vertices to themselves by default
     501                for (i=0;i<nbv;i++) vertices[i].link = vertices +i;
     502
     503                //build quadtree for this geometry (error if we have duplicates (k>0))
     504                for (i=0;i<nbv;i++){
     505                        // set integer coordinate
     506                        vertices[i].i=toI2(vertices[i].r);
     507                        Vertex* v= quadtree.NearestVertex(vertices[i].i.x,vertices[i].i.y);
     508                        if( v && Norme1(v->r - vertices[i]) < eps ){
     509                                // mama's old trick to get j
     510                                GeometricalVertex* vg = (GeometricalVertex*) (void*)v;
     511                                j=vg-v0g;
    687512                                if ( v !=  &(Vertex &) vertices[j]){
    688513                                        throw ErrorException(__FUNCT__,exprintf(" v !=  &(Vertex &) vertices[j]"));
     
    690515                                vertices[i].link = vertices + j;
    691516                                k++;         
    692                           }
     517                        }
    693518                        else  quadtree.Add(vertices[i]);
    694                   }
     519                }
    695520                if (k) {
    696521                        printf("number of distinct vertices= %i, over %i\n",nbv - k,nbv);
     
    702527                }
    703528
    704                 //  verification of cracked edge
     529                //  verification of cracked edge (to be completed)
    705530                for (i=0;i<nbe;i++){
    706531                        if (edges[i].Cracked() ) {
     
    710535                                if ( e1[0].The() == e2[0].The() && e1[1].The() == e2[1].The() )
    711536                                  {
     537                                        //nothing
    712538                                  }
    713539                                else
     
    722548                }
    723549
     550                //build hv and ev
    724551                for (i=0;i<nbv;i++) hv[i]=-1;// empty list
    725 
    726552                for (i=0;i<nbe;i++) {
    727                         R2 v10  =  edges[i].v[1]->r - edges[i].v[0]->r;
     553                        R2 v10=edges[i].v[1]->r - edges[i].v[0]->r;
    728554                        Real8 lv10 = Norme2(v10);
    729555                        if(lv10 == 0) {
     
    731557                        }
    732558                        eangle[i] = atan2(v10.y,v10.x)  ; // angle in [ -Pi,Pi ]
    733                         for (jj=0;jj<2;jj++)
    734                           { // generation of list
    735                                 Int4 v =  Number(edges[i].v[jj]);
    736                                 ev[k] = hv[v];
    737                                 hv[v] = k++;
     559                        for (jj=0;jj<2;jj++){
     560                                Int4 v=Number(edges[i].v[jj]);
     561                                ev[k]=hv[v];
     562                                hv[v]=k++;
    738563                          }
    739564                }
     
    804629                         }
    805630                         edges[i1].Adj[j1] = edges + i;
    806                          edges[i1].SensAdj[j1] = jj;
     631                         edges[i1].DirAdj[j1] = jj;
    807632                 }
    808633
     
    819644                                        if( ! edges[i].v[jj]->Corner())   { // not a Corner       
    820645                                                tg =  edges[i].v[1-jj]->r
    821                                                   - edges[i].Adj[jj]->v[1-edges[i].SensAdj[jj]]->r;
     646                                                  - edges[i].Adj[jj]->v[1-edges[i].DirAdj[jj]]->r;
    822647                                                ltg =  Norme2(tg);
    823648                                                tg =  tg *(lAB/ltg),ltg=lAB;
     
    838663                } // for (i=0;i<nbe;i++)
    839664
    840                 for (int step=0;step<2;step++)
    841                   {
    842                         for (i=0;i<nbe;i++)
    843                          edges[i].SetUnMark();
     665                for (int step=0;step<2;step++){
     666                        for (i=0;i<nbe;i++) edges[i].SetUnMark();
    844667
    845668                        NbOfCurves = 0;
     
    872695                                                  GeometricalVertex *b=(*e)(k1);
    873696                                                  if (a == b ||  b->Required() ) break;
    874                                                   k0 = e->SensAdj[k1];//  vertex in next edge
     697                                                  k0 = e->DirAdj[k1];//  vertex in next edge
    875698                                                  e = e->Adj[k1]; // next edge
    876699
     
    887710                        }
    888711
    889                                  if(step==0) {
    890                                          curves = new Curve[NbOfCurves];
    891                                  }
    892                   }
    893                 for(int i=0;i<NbOfCurves ;i++)
    894                   {
     712                        if(step==0) {
     713                                curves = new Curve[NbOfCurves];
     714                        }
     715                }
     716                for(int i=0;i<NbOfCurves ;i++){
    895717                        GeometricalEdge * be=curves[i].be, *eqbe=be->link;
    896718                        //GeometricalEdge * ee=curves[i].ee, *eqee=be->link;
     
    909731                                if(be->ReverseEqui())
    910732                                 curves[i].Reverse();           
    911                           }
    912                   }
     733                        }
     734                }
    913735
    914736                delete []ev;
     
    918740        }
    919741        /*}}}1*/
     742        /*FUNCTION  Geometry::Contening{{{1*/
     743        GeometricalEdge* Geometry::Contening(const R2 P,  GeometricalEdge * start) const {
     744                GeometricalEdge* on =start,* pon=0;
     745                // walk with the cos on geometry
     746                int k=0;
     747                while(pon != on){ 
     748                        k++;
     749                        pon = on;
     750                        if (k>=100){
     751                                throw ErrorException(__FUNCT__,exprintf("k>=100"));
     752                        }
     753                        R2 A= (*on)[0];
     754                        R2 B= (*on)[1];
     755                        R2 AB = B-A;
     756                        R2 AP = P-A;
     757                        R2 BP = P-B;
     758                        if ( (AB,AP) < 0)
     759                         on = on->Adj[0];
     760                        else if ( (AB,BP)  > 0)
     761                         on = on->Adj[1];
     762                        else
     763                         return on;
     764                }
     765                return on;
     766        }
     767        /*}}}1*/
     768        /*FUNCTION  Geometry::EmptyGeometry(){{{1*/
     769        void Geometry::EmptyGeometry() {
     770                NbRef=0;
     771                name =0;
     772                quadtree=0;
     773                curves=0;
     774                // edgescomponante=0;
     775                triangles=0;
     776                edges=0;
     777                vertices=0;
     778                NbSubDomains=0;
     779                //  nbtf=0;
     780                //  BeginOfCurve=0; 
     781                nbiv=nbv=nbvx=0;
     782                nbe=nbt=nbtx=0;
     783                NbOfCurves=0;
     784                //  BeginOfCurve=0;
     785                subdomains=0;
     786                MaximalAngleOfCorner = 10*Pi/180;
     787        }
     788        /*}}}1*/
     789        /*FUNCTION  Geometry::Geometry::ProjectOnCurve {{{1*/
     790        GeometricalEdge* Geometry::ProjectOnCurve(const Edge & e,Real8 s,Vertex &V,VertexOnGeom &GV ) const {
     791                Real8 save_s=s;
     792                int NbTry=0;
     793retry:   
     794                s=save_s;
     795                GeometricalEdge* on = e.on;
     796                if (!on){
     797                        throw ErrorException(__FUNCT__,exprintf("!on"));
     798                }
     799                if (!e[0].on ||  !e[1].on){
     800                        throw ErrorException(__FUNCT__,exprintf("!e[0].on ||  !e[1].on"));
     801                }
     802                const Vertex &v0=e[0],&v1=e[1];
     803                V.m = Metric(1.0-s, v0,s, v1);
     804                const int mxe =100;
     805                GeometricalEdge *ge[mxe+1];
     806                int    sensge[mxe+1];
     807                Real8  lge[mxe+1];
     808                int bge=mxe/2,tge=bge;
     809                ge[bge] = e.on;
     810                sensge[bge]=1;
     811
     812                R2 V0 = v0,V1=v1,V01=V1-V0;
     813                VertexOnGeom  vg0= *v0.on,  vg1=*v1.on;
     814
     815                //    GeometricalEdge * eg0 = e.on,* eg1 = e.on, *eg=NULL;
     816                GeometricalEdge * eg0=on, *eg1=on;
     817                R2 Ag=(R2) (*on)[0],Bg=(R2)(*on)[1],AB=Bg-Ag;
     818                int OppositeSens = (V01,AB) < 0;
     819                int sens0=0,sens1=1;
     820                if (OppositeSens)
     821                 s=1-s,Exchange(vg0,vg1),Exchange(V0,V1);
     822                while (eg0 != (GeometricalEdge*) vg0  &&  (*eg0)(sens0) != (GeometricalVertex*) vg0){
     823                        if (bge<=0) {
     824                                //          int kkk;
     825                                if(NbTry) {
     826                                        printf("Fatal Error: on the class triangles before call Geometry::ProjectOnCurve\n");
     827                                        printf("That bug might come from:\n");
     828                                        printf(" 1)  a mesh edge  contening more than %i geometrical edges\n",mxe/2);
     829                                        printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
     830                                        printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
     831                                        throw ErrorException(__FUNCT__,exprintf("see above"));
     832                                  }
     833                                NbTry++;
     834                                goto retry;}
     835                                GeometricalEdge* tmpge = eg0;
     836                                ge[--bge] =eg0 = eg0->Adj[sens0];
     837                                if (bge<0 || bge>mxe){
     838                                        throw ErrorException(__FUNCT__,exprintf("bge<0 || bge>mxe"));
     839                                }
     840                                sens0 = 1-( sensge[bge] = tmpge->DirAdj[sens0]);
     841                  }
     842                while (eg1 != (GeometricalEdge*) vg1  &&  (*eg1)(sens1) != (GeometricalVertex*) vg1) {
     843                        if(tge>=mxe ) {
     844                                printf("WARNING: on the class triangles before call Geometry::ProjectOnCurve is having issues (isn't it Eric?)\n");
     845                                NbTry++;
     846                                if (NbTry<2) goto retry;
     847                                printf("Fatal Error: on the class triangles before call Geometry::ProjectOnCurve\n");
     848                                printf("That bug might come from:\n");
     849                                printf(" 1)  a mesh edge  contening more than %i geometrical edges\n",mxe/2);
     850                                printf(" 2)  code bug : be sure that we call   Triangles::SetVertexFieldOn() before\n");
     851                                printf("To solve the problem do a coarsening of the geometrical mesh or change the constant value of mxe (dangerous)\n");
     852                                throw ErrorException(__FUNCT__,exprintf("see above"));
     853                        }
     854
     855                        GeometricalEdge* tmpge = eg1;
     856                        ge[++tge] =eg1 = eg1->Adj[sens1];
     857                        sensge[tge]= sens1 = 1-tmpge->DirAdj[sens1];
     858                        if (tge<0 || tge>mxe){
     859                                throw ErrorException(__FUNCT__,exprintf("(tge<0 || tge>mxe)"));
     860                        }
     861                  }
     862
     863
     864                if ( (*eg0)(sens0) == (GeometricalVertex*) vg0 )
     865                 vg0 = VertexOnGeom( *(Vertex *) vg0,*eg0,sens0);
     866
     867                if ( (*eg1)(sens1) == (GeometricalVertex*) vg1)
     868                 vg1 = VertexOnGeom( *(Vertex *) vg1,*eg1,sens1);
     869
     870                Real8 sg;
     871                if (eg0 == eg1) {
     872                        register Real8 s0= vg0,s1=vg1;
     873                        sg =  s0 * (1.0-s) +  s * s1;
     874                        on=eg0;}
     875                else {
     876                        R2 AA=V0,BB;
     877                        Real8 s0,s1;
     878                        int i=bge;
     879                        Real8 ll=0;
     880                        for(i=bge;i<tge;i++){
     881                                if ( i<0 || i>mxe){
     882                                        throw ErrorException(__FUNCT__,exprintf("i<0 || i>mxe"));
     883                                }
     884                                BB =  (*ge[i])[sensge[i]];
     885                                lge[i]=ll += Norme2(AA-BB);
     886                                AA=BB ;}
     887                                lge[tge]=ll+=Norme2(AA-V1);
     888                                // search the geometrical edge
     889                                if (s>1.0){
     890                                        throw ErrorException(__FUNCT__,exprintf("s>1.0"));
     891                                }
     892                                Real8 ls= s*ll;
     893                                on =0;
     894                                s0 = vg0;
     895                                s1= sensge[bge];
     896                                Real8 l0=0,l1;
     897                                i=bge;
     898                                while (  (l1=lge[i]) < ls ) {
     899                                        if (i<0 || i>mxe){
     900                                                throw ErrorException(__FUNCT__,exprintf("i<0 || i>mxe"));
     901                                        }
     902                                        i++,s0=1-(s1=sensge[i]),l0=l1;}
     903                                        on=ge[i];
     904                                        if (i==tge)
     905                                         s1=vg1;
     906
     907                                        s=(ls-l0)/(l1-l0);
     908                                        sg =  s0 * (1.0-s) +  s * s1;   
     909                }
     910                if (!on){
     911                        throw ErrorException(__FUNCT__,exprintf("!on"));
     912                }
     913                V.r= on->F(sg);
     914                GV=VertexOnGeom(V,*on,sg);
     915                return on;
     916        }
     917        /*}}}1*/
    920918
    921919}
  • issm/trunk/src/c/Bamgx/objects/QuadTree.cpp

    r2865 r2877  
    5151                NbVertices(0),
    5252                NbQuadTreeBoxSearch(0),
    53                 NbVerticesSearch(0)
    54         {
    55          sb =new StorageQuadTreeBox(lenStorageQuadTreeBox);
    56          root=NewQuadTreeBox();
    57         }
     53                NbVerticesSearch(0){
     54                        sb =new StorageQuadTreeBox(lenStorageQuadTreeBox);
     55                        root=NewQuadTreeBox();
     56                }
    5857        /*}}}1*/
    5958        /*FUNCTION QuadTree::~QuadTree(){{{1*/
     
    6564
    6665        /*Methods*/
     66        /*FUNCTION QuadTree::Add{{{1*/
     67        void  QuadTree::Add( Vertex & w){
     68                QuadTreeBox ** pb , *b;
     69                register long i=w.i.x, j=w.i.y,l=MaxISize;
     70                pb = &root;
     71                while( (b=*pb) && (b->n<0)){
     72                        b->n--;
     73                        l >>= 1;
     74                        pb = &b->b[IJ(i,j,l)];
     75                }
     76                if  (b) {     
     77                        if (b->n > 3 &&  b->v[3] == &w) return;
     78                        if (b->n > 2 &&  b->v[2] == &w) return;
     79                        if (b->n > 1 &&  b->v[1] == &w) return;
     80                        if (b->n > 0 &&  b->v[0] == &w) return;
     81                }
     82                if (l==0){
     83                        throw ErrorException(__FUNCT__,exprintf("l==0"));
     84                }
     85                while ((b= *pb) && (b->n == 4)){ // the QuadTreeBox is full
     86                        Vertex *v4[4]; // copy of the QuadTreeBox vertices
     87
     88                        v4[0]= b->v[0];
     89                        v4[1]= b->v[1];
     90                        v4[2]= b->v[2];
     91                        v4[3]= b->v[3];
     92                        b->n = -b->n; // mark is pointer QuadTreeBox
     93                        b->b[0]=b->b[1]=b->b[2]=b->b[3]=0; // set empty QuadTreeBox ptr
     94                        l >>= 1;    // div the size by 2
     95                        for (register int k=0;k<4;k++){ // for the 4 vertices find the sub QuadTreeBox ij
     96                                register int ij;
     97                                register QuadTreeBox * bb =  b->b[ij=IJ(v4[k]->i.x,v4[k]->i.y,l)];
     98                                if (!bb)
     99                                 bb=b->b[ij]=NewQuadTreeBox(); // alloc the QuadTreeBox
     100                                bb->v[bb->n++] = v4[k];
     101                        }
     102                        pb = &b->b[IJ(i,j,l)];
     103                }
     104                if (!(b = *pb)) b=*pb= NewQuadTreeBox(); //  alloc the QuadTreeBox
     105                b->v[b->n++]=&w; // we add the vertex
     106                NbVertices++;   
     107        }
     108        /*}}}1*/
    67109        /*FUNCTION QuadTree::NearestVertex{{{1*/
    68110        Vertex*  QuadTree::NearestVertex(Icoor1 i,Icoor1 j) {
    69                 QuadTreeBox * pb[ MaxDeep ];
    70                 int  pi[ MaxDeep  ];
    71                 Icoor1 ii[  MaxDeep ], jj [ MaxDeep];
     111                QuadTreeBox* pb[MaxDeep];
     112                int  pi[MaxDeep];
     113                Icoor1 ii[MaxDeep], jj [MaxDeep];
    72114                register int l=0; // level
    73115                register QuadTreeBox * b;
     
    80122                Vertex *vn=0;
    81123
    82                 // init for optimisation ---
     124                // init for optimization
    83125                b = root;
    84                 register Int4  n0;
    85                 if (!root->n)
    86                  return vn; // empty tree
    87 
    88                 while( (n0 = b->n) < 0)
    89                   {
     126                register Int4 n0;
     127
     128                if (!root->n) return vn; // empty tree
     129
     130                while( (n0 = b->n) < 0){
    90131                        // search the non empty
    91132                        // QuadTreeBox containing  the point (i,j)
     
    93134                        register  int k = IJ(iplus,jplus,hb2);// QuadTreeBox number of size hb2 contening i;j
    94135                        register QuadTreeBox * b0= b->b[k];
    95                         if ( ( b0 == 0) || (b0->n == 0) )
    96                          break; // null box or empty   => break             
     136                        if ( ( b0 == 0) || (b0->n == 0) ) break; // null box or empty   => break           
    97137                        NbQuadTreeBoxSearch++;
    98138                        b=b0;   
     
    100140                        j0 += J_IJ(k,hb2); // j orign of QuadTreeBox
    101141                        hb = hb2;
    102                   }
    103 
    104 
    105                 if ( n0 > 0)
    106                   { 
    107                         for(register int k=0;k<n0;k++)
    108                           {
     142                }
     143
     144                if ( n0 > 0){ 
     145                        for(register int k=0;k<n0;k++){
    109146                                I2 i2 =  b->v[k]->i;
    110147                                h0 = NORM(iplus,i2.x,jplus,i2.y);
     
    113150                                        vn = b->v[k];}
    114151                                        NbVerticesSearch++;
    115                           }
     152                        }
    116153                        return vn;
    117                   }
    118                 // general case -----
     154                }
     155
     156                // general case
    119157                pb[0]= b;
    120158                pi[0]=b->n>0 ?(int)  b->n : 4  ;
     
    124162                do {   
    125163                        b= pb[l];
    126                         while (pi[l]--)
    127                           {           
     164                        while (pi[l]--){             
    128165                                register int k = pi[l];
    129166
    130                                 if (b->n>0) // Vertex QuadTreeBox none empty
    131                                   {
     167                                if (b->n>0){ // Vertex QuadTreeBox none empty
    132168                                        NbVerticesSearch++;
    133169                                        I2 i2 =  b->v[k]->i;
     
    138174                                                vn = b->v[k];
    139175                                          }
    140                                   }
    141                                 else // Pointer QuadTreeBox
    142                                   {
     176                                }
     177                                else{ // Pointer QuadTreeBox
    143178                                        register QuadTreeBox *b0=b;
    144179                                        NbQuadTreeBoxSearch++;
    145                                         if ((b=b->b[k]))
    146                                           {
     180                                        if ((b=b->b[k])){
    147181                                                hb >>=1 ; // div by 2
    148182                                                register Icoor1 iii = ii[l]+I_IJ(k,hb);
    149183                                                register Icoor1 jjj = jj[l]+J_IJ(k,hb);
    150184
    151                                                 if  (INTER_SEG(iii,iii+hb,iplus-h,iplus+h) && INTER_SEG(jjj,jjj+hb,jplus-h,jplus+h))
    152                                                   {
     185                                                if (INTER_SEG(iii,iii+hb,iplus-h,iplus+h) && INTER_SEG(jjj,jjj+hb,jplus-h,jplus+h)){
    153186                                                        pb[++l]=  b;
    154187                                                        pi[l]= b->n>0 ?(int)  b->n : 4  ;
     
    156189                                                        jj[l]= jjj;
    157190
    158                                                   }
    159                                                 else
    160                                                  b=b0, hb <<=1 ;
    161                                           }
    162                                         else
    163                                         b=b0;
    164                                   }
    165                           }
     191                                                }
     192                                                else{
     193                                                        b=b0, hb <<=1 ;
     194                                                }
     195                                        }
     196                                        else b=b0;
     197                                }
     198                        }
    166199                        hb <<= 1; // mul by 2
    167200                } while (l--);
    168 
    169201                return vn;
    170202        }
     
    280312        }
    281313        /*}}}1*/
     314        /*FUNCTION QuadTree::StorageQuadTreeBox::StorageQuadTreeBox{{{1*/
     315        QuadTree::StorageQuadTreeBox::StorageQuadTreeBox(long ll,StorageQuadTreeBox *nn) {
     316                len = ll;
     317                n = nn;
     318                b = new QuadTreeBox[ll];
     319                for (int i = 0; i <ll;i++)
     320                 b[i].n =0,b[i].b[0]=b[i].b[1]=b[i].b[2]=b[i].b[3]=0;
     321                bc =b;
     322                be = b +ll;
     323                if (!b){
     324                        throw ErrorException(__FUNCT__,exprintf("!b"));
     325                }
     326        }
     327        /*}}}1*/
    282328        /*FUNCTION QuadTree::ToClose {{{1*/
    283329        Vertex *   QuadTree::ToClose(Vertex & v,Real8 seuil,Icoor1 hx,Icoor1 hy){
     
    357403        }
    358404        /*}}}1*/
    359         /*FUNCTION QuadTree::Add{{{1*/
    360         void  QuadTree::Add( Vertex & w){
    361                 QuadTreeBox ** pb , *b;
    362                 register long i=w.i.x, j=w.i.y,l=MaxISize;
    363                 pb = &root;
    364                 while( (b=*pb) && (b->n<0))
    365                   {
    366                         b->n--;
    367                         l >>= 1;
    368                         pb = &b->b[IJ(i,j,l)];
    369                   }
    370                 if  (b) {     
    371                         if (b->n > 3 &&  b->v[3] == &w) return;
    372                         if (b->n > 2 &&  b->v[2] == &w) return;
    373                         if (b->n > 1 &&  b->v[1] == &w) return;
    374                         if (b->n > 0 &&  b->v[0] == &w) return;
    375                 }
    376                 if (l==0){
    377                         throw ErrorException(__FUNCT__,exprintf("l==0"));
    378                 }
    379                 while ((b= *pb) && (b->n == 4)) // the QuadTreeBox is full
    380                   {
    381                         Vertex *v4[4]; // copy of the QuadTreeBox vertices
    382 
    383                         v4[0]= b->v[0];
    384                         v4[1]= b->v[1];
    385                         v4[2]= b->v[2];
    386                         v4[3]= b->v[3];
    387                         b->n = -b->n; // mark is pointer QuadTreeBox
    388                         b->b[0]=b->b[1]=b->b[2]=b->b[3]=0; // set empty QuadTreeBox ptr
    389                         l >>= 1;    // div the size by 2
    390                         for (register int k=0;k<4;k++) // for the 4 vertices find the sub QuadTreeBox ij
    391                           {
    392                                 register int ij;
    393                                 register QuadTreeBox * bb =  b->b[ij=IJ(v4[k]->i.x,v4[k]->i.y,l)];
    394                                 if (!bb)
    395                                  bb=b->b[ij]=NewQuadTreeBox(); // alloc the QuadTreeBox
    396                                 bb->v[bb->n++] = v4[k];
    397                           }
    398                         pb = &b->b[IJ(i,j,l)];
    399                   }
    400                 if (!(b = *pb))
    401                  b=*pb= NewQuadTreeBox(); //  alloc the QuadTreeBox
    402                 b->v[b->n++]=&w; // we add the vertex
    403                 NbVertices++;   
    404         }
    405         /*}}}1*/
    406         /*FUNCTION QuadTree::StorageQuadTreeBox::StorageQuadTreeBox{{{1*/
    407         QuadTree::StorageQuadTreeBox::StorageQuadTreeBox(long ll,StorageQuadTreeBox *nn) {
    408                 len = ll;
    409                 n = nn;
    410                 b = new QuadTreeBox[ll];
    411                 for (int i = 0; i <ll;i++)
    412                  b[i].n =0,b[i].b[0]=b[i].b[1]=b[i].b[2]=b[i].b[3]=0;
    413                 bc =b;
    414                 be = b +ll;
    415                 if (!b){
    416                         throw ErrorException(__FUNCT__,exprintf("!b"));
    417                 }
    418         }
    419         /*}}}1*/
    420405
    421406}
  • issm/trunk/src/c/Bamgx/objects/Triangles.cpp

    r2870 r2877  
    2727
    2828                PreInit(0,"none");
    29                 OnDisk = 1;
    30 
    3129                ReadMesh(bamgmesh,bamgopts);
    3230                SetIntCoor();
     
    3533        /*}}}1*/
    3634        /*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
    37         Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb)
    38           : Gh(*(new Geometry())), BTh(*this) {
     35        Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb) : Gh(*(new Geometry())), BTh(*this) {
    3936
    4037                  char cname[] = "trunc";
     
    729726
    730727        /*Methods*/
     728        /*FUNCTION Triangles::Add{{{1*/
     729        void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3) {
     730                // -------------------------------------------
     731                //             s2
     732                //                                            !
     733                //             /|\                            !
     734                //            / | \                           !
     735                //           /  |  \                          !
     736                //    tt1   /   |   \ tt0                     !
     737                //         /    |s   \                        !
     738                //        /     .     \                       !
     739                //       /  .      `   \                      !
     740                //      / .           ` \                     !
     741                //      ----------------                      !
     742                //   s0       tt2       s1
     743                //--------------------------------------------
     744
     745                Triangle * tt[3]; // the 3 new Triangles
     746                Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
     747                Icoor2  det3local[3];
     748                int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
     749                // infv = ordre of the infini vertex (null)
     750                register int nbd0 =0; // number of zero det3
     751                register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
     752                Icoor2 detOld = t->det;
     753
     754                if (( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) ){
     755                        throw ErrorException(__FUNCT__,exprintf("infv=%g det=%g"));
     756                }
     757
     758                // if det3 do not exist then constuct det3
     759                if (!det3) {
     760                        det3 = det3local; // alloc
     761                        if ( infv<0 ) {
     762                                det3[0]=bamg::det(s ,s1,s2);
     763                                det3[1]=bamg::det(s0,s ,s2);
     764                                det3[2]=bamg::det(s0,s1,s );}
     765                        else {
     766                                // one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
     767                                det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
     768                                det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
     769                                det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
     770
     771
     772                                if (!det3[0]) izerodet=0,nbd0++;
     773                                if (!det3[1]) izerodet=1,nbd0++;
     774                                if (!det3[2]) izerodet=2,nbd0++;
     775
     776                                if  (nbd0 >0 ) // point s on a egde or on a vertex
     777                                 if (nbd0 == 1) {
     778                                         iedge = OppositeEdge[izerodet];
     779                                         TriangleAdjacent ta = t->Adj(iedge);
     780
     781                                         // the point is on the edge
     782                                         // if the point is one the boundary
     783                                         // add the point in outside part
     784                                         if ( t->det >=0) { // inside triangle
     785                                                 if ((( Triangle *) ta)->det < 0 ) {
     786                                                         // add in outside triangle
     787                                                         Add(s,( Triangle *) ta);
     788                                                         return;}
     789                                         }}
     790                                 else {
     791                                         printf("bug (%i): Bug double points in\n",nbd0);
     792                                         throw ErrorException(__FUNCT__,exprintf("See above"));
     793                                 }
     794
     795                                // remove de MarkUnSwap edge
     796                                t->SetUnMarkUnSwap(0);     
     797                                t->SetUnMarkUnSwap(1);     
     798                                t->SetUnMarkUnSwap(2);
     799
     800                                tt[0]= t;
     801                                tt[1]= &triangles[nbt++];
     802                                tt[2]= &triangles[nbt++];
     803
     804                                if (nbt>nbtx) {
     805                                        throw ErrorException(__FUNCT__,exprintf("Not ebough triangles"));
     806                                }
     807
     808                                *tt[1]=   *tt[2]= *t;
     809                                // gestion of the link
     810                                tt[0]->link=tt[1];
     811                                tt[1]->link=tt[2];
     812
     813                                (* tt[0])(OppositeVertex[0])=&s;
     814                                (* tt[1])(OppositeVertex[1])=&s;
     815                                (* tt[2])(OppositeVertex[2])=&s;
     816
     817                                tt[0]->det=det3[0];
     818                                tt[1]->det=det3[1];
     819                                tt[2]->det=det3[2];         
     820
     821                                //  update adj des triangles externe
     822                                tt[0]->SetAdjAdj(0);
     823                                tt[1]->SetAdjAdj(1);
     824                                tt[2]->SetAdjAdj(2);
     825                                //  update des adj des 3 triangle interne
     826                                const int i0 = 0;
     827                                const int i1= NextEdge[i0];
     828                                const int i2 = PreviousEdge[i0];
     829
     830                                tt[i0]->SetAdj2(i2,tt[i2],i0);
     831                                tt[i1]->SetAdj2(i0,tt[i0],i1);
     832                                tt[i2]->SetAdj2(i1,tt[i1],i2);
     833
     834                                tt[0]->SetTriangleContainingTheVertex();
     835                                tt[1]->SetTriangleContainingTheVertex();
     836                                tt[2]->SetTriangleContainingTheVertex();
     837
     838
     839                                // swap if the point s is on a edge
     840                                if(izerodet>=0) {
     841                                        int rswap =tt[izerodet]->swap(iedge);
     842
     843                                        if (!rswap) {
     844                                                throw ErrorException(__FUNCT__,exprintf("swap the point s is on a edge"));
     845                                        }
     846                                }
     847        }
     848        /*}}}1*/
     849        /*FUNCTION Triangles::BoundAnisotropy{{{1*/
     850        void  Triangles::BoundAnisotropy(Real8 anisomax,Real8 hminaniso) {
     851                long int verbosity=0;
     852
     853                double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
     854                if (verbosity > 1)  printf("   BoundAnisotropy by %g\n",anisomax);
     855                Real8 h1=1.e30,h2=1e-30,rx=0;
     856                Real8 coef = 1./(anisomax*anisomax);
     857                Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
     858                for (Int4 i=0;i<nbv;i++)
     859                  {
     860
     861                        MatVVP2x2 Vp(vertices[i]);
     862                        double lmax=Vp.lmax();
     863                        h1=Min(h1,Vp.lmin());
     864                        h2=Max(h2,Vp.lmax());
     865                        rx = Max(rx,Vp.Aniso2());
     866
     867                        Vp *= Min(lminaniso,lmax)/lmax;
     868
     869                        Vp.BoundAniso2(coef);
     870
     871                        hn1=Min(hn1,Vp.lmin());
     872                        hn2=Max(hn2,Vp.lmax());
     873                        rnx = Max(rnx,Vp.Aniso2());
     874
     875
     876                        vertices[i].m = Vp;
     877
     878                  }
     879
     880                if (verbosity>2){
     881                        printf("      input:  Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(h2,-0.5),pow(h1,-0.5),pow(rx,0.5));
     882                        printf("      output: Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
     883                }
     884        }
     885        /*}}}1*/
    731886        /*FUNCTION Triangles::ConsGeometry{{{1*/
    732887        void Triangles::ConsGeometry(Real8 cutoffradian,int *equiedges) // construct a geometry if no geo
     
    772927                if (nbe !=  edge4->nb()){
    773928                        throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i, nbe4=%i",nbe,edge4->nb()));
    774                   }
     929                }
    775930                for (i=0;i<nbt;i++){
    776931                        for  (j=0;j<3;j++) {
     
    810965                        printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv);
    811966                }
    812                         // check the consistant of edge[].adj and the geometrical required  vertex
     967                // check the consistant of edge[].adj and the geometrical required  vertex
     968                k=0;
     969                kk=0;
     970                Int4 it;
     971
     972                for (i=0;i<nbedges;i++)
     973                 if (st[i] <-1) {// edge internal
     974                         it =  (-2-st[i])/3;
     975                         j  =  (int) ((-2-st[i])%3);
     976                         Triangle & tt = * triangles[it].TriangleAdj(j);
     977                         if (triangles[it].color != tt.color|| i < nbeold) k++;
     978                 }
     979                 else if (st[i] >=0) // edge alone
     980                  kk++;
     981
     982                k += kk;
     983                kk=0;
     984                if (k) {
     985                        // construction of the edges
     986                        nbe = k;
     987                        Edge * edgessave = edges;
     988                        edges = new Edge[nbe];
     989                        k =0;
     990                        // construction of the edges
     991                        if(verbosity>4) printf("   Construction of the edges %i\n",nbe);
     992
     993                        for (i=0;i<nbedges;i++){
     994                                Int4  add= -1;
     995
     996                                if (st[i] <-1) // edge internal
     997                                  {
     998                                        it =  (-2-st[i])/3;
     999                                        j  =  (int) ((-2-st[i])%3);
     1000                                        Triangle & tt = * triangles[it].TriangleAdj(j);
     1001                                        if (triangles[it].color !=  tt.color || i < nbeold) // Modif FH 06122055
     1002                                         add=k++;
     1003                                  }
     1004                                else if (st[i] >=0) // edge alone
     1005                                  {
     1006                                        it = st[i]/3;
     1007                                        j  = (int) (st[i]%3);
     1008                                        add=k++;
     1009                                  }
     1010
     1011                                if (add>=0 && add < nbe)
     1012                                  {
     1013
     1014                                        edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
     1015                                        edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
     1016                                        edges[add].on=0;
     1017                                        if (i<nbeold) // in file edge // Modif FH 06122055
     1018                                          {
     1019                                                edges[add].ref = edgessave[i].ref;                   
     1020                                                edges[add].on = edgessave[i].on; //  HACK pour recuperer les aretes requise midf FH avril 2006 ????
     1021                                          }
     1022                                        else
     1023                                         edges[add].ref = Min(edges[add].v[0]->ref(),edges[add].v[1]->ref()); // no a good choice
     1024                                  }
     1025                        }
     1026                        if (k!=nbe){
     1027                                throw ErrorException(__FUNCT__,exprintf("k!=nbe"));
     1028                        }
     1029                        if (edgessave) delete [] edgessave;
     1030                }
     1031
     1032                // construction of edges[].adj
     1033                for (i=0;i<nbv;i++)
     1034                 vertices[i].color =0;
     1035                for (i=0;i<nbe;i++)
     1036                 for (j=0;j<2;j++)
     1037                  edges[i].v[j]->color++;
     1038
     1039                for (i=0;i<nbv;i++)
     1040                 vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
     1041                for (i=0;i<nbe;i++)
     1042                 for (j=0;j<2;j++)
     1043                        {
     1044                         Vertex *v=edges[i].v[j];
     1045                         Int4 i0=v->color,j0;
     1046                         if(i0<0)
     1047                          edges[i ].adj[ j ]=0;  // Add FH Jan 2008   
     1048                         if(i0==-1)
     1049                          v->color=i*2+j;
     1050                         else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
     1051                                 j0 =  i0%2;
     1052                                 i0 =  i0/2;
     1053                                 if (v!=edges[i0 ].v[j0]){
     1054                                         throw ErrorException(__FUNCT__,exprintf("v!=edges[i0 ].v[j0]"));
     1055                                 }
     1056                                 edges[i ].adj[ j ] =edges +i0;
     1057                                 edges[i0].adj[ j0] =edges +i ;
     1058                                 v->color = -3;}
     1059                        }
     1060                // now reconstruct the sub domain info
     1061                if (NbSubDomains){
     1062                        throw ErrorException(__FUNCT__,exprintf("NbSubDomains should be 0"));
     1063                }
     1064                NbSubDomains=0;
     1065
     1066                  {
     1067                        Int4 it;
     1068                        // find all the sub domain
     1069                        Int4 *colorT = new Int4[nbt];
     1070                        Triangle *tt,*t;
     1071                        Int4 k;
     1072                        for ( it=0;it<nbt;it++)
     1073                         colorT[it]=-1;
     1074                        for (it=0;it<nbt;it++)
     1075                          {
     1076                                if (colorT[it]<0)
     1077                                  {
     1078                                        colorT[it]=NbSubDomains;
     1079                                        Int4 level =1,j,jt,kolor=triangles[it].color;
     1080                                        st[0]=it; // stack
     1081                                        st[1]=0;
     1082                                        k=1;
     1083                                        while (level>0)
     1084                                         if( ( j=st[level]++) <3)
     1085                                                {
     1086                                                 t = &triangles[st[level-1]];
     1087                                                 tt=t->TriangleAdj((int)j);
     1088
     1089                                                 if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor))
     1090                                                        {
     1091                                                         colorT[jt]=NbSubDomains;
     1092                                                         st[++level]=jt;
     1093                                                         st[++level]=0;
     1094                                                         k++;
     1095                                                        }
     1096                                                }
     1097                                         else
     1098                                          level-=2;
     1099                                        NbSubDomains++;
     1100                                  }
     1101                          }
     1102                        if (verbosity> 3) printf("      The Number of sub domain = %i\n",NbSubDomains);
     1103
     1104                        Int4 isd;
     1105                        subdomains = new SubDomain[NbSubDomains];
     1106                        for (isd=0;isd<NbSubDomains;isd++)
     1107                          {
     1108                                subdomains[isd].head =0;
     1109                          }
    8131110                        k=0;
    814                         kk=0;
    815                         Int4 it;
    816 
    817                         for (i=0;i<nbedges;i++)
    818                          if (st[i] <-1) {// edge internal
    819                                  it =  (-2-st[i])/3;
    820                                  j  =  (int) ((-2-st[i])%3);
    821                                  Triangle & tt = * triangles[it].TriangleAdj(j);
    822                                  if (triangles[it].color != tt.color|| i < nbeold) k++;
    823                          }
    824                          else if (st[i] >=0) // edge alone
    825                           kk++;
    826 
    827                         k += kk;
    828                         kk=0;
    829                         if (k) {
    830                                 // construction of the edges
    831                                 nbe = k;
    832                                 Edge * edgessave = edges;
    833                                 edges = new Edge[nbe];
    834                                 k =0;
    835                                 // construction of the edges
    836                                 if(verbosity>4) printf("   Construction of the edges %i\n",nbe);
    837 
    838                                 for (i=0;i<nbedges;i++){
    839                                         Int4  add= -1;
    840 
    841                                         if (st[i] <-1) // edge internal
    842                                           {
    843                                                 it =  (-2-st[i])/3;
    844                                                 j  =  (int) ((-2-st[i])%3);
    845                                                 Triangle & tt = * triangles[it].TriangleAdj(j);
    846                                                 if (triangles[it].color !=  tt.color || i < nbeold) // Modif FH 06122055
    847                                                  add=k++;
    848                                           }
    849                                         else if (st[i] >=0) // edge alone
    850                                           {
    851                                                 it = st[i]/3;
    852                                                 j  = (int) (st[i]%3);
    853                                                 add=k++;
    854                                           }
    855 
    856                                         if (add>=0 && add < nbe)
    857                                           {
    858 
    859                                                 edges[add].v[0] = &triangles[it][VerticesOfTriangularEdge[j][0]];
    860                                                 edges[add].v[1] = &triangles[it][VerticesOfTriangularEdge[j][1]];
    861                                                 edges[add].on=0;
    862                                                 if (i<nbeold) // in file edge // Modif FH 06122055
    863                                                   {
    864                                                         edges[add].ref = edgessave[i].ref;                   
    865                                                         edges[add].on = edgessave[i].on; //  HACK pour recuperer les aretes requise midf FH avril 2006 ????
    866                                                   }
    867                                                 else
    868                                                  edges[add].ref = Min(edges[add].v[0]->ref(),edges[add].v[1]->ref()); // no a good choice
    869                                           }
    870                                   }
    871                                 if (k!=nbe){
    872                                         throw ErrorException(__FUNCT__,exprintf("k!=nbe"));
     1111                        for (it=0;it<nbt;it++)
     1112                         for (int j=0;j<3;j++)
     1113                                {
     1114                                 tt=triangles[it].TriangleAdj(j);
     1115                                 if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head)
     1116                                        {
     1117                                         subdomains[isd].head = triangles+it;
     1118                                         subdomains[isd].ref =  triangles[it].color;
     1119                                         subdomains[isd].sens = j; // hack
     1120                                         subdomains[isd].edge = 0;
     1121                                         k++;
     1122                                        }
     1123                                } 
     1124                        if (k!= NbSubDomains){
     1125                                throw ErrorException(__FUNCT__,exprintf("k!= NbSubDomains"));
     1126                        }
     1127
     1128                        delete [] colorT;
     1129
     1130
     1131                  }     
     1132                delete [] st;
     1133                // now make the geometry
     1134                // 1 compress the vertices
     1135                Int4 * colorV = new Int4[nbv];
     1136                for (i=0;i<nbv;i++)
     1137                 colorV[i]=-1;
     1138                for (i=0;i<nbe;i++)
     1139                 for ( j=0;j<2;j++)
     1140                  colorV[Number(edges[i][j])]=0;
     1141                k=0;
     1142                for (i=0;i<nbv;i++)
     1143                 if(!colorV[i])
     1144                  colorV[i]=k++;
     1145
     1146                Gh.nbv=k;
     1147                Gh.nbe = nbe;
     1148                Gh.vertices = new GeometricalVertex[k];
     1149                Gh.edges = new GeometricalEdge[nbe];
     1150                Gh.NbSubDomains = NbSubDomains;
     1151                Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
     1152                if (verbosity>3) printf("   number of vertices = %i\n   number of edges = %i\n",Gh.nbv,Gh.nbe);
     1153                NbVerticesOnGeomVertex = Gh.nbv;
     1154                VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
     1155                NbVerticesOnGeomEdge =0;
     1156                VerticesOnGeomEdge =0;
     1157                  {
     1158                        Int4 j;
     1159                        for (i=0;i<nbv;i++)
     1160                         if((j=colorV[i])>=0)
     1161                                {
     1162
     1163                                 Vertex & v = Gh.vertices[j];
     1164                                 v = vertices[i];
     1165                                 v.color =0;
     1166                                 VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
    8731167                                }
    874                                 if (edgessave) delete [] edgessave;
     1168
     1169                  }
     1170                edge4= new SetOfEdges4(nbe,nbv); 
     1171
     1172                Real4 * len = new Real4[Gh.nbv];
     1173                for(i=0;i<Gh.nbv;i++)
     1174                 len[i]=0;
     1175
     1176                Gh.pmin =  Gh.vertices[0].r;
     1177                Gh.pmax =  Gh.vertices[0].r;
     1178                // recherche des extrema des vertices pmin,pmax
     1179                for (i=0;i<Gh.nbv;i++) {
     1180                        Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
     1181                        Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
     1182                        Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
     1183                        Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
     1184                }
     1185
     1186                R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
     1187                Gh.pmin -=  DD05;
     1188                Gh.pmax +=  DD05;
     1189
     1190                Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
     1191                if (Gh.coefIcoor<=0){
     1192                        throw ErrorException(__FUNCT__,exprintf("Gh.coefIcoor<=0"));
     1193                }
     1194
     1195                Real8 hmin = HUGE_VAL;
     1196                int kreq=0;
     1197                for (i=0;i<nbe;i++)
     1198                  {
     1199                        Int4 i0 = Number(edges[i][0]);
     1200                        Int4 i1 = Number(edges[i][1]);
     1201                        Int4 j0 =        colorV[i0];
     1202                        Int4 j1 =  colorV[i1];
     1203
     1204                        Gh.edges[i].v[0] = Gh.vertices +  j0;
     1205                        Gh.edges[i].v[1] = Gh.vertices +  j1;
     1206                        Gh.edges[i].flag = 0;
     1207                        Gh.edges[i].tg[0]=R2();
     1208                        Gh.edges[i].tg[1]=R2();
     1209                        bool requis= edges[i].on;
     1210                        if(requis) kreq++;
     1211                        edges[i].on =  Gh.edges + i;
     1212                        if(equiedges && i < nbeold ) {
     1213                                int j=equiedges[i]/2;
     1214                                int sens=equiedges[i]%2;
     1215                                if(i!=j && equiedges[i]>=0) {
     1216                                        if( sens==0)
     1217                                         Gh.edges[i].SetEqui();
     1218                                        else
     1219                                         Gh.edges[i].SetReverseEqui();
     1220                                        Gh.edges[i].link= & Gh.edges[j];
     1221                                }
     1222
     1223                        }
     1224                        if(requis)  {  // correction fevr 2009 JYU ...
     1225                                Gh.edges[i].v[0]->SetRequired();
     1226                                Gh.edges[i].v[1]->SetRequired();
     1227                                Gh.edges[i].SetRequired(); // fin modif ...
     1228                        }
     1229                        R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
     1230                        Real8 l12=Norme2(x12);       
     1231                        hmin = Min(hmin,l12);
     1232
     1233                        Gh.vertices[j1].color++;
     1234                        Gh.vertices[j0].color++;
     1235
     1236                        len[j0]+= l12;
     1237                        len[j1] += l12;
     1238                        hmin = Min(hmin,l12);
     1239                        Gh.edges[i].ref  = edges[i].ref;
     1240
     1241                        k = edge4->addtrie(i0,i1);
     1242                        if (k != i){
     1243                                throw ErrorException(__FUNCT__,exprintf("k != i"));
     1244                        }
     1245
     1246                  }
     1247
     1248
     1249                for (i=0;i<Gh.nbv;i++)
     1250                 if (Gh.vertices[i].color > 0)
     1251                  Gh.vertices[i].m=  Metric(len[i] /(Real4) Gh.vertices[i].color);
     1252                 else
     1253                  Gh.vertices[i].m=  Metric(hmin);
     1254                delete [] len;
     1255                for (i=0;i<NbSubDomains;i++)
     1256                  {
     1257                        Int4 it = Number(subdomains[i].head);
     1258                        int j = subdomains[i].sens;
     1259                        Int4 i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
     1260                        Int4 i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
     1261                        k = edge4->findtrie(i0,i1);
     1262                        if(k>=0)
     1263                          {
     1264                                subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
     1265                                subdomains[i].edge = edges+k;
     1266                                Gh.subdomains[i].edge = Gh.edges + k;
     1267                                Gh.subdomains[i].sens  =  subdomains[i].sens;
     1268                                Gh.subdomains[i].ref =  subdomains[i].ref;
    8751269                          }
    876 
    877                         // construction of edges[].adj
    878                         for (i=0;i<nbv;i++)
    879                          vertices[i].color =0;
    880                         for (i=0;i<nbe;i++)
    881                          for (j=0;j<2;j++)
    882                           edges[i].v[j]->color++;
    883 
    884                         for (i=0;i<nbv;i++)
    885                          vertices[i].color = (vertices[i].color ==2) ? -1 : -2;
    886                         for (i=0;i<nbe;i++)
    887                          for (j=0;j<2;j++)
    888                                 {
    889                                  Vertex *v=edges[i].v[j];
    890                                  Int4 i0=v->color,j0;
    891                                  if(i0<0)
    892                                   edges[i ].adj[ j ]=0;  // Add FH Jan 2008   
    893                                  if(i0==-1)
    894                                   v->color=i*2+j;
    895                                  else if (i0>=0) {// i and i0 edge are adjacent by the vertex v
    896                                          j0 =  i0%2;
    897                                          i0 =  i0/2;
    898                                          if (v!=edges[i0 ].v[j0]){
    899                                                  throw ErrorException(__FUNCT__,exprintf("v!=edges[i0 ].v[j0]"));
    900                                          }
    901                                          edges[i ].adj[ j ] =edges +i0;
    902                                          edges[i0].adj[ j0] =edges +i ;
    903                                          v->color = -3;}
    904                                 }
    905                         // now reconstruct the sub domain info
    906                         if (NbSubDomains){
    907                                 throw ErrorException(__FUNCT__,exprintf("NbSubDomains should be 0"));
    908                         }
    909                         NbSubDomains=0;
    910 
    911                           {
    912                                 Int4 it;
    913                                 // find all the sub domain
    914                                 Int4 *colorT = new Int4[nbt];
    915                                 Triangle *tt,*t;
    916                                 Int4 k;
    917                                 for ( it=0;it<nbt;it++)
    918                                  colorT[it]=-1;
    919                                 for (it=0;it<nbt;it++)
    920                                   {
    921                                         if (colorT[it]<0)
    922                                           {
    923                                                 colorT[it]=NbSubDomains;
    924                                                 Int4 level =1,j,jt,kolor=triangles[it].color;
    925                                                 st[0]=it; // stack
    926                                                 st[1]=0;
    927                                                 k=1;
    928                                                 while (level>0)
    929                                                  if( ( j=st[level]++) <3)
    930                                                         {
    931                                                          t = &triangles[st[level-1]];
    932                                                          tt=t->TriangleAdj((int)j);
    933 
    934                                                          if ( ! t->Locked(j) && tt && (colorT[jt = Number(tt)] == -1) && ( tt->color==kolor))
    935                                                                 {
    936                                                                  colorT[jt]=NbSubDomains;
    937                                                                  st[++level]=jt;
    938                                                                  st[++level]=0;
    939                                                                  k++;
    940                                                                 }
    941                                                         }
    942                                                  else
    943                                                   level-=2;
    944                                                 NbSubDomains++;
    945                                           }
    946                                   }
    947                                 if (verbosity> 3) printf("      The Number of sub domain = %i\n",NbSubDomains);
    948 
    949                                 Int4 isd;
    950                                 subdomains = new SubDomain[NbSubDomains];
    951                                 for (isd=0;isd<NbSubDomains;isd++)
    952                                   {
    953                                         subdomains[isd].head =0;
    954                                   }
    955                                 k=0;
    956                                 for (it=0;it<nbt;it++)
    957                                  for (int j=0;j<3;j++)
    958                                         {
    959                                          tt=triangles[it].TriangleAdj(j);
    960                                          if ((!tt || tt->color != triangles[it].color) && !subdomains[isd=colorT[it]].head)
    961                                                 {
    962                                                  subdomains[isd].head = triangles+it;
    963                                                  subdomains[isd].ref =  triangles[it].color;
    964                                                  subdomains[isd].sens = j; // hack
    965                                                  subdomains[isd].edge = 0;
    966                                                  k++;
    967                                                 }
    968                                         } 
    969                                 if (k!= NbSubDomains){
    970                                         throw ErrorException(__FUNCT__,exprintf("k!= NbSubDomains"));
    971                                 }
    972 
    973                                 delete [] colorT;
    974 
    975 
    976                           }     
    977                         delete [] st;
    978                         // now make the geometry
    979                         // 1 compress the vertices
    980                         Int4 * colorV = new Int4[nbv];
    981                         for (i=0;i<nbv;i++)
    982                          colorV[i]=-1;
    983                         for (i=0;i<nbe;i++)
    984                          for ( j=0;j<2;j++)
    985                           colorV[Number(edges[i][j])]=0;
    986                         k=0;
    987                         for (i=0;i<nbv;i++)
    988                          if(!colorV[i])
    989                           colorV[i]=k++;
    990 
    991                         Gh.nbv=k;
    992                         Gh.nbe = nbe;
    993                         Gh.vertices = new GeometricalVertex[k];
    994                         Gh.edges = new GeometricalEdge[nbe];
    995                         Gh.NbSubDomains = NbSubDomains;
    996                         Gh.subdomains = new GeometricalSubDomain[NbSubDomains];
    997                         if (verbosity>3) printf("   number of vertices = %i\n   number of edges = %i\n",Gh.nbv,Gh.nbe);
    998                         NbVerticesOnGeomVertex = Gh.nbv;
    999                         VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex];
    1000                         NbVerticesOnGeomEdge =0;
    1001                         VerticesOnGeomEdge =0;
    1002                           {
    1003                                 Int4 j;
    1004                                 for (i=0;i<nbv;i++)
    1005                                  if((j=colorV[i])>=0)
    1006                                         {
    1007 
    1008                                          Vertex & v = Gh.vertices[j];
    1009                                          v = vertices[i];
    1010                                          v.color =0;
    1011                                          VerticesOnGeomVertex[j] = VertexOnGeom(vertices[i], Gh.vertices[j]);
    1012                                         }
    1013 
    1014                           }
    1015                         edge4= new SetOfEdges4(nbe,nbv); 
    1016 
    1017                         Real4 * len = new Real4[Gh.nbv];
    1018                         for(i=0;i<Gh.nbv;i++)
    1019                          len[i]=0;
    1020 
    1021                         Gh.pmin =  Gh.vertices[0].r;
    1022                         Gh.pmax =  Gh.vertices[0].r;
    1023                         // recherche des extrema des vertices pmin,pmax
    1024                         for (i=0;i<Gh.nbv;i++) {
    1025                                 Gh.pmin.x = Min(Gh.pmin.x,Gh.vertices[i].r.x);
    1026                                 Gh.pmin.y = Min(Gh.pmin.y,Gh.vertices[i].r.y);
    1027                                 Gh.pmax.x = Max(Gh.pmax.x,Gh.vertices[i].r.x);
    1028                                 Gh.pmax.y = Max(Gh.pmax.y,Gh.vertices[i].r.y);
    1029                         }
    1030 
    1031                         R2 DD05 = (Gh.pmax-Gh.pmin)*0.05;
    1032                         Gh.pmin -=  DD05;
    1033                         Gh.pmax +=  DD05;
    1034 
    1035                         Gh.coefIcoor= (MaxICoor)/(Max(Gh.pmax.x-Gh.pmin.x,Gh.pmax.y-Gh.pmin.y));
    1036                         if (Gh.coefIcoor<=0){
    1037                                 throw ErrorException(__FUNCT__,exprintf("Gh.coefIcoor<=0"));
    1038                         }
    1039 
    1040                         Real8 hmin = HUGE_VAL;
    1041                         int kreq=0;
    1042                         for (i=0;i<nbe;i++)
    1043                           {
    1044                                 Int4 i0 = Number(edges[i][0]);
    1045                                 Int4 i1 = Number(edges[i][1]);
    1046                                 Int4 j0 =        colorV[i0];
    1047                                 Int4 j1 =  colorV[i1];
    1048 
    1049                                 Gh.edges[i].v[0] = Gh.vertices +  j0;
    1050                                 Gh.edges[i].v[1] = Gh.vertices +  j1;
    1051                                 Gh.edges[i].flag = 0;
    1052                                 Gh.edges[i].tg[0]=R2();
    1053                                 Gh.edges[i].tg[1]=R2();
    1054                                 bool requis= edges[i].on;
    1055                                 if(requis) kreq++;
    1056                                 edges[i].on =  Gh.edges + i;
    1057                                 if(equiedges && i < nbeold ) {
    1058                                         int j=equiedges[i]/2;
    1059                                         int sens=equiedges[i]%2;
    1060                                         if(i!=j && equiedges[i]>=0) {
    1061                                                 if( sens==0)
    1062                                                  Gh.edges[i].SetEqui();
    1063                                                 else
    1064                                                  Gh.edges[i].SetReverseEqui();
    1065                                                 Gh.edges[i].link= & Gh.edges[j];
    1066                                         }
    1067 
    1068                                 }
    1069                                 if(requis)  {  // correction fevr 2009 JYU ...
    1070                                         Gh.edges[i].v[0]->SetRequired();
    1071                                         Gh.edges[i].v[1]->SetRequired();
    1072                                         Gh.edges[i].SetRequired(); // fin modif ...
    1073                                 }
    1074                                 R2 x12 = Gh.vertices[j0].r-Gh.vertices[j1].r;
    1075                                 Real8 l12=Norme2(x12);       
    1076                                 hmin = Min(hmin,l12);
    1077 
    1078                                 Gh.vertices[j1].color++;
    1079                                 Gh.vertices[j0].color++;
    1080 
    1081                                 len[j0]+= l12;
    1082                                 len[j1] += l12;
    1083                                 hmin = Min(hmin,l12);
    1084                                 Gh.edges[i].ref  = edges[i].ref;
    1085 
    1086                                 k = edge4->addtrie(i0,i1);
    1087                                 if (k != i){
    1088                                         throw ErrorException(__FUNCT__,exprintf("k != i"));
    1089                                 }
    1090 
    1091                           }
    1092 
    1093 
    1094                         for (i=0;i<Gh.nbv;i++)
    1095                          if (Gh.vertices[i].color > 0)
    1096                           Gh.vertices[i].m=  Metric(len[i] /(Real4) Gh.vertices[i].color);
    1097                          else
    1098                           Gh.vertices[i].m=  Metric(hmin);
    1099                         delete [] len;
    1100                         for (i=0;i<NbSubDomains;i++)
    1101                           {
    1102                                 Int4 it = Number(subdomains[i].head);
    1103                                 int j = subdomains[i].sens;
    1104                                 Int4 i0 = Number(triangles[it][VerticesOfTriangularEdge[j][0]]);
    1105                                 Int4 i1 = Number(triangles[it][VerticesOfTriangularEdge[j][1]]);
    1106                                 k = edge4->findtrie(i0,i1);
    1107                                 if(k>=0)
    1108                                   {
    1109                                         subdomains[i].sens = (vertices + i0 == edges[k].v[0]) ? 1 : -1;
    1110                                         subdomains[i].edge = edges+k;
    1111                                         Gh.subdomains[i].edge = Gh.edges + k;
    1112                                         Gh.subdomains[i].sens  =  subdomains[i].sens;
    1113                                         Gh.subdomains[i].ref =  subdomains[i].ref;
    1114                                   }
    1115                                 else
    1116                                  throw ErrorException(__FUNCT__,exprintf("%i should be >=0"));
    1117                           }
    1118 
    1119                         delete edge4;
    1120                         delete [] colorV;
    1121                         //  -- unset adj
    1122                         for (i=0;i<nbt;i++)
    1123                          for ( j=0;j<3;j++)
    1124                           triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
     1270                        else
     1271                         throw ErrorException(__FUNCT__,exprintf("%i should be >=0"));
     1272                  }
     1273
     1274                delete edge4;
     1275                delete [] colorV;
     1276                //  -- unset adj
     1277                for (i=0;i<nbt;i++)
     1278                 for ( j=0;j<3;j++)
     1279                  triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
    11251280
    11261281          }
    11271282        /*}}}1*/
    1128         /*FUNCTION Triangles::ProjectOnCurve{{{1*/
    1129         GeometricalEdge*   Triangles::ProjectOnCurve( Edge & BhAB, Vertex &  vA, Vertex & vB,
    1130                                 Real8 theta,Vertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
    1131                 void *pA=0,*pB=0;
    1132                 Real8 tA=0,tB=0;
    1133                 R2 A=vA,B=vB;
    1134                 Vertex * pvA=&vA, * pvB=&vB;
    1135                 if (vA.vint == IsVertexOnVertex){
    1136                         pA=vA.onbv;
    1137                 }
    1138                 else if (vA.vint == IsVertexOnEdge){
    1139                         pA=vA.onbe->be;
    1140                         tA=vA.onbe->abcisse;
    1141                 }
    1142                 else {
    1143                         throw ErrorException(__FUNCT__,exprintf("ProjectOnCurve On Vertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vA)));
    1144                 }
    1145 
    1146                 if (vB.vint == IsVertexOnVertex){
    1147                         pB=vB.onbv;
    1148                 }
    1149                 else if(vB.vint == IsVertexOnEdge){
    1150                         pB=vB.onbe->be;
    1151                         tB=vB.onbe->abcisse;
    1152                 }
    1153                 else {
    1154                         throw ErrorException(__FUNCT__,exprintf("ProjectOnCurve On Vertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vB)));
    1155                 }
    1156                 Edge * e = &BhAB;
    1157                 if (!pA || !pB || !e){
    1158                         throw ErrorException(__FUNCT__,exprintf("!pA || !pB || !e"));
    1159                 }
    1160                 // be carefull the back ground edge e is on same geom edge
    1161                 // of the initiale edge def by the 2 vertex A B;
    1162                 //check Is a background Mesh;   
    1163                 if (e<BTh.edges || e>=BTh.edges+BTh.nbe){
    1164                         throw ErrorException(__FUNCT__,exprintf("e<BTh.edges || e>=BTh.edges+BTh.nbe"));
    1165                 }
    1166                 // walk on BTh edge
    1167                 //not finish ProjectOnCurve with BackGround Mesh);
    1168                 // 1 first find a back ground edge contening the vertex A
    1169                 // 2 walk n back gound boundary to find the final vertex B
    1170 
    1171                 if( vA.vint == IsVertexOnEdge)
    1172                   { // find the start edge
    1173                         e = vA.onbe->be;         
    1174 
    1175                   }
    1176                 else if (vB.vint == IsVertexOnEdge)
    1177                   {
    1178                         theta = 1-theta;
    1179                         Exchange(tA,tB);
    1180                         Exchange(pA,pB);
    1181                         Exchange(pvA,pvB);
    1182                         Exchange(A,B);
    1183                         e =  vB.onbe->be;
    1184 
    1185                   }
    1186                 else{ // do the search by walking
    1187                         throw ErrorException(__FUNCT__,exprintf("case not supported yet"));
    1188                   }
    1189 
    1190                 // find the direction of walking with sens of edge and pA,PB;
    1191                 R2 AB=B-A;
    1192 
    1193                 Real8 cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
    1194                 int kkk=0;
    1195                 int sens = (cosE01AB>0) ? 1 : 0;
    1196 
    1197                 //   Real8 l=0; // length of the edge AB
    1198                 Real8 abscisse = -1;
    1199 
    1200                 for (int cas=0;cas<2;cas++){
    1201                         // 2 times algo:
    1202                         //    1 for computing the length l
    1203                         //    2 for find the vertex
    1204                         int  iii;
    1205                         Vertex  *v0=pvA,*v1;
    1206                         Edge *neee,*eee;
    1207                         Real8 lg =0; // length of the curve
    1208                         Real8 te0;
    1209                         // we suppose take the curve's abcisse
    1210                         for ( eee=e,iii=sens,te0=tA;
    1211                                                 eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
    1212                                                 neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii ) {
    1213 
    1214                                 kkk=kkk+1;
    1215                                 if (kkk>=100){
    1216                                         throw ErrorException(__FUNCT__,exprintf("kkk>=100"));
     1283        /*FUNCTION Triangles::ConsRefTriangle{{{1*/
     1284        Int4  Triangles::ConsRefTriangle(Int4* reft) const {
     1285                long int verbosity=0;
     1286                register Triangle *t0,*t;
     1287                register Int4 k=0, num;   
     1288                for (Int4 it=0;it<nbt;it++) reft[it]=-1; // outside triangle
     1289                for (Int4 i=0;i<NbSubDomains;i++){
     1290                        t=t0=subdomains[i].head;
     1291                        if (!t0){ // no empty sub domai{
     1292                                throw ErrorException(__FUNCT__,exprintf("!t0"));
     1293                        }
     1294                        // register Int4 color=i+1;// because the color 0 is outside triangle
     1295                        do { k++;
     1296                                num = Number(t);
     1297                                if (num<0 || num>=nbt){
     1298                                        throw ErrorException(__FUNCT__,exprintf("num<0 || num>=nbt"));
    12171299                                }
    1218                                 if (!eee){
    1219                                         throw ErrorException(__FUNCT__,exprintf("!eee"));
     1300                                reft[num]=i;
     1301                        }
     1302                        while (t0 != (t=t->link));
     1303                        }
     1304                        return k;   
     1305                }
     1306                /*}}}1*/
     1307                /*FUNCTION Triangles::Crack{{{1*/
     1308                int  Triangles::Crack() {
     1309                        if (NbCrackedEdges!=0 && NbCrackedVertices<=0);{
     1310                                throw ErrorException(__FUNCT__,exprintf("NbCrackedEdges!=0 && NbCrackedVertices<=0"));
     1311                        }
     1312                        for (int i=0;i<NbCrackedEdges;i++) CrackedEdges[i].Crack();
     1313                        return NbCrackedEdges;
     1314                }
     1315                /*}}}1*/
     1316                /*FUNCTION Triangles::CrackMesh{{{1*/
     1317                int Triangles::CrackMesh() {
     1318                        long int verbosity=0;
     1319                        Triangles *CurrentThOld = CurrentTh;
     1320                        //  computed the number of cracked edge
     1321                        int i,k;
     1322                        for (k=i=0;i<nbe;i++)
     1323                         if(edges[i].on->Cracked()) k++;
     1324                        if( k==0) return 0;
     1325                        CurrentTh = this;
     1326                        printf("      number of Cracked Edges = %i\n",k);
     1327                        NbCrackedEdges =k;
     1328                        CrackedEdges = new  CrackedEdge[k];
     1329                        //  new edge
     1330                        Edge * e = new Edge[ nbe + k];
     1331
     1332                        // copy
     1333                        for (i=0;i<nbe;i++)
     1334                         e[i] = edges[i];
     1335                        delete edges;
     1336                        edges = e;
     1337
     1338                        const int  nbe0  = nbe;
     1339                        for (k=i=0;i<nbe0;i++) // on double les arete cracked
     1340                         if(edges[i].on->Cracked())
     1341                                {
     1342                                 e[nbe] = e[i];
     1343                                 //  return the edge
     1344                                 e[nbe].v[0] =  e[i].v[1];
     1345                                 e[nbe].v[1] =  e[i].v[0];
     1346                                 e[nbe].on = e[i].on->link ; // fqux
     1347                                 CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
     1348                                 nbe++;
    12201349                                }
    1221                                 Real8 lg0 = lg;
    1222                                 Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
    1223                                 lg += dp;
    1224                                 if (cas && abscisse <= lg) { // ok we find the geom edge
    1225                                         Real8 sss  =   (abscisse-lg0)/dp;
    1226                                         Real8 thetab = te0*(1-sss)+ sss*iii;
    1227                                         if (thetab<0 || thetab>1){
    1228                                                 throw ErrorException(__FUNCT__,exprintf("thetab<0 || thetab>1"));
     1350                        ReMakeTriangleContainingTheVertex() ;
     1351                        // 
     1352                        int nbcrakev  =0;
     1353                        Vertex *vlast = vertices + nbv;
     1354                        Vertex *vend = vertices + nbvx; // end of array
     1355                        for (int iv=0;iv<nbv;iv++) // vertex
     1356                          {
     1357                                Vertex & v= vertices[iv];
     1358                                Vertex * vv = & v; 
     1359                                int kk=0; // nb cracked
     1360                                int kc=0;
     1361                                int kkk =0; // nb triangle  with same number
     1362                                Triangle * tbegin = v.t;
     1363                                int i  = v.vint;       
     1364                                if (!tbegin || (i<0) || (i>=3)){
     1365                                        throw ErrorException(__FUNCT__,exprintf("!tbegin || (i<0) || (i>=3)"));
     1366                                }
     1367                                // turn around the vertex v
     1368                                TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
     1369                                int k=0;
     1370                                do {
     1371                                        int kv = VerticesOfTriangularEdge[ta][1];
     1372                                        k++;
     1373                                        Triangle * tt (ta);
     1374                                        if ( ta.Cracked() )
     1375                                          {   
     1376                                                TriangleAdjacent tta=(ta.Adj());
     1377                                                if (!tta.Cracked()){
     1378                                                        throw ErrorException(__FUNCT__,exprintf("!tta.Cracked()"));
     1379                                                }
     1380                                                if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart               
     1381                                                if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
     1382                                                kk++;// number of cracked edge view                 
     1383                                          }
     1384                                        if ( tt->link ) { // if good triangles store the value
     1385                                                int it = Number(tt);
     1386                                                if (it>=nt){
     1387                                                        throw ErrorException(__FUNCT__,exprintf("(it>=nt)"));
     1388                                                }
     1389                                                (*tt)(kv)= vv; //   Change the vertex of triangle
     1390                                                if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref
     1391                                                //        tt->SetTriangleContainingTheVertex();
     1392                                                kkk++;
     1393                                        } else if (kk) { // crack + boundary
     1394                                                if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
    12291395                                        }
    1230                                         BR = VertexOnEdge(&R,eee,thetab);
    1231                                         return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
    1232                                   }
     1396
     1397                                        ta = Next(ta).Adj();
     1398                                } while ( (tbegin != ta));
     1399                                if (!k){
     1400                                        throw ErrorException(__FUNCT__,exprintf("!k"));
     1401                                }
     1402                                if (kc)  nbcrakev++;
    12331403                          }
    1234                         // we find the end
    1235                         if (v1 != pvB){
    1236                                 if (( void*) v1 == pB)
    1237                                  tB = iii;
    1238 
    1239                                 Real8 lg0 = lg;
    1240                                 if (!eee){
    1241                                         throw ErrorException(__FUNCT__,exprintf("!eee"));
    1242                                 }
    1243                                 v1 = pvB;
    1244                                 Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
    1245                                 lg += dp;       
    1246                                 abscisse = lg*theta;
    1247                                 if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
    1248                                   { // ok we find the geom edge
    1249                                         Real8 sss  =   (abscisse-lg0)/dp;
    1250                                         Real8 thetab = te0*(1-sss)+ sss*tB;
    1251                                         if (thetab<0 || thetab>1){
    1252                                                 throw ErrorException(__FUNCT__,exprintf("thetab<0 || thetab>1"));
    1253                                         }
    1254                                         BR = VertexOnEdge(&R,eee,thetab);
    1255                                         return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
    1256                                   }
    1257                           }
    1258                         abscisse = lg*theta;
    1259 
    1260                   }
    1261                 throw ErrorException(__FUNCT__,exprintf("Big bug..."));
    1262                 return 0; // just for the compiler
    1263         }                 
    1264         /*}}}1*/
    1265         /*FUNCTION Triangles::MakeQuadrangles{{{1*/
    1266         void Triangles::MakeQuadrangles(double costheta){
    1267                 long int verbosity=0;
    1268 
    1269                 if (verbosity>2) printf("MakeQuadrangles costheta = %g\n",costheta);
    1270 
    1271                 if (costheta >1) {
    1272                         if (verbosity>5) printf("   do nothing: costheta > 1\n");
    1273                 }
    1274 
    1275 
    1276                         Int4 nbqq = (nbt*3)/2;
    1277                         DoubleAndInt4  *qq = new DoubleAndInt4[nbqq];
    1278 
    1279                         Int4 i,ij;
    1280                         int j;
    1281                         Int4 k=0;
    1282                         for (i=0;i<nbt;i++)
    1283                          for (j=0;j<3;j++)
    1284                           if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
    1285                                 qq[k++].i3j=i*3+j;
    1286                         //  sort  qq
    1287                         HeapSort(qq,k);
    1288 
    1289                         Int4 kk=0;
    1290                         for (ij=0;ij<k;ij++) {
    1291                                 i=qq[ij].i3j/3;
    1292                                 j=(int) (qq[ij].i3j%3);
    1293                                 // optisamition no float computation 
    1294                                 if (triangles[i].QualityQuad(j,0) >=costheta)
    1295                                  triangles[i].SetHidden(j),kk++;
    1296                           }
    1297                         NbOfQuad = kk;
    1298                         if (verbosity>2){
    1299                                 printf("   number of quadrilaterals    = %i\n",NbOfQuad);
    1300                                 printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
    1301                                 printf("   number of outside triangles = %i\n",NbOutT);
    1302                         }
    1303                         delete [] qq;
    1304         }
    1305         /*}}}1*/
    1306         /*FUNCTION Triangles::SplitElement{{{1*/
    1307         int  Triangles::SplitElement(int choice){
    1308                 long int verbosity=0;
    1309 
    1310                 Direction NoDirOfSearch;
    1311                 const  int withBackground = &BTh != this && &BTh;
    1312 
    1313                 ReNumberingTheTriangleBySubDomain();
    1314                 //int nswap =0;
    1315                 const Int4 nfortria( choice ? 4 : 6);
    1316                 if(withBackground)
    1317                   {
    1318                         BTh.SetVertexFieldOn();
    1319                         SetVertexFieldOnBTh();
    1320                   }
    1321                 else
    1322                  BTh.SetVertexFieldOn();
    1323 
    1324                 Int4 newnbt=0,newnbv=0;
    1325                 Int4 * kedge = 0;
    1326                 Int4 newNbOfQuad=NbOfQuad;
    1327                 Int4 * ksplit= 0, * ksplitarray=0;
    1328                 Int4 kkk=0;
    1329                 int ret =0;
    1330                 if (nbvx<nbv+nbe) return 1;//   
    1331                 Triangles *  OCurrentTh= CurrentTh;
    1332                 CurrentTh = this;
    1333                 // 1) create  the new points by spliting the internal edges
    1334                 // set the
    1335                 Int4 nbvold = nbv;
    1336                 Int4 nbtold = nbt;
    1337                 Int4 NbOutTold  = NbOutT;
    1338                 Int4  NbEdgeOnGeom=0;
    1339                 Int4 i;
    1340 
    1341                 nbt = nbt - NbOutT; // remove all the  the ouside triangles
    1342                 Int4 nbtsave = nbt;
    1343                 Triangle * lastT = triangles + nbt;
    1344                 for (i=0;i<nbe;i++)
    1345                  if(edges[i].on) NbEdgeOnGeom++;
    1346                 Int4 newnbe=nbe+nbe;
    1347                 //  Int4 newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
    1348                 Int4 newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
    1349                 // Int4 newNbVertexOnBThVertex=NbVertexOnBThVertex;
    1350                 Int4 newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
    1351 
    1352                 // do allocation for pointeur to the geometry and background
    1353                 VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
    1354                 VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
    1355                 if (NbVerticesOnGeomEdge)
    1356                  memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
    1357                 if (NbVertexOnBThEdge)
    1358                  memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
    1359                 Edge *newedges = new Edge [newnbe];
    1360                 //  memcpy(newedges,edges,sizeof(Edge)*nbe);
    1361                 SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
    1362                 Int4 k=nbv;
    1363                 Int4 kk=0;
    1364                 Int4 kvb = NbVertexOnBThEdge;
    1365                 Int4 kvg = NbVerticesOnGeomEdge;
    1366                 Int4 ie =0;
    1367                 Edge ** edgesGtoB=0;
    1368                 if (withBackground)
    1369                  edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
    1370                 Int4 ferr=0;
    1371                 for (i=0;i<nbe;i++)
    1372                  newedges[ie].on=0;
    1373 
    1374                 for (i=0;i<nbe;i++)
    1375                   {
    1376                         GeometricalEdge *ong =  edges[i].on;
    1377 
    1378                         newedges[ie]=edges[i];
    1379                         newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
    1380                         newedges[ie].adj[1]=newedges + ie +1;
    1381                         R2 A = edges[i][0],B = edges[i][1];
    1382 
    1383 
    1384                         kk += (i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
    1385                         if (ong) // a geometrical edges
    1386                           {
    1387                                 if (withBackground){
    1388                                         // walk on back ground mesh
    1389                                         //  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge);
    1390                                         // a faire -- difficile
    1391                                         // the first PB is to now a background edge between the 2 vertices
    1392                                         if (!edgesGtoB){
    1393                                                 throw ErrorException(__FUNCT__,exprintf("!edgesGtoB"));
    1394                                         }
    1395                                         ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].on)],
    1396                                                                 edges[i][0],edges[i][1],0.5,vertices[k],
    1397                                                                 newVertexOnBThEdge[kvb],
    1398                                                                 newVerticesOnGeomEdge[kvg++]);
    1399                                         vertices[k].ReferenceNumber= edges[i].ref;
    1400                                         vertices[k].DirOfSearch =   NoDirOfSearch;       
    1401                                         ;
    1402                                         // get the Info on background mesh
    1403                                         Real8 s =        newVertexOnBThEdge[kvb];
    1404                                         Vertex &  bv0  = newVertexOnBThEdge[kvb][0];
    1405                                         Vertex &  bv1  = newVertexOnBThEdge[kvb][1];
    1406                                         // compute the metrix of the new points
    1407                                         vertices[k].m =  Metric(1-s,bv0,s,bv1);
    1408                                         kvb++;
    1409                                   }
    1410                                 else
    1411                                   {
    1412                                         ong=Gh.ProjectOnCurve(edges[i],
    1413                                                                 0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
    1414                                         // vertices[k].i = toI2( vertices[k].r);
    1415                                         vertices[k].ReferenceNumber = edges[i].ref;
    1416                                         vertices[k].DirOfSearch = NoDirOfSearch;
    1417                                         vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);             
    1418                                   } 
    1419                           }
    1420                         else // straigth line edge ---
    1421                           {
    1422                                 vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
    1423                                 vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
    1424                                 vertices[k].on = 0;
    1425                           }
    1426                         //vertices[k].i = toI2( vertices[k].r);
    1427                         R2 AB =  vertices[k].r;
    1428                         R2 AA = (A+AB)*0.5;
    1429                         R2 BB = (AB+B)*0.5;
    1430                         vertices[k].ReferenceNumber = edges[i].ref;
    1431                         vertices[k].DirOfSearch = NoDirOfSearch;
    1432 
    1433                         newedges[ie].on = Gh.Contening(AA,ong);
    1434                         newedges[ie++].v[1]=vertices+k;
    1435 
    1436                         newedges[ie]=edges[i];
    1437                         newedges[ie].adj[0]=newedges + ie -1;
    1438                         newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
    1439                         newedges[ie].on =  Gh.Contening(BB,ong);
    1440                         newedges[ie++].v[0]=vertices+k;
    1441                         k++;
    1442                   }
    1443                 if (edgesGtoB) delete [] edgesGtoB;
    1444                 edgesGtoB=0;
    1445 
    1446                 newnbv=k;
    1447                 newNbVerticesOnGeomEdge=kvg;
    1448                 if (newnbv> nbvx) goto Error;// bug
    1449 
    1450                 nbv = k;
    1451 
    1452 
    1453                 kedge = new Int4[3*nbt+1];
    1454                 ksplitarray = new Int4[nbt+1];
    1455                 ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
    1456 
    1457                 for (i=0;i<3*nbt;i++)
    1458                  kedge[i]=-1;
    1459 
    1460                 // 
    1461 
    1462                 for (i=0;i<nbt;i++) {
    1463                         Triangle & t = triangles[i];
    1464                         if (!t.link){
    1465                                 throw ErrorException(__FUNCT__,exprintf("!t.link"));
    1466                         }
    1467                         for(int j=0;j<3;j++)
    1468                           {
    1469                                 const TriangleAdjacent ta = t.Adj(j);
    1470                                 const Triangle & tt = ta;
    1471                                 if (&tt >= lastT)
    1472                                  t.SetAdj2(j,0,0);// unset adj
    1473                                 const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
    1474                                 const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
    1475                                 Int4  ke =edge4->findtrie(Number(v0),Number(v1));
    1476                                 if (ke>0)
    1477                                   {
    1478                                         Int4 ii = Number(tt);
    1479                                         int  jj = ta;
    1480                                         Int4 ks = ke + nbvold;
    1481                                         kedge[3*i+j] = ks;
    1482                                         if (ii<nbt) // good triangle
    1483                                          kedge[3*ii+jj] = ks;
    1484                                         Vertex &A=vertices[ks];
    1485                                         Real8 aa,bb,cc,dd;
    1486                                         if ((dd=Area2(v0.r,v1.r,A.r)) >=0){
    1487                                                 // warning PB roundoff error
    1488                                                 if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0
    1489                                                                                 ||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0 
    1490                                                                                 ||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0)){
    1491                                                         printf("%i not in triangle %i In= %i %i %i %i %i\n",ke + nbvold,i,!!t.link,aa,bb,cc,dd);
    1492                                                         throw ErrorException(__FUNCT__,exprintf("Number of triangles with P2 interpolation Problem"));
     1404
     1405                        if ( nbcrakev )
     1406                         for (int iec =0;iec < NbCrackedEdges; iec ++)
     1407                          CrackedEdges[iec].Set();
     1408
     1409                        //  set the ref
     1410                        NbCrackedVertices =   nbcrakev;
     1411                        // int nbvo = nbv;
     1412                        nbv = vlast - vertices;
     1413                        int nbnewv =  nbv - nbv; // nb of new vrtices
     1414                        if (nbcrakev && verbosity > 1 ) printf("      number of Cracked vertices = %i, number of created vertices = %i\n",nbcrakev,nbnewv);
     1415                        // all the new vertices are on geometry
     1416                        if (nbnewv)
     1417                          { //
     1418                                Int4 n = nbnewv+NbVerticesOnGeomVertex;
     1419                                Int4 i,j,k;
     1420                                VertexOnGeom * vog = new VertexOnGeom[n];
     1421                                for ( i =0; i<NbVerticesOnGeomVertex;i++)
     1422                                 vog[i]=VerticesOnGeomVertex[i];
     1423                                delete [] VerticesOnGeomVertex;
     1424                                VerticesOnGeomVertex = vog;
     1425                                // loop on cracked edge
     1426                                Vertex * LastOld = vertices + nbv - nbnewv;
     1427                                for (int iec =0;iec < NbCrackedEdges; iec ++)
     1428                                 for (k=0;k<2;k++)
     1429                                        {
     1430                                         Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
     1431                                         for (j=0;j<2;j++)
     1432                                                {
     1433                                                 Vertex * v = e(j);
     1434                                                 if ( v >=  LastOld)
     1435                                                        { // a new vertex
     1436                                                         Int4 old = v->ReferenceNumber ; // the old same vertex
     1437                                                         Int4 i  = ( v - LastOld);
     1438                                                         //  if the old is on vertex => warning
     1439                                                         // else the old is on edge => ok
     1440                                                         vog[i] = vog[old];
     1441                                                         //                 vog[i].mv = v;
     1442                                                         //g[i].ge = ;
     1443                                                         //og[i].abcisse = ;
     1444                                                        }
     1445
    14931446                                                }
    14941447                                        }
    1495                                         else {
    1496                                                 if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0
    1497                                                                                 ||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0
    1498                                                                                 ||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)){
    1499                                                         printf("%i not in triangle %i In= %i %i %i %i %i\n",ke + nbvold,ii,!!tt.link,aa,bb,cc,dd);
    1500                                                         throw ErrorException(__FUNCT__,exprintf("Number of triangles with P2 interpolation Problem"));
    1501                                                 }
    1502                                         }
    1503                                   }
     1448
     1449                                NbVerticesOnGeomVertex = n;
    15041450                          }
    1505                 }
    1506 
    1507                 for (i=0;i<nbt;i++){
    1508                         ksplit[i]=1; // no split by default
    1509                         const Triangle & t = triangles[ i];
    1510                         int nbsplitedge =0;
    1511                         int nbinvisible =0;
    1512                         int invisibleedge=0;
    1513                         int kkk[3];     
    1514                         for (int j=0;j<3;j++)
    1515                           {
    1516                                 if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
    1517 
    1518                                 const TriangleAdjacent ta = t.Adj(j);
    1519                                 const Triangle & tt = ta;
    1520 
    1521 
    1522                                 const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
    1523                                 const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
    1524                                 if ( kedge[3*i+j] < 0)
    1525                                   {
    1526                                         Int4  ke =edge4->findtrie(Number(v0),Number(v1));
    1527                                         if (ke<0) // new
    1528                                           {
    1529                                                 if (&tt) // internal triangles all the boundary
    1530                                                   { // new internal edges
    1531                                                         Int4 ii = Number(tt);
    1532                                                         int  jj = ta;
    1533 
    1534                                                         kedge[3*i+j]=k;// save the vertex number
    1535                                                         kedge[3*ii+jj]=k;
    1536                                                         if (k<nbvx)
    1537                                                           {
    1538                                                                 vertices[k].r = ((R2) v0+(R2) v1 )/2;
    1539                                                                 //vertices[k].i = toI2( vertices[k].r);
    1540                                                                 vertices[k].ReferenceNumber=0;
    1541                                                                 vertices[k].DirOfSearch =NoDirOfSearch;
    1542                                                                 vertices[k].m =  Metric(0.5,v0,0.5,v1);
    1543                                                           }
    1544                                                         k++;
    1545                                                         kkk[nbsplitedge++]=j;                 
    1546                                                   } // tt
    1547                                                 else
    1548                                                  throw ErrorException(__FUNCT__,exprintf("Bug..."));
    1549                                           } // ke<0           
    1550                                         else
    1551                                           { // ke >=0
    1552                                                 kedge[3*i+j]=nbvold+ke;
    1553                                                 kkk[nbsplitedge++]=j;// previously splited
    1554                                           }
    1555                                   }
    1556                                 else
    1557                                  kkk[nbsplitedge++]=j;// previously splited
    1558 
    1559                           }
    1560                         if (nbinvisible>=2){
    1561                                 throw ErrorException(__FUNCT__,exprintf("nbinvisible>=2"));
    1562                         }
    1563                         switch (nbsplitedge) {
    1564                                 case 0: ksplit[i]=10; newnbt++; break;   // nosplit
    1565                                 case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2
    1566                                 case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3
    1567                                 case 3:
    1568                                                   if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
    1569                                                   else   ksplit[i]=10*nfortria,newnbt+=nfortria;
    1570                                                   break;
    1571                         }
    1572                         if (ksplit[i]<40){
    1573                                 throw ErrorException(__FUNCT__,exprintf("ksplit[i]<40"));
    1574                         }
    1575                   }
    1576                 //  now do the element split
    1577                 newNbOfQuad = 4*NbOfQuad;
    1578                 nbv = k;
    1579                 kkk = nbt;
    1580                 ksplit[-1] = nbt;
    1581                 // look on  old true  triangles
    1582 
    1583                 for (i=0;i<nbtsave;i++){
    1584                         int  nbmkadj=0;
    1585                         Int4 mkadj [100];
    1586                         mkadj[0]=i;
    1587                         Int4 kk=ksplit[i]/10;
    1588                         int  ke=(int) (ksplit[i]%10);
    1589                         if (kk>=7 || kk<=0){
    1590                                 throw ErrorException(__FUNCT__,exprintf("kk>=7 || kk<=0"));
    1591                         }
    1592 
    1593                         // def the numbering   k (edge) i vertex
    1594                         int k0 = ke;
    1595                         int k1 = NextEdge[k0];
    1596                         int k2 = PreviousEdge[k0];
    1597                         int i0 = OppositeVertex[k0];
    1598                         int i1 = OppositeVertex[k1];
    1599                         int i2 = OppositeVertex[k2];
    1600 
    1601                         Triangle &t0=triangles[i];
    1602                         Vertex * v0=t0(i0);           
    1603                         Vertex * v1=t0(i1);           
    1604                         Vertex * v2=t0(i2);
    1605 
    1606                         if (nbmkadj>=10){
    1607                                 throw ErrorException(__FUNCT__,exprintf("nbmkadj>=10"));
    1608                         }
    1609                         // --------------------------
    1610                         TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
    1611                         // save the flag Hidden
    1612                         int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
    1613                         // un set all adj -- save Hidden flag --
    1614                         t0.SetAdj2(0,0,hid[0]);
    1615                         t0.SetAdj2(1,0,hid[1]);
    1616                         t0.SetAdj2(2,0,hid[2]);
    1617                         // --  remake
    1618                         switch  (kk) {
    1619                                 case 1: break;// nothing
    1620                                 case 2: //
    1621                                                   {
    1622                                                         Triangle &t1=triangles[kkk++];
    1623                                                         t1=t0;
    1624                                                         if (kedge[3*i+i0]<0){
    1625                                                                 throw ErrorException(__FUNCT__,exprintf("kedge[3*i+i0]<0"));
    1626                                                         }
    1627                                                         Vertex * v3 = vertices + kedge[3*i+k0];
    1628 
    1629                                                         t0(i2) = v3;
    1630                                                         t1(i1) = v3;
    1631                                                         t0.SetAllFlag(k2,0);
    1632                                                         t1.SetAllFlag(k1,0);
    1633                                                   }
    1634                                                 break;
    1635                                 case 3: //
    1636                                                   {
    1637                                                         Triangle &t1=triangles[kkk++];
    1638                                                         Triangle &t2=triangles[kkk++];
    1639                                                         t2=t1=t0;
    1640                                                         if (kedge[3*i+k1]<0){
    1641                                                                 throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k1]<0"));
    1642                                                         }
    1643                                                         if (kedge[3*i+k2]<0){
    1644                                                                 throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k2]<0"));
    1645                                                         }
    1646 
    1647                                                         Vertex * v01 = vertices + kedge[3*i+k2];
    1648                                                         Vertex * v02 = vertices + kedge[3*i+k1];
    1649                                                         t0(i1) = v01;
    1650                                                         t0(i2) = v02;
    1651                                                         t1(i2) = v02;
    1652                                                         t1(i0) = v01;
    1653                                                         t2(i0) = v02;
    1654                                                         t0.SetAllFlag(k0,0);
    1655                                                         t1.SetAllFlag(k1,0);
    1656                                                         t1.SetAllFlag(k0,0);
    1657                                                         t2.SetAllFlag(k2,0);
    1658                                                   }
    1659                                                 break;
    1660                                 case 4: //
    1661                                 case 6: // split in 4
    1662                                                   {
    1663                                                         Triangle &t1=triangles[kkk++];
    1664                                                         Triangle &t2=triangles[kkk++];
    1665                                                         Triangle &t3=triangles[kkk++];
    1666                                                         t3=t2=t1=t0;
    1667                                                         if (kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0){
    1668                                                                 throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0"));
    1669                                                         }
    1670                                                         Vertex * v12 = vertices + kedge[3*i+k0];
    1671                                                         Vertex * v02 = vertices + kedge[3*i+k1];
    1672                                                         Vertex * v01 = vertices + kedge[3*i+k2];
    1673                                                         t0(i1) = v01;
    1674                                                         t0(i2) = v02;
    1675                                                         t0.SetAllFlag(k0,hid[k0]);
    1676 
    1677                                                         t1(i0) = v01;
    1678                                                         t1(i2) = v12;
    1679                                                         t0.SetAllFlag(k1,hid[k1]);
    1680 
    1681                                                         t2(i0) = v02;
    1682                                                         t2(i1) = v12;
    1683                                                         t2.SetAllFlag(k2,hid[k2]);
    1684 
    1685                                                         t3(i0) = v12;
    1686                                                         t3(i1) = v02;
    1687                                                         t3(i2) = v01;
    1688 
    1689                                                         t3.SetAllFlag(0,hid[0]);           
    1690                                                         t3.SetAllFlag(1,hid[1]);           
    1691                                                         t3.SetAllFlag(2,hid[2]);
    1692 
    1693                                                         if ( kk == 6)
    1694                                                           {
    1695 
    1696                                                                 Triangle &t4=triangles[kkk++];
    1697                                                                 Triangle &t5=triangles[kkk++];
    1698 
    1699                                                                 t4 = t3;
    1700                                                                 t5 = t3;
    1701 
    1702                                                                 t0.SetHidden(k0);
    1703                                                                 t1.SetHidden(k1);
    1704                                                                 t2.SetHidden(k2);
    1705                                                                 t3.SetHidden(0);
    1706                                                                 t4.SetHidden(1);
    1707                                                                 t5.SetHidden(2);
    1708 
    1709                                                                 if (nbv < nbvx )
    1710                                                                   {
    1711                                                                         vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
    1712                                                                         vertices[nbv].ReferenceNumber =0;
    1713                                                                         vertices[nbv].DirOfSearch =NoDirOfSearch;
    1714                                                                         //vertices[nbv].i = toI2(vertices[nbv].r);
    1715                                                                         Real8 a3[]={1./3.,1./3.,1./3.};
    1716                                                                         vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
    1717                                                                         Vertex * vc =  vertices +nbv++;
    1718                                                                         t3(i0) = vc;
    1719                                                                         t4(i1) = vc;
    1720                                                                         t5(i2) = vc;
    1721 
    1722                                                                   }
    1723                                                                 else
    1724                                                                  goto Error;
    1725                                                           }
    1726 
    1727                                                   }
    1728                                                 break;         
    1729                         }
    1730 
    1731                         // save all the new triangles
    1732                         mkadj[nbmkadj++]=i;
    1733                         Int4 jj;
    1734                         if (t0.link)
    1735                          for (jj=nbt;jj<kkk;jj++)
    1736                                 {
    1737                                  triangles[jj].link=t0.link;
    1738                                  t0.link= triangles+jj;
    1739                                  mkadj[nbmkadj++]=jj;
    1740                                 }
    1741                         if (nbmkadj>13){// 13 = 6 + 4 +
    1742                                 throw ErrorException(__FUNCT__,exprintf("nbmkadj>13"));
    1743                         }
    1744 
    1745                         if (kk==6)  newNbOfQuad+=3;
    1746                         for (jj=ksplit[i-1];jj<kkk;jj++) nbt = kkk;
    1747                         ksplit[i]= nbt; // save last adresse of the new triangles
    1748                         kkk = nbt;
    1749                   }
    1750 
    1751                 for (i=0;i<nbv;i++) vertices[i].m = vertices[i].m*2.;
    1752 
    1753                 if(withBackground)
    1754                  for (i=0;i<BTh.nbv;i++)
    1755                   BTh.vertices[i].m =  BTh.vertices[i].m*2.;
    1756 
    1757 
    1758                 ret = 2;
    1759                 if (nbt>= nbtx) goto Error; // bug
    1760                 if (nbv>= nbvx) goto Error; // bug
    1761                 // generation of the new triangles
    1762 
    1763                 SetIntCoor("In SplitElement");
    1764 
    1765                 ReMakeTriangleContainingTheVertex();
    1766                 if(withBackground)
    1767                  BTh.ReMakeTriangleContainingTheVertex();
    1768 
    1769                 delete [] edges;
    1770                 edges = newedges;
    1771                 nbe = newnbe;
    1772                 NbOfQuad = newNbOfQuad;
    1773 
    1774                 for (i=0;i<NbSubDomains;i++)
    1775                   {
    1776                         Int4 k = subdomains[i].edge- edges;
    1777                         subdomains[i].edge =  edges+2*k; // spilt all edge in 2
    1778                   }
    1779 
    1780                 if (ksplitarray) delete [] ksplitarray;
    1781                 if (kedge) delete [] kedge;
    1782                 if (edge4) delete edge4;
    1783                 if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
    1784                 VerticesOnGeomEdge= newVerticesOnGeomEdge;
    1785                 if(VertexOnBThEdge) delete []  VertexOnBThEdge;
    1786                 VertexOnBThEdge = newVertexOnBThEdge;
    1787                 NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
    1788                 NbVertexOnBThEdge=newNbVertexOnBThEdge;
    1789                 //  ReMakeTriangleContainingTheVertex();
    1790 
    1791                 FillHoleInMesh();
    1792 
    1793                 if (verbosity>2){
    1794                         printf("   number of quadrilaterals    = %i\n",NbOfQuad);
    1795                         printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
    1796                         printf("   number of outside triangles = %i\n",NbOutT);
    1797                 }
    1798 
    1799                 CurrentTh=OCurrentTh;
    1800                 return 0; //ok
    1801 
    1802 Error:
    1803                 nbv = nbvold;
    1804                 nbt = nbtold;
    1805                 NbOutT = NbOutTold;
    1806                 // cleaning memory ---
    1807                 delete newedges;
    1808                 if (ksplitarray) delete [] ksplitarray;
    1809                 if (kedge) delete [] kedge;
    1810                 if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
    1811                 if (edge4) delete edge4;
    1812                 if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
    1813 
    1814 
    1815                 CurrentTh= OCurrentTh;
    1816                 return ret; // ok
    1817         }
    1818         /*}}}1*/
    1819         /*FUNCTION Triangles::swap{{{1*/
    1820         int Triangle::swap(Int2 a,int koption){
    1821                 if(a/4 !=0) return 0;// arete lock or MarkUnSwap
    1822 
    1823                 register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
    1824                 register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
    1825                 if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
    1826 
    1827                 register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
    1828                 register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
    1829                 register Vertex  *s1=t1->ns[OppositeVertex[a1]];
    1830                 register Vertex  *s2=t2->ns[OppositeVertex[a2]];
    1831 
    1832                 Icoor2 det1=t1->det , det2=t2->det ;
    1833                 Icoor2 detT = det1+det2;
    1834                 Icoor2 detA = Abs(det1) + Abs(det2);
    1835                 Icoor2 detMin = Min(det1,det2);
    1836 
    1837                 int OnSwap = 0;       
    1838                 // si 2 triangle infini (bord) => detT = -2;
    1839                 if (sa == 0) {// les deux triangles sont frontieres
    1840                         det2=bamg::det(s2->i,sb->i,s1->i);
    1841                         OnSwap = det2 >0;}
    1842                 else if (sb == 0) { // les deux triangles sont frontieres
    1843                         det1=bamg::det(s1->i,sa->i,s2->i);
    1844                         OnSwap = det1 >0;}
    1845                 else if(( s1 != 0) && (s2 != 0) ) {
    1846                         det1 = bamg::det(s1->i,sa->i,s2->i);
    1847                         det2 = detT - det1;
    1848                         OnSwap = (Abs(det1) + Abs(det2)) < detA;
    1849 
    1850                         Icoor2 detMinNew=Min(det1,det2);
    1851                         //     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
    1852                         if (! OnSwap &&(detMinNew>0)) {
    1853                                 OnSwap = detMin ==0;
    1854                                 if (! OnSwap) {
    1855                                         int  kopt = koption;
    1856                                         while (1)
    1857                                          if(kopt) {
    1858                                                  // critere de Delaunay pure isotrope
    1859                                                  register Icoor2 xb1 = sb->i.x - s1->i.x,
    1860                                                                          x21 = s2->i.x - s1->i.x,
    1861                                                                          yb1 = sb->i.y - s1->i.y,
    1862                                                                          y21 = s2->i.y - s1->i.y,
    1863                                                                          xba = sb->i.x - sa->i.x,
    1864                                                                          x2a = s2->i.x - sa->i.x,
    1865                                                                          yba = sb->i.y - sa->i.y,
    1866                                                                          y2a = s2->i.y - sa->i.y;
    1867                                                  register double
    1868                                                         cosb12 =  double(xb1*x21 + yb1*y21),
    1869                                                                          cosba2 =  double(xba*x2a + yba*y2a) ,
    1870                                                                          sinb12 = double(det2),
    1871                                                                          sinba2 = double(t2->det);
    1872 
    1873 
    1874                                                  // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
    1875                                                  OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
    1876                                                  break;
    1877                                          }
    1878                                          else
    1879                                                 {       
    1880                                                  // critere de Delaunay anisotrope
    1881                                                  Real8 som;
    1882                                                  I2 AB=(I2) *sb - (I2) *sa;
    1883                                                  I2 MAB2=((I2) *sb + (I2) *sa);
    1884                                                  R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
    1885                                                  I2 A1=(I2) *s1 - (I2) *sa;
    1886                                                  I2 D = (I2) * s1 - (I2) * sb ;
    1887                                                  R2 S2(s2->i.x,s2->i.y);
    1888                                                  R2 S1(s1->i.x,s1->i.y);
    1889                                                         {
    1890                                                          Metric M=s1->m;
    1891                                                          R2 ABo = M.Orthogonal(AB);
    1892                                                          R2 A1o = M.Orthogonal(A1);
    1893                                                          // (A+B)+ x ABo = (S1+B)/2+ y A1
    1894                                                          // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
    1895                                                          double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
    1896                                                          double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
    1897                                                          if (Abs(d) > dd*1.e-3) {
    1898                                                                  R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
    1899                                                                  som  = M(C - S2)/M(C - S1);
    1900                                                          } else
    1901                                                                 {kopt=1;continue;}
    1902 
    1903                                                         }
    1904                                                         {
    1905                                                          Metric M=s2->m;
    1906                                                          R2 ABo = M.Orthogonal(AB);
    1907                                                          R2 A1o = M.Orthogonal(A1);
    1908                                                          // (A+B)+ x ABo = (S1+B)/2+ y A1
    1909                                                          // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
    1910                                                          double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
    1911                                                          double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
    1912                                                          if(Abs(d) > dd*1.e-3) {
    1913                                                                  R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
    1914                                                                  som  += M(C - S2)/M(C -  S1);
    1915                                                          } else
    1916                                                                 {kopt=1;continue;}
    1917                                                         }
    1918                                                  OnSwap = som < 2;
    1919                                                  break;
    1920                                                 }
    1921 
    1922                                 } // OnSwap
    1923                         } // (! OnSwap &&(det1 > 0) && (det2 > 0) )
    1924                 }
    1925                 if( OnSwap )
    1926                  bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
    1927                 else {
    1928                         NbUnSwap ++;
    1929                         t1->SetMarkUnSwap(a1);     
    1930                 }
    1931                 return OnSwap;
    1932         }
    1933         /*}}}1*/
    1934         /*FUNCTION Triangles::MetricAt{{{1*/
    1935         Metric Triangles::MetricAt(const R2 & A) const {
    1936                 I2 a = toI2(A);
    1937                 Icoor2 deta[3];
    1938                 Triangle * t =FindTriangleContening(a,deta);
    1939                 if (t->det <0) { // outside
    1940                         double ba,bb;
    1941                         TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
    1942                         return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
    1943                 else { // inside
    1944                         Real8   aa[3];
    1945                         Real8 s = deta[0]+deta[1]+deta[2];
    1946                         aa[0]=deta[0]/s;
    1947                         aa[1]=deta[1]/s;
    1948                         aa[2]=deta[2]/s;
    1949                         return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
    1950                 }
    1951         }
    1952         /*}}}1*/
    1953         /*FUNCTION Triangles::Add{{{1*/
    1954         void Triangles::Add( Vertex & s,Triangle * t, Icoor2 * det3) {
    1955                 // -------------------------------------------
    1956                 //             s2
    1957                 //                                            !
    1958                 //             /|\                            !
    1959                 //            / | \                           !
    1960                 //           /  |  \                          !
    1961                 //    tt1   /   |   \ tt0                     !
    1962                 //         /    |s   \                        !
    1963                 //        /     .     \                       !
    1964                 //       /  .      `   \                      !
    1965                 //      / .           ` \                     !
    1966                 //      ----------------                      !
    1967                 //   s0       tt2       s1
    1968                 //--------------------------------------------
    1969 
    1970                 Triangle * tt[3]; // the 3 new Triangles
    1971                 Vertex &s0 = (* t)[0], &s1=(* t)[1], &s2=(* t)[2];
    1972                 Icoor2  det3local[3];
    1973                 int infv = &s0 ?  ((  &s1 ? ( &s2  ? -1 : 2) : 1  )) : 0;
    1974                 // infv = ordre of the infini vertex (null)
    1975                 register int nbd0 =0; // number of zero det3
    1976                 register int izerodet=-1,iedge; // izerodet = egde contening the vertex s
    1977                 Icoor2 detOld = t->det;
    1978 
    1979                 if (( infv <0 ) && (detOld <0) ||  ( infv >=0  ) && (detOld >0) ){
    1980                         throw ErrorException(__FUNCT__,exprintf("infv=%g det=%g"));
    1981                 }
    1982 
    1983                 // if det3 do not exist then constuct det3
    1984                 if (!det3) {
    1985                         det3 = det3local; // alloc
    1986                         if ( infv<0 ) {
    1987                                 det3[0]=bamg::det(s ,s1,s2);
    1988                                 det3[1]=bamg::det(s0,s ,s2);
    1989                                 det3[2]=bamg::det(s0,s1,s );}
    1990                         else {
    1991                                 // one of &s1  &s2  &s0 is NULL so (&si || &sj) <=> !&sk
    1992                                 det3[0]=  &s0 ? -1  : bamg::det(s ,s1,s2) ;
    1993                                 det3[1]=  &s1 ? -1 : bamg::det(s0,s ,s2) ;
    1994                                 det3[2]=  &s2 ? -1 : bamg::det(s0,s1,s ) ;}}
    1995 
    1996 
    1997                                 if (!det3[0]) izerodet=0,nbd0++;
    1998                                 if (!det3[1]) izerodet=1,nbd0++;
    1999                                 if (!det3[2]) izerodet=2,nbd0++;
    2000 
    2001                                 if  (nbd0 >0 ) // point s on a egde or on a vertex
    2002                                  if (nbd0 == 1) {
    2003                                          iedge = OppositeEdge[izerodet];
    2004                                          TriangleAdjacent ta = t->Adj(iedge);
    2005 
    2006                                          // the point is on the edge
    2007                                          // if the point is one the boundary
    2008                                          // add the point in outside part
    2009                                          if ( t->det >=0) { // inside triangle
    2010                                                  if ((( Triangle *) ta)->det < 0 ) {
    2011                                                          // add in outside triangle
    2012                                                          Add(s,( Triangle *) ta);
    2013                                                          return;}
    2014                                          }}
    2015                                  else {
    2016                                          printf("bug (%i): Bug double points in\n",nbd0);
    2017                                          throw ErrorException(__FUNCT__,exprintf("See above"));
    2018                                  }
    2019 
    2020                                 // remove de MarkUnSwap edge
    2021                                 t->SetUnMarkUnSwap(0);     
    2022                                 t->SetUnMarkUnSwap(1);     
    2023                                 t->SetUnMarkUnSwap(2);
    2024 
    2025                                 tt[0]= t;
    2026                                 tt[1]= &triangles[nbt++];
    2027                                 tt[2]= &triangles[nbt++];
    2028 
    2029                                 if (nbt>nbtx) {
    2030                                         throw ErrorException(__FUNCT__,exprintf("Not ebough triangles"));
    2031                                 }
    2032 
    2033                                 *tt[1]=   *tt[2]= *t;
    2034                                 // gestion of the link
    2035                                 tt[0]->link=tt[1];
    2036                                 tt[1]->link=tt[2];
    2037 
    2038                                 (* tt[0])(OppositeVertex[0])=&s;
    2039                                 (* tt[1])(OppositeVertex[1])=&s;
    2040                                 (* tt[2])(OppositeVertex[2])=&s;
    2041 
    2042                                 tt[0]->det=det3[0];
    2043                                 tt[1]->det=det3[1];
    2044                                 tt[2]->det=det3[2];         
    2045 
    2046                                 //  update adj des triangles externe
    2047                                 tt[0]->SetAdjAdj(0);
    2048                                 tt[1]->SetAdjAdj(1);
    2049                                 tt[2]->SetAdjAdj(2);
    2050                                 //  update des adj des 3 triangle interne
    2051                                 const int i0 = 0;
    2052                                 const int i1= NextEdge[i0];
    2053                                 const int i2 = PreviousEdge[i0];
    2054 
    2055                                 tt[i0]->SetAdj2(i2,tt[i2],i0);
    2056                                 tt[i1]->SetAdj2(i0,tt[i0],i1);
    2057                                 tt[i2]->SetAdj2(i1,tt[i1],i2);
    2058 
    2059                                 tt[0]->SetTriangleContainingTheVertex();
    2060                                 tt[1]->SetTriangleContainingTheVertex();
    2061                                 tt[2]->SetTriangleContainingTheVertex();
    2062 
    2063 
    2064                                 // swap if the point s is on a edge
    2065                                 if(izerodet>=0) {
    2066                                         int rswap =tt[izerodet]->swap(iedge);
    2067 
    2068                                         if (!rswap) {
    2069                                                 throw ErrorException(__FUNCT__,exprintf("swap the point s is on a edge"));
    2070                                         }
    2071                                 }
    2072         }
    2073         /*}}}1*/
    2074         /*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
    2075         Int4  Triangles::SplitInternalEdgeWithBorderVertices(){
    2076                 Int4 NbSplitEdge=0;
    2077                 SetVertexFieldOn(); 
    2078                 Int4 it;
    2079                 Int4 nbvold=nbv;
    2080                 long int verbosity=2;
    2081                 for (it=0;it<nbt;it++){
    2082                         Triangle &t=triangles[it];
    2083                         if (t.link)
    2084                          for (int j=0;j<3;j++)
    2085                           if(!t.Locked(j) && !t.Hidden(j)){
    2086                                   Triangle &tt = *t.TriangleAdj(j);
    2087                                   if ( &tt && tt.link && it < Number(tt))
    2088                                          { // an internal edge
    2089                                           Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
    2090                                           Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
    2091                                           if (v0.on && v1.on){
    2092                                                   R2 P= ((R2) v0 + (R2) v1)*0.5;
    2093                                                   if ( nbv<nbvx) {
    2094                                                           vertices[nbv].r = P;
    2095                                                           vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
    2096                                                           vertices[nbv].ReferenceNumber=0;
    2097                                                           vertices[nbv].DirOfSearch = NoDirOfSearch ;
    2098                                                   }
    2099                                                   NbSplitEdge++;
    2100                                                  }
    2101                                          }
    2102                           }
    2103                 }
    2104                 ReMakeTriangleContainingTheVertex();   
    2105                 if (nbvold!=nbv){
    2106                         Int4  iv = nbvold;
    2107                         Int4 NbSwap = 0;
    2108                         Icoor2 dete[3]; 
    2109                         for (Int4 i=nbvold;i<nbv;i++) {// for all the new point
    2110                                 Vertex & vi = vertices[i];
    2111                                 vi.i = toI2(vi.r);
    2112                                 vi.r = toR2(vi.i);
    2113 
    2114                                 // a good new point
    2115                                 vi.ReferenceNumber=0;
    2116                                 vi.DirOfSearch =NoDirOfSearch;
    2117                                 Triangle *tcvi = FindTriangleContening(vi.i,dete);
    2118                                 if (tcvi && !tcvi->link) {
    2119                                         printf("problem inserting point\n");
    2120                                 }
    2121 
    2122                                 quadtree->Add(vi);
    2123                                 if (!tcvi || tcvi->det<0){// internal
    2124                                         throw ErrorException(__FUNCT__,exprintf("!tcvi || tcvi->det < 0"));
    2125                                 }
    2126                                 Add(vi,tcvi,dete);
    2127                                 NbSwap += vi.Optim(1);         
    2128                                 iv++;
    2129                                 //      }
    2130                         }
    2131                         if (verbosity>3) {
    2132                                 printf("   number of points: %i\n",iv);
    2133                                 printf("   number of swap to  split internal edges with border vertices: %i\n",NbSwap);
    2134                                 nbv = iv;
    2135                         }
    2136                 }
    2137                 if (NbSplitEdge>nbv-nbvold) printf("WARNING: not enough vertices  to split all internal edges, we lost %i edges...\n",NbSplitEdge - ( nbv-nbvold));
    2138                 if (verbosity>2) printf("SplitInternalEdgeWithBorderVertices: Number of splited edge %i\n",NbSplitEdge);
    2139 
    2140                 return  NbSplitEdge;
    2141         }
    2142         /*}}}1*/
    2143         /*FUNCTION Triangles::InsertNewPoints{{{1*/
    2144         Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) {
    2145                 long int verbosity=2;
    2146                 Real8 seuil= 1.414/2 ;// for two close point
    2147                 Int4 i;
    2148                 // insertion part ---
    2149 
    2150                 const Int4 nbvnew = nbv-nbvold;
    2151                 if (verbosity>5) printf("      Try to Insert the %i new points\n",nbvnew);
    2152                 Int4 NbSwap=0;
    2153                 Icoor2 dete[3];
    2154 
    2155                 // construction d'un ordre aleatoire
    2156                 if (! nbvnew)
    2157                  return 0;
    2158                 if (nbvnew) {
    2159                         const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
    2160                         Int4 k3 = rand()%nbvnew ;
    2161                         for (Int4 is3=0; is3<nbvnew; is3++) {
    2162                                 register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
    2163                                 register Int4 i = nbvold+is3;
    2164                                 ordre[i]= vertices + j;
    2165                                 ordre[i]->ReferenceNumber=i;
    2166                         }
    2167                         // be carefull
    2168                         Int4  iv = nbvold;
    2169                         for (i=nbvold;i<nbv;i++)
    2170                           {// for all the new point
    2171                                 Vertex & vi = *ordre[i];
    2172                                 vi.i = toI2(vi.r);
    2173                                 vi.r = toR2(vi.i);
    2174                                 Real4 hx,hy;
    2175                                 vi.m.Box(hx,hy);
    2176                                 Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
    2177                                 if (!quadtree->ToClose(vi,seuil,hi,hj))
    2178                                   {
    2179                                         // a good new point
    2180                                         Vertex & vj = vertices[iv];
    2181                                         Int4 j = vj.ReferenceNumber;
    2182                                         if ( &vj!= ordre[j]){
    2183                                                 throw ErrorException(__FUNCT__,exprintf("&vj!= ordre[j]"));
    2184                                         }
    2185                                         if(i!=j)
    2186                                           { //  for valgring
    2187                                                 Exchange(vi,vj);
    2188                                                 Exchange(ordre[j],ordre[i]);
    2189                                           }
    2190                                         vj.ReferenceNumber=0;
    2191                                         Triangle *tcvj = FindTriangleContening(vj.i,dete);
    2192                                         if (tcvj && !tcvj->link){
    2193                                                 throw ErrorException(__FUNCT__,exprintf("problem inserting point"));
    2194                                         }
    2195                                         quadtree->Add(vj);
    2196                                         Add(vj,tcvj,dete);
    2197                                         NbSwap += vj.Optim(1);         
    2198                                         iv++;
    2199                                   }
    2200                           }
    2201                         if (verbosity>3) {
    2202                                 printf("   number of new points: %i\n",iv);
    2203                                 printf("   number of to close (?) points: %i\n",nbv-iv);
    2204                                 printf("   number of swap after: %i\n",NbSwap);
    2205                         }
    2206                                 nbv = iv;
    2207                 }
    2208 
    2209                 for (i=nbvold;i<nbv;i++) NbSwap += vertices[i].Optim(1); 
    2210                 if (verbosity>3) printf("   NbSwap=%i\n",NbSwap);
    2211 
    2212                 NbTSwap +=  NbSwap ;
    2213                 return nbv-nbvold;
    2214         }
    2215         /*}}}1*/
    2216         /*FUNCTION Triangles::NewPoints{{{1*/
    2217         void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex) {
    2218                 long int verbosity=2;
    2219                 Int4 nbtold(nbt),nbvold(nbv);
    2220                 if (verbosity>2)  printf("   Triangles::NewPoints\n");
    2221                 Int4 i,k;
    2222                 int j;
    2223                 Int4 *first_np_or_next_t = new Int4[nbtx];
    2224                 Int4 NbTSwap =0;
    2225                 //    insert old point
    2226                 nbtold = nbt;
    2227 
    2228                 if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx)){
    2229                         //   Bh.SetVertexFieldOn();
    2230                         for (i=0;i<Bh.nbv;i++)
    2231                           {
    2232                                 Vertex & bv = Bh[i];
    2233                                 if (!bv.on) {
    2234                                         vertices[nbv].r = bv.r;
    2235                                         vertices[nbv++].m = bv.m;}
    2236                           }
    2237                         int nbv1=nbv;
    2238                         Bh.ReMakeTriangleContainingTheVertex();     
    2239                         InsertNewPoints(nbvold,NbTSwap)   ;           
    2240                   } 
    2241                 else
    2242                  Bh.ReMakeTriangleContainingTheVertex();     
    2243 
    2244                 Triangle *t;
    2245                 // generation of the list of next Triangle
    2246                 // at 1 time we test all the triangles
    2247                 Int4 Headt =0,next_t;
    2248                 for(i=0;i<nbt;i++)
    2249                  first_np_or_next_t[i]=-(i+1);
    2250                 // end list i >= nbt
    2251                 // the list of test triangle is
    2252                 // the next traingle on i is  -first_np_or_next_t[i]
    2253                 int iter=0;
    2254                 // Big loop
    2255                 do {
    2256                         iter++;
    2257                         nbtold = nbt;
    2258                         nbvold = nbv;
    2259 
    2260                         // default size of  IntersectionTriangle
    2261 
    2262                         i=Headt;
    2263                         next_t=-first_np_or_next_t[i];
    2264                         for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
    2265                           { // for each triangle  t
    2266                                 // we can change first_np_or_next_t[i]
    2267                                 if (i<0 || i>=nbt ){
    2268                                         throw ErrorException(__FUNCT__,exprintf("i<0 || i>=nbt"));
    2269                                 }
    2270                                 first_np_or_next_t[i] = iter;
    2271                                 for(j=0;j<3;j++)
    2272                                   { // for each edge
    2273                                         TriangleAdjacent tj(t,j);
    2274                                         Vertex & vA = * tj.EdgeVertex(0);
    2275                                         Vertex & vB = * tj.EdgeVertex(1);
    2276 
    2277                                         if (!t->link) continue;// boundary
    2278                                         if (t->det <0) continue;
    2279                                         if (t->Locked(j)) continue;
    2280 
    2281                                         TriangleAdjacent tadjj = t->Adj(j);       
    2282                                         Triangle * ta= tadjj;
    2283 
    2284                                         if (ta->det <0) continue;         
    2285 
    2286                                         R2 A = vA;
    2287                                         R2 B = vB;
    2288 
    2289                                         k=Number(ta);
    2290 
    2291                                         if(first_np_or_next_t[k]==iter)  // this edge is done before
    2292                                          continue; // next edge of the triangle
    2293 
    2294                                         //const Int4 NbvOld = nbv;
    2295                                         lIntTria.SplitEdge(Bh,A,B);
    2296                                         lIntTria.NewPoints(vertices,nbv,nbvx);
    2297                                   } // end loop for each edge
    2298 
    2299                           }// for triangle   
    2300 
    2301                         if (!InsertNewPoints(nbvold,NbTSwap))
    2302                          break;
    2303 
    2304                         for (i=nbtold;i<nbt;i++)
    2305                          first_np_or_next_t[i]=iter;
    2306 
    2307                         Headt = nbt; // empty list
    2308                         for (i=nbvold;i<nbv;i++)
    2309                           { // for all the triangle contening the vertex i
    2310                                 Vertex * s  = vertices + i;
    2311                                 TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
    2312                                 Triangle * tbegin= (Triangle*) ta;
    2313                                 Int4 kt;
    2314                                 do {
    2315                                         kt = Number((Triangle*) ta);
    2316                                         if (first_np_or_next_t[kt]>0)
    2317                                          first_np_or_next_t[kt]=-Headt,Headt=kt;
    2318                                         if (ta.EdgeVertex(0)!=s){
    2319                                                 throw ErrorException(__FUNCT__,exprintf("ta.EdgeVertex(0)!=s"));
    2320                                         }
    2321                                         ta = Next(Adj(ta));
    2322                                 } while ( (tbegin != (Triangle*) ta));
    2323                           }   
    2324 
    2325                 } while (nbv!=nbvold);
    2326 
    2327                 delete []  first_np_or_next_t;
    2328 
    2329                 Int4 NbSwapf =0,NbSwp;
    2330 
    2331                 // bofbof
    2332 
    2333 
    2334                 NbSwp = NbSwapf;
    2335                 for (i=0;i<nbv;i++)
    2336                  NbSwapf += vertices[i].Optim(0);
    2337                 /*
    2338                         for (i=0;i<nbv;i++)
    2339                         NbSwapf += vertices[i].Optim(0);
    2340                         for (i=0;i<nbv;i++)
    2341                         NbSwapf += vertices[i].Optim(0);
    2342                         for (i=0;i<nbv;i++)
    2343                         NbSwapf += vertices[i].Optim(0);
    2344                         for (i=0;i<nbv;i++)
    2345                         NbSwapf += vertices[i].Optim(0);
    2346                         */
    2347                 NbTSwap +=  NbSwapf ;
    2348         }
    2349         /*}}}1*/
    2350         /*FUNCTION Triangles::Insert{{{1*/
    2351         void Triangles::Insert() {
    2352                 long int verbosity=2;
    2353                 if (verbosity>2) printf("   Insert initial %i vertices\n",nbv);
    2354                 Triangles * OldCurrentTh =CurrentTh;
    2355 
    2356                 CurrentTh=this;
    2357                 SetIntCoor();
    2358                 Int4 i;
    2359                 for (i=0;i<nbv;i++) ordre[i]= &vertices[i] ;
    2360 
    2361                 // construction d'un ordre aleatoire
    2362                 const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
    2363                 Int4 k3 = rand()%nbv ;
    2364                 for (int is3=0; is3<nbv; is3++)
    2365                  ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
    2366 
    2367                 for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;){
    2368                         if  ( ++i >= nbv) {
    2369                                 throw ErrorException(__FUNCT__,exprintf("all the vertices are aligned"));
    2370                         }
    2371                 }
    2372                 // echange i et 2 dans ordre afin
    2373                 // que les 3 premiers ne soit pas aligne
    2374                 Exchange( ordre[2], ordre[i]);
    2375 
    2376                 // on ajoute un point a l'infini pour construire le maillage
    2377                 // afin d'avoir une definition simple des aretes frontieres
    2378                 nbt = 2;
    2379 
    2380                 // on construit un maillage trivale forme
    2381                 // d'une arete et de 2 triangles
    2382                 // construit avec le 2 aretes orientes et
    2383                 Vertex *  v0=ordre[0], *v1=ordre[1];
    2384 
    2385                 triangles[0](0) = 0; // sommet pour infini
    2386                 triangles[0](1) = v0;
    2387                 triangles[0](2) = v1;
    2388 
    2389                 triangles[1](0) = 0;// sommet pour infini
    2390                 triangles[1](2) = v0;
    2391                 triangles[1](1) = v1;
    2392                 const int e0 = OppositeEdge[0];
    2393                 const int e1 = NextEdge[e0];
    2394                 const int e2 = PreviousEdge[e0];
    2395                 triangles[0].SetAdj2(e0, &triangles[1] ,e0);
    2396                 triangles[0].SetAdj2(e1, &triangles[1] ,e2);
    2397                 triangles[0].SetAdj2(e2, &triangles[1] ,e1);
    2398 
    2399                 triangles[0].det = -1;  // faux triangles
    2400                 triangles[1].det = -1;  // faux triangles
    2401 
    2402                 triangles[0].SetTriangleContainingTheVertex();
    2403                 triangles[1].SetTriangleContainingTheVertex();
    2404 
    2405                 triangles[0].link=&triangles[1];
    2406                 triangles[1].link=&triangles[0];
    2407 
    2408                 //  nbtf = 2;
    2409                 if (  !quadtree )  quadtree = new QuadTree(this,0);
    2410                 quadtree->Add(*v0);
    2411                 quadtree->Add(*v1);
    2412 
    2413                 //the vertices are added one by one
    2414                 Int4 NbSwap=0;
    2415 
    2416 
    2417                 if (verbosity>3) printf("   Begining of insertion process...\n");
    2418 
    2419                 for (Int4 icount=2; icount<nbv; icount++) {
    2420                         Vertex *vi  = ordre[icount];
    2421                         Icoor2 dete[3];
    2422                         Triangle *tcvi = FindTriangleContening(vi->i,dete);
    2423                         quadtree->Add(*vi);
    2424                         Add(*vi,tcvi,dete);
    2425                         NbSwap += vi->Optim(1,0);
    2426                 }
    2427                 if (verbosity>3) {
    2428                         printf("      NbSwap of insertion: %i\n",NbSwap);
    2429                         printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
    2430                         printf("      NbUnSwap:            %i\n",NbUnSwap);
    2431                         printf("      NbUnSwap/nbv         %i\n",NbUnSwap/nbv);
    2432                 }
    2433                 NbUnSwap = 0;
    2434                 // construction d'un ordre aleatoire
    2435                 //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
    2436 #ifdef NBLOOPOPTIM
    2437 
    2438                 k3 = rand()%nbv ;
    2439                 for (int is4=0; is4<nbv; is4++)
    2440                  ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
    2441 
    2442                 for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++)
    2443                   {
    2444                         Int4  NbSwap = 0;
    2445                         for (int is1=0; is1<nbv; is1++)
    2446                          NbSwap += ordre[is1]->Optim(0,0);
    2447                         if (verbosity>3) {
    2448                                 printf("      Optim Loop: %i\n",Nbloop);
    2449                                 printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
    2450                                 printf("      NbUnSwap:            %i\n",NbUnSwap);
    2451                                 printf("      NbUnSwap/nbv         %i\n",NbUnSwap/nbv);
    2452                         }
    2453                         NbUnSwap = 0;
    2454                         if(!NbSwap) break;
    2455                   }
    2456                 ReMakeTriangleContainingTheVertex();
    2457                 // because we break the TriangleContainingTheVertex
    2458 #endif
    2459                 CurrentTh=OldCurrentTh;
    2460         }
    2461         /*}}}1*/
     1451                        SetVertexFieldOn();
     1452
     1453                        if (vlast >= vend) { 
     1454                                throw ErrorException(__FUNCT__,exprintf("Not enougth vertices: to crack the mesh we need %i vertices",nbv));
     1455                        }
     1456                        CurrentTh = CurrentThOld;
     1457                        return  NbCrackedVertices;
     1458                }
     1459                /*}}}1*/
    24621460        /*FUNCTION Triangles::ForceBoundary{{{1*/
    24631461        void Triangles::ForceBoundary() {
     
    24971495        }
    24981496        /*}}}1*/
     1497        /*FUNCTION Triangles::FillHoleInMesh{{{1*/
     1498        void Triangles::FillHoleInMesh() {
     1499
     1500                Triangles* OldCurrentTh =CurrentTh;
     1501                CurrentTh=this;
     1502
     1503                int verbosity=0;
     1504
     1505                // generation of the integer coordinate
     1506                  {
     1507
     1508                        // find extrema coordinates of vertices pmin,pmax
     1509                        Int4 i;
     1510                        if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv);
     1511
     1512                        //initialize ordre
     1513                        if (!ordre){
     1514                                throw ErrorException(__FUNCT__,exprintf("!ordre"));
     1515                        }
     1516                        for (i=0;i<nbv;i++) ordre[i]=0;
     1517
     1518                        NbSubDomains =0;
     1519
     1520                        /* generation of the adjacence of the triangles*/
     1521
     1522                        SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
     1523
     1524                        //initialize st
     1525                        Int4* st = new Int4[nbt*3];
     1526                        for (i=0;i<nbt*3;i++) st[i]=-1;
     1527
     1528                        //check number of edges
     1529                        Int4 kk =0;
     1530                        for (i=0;i<nbe;i++){
     1531                                kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
     1532                        }
     1533                        if (kk != nbe) {
     1534                                throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
     1535                        }
     1536
     1537                        //
     1538                        for (i=0;i<nbt;i++){
     1539                                for (int j=0;j<3;j++) {
     1540                                        Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
     1541                                                                Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
     1542                                        Int4 invisible = triangles[i].Hidden(j);
     1543                                        if(st[k]==-1){
     1544                                                st[k]=3*i+j;
     1545                                        }
     1546                                        else if(st[k]>=0) {
     1547                                                if (triangles[i].TriangleAdj(j) || triangles[st[k] / 3].TriangleAdj((int) (st[k]%3))){
     1548                                                        throw ErrorException(__FUNCT__,exprintf("(triangles[i].TriangleAdj(j) || triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)))"));
     1549                                                }
     1550
     1551                                                triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
     1552                                                if (invisible)  triangles[i].SetHidden(j);
     1553                                                if (k<nbe) {
     1554                                                        triangles[i].SetLocked(j);
     1555                                                }
     1556                                                st[k]=-2-st[k];
     1557                                        }
     1558                                        else {
     1559                                                throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
     1560                                                                                Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
     1561                                        }
     1562                                }
     1563                        }
     1564                        if(verbosity>5) {
     1565                                printf("         info on Mesh %s:\n",name);
     1566                                printf("            - number of vertices    = %i \n",nbv);
     1567                                printf("            - number of triangles   = %i \n",nbt);
     1568                                printf("            - number of given edges = %i \n",nbe);
     1569                                printf("            - number of all edges   = %i \n"  ,edge4->nb());
     1570                                printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv);
     1571                        }
     1572
     1573                        // check the consistant of edge[].adj and the geometrical required  vertex
     1574                        Int4 k=0;
     1575                        for (i=0;i<edge4->nb();i++){
     1576                                if (st[i] >=0){ // edge alone
     1577                                        if (i < nbe) {
     1578                                                Int4 i0=edge4->i(i);
     1579                                                ordre[i0] = vertices+i0;
     1580                                                Int4 i1=edge4->j(i);
     1581                                                ordre[i1] = vertices+i1;
     1582                                        }
     1583                                        else {
     1584                                                k=k+1;
     1585                                                if (k <20) {
     1586                                                        throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
     1587                                                }
     1588                                        }
     1589                                }
     1590                        }
     1591                        if(k != 0) {
     1592                                throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
     1593                        }
     1594
     1595                        /* mesh generation with boundary points*/
     1596                        Int4 nbvb = 0;
     1597                        for (i=0;i<nbv;i++){
     1598                                vertices[i].t=0;
     1599                                vertices[i].vint=0;
     1600                                if (ordre[i]){
     1601                                        ordre[nbvb++] = ordre[i];
     1602                                }
     1603                        }
     1604
     1605                        Triangle* savetriangles= triangles;
     1606                        Int4 savenbt=nbt;
     1607                        Int4 savenbtx=nbtx;
     1608                        SubDomain * savesubdomains = subdomains;
     1609                        subdomains = 0;
     1610
     1611                        Int4  Nbtriafillhole = 2*nbvb;
     1612                        Triangle* triafillhole =new Triangle[Nbtriafillhole];
     1613                        triangles =  triafillhole;
     1614
     1615                        nbt=2;
     1616                        nbtx= Nbtriafillhole;
     1617
     1618                        for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
     1619                         if  ( ++i >= nbvb) {
     1620                                 throw ErrorException(__FUNCT__,exprintf("FillHoleInMesh: All the vertices are aligned"));
     1621                         }
     1622                        Exchange( ordre[2], ordre[i]);
     1623
     1624                        Vertex *  v0=ordre[0], *v1=ordre[1];
     1625
     1626
     1627                        triangles[0](0) = 0; // sommet pour infini
     1628                        triangles[0](1) = v0;
     1629                        triangles[0](2) = v1;
     1630
     1631                        triangles[1](0) = 0;// sommet pour infini
     1632                        triangles[1](2) = v0;
     1633                        triangles[1](1) = v1;
     1634                        const int e0 = OppositeEdge[0];
     1635                        const int e1 = NextEdge[e0];
     1636                        const int e2 = PreviousEdge[e0];
     1637                        triangles[0].SetAdj2(e0, &triangles[1] ,e0);
     1638                        triangles[0].SetAdj2(e1, &triangles[1] ,e2);
     1639                        triangles[0].SetAdj2(e2, &triangles[1] ,e1);
     1640
     1641                        triangles[0].det = -1;  // faux triangles
     1642                        triangles[1].det = -1;  // faux triangles
     1643
     1644                        triangles[0].SetTriangleContainingTheVertex();
     1645                        triangles[1].SetTriangleContainingTheVertex();
     1646
     1647                        triangles[0].link=&triangles[1];
     1648                        triangles[1].link=&triangles[0];
     1649
     1650                        if (!quadtree )
     1651                         delete  quadtree; // ->ReInitialise();
     1652
     1653                        quadtree = new QuadTree(this,0);
     1654                        quadtree->Add(*v0);
     1655                        quadtree->Add(*v1);
     1656
     1657                        // We add the vertices one by one
     1658                        Int4 NbSwap=0;
     1659                        for (Int4 icount=2; icount<nbvb; icount++) {
     1660                                Vertex *vi  = ordre[icount];
     1661                                Icoor2 dete[3];
     1662                                Triangle *tcvi = FindTriangleContening(vi->i,dete);
     1663                                quadtree->Add(*vi);
     1664                                Add(*vi,tcvi,dete);
     1665                                NbSwap += vi->Optim(1,1);
     1666                        }
     1667
     1668                        // inforce the boundary
     1669                        TriangleAdjacent ta(0,0);
     1670                        Int4 nbloss = 0,knbe=0;
     1671                        for ( i = 0; i < nbe; i++){
     1672                                if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
     1673                                        Vertex & a=edges[i][0], & b =    edges[i][1];
     1674                                        if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
     1675                                          {
     1676                                                knbe++;
     1677                                                if (ForceEdge(a,b,ta)<0)
     1678                                                 nbloss++;
     1679                                          }
     1680                                }
     1681                        }
     1682                        if(nbloss) {
     1683                                throw ErrorException(__FUNCT__,exprintf("we lost(?) %i edges other %i",nbloss,knbe));
     1684                        }
     1685
     1686                        FindSubDomain(1);
     1687                        // remove all the hole
     1688                        // remove all the good sub domain
     1689                        Int4 krm =0;
     1690                        for (i=0;i<nbt;i++){
     1691                                if (triangles[i].link){ // remove triangles
     1692                                        krm++;
     1693                                        for (int j=0;j<3;j++)
     1694                                          {
     1695                                                TriangleAdjacent ta =  triangles[i].Adj(j);
     1696                                                Triangle & tta = * (Triangle *) ta;
     1697                                                if(! tta.link) // edge between remove and not remove
     1698                                                  { // change the link of ta;
     1699                                                        int ja = ta;
     1700                                                        Vertex *v0= ta.EdgeVertex(0);
     1701                                                        Vertex *v1= ta.EdgeVertex(1);
     1702                                                        Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
     1703                                                        if (st[k]<0){
     1704                                                                throw ErrorException(__FUNCT__,exprintf("st[k]<0"));
     1705                                                        }
     1706                                                        tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
     1707                                                        ta.SetLock();
     1708                                                        st[k]=-2-st[k];
     1709                                                  }
     1710                                          }
     1711                                }
     1712                        }
     1713                        Int4 NbTfillHoll =0;
     1714                        for (i=0;i<nbt;i++){
     1715                                if (triangles[i].link) {
     1716                                        triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
     1717                                        triangles[i].color=-1;
     1718                                }
     1719                                else
     1720                                  {
     1721                                        triangles[i].color= savenbt+ NbTfillHoll++;
     1722                                  }
     1723                        }
     1724                        if (savenbt+NbTfillHoll>savenbtx ){
     1725                                throw ErrorException(__FUNCT__,exprintf("savenbt+NbTfillHoll>savenbtx"));
     1726                        }
     1727                        // copy of the outside triangles in saveTriangles
     1728                        for (i=0;i<nbt;i++){
     1729                                if(triangles[i].color>=0) {
     1730                                        savetriangles[savenbt]=triangles[i];
     1731                                        savetriangles[savenbt].link=0;
     1732                                        savenbt++;
     1733                                }
     1734                        }
     1735                        // gestion of the adj
     1736                        k =0;
     1737                        Triangle * tmax = triangles + nbt;
     1738                        for (i=0;i<savenbt;i++) 
     1739                          {
     1740                                Triangle & ti = savetriangles[i];
     1741                                for (int j=0;j<3;j++)
     1742                                  {
     1743                                        Triangle * ta = ti.TriangleAdj(j);
     1744                                        int aa = ti.NuEdgeTriangleAdj(j);
     1745                                        int lck = ti.Locked(j);
     1746                                        if (!ta) k++; // bug
     1747                                        else if ( ta >= triangles && ta < tmax)
     1748                                          {
     1749                                                ta= savetriangles + ta->color;
     1750                                                ti.SetAdj2(j,ta,aa);
     1751                                                if(lck) ti.SetLocked(j);
     1752                                          }
     1753                                  }
     1754                          }
     1755                        //       OutSidesTriangles = triangles;
     1756                        //      Int4 NbOutSidesTriangles = nbt;
     1757
     1758                        // restore triangles;
     1759                        nbt=savenbt;
     1760                        nbtx=savenbtx;
     1761                        delete [] triangles;
     1762                        delete [] subdomains;
     1763                        triangles = savetriangles;
     1764                        subdomains = savesubdomains;
     1765                        if (k) {
     1766                                throw ErrorException(__FUNCT__,exprintf("number of triangles edges alone = %i",k));
     1767                        }
     1768                        FindSubDomain();
     1769
     1770                        delete edge4;
     1771                        delete [] st;
     1772                        for (i=0;i<nbv;i++)
     1773                         quadtree->Add(vertices[i]);
     1774
     1775                        SetVertexFieldOn();
     1776
     1777                        for (i=0;i<nbe;i++)
     1778                         if(edges[i].on)
     1779                          for(int j=0;j<2;j++)
     1780                                if (!edges[i].adj[j])
     1781                                 if(!edges[i][j].on->IsRequiredVertex()) {
     1782                                         throw ErrorException(__FUNCT__,exprintf("adj and vertex required esge(?)"));
     1783                                 }
     1784                  }
     1785                CurrentTh=OldCurrentTh;
     1786        }
     1787        /*}}}1*/
    24991788        /*FUNCTION Triangles::FindSubDomain{{{1*/
    2500         void Triangles::FindSubDomain(int OutSide=0) {
     1789        void Triangles::FindSubDomain(int OutSide) {
    25011790                long int verbosity=0;
    25021791
     
    27472036        }
    27482037        /*}}}1*/
    2749         /*FUNCTION Triangles::ReNumberingVertex{{{1*/
    2750         void Triangles::ReNumberingVertex(Int4 * renu) {
    2751                 // warning be carfull because pointeur
    2752                 // from on mesh to over mesh
    2753                 //  --  so do ReNumbering a the beginning
    2754                 Vertex * ve = vertices+nbv;
    2755                 Int4 it,ie,i;
    2756 
    2757                 for ( it=0;it<nbt;it++)
    2758                  triangles[it].ReNumbering(vertices,ve,renu);
    2759 
    2760                 for ( ie=0;ie<nbe;ie++)
    2761                  edges[ie].ReNumbering(vertices,ve,renu);
    2762 
    2763                 for (i=0;i< NbVerticesOnGeomVertex;i++)
    2764                   {
    2765                         Vertex *v = VerticesOnGeomVertex[i].mv;
    2766                         if (v>=vertices && v < ve)
    2767                          VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
    2768                   }
    2769 
    2770                 for (i=0;i< NbVerticesOnGeomEdge;i++)
    2771                   {
    2772                         Vertex *v =VerticesOnGeomEdge[i].mv;
    2773                         if (v>=vertices && v < ve)
    2774                          VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
    2775                   }
    2776 
    2777                 for (i=0;i< NbVertexOnBThVertex;i++)
    2778                   {
    2779                         Vertex *v=VertexOnBThVertex[i].v;
    2780                         if (v>=vertices && v < ve)
    2781                          VertexOnBThVertex[i].v=vertices+renu[Number(v)];
    2782                   }
    2783 
    2784                 for (i=0;i< NbVertexOnBThEdge;i++)
    2785                   {
    2786                         Vertex *v=VertexOnBThEdge[i].v;
    2787                         if (v>=vertices && v < ve)
    2788                          VertexOnBThEdge[i].v=vertices+renu[Number(v)];
    2789                   }
    2790 
    2791                 // move the Vertices without a copy of the array
    2792                 // be carefull not trivial code
    2793                 Int4 j;
    2794                 for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
    2795                  if (renu[it] >= 0) // a new sub cycle
    2796                         {
    2797                          i=it;
    2798                          Vertex ti=vertices[i],tj;
    2799                          while ( (j=renu[i]) >= 0)
    2800                                 { // i is old, and j is new
    2801                                  renu[i] = -1-renu[i]; // mark
    2802                                  tj = vertices[j]; // save new
    2803                                  vertices[j]= ti; // new <- old
    2804                                  i=j;     // next
    2805                                  ti = tj;
    2806                                 } 
    2807                         }
    2808                 if (quadtree)
    2809                   {  delete quadtree;
    2810                         quadtree = new QuadTree(this);
    2811                   }
    2812                 for ( it=0;it<nbv;it++)
    2813                  renu[i]= -renu[i]-1;
    2814 
     2038        /*FUNCTION Triangles::FindTriangleContening{{{1*/
     2039        Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
     2040                Triangle * t=0;
     2041                int j,jp,jn,jj;
     2042                if (tstart) t=tstart;
     2043                else {
     2044                        if (!quadtree){
     2045                                throw ErrorException(__FUNCT__,exprintf("!quadtree"));
     2046                        }
     2047                        Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
     2048
     2049                        if (! a || !a->t ) {
     2050                                if (a) {
     2051                                        printf("TriangleConteningTheVertex vertex number %i, another call to ReMakeTriangleContainingTheVertex was required\n", Number(a));
     2052                                }
     2053                                throw ErrorException(__FUNCT__,exprintf("problem in Triangles::FindTriangleContening"));
     2054                        }
     2055                        if (a<vertices || a>=vertices+nbv){
     2056                                throw ErrorException(__FUNCT__,exprintf("a<vertices || a>=vertices+nbv"));
     2057                        }
     2058                        t = a->t;
     2059                        if (t<triangles || t>=triangles+nbt){
     2060                                throw ErrorException(__FUNCT__,exprintf("t<triangles || t>=triangles+nbt"));
     2061                        }
     2062                }
     2063                Icoor2  detop ;
     2064                int kkkk =0; // number of test triangle
     2065
     2066                while ( t->det < 0){ // the initial triangles is outside 
     2067                        int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
     2068                        if (k0<0){ // k0 the NULL  vertex
     2069                                throw ErrorException(__FUNCT__,exprintf("k0<0"));
     2070                        }
     2071                        int k1=NextVertex[k0],k2=PreviousVertex[k0];
     2072                        dete[k0]=det(B,(*t)[k1],(*t)[k2]);
     2073                        dete[k1]=dete[k2]=-1;     
     2074                        if (dete[k0] > 0) // outside B
     2075                         return t;
     2076                        t = t->TriangleAdj(OppositeEdge[k0]);
     2077                        kkkk++;
     2078                        if (kkkk>=2){
     2079                                throw ErrorException(__FUNCT__,exprintf("kkkk>=2"));
     2080                        }
     2081                }
     2082
     2083                jj=0;
     2084                detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
     2085
     2086                while(t->det  > 0 ) {
     2087                        kkkk++;
     2088                        if (kkkk>=2000){
     2089                                throw ErrorException(__FUNCT__,exprintf("kkkk>=2000"));
     2090                        }
     2091                        j= OppositeVertex[jj];
     2092                        dete[j] = detop;  //det(*b,*s1,*s2);
     2093                        jn = NextVertex[j];
     2094                        jp = PreviousVertex[j];
     2095                        dete[jp]= det(*(*t)(j),*(*t)(jn),B);
     2096                        dete[jn] = t->det-dete[j] -dete[jp];
     2097
     2098                        // count the number k of  dete <0
     2099                        int k=0,ii[3];
     2100                        if (dete[0] < 0 ) ii[k++]=0;
     2101                        if (dete[1] < 0 ) ii[k++]=1;
     2102                        if (dete[2] < 0 ) ii[k++]=2;
     2103                        // 0 => ok
     2104                        // 1 => go in way 1
     2105                        // 2 => two way go in way 1 or 2 randomly
     2106
     2107                        if (k==0) break;
     2108                        if (k == 2 && BinaryRand()) Exchange(ii[0],ii[1]);
     2109                        if ( k>=3){
     2110                                throw ErrorException(__FUNCT__,exprintf("k>=3"));
     2111                        }
     2112                        TriangleAdjacent t1 = t->Adj(jj=ii[0]);
     2113                        if ((t1.det() < 0 ) && (k == 2))
     2114                         t1 = t->Adj(jj=ii[1]);
     2115                        t=t1;
     2116                        j=t1;// for optimisation we now the -det[OppositeVertex[j]];
     2117                        detop = -dete[OppositeVertex[jj]];
     2118                        jj = j;
     2119                }
     2120
     2121                if (t->det<0) // outside triangle
     2122                 dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
     2123                //  NbOfTriangleSearchFind += kkkk; 
     2124                return t;
    28152125        }
    28162126        /*}}}1*/
    2817         /*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
    2818         void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress) {
    2819                 long int verbosity=0;
    2820                 Int4 *renu= new Int4[nbt];
    2821                 register Triangle *t0,*t,*te=triangles+nbt;
    2822                 register Int4 k=0,it,i,j;
    2823 
    2824                 for ( it=0;it<nbt;it++)
    2825                  renu[it]=-1; // outside triangle
    2826                 for ( i=0;i<NbSubDomains;i++)
    2827                   {
    2828                         t=t0=subdomains[i].head;
    2829                         if (!t0){ // not empty sub domain
    2830                                 throw ErrorException(__FUNCT__,exprintf("!t0"));
    2831                         }
    2832                         do {
    2833                                 Int4 kt = Number(t);
    2834                                 if (kt<0 || kt >= nbt ){
    2835                                         throw ErrorException(__FUNCT__,exprintf("kt<0 || kt >= nbt"));
     2127        /*FUNCTION Triangles::GeomToTriangles0{{{1*/
     2128        void Triangles::GeomToTriangles0(Int4 inbvx) {
     2129                /*Generate mesh from geometry*/
     2130
     2131                Gh.NbRef++;// add a ref to GH
     2132
     2133                Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
     2134                Real8 lcurve,lstep,s;
     2135
     2136                R2 AB;
     2137                GeometricalVertex *a,*b;
     2138                Vertex *va,*vb;
     2139                GeometricalEdge * e;
     2140
     2141                //initialize this
     2142                PreInit(inbvx);
     2143
     2144                int  background = &BTh != this;
     2145                nbv=0;
     2146                NbVerticesOnGeomVertex=0;
     2147                NbVerticesOnGeomEdge=0;
     2148
     2149                //Compute bumber of vertices on geometrical vertex
     2150                for (i=0;i<Gh.nbv;i++){
     2151                        if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
     2152                }
     2153
     2154                //initialize VerticesOnGeomVertex
     2155                VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex]; 
     2156                if( NbVerticesOnGeomVertex >= nbvx) {
     2157                        throw ErrorException(__FUNCT__,exprintf("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx));
     2158                }
     2159
     2160                //compute nbv (number of vertices)
     2161                nbv=0;
     2162                for (i=0;i<Gh.nbv;i++){
     2163                        if (Gh[i].Required() && Gh[i].IsThe()) {//Gh  vertices Required
     2164                                if (nbv<nbvx) vertices[nbv]=Gh[i];
     2165                                Gh[i].to = vertices + nbv;// save Geom -> Th
     2166                                VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
     2167                                nbv++;
     2168                        }
     2169                }
     2170
     2171                //check that edges is empty
     2172                if (edges){
     2173                        throw ErrorException(__FUNCT__,exprintf("edges"));
     2174                }
     2175
     2176                // 2 step
     2177                // step=0 to compute the number of edges + alloc at end
     2178                // step=1 to construct the edges
     2179                for (int step=0;step<2;step++){
     2180
     2181                        //initialize number of edges and number of edges max
     2182                        Int4 nbex=0;
     2183                        nbe=0;
     2184                        Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
     2185
     2186
     2187                        Gh.UnMarkEdges();       
     2188                        NbOfCurves = 0;
     2189
     2190                        //go through the edges of the geometry
     2191                        for (i=0;i<Gh.nbe;i++) {
     2192                                GeometricalEdge &ei=Gh.edges[i];   
     2193                                if (!ei.Dup()){ // a good curve (not dup)
     2194                                        for(int j=0;j<2;j++) {
     2195                                                if (!ei.Mark() && ei[j].Required()) {
     2196                                                        // warning ei.Mark() can be change in loop for(j=0;j<2;j++)
     2197                                                        Int4 nbvend=0;
     2198                                                        Edge* PreviousNewEdge=NULL;
     2199
     2200                                                        lstep = -1;//do not create points
     2201                                                        if(ei.Required()){
     2202                                                                if (j==0){
     2203                                                                        if(step==0) nbe++;
     2204                                                                        else{
     2205                                                                                e=&ei;
     2206                                                                                a=ei(0)->The();
     2207                                                                                b=ei(1)->The();
     2208                                                                                if (!edges){
     2209                                                                                        throw ErrorException(__FUNCT__,exprintf("!edges"));
     2210                                                                                }
     2211                                                                                edges[nbe].v[0]=a->to;
     2212                                                                                edges[nbe].v[1]=b->to;;
     2213                                                                                edges[nbe].ref = e->ref;
     2214                                                                                edges[nbe].on = e;
     2215                                                                                edges[nbe].adj[0] = 0;
     2216                                                                                edges[nbe].adj[1] = 0;
     2217                                                                                nbe++;
     2218                                                                        }
     2219                                                                }
     2220                                                        }
     2221                                                        else { // on curve ------
     2222                                                                for ( int kstep=0;kstep<= step;kstep++){
     2223                                                                        // if 2nd step where 2 step
     2224                                                                        // 1 compute the length of the curve
     2225                                                                        // 2 create the points and edge
     2226                                                                        PreviousNewEdge=0;
     2227                                                                        NbNewPoints=0;
     2228                                                                        NbEdgeCurve=0;
     2229                                                                        if (nbvend>=nbvx){
     2230                                                                                throw ErrorException(__FUNCT__,exprintf("nbvend>=nbvx"));
     2231                                                                        }
     2232                                                                        lcurve =0;
     2233                                                                        s = lstep;
     2234                                                                        int k=j;
     2235                                                                        e = & ei;
     2236                                                                        a=ei(k)->The();
     2237                                                                        va = a->to;
     2238                                                                        e->SetMark();
     2239
     2240                                                                        // if SameGeo  We have go in the background geometry
     2241                                                                        // to find the discretisation of the curve
     2242                                                                        for(;;){
     2243                                                                                k = 1-k;
     2244                                                                                b= (*e)(k)->The();
     2245                                                                                AB = b->r - a->r;
     2246                                                                                Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
     2247                                                                                Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
     2248                                                                                Real8 ledge = (MA(AB) + MB(AB))/2;
     2249
     2250                                                                                const int MaxSubEdge = 10;
     2251                                                                                int NbSubEdge = 1;
     2252                                                                                Real8 lSubEdge[MaxSubEdge];
     2253                                                                                R2 A,B;
     2254                                                                                if (ledge < 1.5) lSubEdge[0] = ledge;
     2255                                                                                else {
     2256                                                                                        NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
     2257                                                                                        A= a->r;
     2258                                                                                        Metric MAs =MA,MBs;
     2259                                                                                        ledge = 0;
     2260                                                                                        Real8 x =0, xstep= 1. /  NbSubEdge;
     2261                                                                                        for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
     2262                                                                                                x += xstep;
     2263                                                                                                B =  e->F(k ? x : 1-x);
     2264                                                                                                MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
     2265                                                                                                AB = A-B;
     2266                                                                                                lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
     2267                                                                                        }
     2268                                                                                }
     2269
     2270                                                                                Real8 lcurveb = lcurve+ ledge ;
     2271                                                                                while (lcurve<=s && s <= lcurveb && nbv < nbvend){
     2272                                                                                        // New points
     2273
     2274                                                                                        // Real8 aa=(lcurveb-s)/ledge;
     2275                                                                                        // Real8 bb=(s-lcurve)/ledge;
     2276
     2277                                                                                        Real8 ss = s-lcurve;
     2278                                                                                        // 1) find the SubEdge containing ss by dichotomie
     2279                                                                                        int kk0=-1,kk1=NbSubEdge-1,kkk;
     2280                                                                                        Real8 ll0=0,ll1=ledge,llk;
     2281                                                                                        while (kk1-kk0>1)
     2282                                                                                          {
     2283                                                                                                if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
     2284                                                                                                 kk1=kkk,ll1=llk;
     2285                                                                                                else
     2286                                                                                                 kk0=kkk,ll0=llk;}
     2287                                                                                                if (kk1 == kk0){
     2288                                                                                                        throw ErrorException(__FUNCT__,exprintf("kk1 == kk0"));
     2289                                                                                                }
     2290
     2291                                                                                                Real8 sbb = (ss-ll0  )/(ll1-ll0);
     2292                                                                                                Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
     2293
     2294                                                                                                // new vertex on edge
     2295                                                                                                vb = &vertices[nbv++];
     2296                                                                                                vb->m = Metric(aa,a->m,bb,b->m);
     2297                                                                                                vb->ReferenceNumber = e->ref;
     2298                                                                                                vb->DirOfSearch =NoDirOfSearch;
     2299                                                                                                Real8 abcisse = k ? bb : aa;
     2300                                                                                                vb->r =  e->F( abcisse );
     2301                                                                                                VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);       
     2302
     2303                                                                                                // to take into account the sens of the edge
     2304                                                                                                s += lstep;
     2305                                                                                                edges[nbe].v[0]=va;
     2306                                                                                                edges[nbe].v[1]=vb;
     2307                                                                                                edges[nbe].ref = e->ref;
     2308                                                                                                edges[nbe].on = e;
     2309                                                                                                edges[nbe].adj[0] = PreviousNewEdge;
     2310                                                                                                if(PreviousNewEdge)
     2311                                                                                                 PreviousNewEdge->adj[1] = &edges[nbe];
     2312                                                                                                PreviousNewEdge = edges + nbe;
     2313                                                                                                nbe++;
     2314                                                                                                va = vb;
     2315                                                                                }
     2316                                                                                lcurve = lcurveb;
     2317                                                                                e->SetMark();
     2318                                                                                a=b;
     2319                                                                                if (b->Required() ) break;
     2320                                                                                int kprev=k;
     2321                                                                                k = e->DirAdj[kprev];// next vertices
     2322                                                                                e = e->Adj[kprev];
     2323                                                                                if (!e){
     2324                                                                                        throw ErrorException(__FUNCT__,exprintf("!e"));
     2325                                                                                }
     2326                                                                        }// for(;;)
     2327                                                                        vb = b->to;
     2328                                                                        NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
     2329                                                                        NbNewPoints = NbEdgeCurve-1;
     2330                                                                        if(!kstep){
     2331                                                                                NbVerticesOnGeomEdge0 += NbNewPoints;
     2332                                                                                NbOfCurves++;
     2333                                                                        }
     2334                                                                        nbvend=nbv+NbNewPoints;
     2335                                                                        lstep = lcurve / NbEdgeCurve;
     2336                                                                }// end of curve --
     2337                                                                if (edges) { // last edges of the curves
     2338                                                                        edges[nbe].v[0]=va;
     2339                                                                        edges[nbe].v[1]=vb;
     2340                                                                        edges[nbe].ref = e->ref;
     2341                                                                        edges[nbe].on = e;
     2342                                                                        edges[nbe].adj[0] = PreviousNewEdge;
     2343                                                                        edges[nbe].adj[1] = 0;
     2344                                                                        if(PreviousNewEdge) PreviousNewEdge->adj[1] = & edges[nbe];
     2345                                                                        nbe++;
     2346                                                                }
     2347                                                                else nbe += NbEdgeCurve;
     2348                                                        } // end on  curve ---
     2349                                                } // if (edges[i][j].Corner()) 
     2350                                        }
    28362351                                }
    2837                                 if (renu[kt]!=-1){
    2838                                         throw ErrorException(__FUNCT__,exprintf("renu[kt]!=-1"));
     2352                        } // for (i=0;i<nbe;i++)
     2353                        if(!step) {
     2354                                if (edges){
     2355                                        throw ErrorException(__FUNCT__,exprintf("edges"));
    28392356                                }
    2840                                 renu[kt]=k++;
    2841                         }
    2842                         while (t0 != (t=t->link));
    2843                   }
    2844                 // take is same numbering if possible   
    2845                 if(justcompress)
    2846                  for ( k=0,it=0;it<nbt;it++)
    2847                   if(renu[it] >=0 )
    2848                         renu[it]=k++;
    2849 
    2850                 // put the outside triangles at the end
    2851                 for ( it=0;it<nbt;it++){
    2852                         if (renu[it]==-1) renu[it]=k++;
    2853                 }
    2854                 if (k != nbt){
    2855                         throw ErrorException(__FUNCT__,exprintf("k != nbt"));
    2856                 }
    2857                 // do the change on all the pointeur
    2858                 for ( it=0;it<nbt;it++)
    2859                  triangles[it].ReNumbering(triangles,te,renu);
    2860 
    2861                 for ( i=0;i<NbSubDomains;i++)
    2862                  subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
    2863 
    2864                 // move the Triangles  without a copy of the array
    2865                 // be carefull not trivial code
    2866                 for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
    2867                  if (renu[it] >= 0) // a new sub cycle
    2868                         {
    2869                          i=it;
    2870                          Triangle ti=triangles[i],tj;
    2871                          while ( (j=renu[i]) >= 0)
    2872                                 { // i is old, and j is new
    2873                                  renu[i] = -1; // mark
    2874                                  tj = triangles[j]; // save new
    2875                                  triangles[j]= ti; // new <- old
    2876                                  i=j;     // next
    2877                                  ti = tj;
    2878                                 } 
    2879                         }
    2880                 delete [] renu;
    2881                 nt = nbt - NbOutT;
    2882 
    2883         }
    2884         /*}}}1*/
    2885         /*FUNCTION Triangles::ConsRefTriangle{{{1*/
    2886         Int4  Triangles::ConsRefTriangle(Int4* reft) const {
    2887                 long int verbosity=0;
    2888                 register Triangle *t0,*t;
    2889                 register Int4 k=0, num;   
    2890                 for (Int4 it=0;it<nbt;it++) reft[it]=-1; // outside triangle
    2891                 for (Int4 i=0;i<NbSubDomains;i++){
    2892                         t=t0=subdomains[i].head;
    2893                         if (!t0){ // no empty sub domai{
    2894                                 throw ErrorException(__FUNCT__,exprintf("!t0"));
    2895                         }
    2896                         // register Int4 color=i+1;// because the color 0 is outside triangle
    2897                         do { k++;
    2898                                 num = Number(t);
    2899                                 if (num<0 || num>=nbt){
    2900                                         throw ErrorException(__FUNCT__,exprintf("num<0 || num>=nbt"));
     2357                                if (VerticesOnGeomEdge){
     2358                                        throw ErrorException(__FUNCT__,exprintf("VerticesOnGeomEdge"));
    29012359                                }
    2902                                 reft[num]=i;
    2903                         }
    2904                         while (t0 != (t=t->link));
    2905                   }
    2906                 return k;   
     2360                                edges = new Edge[nbex=nbe];
     2361                                if(NbVerticesOnGeomEdge0)
     2362                                 VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
     2363                                if (!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0){
     2364                                        throw ErrorException(__FUNCT__,exprintf("!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0"));
     2365                                }
     2366                                // do the vertex on a geometrical vertex
     2367                                NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
     2368                        }
     2369                        else if (NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0){
     2370                                throw ErrorException(__FUNCT__,exprintf("NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0"));
     2371                        }
     2372                }
     2373
     2374                Insert();
     2375                ForceBoundary();
     2376                FindSubDomain();
     2377
     2378                // NewPointsOld(*this) ;
     2379                NewPoints(*this,0) ;
     2380                CurrentTh = 0;
    29072381        }
    29082382        /*}}}1*/
     
    32482722        }
    32492723        /*}}}1*/
    3250         /*FUNCTION Triangles::GeomToTriangles0{{{1*/
    3251         void Triangles::GeomToTriangles0(Int4 inbvx) {
    3252                 Gh.NbRef++;// add a ref to GH
    3253 
    3254 
    3255                 Int4 i,NbOfCurves=0,NbNewPoints,NbEdgeCurve;
    3256                 Real8 lcurve, lstep,s;
    3257 
    3258                 R2 AB;
    3259                 GeometricalVertex *a,*b;
    3260                 Vertex *va,*vb;
    3261                 GeometricalEdge * e;
    3262                 PreInit(inbvx);
    3263                 int  background = &BTh != this;
    3264                 //  int  SameGeom = background && (&BTh.Gh == &Gh);
    3265                 nbv = 0;
    3266                 NbVerticesOnGeomVertex=0;
    3267                 NbVerticesOnGeomEdge=0;
    3268                 for (i=0;i<Gh.nbv;i++)
    3269                  if (Gh[i].Required() && Gh[i].IsThe() ) NbVerticesOnGeomVertex++;
    3270                 VerticesOnGeomVertex = new VertexOnGeom[NbVerticesOnGeomVertex]; 
    3271                 //
    3272                 if( NbVerticesOnGeomVertex >= nbvx) {
    3273                         throw ErrorException(__FUNCT__,exprintf("too many vertices on geometry: %i >= %i",NbVerticesOnGeomVertex,nbvx));
    3274                 }
    3275                 for (i=0;i<Gh.nbv;i++)
    3276                  if (Gh[i].Required()&& Gh[i].IsThe()  ) {//Gh  vertices Required
    3277                          if (nbv < nbvx)
    3278                           vertices[nbv] = Gh[i];
    3279                          Gh[i].to = vertices + nbv;// save Geom -> Th
    3280                          VerticesOnGeomVertex[nbv]= VertexOnGeom(*Gh[i].to,Gh[i]);
    3281                          nbv++;
    3282                  }
    3283 
    3284                 // Method in 2 step:  0 and 1
    3285                 // 1) compute de nb of edge
    3286                 // 2) construct the edge   
    3287                 // generation of the curves
    3288                 if (edges){
    3289                         throw ErrorException(__FUNCT__,exprintf("edges"));
    3290                 }
    3291                 // 2 step
    3292                 // --step=0 to compute the number of edges + alloc at end
    3293                 // --step=1 to construct the edges
    3294                 for (int step=0;step<2;step++)
    3295                   {//  for (int step=0;step<2;step++)
    3296                         Int4 nbex = 0;
    3297                         nbe = 0;
    3298                         Int4 NbVerticesOnGeomEdge0=NbVerticesOnGeomEdge;
    3299                         Gh.UnMarkEdges();       
    3300                         NbOfCurves = 0;
    3301                         for (i=0;i<Gh.nbe;i++) {
    3302                                 GeometricalEdge & ei = Gh.edges[i];   
    3303                                 if (!ei.Dup()) // a good curve (not dup )
    3304                                  for(int j=0;j<2;j++)
    3305                                   if (!ei.Mark() && ei[j].Required()) {
    3306                                           // warning ei.Mark() can be change in loop for(j=0;j<2;j++)
    3307                                           Int4 nbvend  =0;
    3308 
    3309                                           Edge * PreviousNewEdge=0;
    3310 
    3311                                           lstep = -1;//to do not create points
    3312                                           if(ei.Required())
    3313                                                  {
    3314                                                   if (j==0)
    3315                                                         if(step==0)
    3316                                                          nbe++;
    3317                                                         else
    3318                                                           {
    3319                                                                 e = & ei;
    3320                                                                 a=ei(0)->The();
    3321                                                                 b=ei(1)->The();
    3322                                                                 if (!edges){
    3323                                                                         throw ErrorException(__FUNCT__,exprintf("!edges"));
    3324                                                                 }
    3325                                                                 edges[nbe].v[0]=a->to;
    3326                                                                 edges[nbe].v[1]=b->to;;
    3327                                                                 edges[nbe].ref = e->ref;
    3328                                                                 edges[nbe].on = e;
    3329                                                                 edges[nbe].adj[0] = 0;
    3330                                                                 edges[nbe].adj[1] = 0;
    3331                                                                 nbe++;}
    3332                                                  }
    3333                                           else
    3334                                                  { // on curve ------
    3335                                                   for ( int kstep=0;kstep<= step;kstep++)
    3336                                                          { // begin  for ( int kstep=0;kstep<= step;kstep++)
    3337                                                           // if 2nd step where 2 step
    3338                                                           // -- 1 compute le length of the curve
    3339                                                           // -- create the points and edge
    3340                                                           PreviousNewEdge=0;
    3341                                                           NbNewPoints=0;
    3342                                                           NbEdgeCurve=0;
    3343                                                           if (nbvend>=nbvx){
    3344                                                                   throw ErrorException(__FUNCT__,exprintf("nbvend>=nbvx"));
    3345                                                           }
    3346                                                           lcurve =0;
    3347                                                           s = lstep;
    3348                                                           int k=j;
    3349                                                           e = & ei;
    3350                                                           a=ei(k)->The();
    3351                                                           va = a->to;
    3352                                                           e->SetMark();
    3353 
    3354                                                           // if SameGeo  We have go in the background geometry
    3355                                                           // to find the discretisation of the curve
    3356 
    3357                                                           for(;;)
    3358                                                                  {
    3359                                                                   k = 1-k;
    3360                                                                   b= (*e)(k)->The();
    3361                                                                   AB = b->r - a->r;
    3362                                                                   Metric MA = background ? BTh.MetricAt(a->r) :a->m ;
    3363                                                                   Metric MB =  background ? BTh.MetricAt(b->r) :b->m ;
    3364                                                                   Real8 ledge = (MA(AB) + MB(AB))/2;
    3365                                                                   //
    3366                                                                   const int MaxSubEdge = 10;
    3367                                                                   int NbSubEdge = 1;
    3368                                                                   Real8 lSubEdge[MaxSubEdge];
    3369                                                                   R2 A,B;
    3370                                                                   if (ledge < 1.5)
    3371                                                                         lSubEdge[0] = ledge;
    3372                                                                   else {
    3373                                                                           NbSubEdge = Min( MaxSubEdge, (int) (ledge +0.5));
    3374                                                                           A= a->r;
    3375                                                                           Metric MAs =MA,MBs;
    3376                                                                           ledge = 0;
    3377                                                                           Real8 x =0, xstep= 1. /  NbSubEdge;
    3378                                                                           for (int kk=0; kk < NbSubEdge; kk++,A=B,MAs=MBs ) {
    3379                                                                                   x += xstep;
    3380                                                                                   B =  e->F(k ? x : 1-x);
    3381                                                                                   MBs= background ? BTh.MetricAt(B) :Metric(1-x, MA, x ,MB);
    3382                                                                                   AB = A-B;
    3383                                                                                   lSubEdge[kk]= (ledge += (MAs(AB)+MBs(AB))/2);
    3384                                                                           }
    3385                                                                   }
    3386 
    3387                                                                   Real8 lcurveb = lcurve+ ledge ;
    3388                                                                   while (lcurve<=s && s <= lcurveb && nbv < nbvend)
    3389                                                                          {
    3390                                                                           // New points
    3391 
    3392                                                                           // Real8 aa=(lcurveb-s)/ledge;
    3393                                                                           // Real8 bb=(s-lcurve)/ledge;
    3394 
    3395                                                                           Real8 ss = s-lcurve;
    3396                                                                           // 1) find the SubEdge containing ss by dichotomie
    3397                                                                           int kk0=-1,kk1=NbSubEdge-1,kkk;
    3398                                                                           Real8 ll0=0,ll1=ledge,llk;
    3399                                                                           while (kk1-kk0>1)
    3400                                                                                  {
    3401                                                                                   if (ss < (llk=lSubEdge[kkk=(kk0+kk1)/2]))
    3402                                                                                         kk1=kkk,ll1=llk;
    3403                                                                                   else
    3404                                                                                         kk0=kkk,ll0=llk;}
    3405                                                                                   if (kk1 == kk0){
    3406                                                                                           throw ErrorException(__FUNCT__,exprintf("kk1 == kk0"));
    3407                                                                                   }
    3408 
    3409                                                                                   Real8 sbb = (ss-ll0  )/(ll1-ll0);
    3410                                                                                   Real8 bb = (kk1+sbb)/NbSubEdge, aa=1-bb;
    3411 
    3412                                                                                   // new vertex on edge
    3413                                                                                   vb = &vertices[nbv++];
    3414                                                                                   vb->m = Metric(aa,a->m,bb,b->m);
    3415                                                                                   vb->ReferenceNumber = e->ref;
    3416                                                                                   vb->DirOfSearch =NoDirOfSearch;
    3417                                                                                   Real8 abcisse = k ? bb : aa;
    3418                                                                                   vb->r =  e->F( abcisse );
    3419                                                                                   VerticesOnGeomEdge[NbVerticesOnGeomEdge++]= VertexOnGeom(*vb,*e,abcisse);       
    3420 
    3421                                                                                   // to take in account the sens of the edge
    3422 
    3423                                                                                   s += lstep;
    3424                                                                                   edges[nbe].v[0]=va;
    3425                                                                                   edges[nbe].v[1]=vb;
    3426                                                                                   edges[nbe].ref = e->ref;
    3427                                                                                   edges[nbe].on = e;
    3428                                                                                   edges[nbe].adj[0] = PreviousNewEdge;
    3429                                                                                   if(PreviousNewEdge)
    3430                                                                                         PreviousNewEdge->adj[1] = &edges[nbe];
    3431                                                                                   PreviousNewEdge = edges + nbe;
    3432                                                                                   nbe++;
    3433                                                                                   va = vb;
    3434                                                                          }
    3435                                                                   lcurve = lcurveb;
    3436                                                                   e->SetMark();
    3437                                                                   a=b;
    3438                                                                   if (b->Required() ) break;
    3439                                                                   int kprev=k;
    3440                                                                   k = e->SensAdj[kprev];// next vertices
    3441                                                                   e = e->Adj[kprev];
    3442                                                                   if (!e){
    3443                                                                           throw ErrorException(__FUNCT__,exprintf("!e"));
    3444                                                                   }
    3445                                                                  }// for(;;)
    3446                                                           vb = b->to;
    3447                                                           NbEdgeCurve = Max((Int4) (lcurve +0.5), (Int4) 1);
    3448                                                           NbNewPoints = NbEdgeCurve-1;
    3449                                                           if(!kstep)
    3450                                                                  { NbVerticesOnGeomEdge0 += NbNewPoints;
    3451                                                                   NbOfCurves++;}
    3452 
    3453                                                                   nbvend=nbv+NbNewPoints;
    3454 
    3455                                                                   lstep = lcurve / NbEdgeCurve;
    3456                                                          }
    3457                                                   // end of curve --
    3458                                                   if (edges) { // last edges of the curves
    3459                                                           edges[nbe].v[0]=va;
    3460                                                           edges[nbe].v[1]=vb;
    3461                                                           edges[nbe].ref = e->ref;
    3462                                                           edges[nbe].on = e;
    3463                                                           edges[nbe].adj[0] = PreviousNewEdge;
    3464                                                           edges[nbe].adj[1] = 0;
    3465                                                           if(PreviousNewEdge)
    3466                                                                 PreviousNewEdge->adj[1] = & edges[nbe];
    3467 
    3468                                                           nbe++;}
    3469                                                   else
    3470                                                         nbe += NbEdgeCurve;
    3471                                                  } // end on  curve ---
    3472                                   } // if (edges[i][j].Corner()) 
    3473                         } // for (i=0;i<nbe;i++)
    3474                         if(!step) {
    3475                                 if (edges){
    3476                                         throw ErrorException(__FUNCT__,exprintf("edges"));
    3477                                 }
    3478                                 if (VerticesOnGeomEdge){
    3479                                         throw ErrorException(__FUNCT__,exprintf("VerticesOnGeomEdge"));
    3480                                 }
    3481                                 edges = new Edge[nbex=nbe];
    3482                                 if(NbVerticesOnGeomEdge0)
    3483                                  VerticesOnGeomEdge = new VertexOnGeom[NbVerticesOnGeomEdge0];
    3484                                 if (!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0){
    3485                                         throw ErrorException(__FUNCT__,exprintf("!VerticesOnGeomEdge && NbVerticesOnGeomEdge0!=0"));
    3486                                 }
    3487                                 // do the vertex on a geometrical vertex
    3488                                 NbVerticesOnGeomEdge0 = NbVerticesOnGeomEdge;       
    3489                         }
    3490                         else if (NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0){
    3491                                 throw ErrorException(__FUNCT__,exprintf("NbVerticesOnGeomEdge != NbVerticesOnGeomEdge0"));
    3492                         }
    3493                   } // for (step=0;step<2;step++)
    3494 
    3495                 Insert();
    3496                 ForceBoundary();
    3497                 FindSubDomain();
    3498 
    3499                 // NewPointsOld(*this) ;
    3500                 NewPoints(*this,0) ;
    3501                 CurrentTh = 0;
     2724/*FUNCTION Triangles::IntersectConsMetric{{{1*/
     2725void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols,
     2726                        const  Real8 hmin1,const Real8 hmax1,const Real8 coef,
     2727                        const Real8 anisomax ,const Real8 CutOff,const int NbJacobi,
     2728                        const int DoNormalisation,const double power,const int choice)
     2729{ //  the array of solution s is store   
     2730        // sol0,sol1,...,soln    on vertex 0
     2731        //  sol0,sol1,...,soln   on vertex 1
     2732        //  etc.
     2733        //  choise = 0 =>  H is computed with green formule
     2734        //   otherwise  => H is computed from P2 on 4T
     2735        const int dim = 2;
     2736
     2737        long int verbosity=0;
     2738
     2739        int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ;
     2740
     2741        // computation of the nb of field
     2742        Int4 ntmp = 0;
     2743        if (typsols)
     2744          {
     2745                for (Int4 i=0;i<nbsol;i++)
     2746                 ntmp += sizeoftype[typsols[i]];
     2747          }
     2748        else
     2749         ntmp = nbsol;
     2750
     2751        // n is the total number of fields
     2752
     2753        const Int4 n = ntmp;
     2754
     2755        Int4 i,k,iA,iB,iC,iv;
     2756        R2 O(0,0);
     2757        int RelativeMetric = CutOff>1e-30;
     2758        Real8 hmin = Max(hmin1,MinimalHmin());
     2759        Real8 hmax = Min(hmax1,MaximalHmax());
     2760        Real8 coef2 = 1/(coef*coef);
     2761
     2762        if(verbosity>1) {
     2763                printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",n,nbt,nbv);
     2764                printf("      coef = %g\n",coef);
     2765                printf("      hmin = %g hmax = %g\n",hmin,hmax);
     2766                printf("      anisomax = %g nb Jacobi = %i, power = %i\n",anisomax,NbJacobi,power);
     2767                if (RelativeMetric) printf("      RelativeErr with CutOff= %g\n",CutOff);
     2768                else printf("      Absolute error\n");
    35022769        }
    3503         /*}}}1*/
    3504         /*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
    3505         Edge** Triangles::MakeGeometricalEdgeToEdge() {
    3506                 if (!Gh.nbe){
    3507                         throw ErrorException(__FUNCT__,exprintf("!Gh.nbe"));
    3508                 }
    3509                 Edge **e= new (Edge* [Gh.nbe]);
    3510 
    3511                 Int4 i;
    3512                 for ( i=0;i<Gh.nbe ; i++)
    3513                  e[i]=NULL;
    3514                 for ( i=0;i<nbe ; i++)
    3515                   {
    3516                         Edge * ei = edges+i;
    3517                         GeometricalEdge *on = ei->on;
    3518                         e[Gh.Number(on)] = ei;   
     2770        double *ss=(double*)s;
     2771
     2772        double sA,sB,sC;
     2773
     2774        Real8 *detT = new Real8[nbt];
     2775        Real8 *Mmass= new Real8[nbv];
     2776        Real8 *Mmassxx= new Real8[nbv];
     2777        Real8 *dxdx= new Real8[nbv];
     2778        Real8 *dxdy= new Real8[nbv];
     2779        Real8 *dydy= new Real8[nbv];
     2780        Real8 *workT= new Real8[nbt];
     2781        Real8 *workV= new Real8[nbv];
     2782        int *OnBoundary = new int[nbv];
     2783        for (iv=0;iv<nbv;iv++)
     2784          {
     2785                Mmass[iv]=0;
     2786                OnBoundary[iv]=0;
     2787                Mmassxx[iv]=0;
     2788          }
     2789
     2790        for (i=0;i<nbt;i++)
     2791         if(triangles[i].link) // the real triangles
     2792                {
     2793                 const Triangle &t=triangles[i];
     2794                 // coor of 3 vertices
     2795                 R2 A=t[0];
     2796                 R2 B=t[1];
     2797                 R2 C=t[2];
     2798
     2799
     2800                 // number of the 3 vertices
     2801                 iA = Number(t[0]);
     2802                 iB = Number(t[1]);
     2803                 iC = Number(t[2]);
     2804
     2805                 Real8 dett = bamg::Area2(A,B,C);
     2806                 detT[i]=dett;
     2807                 dett /= 6;
     2808
     2809                 // construction of on boundary
     2810                 int nbb =0;
     2811                 for(int j=0;j<3;j++)
     2812                        {
     2813                         Triangle *ta=t.Adj(j);
     2814                         if ( ! ta || !ta->link) // no adj triangle => edge on boundary
     2815                          OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1,
     2816                                 OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1,
     2817                                 nbb++;
     2818                        }
     2819
     2820                 workT[i] = nbb;
     2821                 Mmass[iA] += dett;
     2822                 Mmass[iB] += dett;
     2823                 Mmass[iC] += dett;
     2824
     2825                 if((nbb==0)|| !choice)
     2826                        {
     2827                         Mmassxx[iA] += dett;
     2828                         Mmassxx[iB] += dett;
     2829                         Mmassxx[iC] += dett;
     2830                        }
     2831                }
     2832         else
     2833          workT[i]=-1;
     2834
     2835        for (Int4 nusol=0;nusol<nbsol;nusol++)
     2836          { //for all Solution 
     2837
     2838                Real8 smin=ss[0],smax=ss[0];
     2839
     2840                Real8 h1=1.e30,h2=1e-30,rx=0;
     2841                Real8 coef = 1./(anisomax*anisomax);
     2842                Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
     2843                int nbfield = typsols? sizeoftype[typsols[nusol]] : 1;
     2844                if (nbfield == 1)
     2845                 for ( iv=0,k=0; iv<nbv; iv++,k+=n )
     2846                        {
     2847                         dxdx[iv]=dxdy[iv]=dydy[iv]=0;
     2848                         smin=Min(smin,ss[k]);
     2849                         smax=Max(smax,ss[k]);
     2850                        }
     2851                else
     2852                  {
     2853                        //  cas vectoriel
     2854                        for ( iv=0,k=0; iv<nbv; iv++,k+=n )
     2855                          {     
     2856                                double v=0;                 
     2857                                for (int i=0;i<nbfield;i++)
     2858                                 v += ss[k+i]*ss[k+i];
     2859                                v = sqrt(v);
     2860                                smin=Min(smin,v);
     2861                                smax=Max(smax,v);
     2862                          }
    35192863                  }
    3520                 for ( i=0;i<nbe ; i++)
    3521                  for (int ii=0;ii<2;ii++) {
    3522                          Edge * ei = edges+i;
    3523                          GeometricalEdge *on = ei->on;
    3524                          int j= ii;
    3525                          while (!(*on)[j].Required()) {
    3526                                  Adj(on,j); // next geom edge
    3527                                  j=1-j;
    3528                                  if (e[Gh.Number(on)])  break; // optimisation     
    3529                                  e[Gh.Number(on)] = ei;
    3530                          }
    3531                  }
    3532 
    3533                 int kk=0;
    3534                 for ( i=0;i<Gh.nbe ; i++){
    3535                         if (!e[i]){
    3536                                 kk++;
    3537                                 if(kk<10) printf("BUG: the geometrical edge %i is on no edge curve\n",i);
    3538                         }
    3539                 }
    3540                 if(kk) throw ErrorException(__FUNCT__,exprintf("See above"));
    3541 
    3542                 return e;
    3543         }
    3544         /*}}}1*/
    3545         /*FUNCTION Triangles::SetIntCoor{{{1*/
    3546         void Triangles::SetIntCoor(const char * strfrom) {
    3547                 pmin =  vertices[0].r;
    3548                 pmax =  vertices[0].r;
    3549 
    3550                 // recherche des extrema des vertices pmin,pmax
    3551                 Int4 i;
    3552                 for (i=0;i<nbv;i++) {
    3553                         pmin.x = Min(pmin.x,vertices[i].r.x);
    3554                         pmin.y = Min(pmin.y,vertices[i].r.y);
    3555                         pmax.x = Max(pmax.x,vertices[i].r.x);
    3556                         pmax.y = Max(pmax.y,vertices[i].r.y);
    3557                 }
    3558                 R2 DD = (pmax-pmin)*0.05;
    3559                 pmin = pmin-DD;
    3560                 pmax = pmax+DD;
    3561                 coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
    3562                 if (coefIcoor<=0){
    3563                         throw ErrorException(__FUNCT__,exprintf("coefIcoor<=0"));
    3564                 }
    3565 
    3566                 // generation of integer coord 
    3567                 for (i=0;i<nbv;i++) {
    3568                         vertices[i].i = toI2(vertices[i].r);   
    3569                 }
    3570 
    3571                 // computation of the det
    3572                 int Nberr=0;
    3573                 for (i=0;i<nbt;i++) {
    3574                         Vertex & v0 = triangles[i][0];
    3575                         Vertex & v1 = triangles[i][1];
    3576                         Vertex & v2 = triangles[i][2];
    3577                         if ( &v0 && &v1 &&  &v2 ) // a good triangles;
    3578                           {
    3579                                 triangles[i].det= det(v0,v1,v2);
    3580                                 if (triangles[i].det <=0 && Nberr++ <10){
    3581                                         if(Nberr==1)
    3582                                          if (strfrom){
    3583                                                  throw ErrorException(__FUNCT__,exprintf("Fatal error %s (SetInCoor) : area of Triangle %i < 0",strfrom,i));
    3584                                          }
    3585                                          else{
    3586                                                  throw ErrorException(__FUNCT__,exprintf("Fatal error (SetInCoor) : area of Triangle %i < 0",i));
    3587                                          }
    3588                                 }
    3589                           }
    3590                         else triangles[i].det= -1; // Null triangle;
    3591                 }
    3592         }
    3593         /*}}}1*/
    3594         /*FUNCTION Triangles::FillHoleInMesh{{{1*/
    3595         void Triangles::FillHoleInMesh() {
    3596 
    3597                 Triangles* OldCurrentTh =CurrentTh;
    3598                 CurrentTh=this;
    3599 
    3600                 int verbosity=0;
    3601 
    3602                 // generation of the integer coordinate
     2864                Real8 sdelta = smax-smin;
     2865                Real8 absmax=Max(Abs(smin),Abs(smax));
     2866                Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2;
     2867
     2868                if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, cnorm = %g, number of fields = %i\n",nusol,smin,smax,sdelta,cnorm,nbfield);
     2869
     2870                if ( sdelta < 1.0e-10*Max(absmax,1e-20) && (nbfield ==1)) {
     2871                        if (verbosity>2) printf("      Solution %i is constant, skipping...\n");
     2872                        continue;
     2873                }
     2874
     2875                double *sf  = ss;
     2876                for (Int4 nufield=0;nufield<nbfield;nufield++,ss++)
    36032877                  {
    3604 
    3605                         // find extrema coordinates of vertices pmin,pmax
    3606                         Int4 i;
    3607                         if(verbosity>2) printf("      Filling holes in mesh of %i vertices\n",nbv);
    3608 
    3609                         //initialize ordre
    3610                         if (!ordre){
    3611                                 throw ErrorException(__FUNCT__,exprintf("!ordre"));
    3612                         }
    3613                         for (i=0;i<nbv;i++) ordre[i]=0;
    3614 
    3615                         NbSubDomains =0;
    3616 
    3617                         /* generation of the adjacence of the triangles*/
    3618 
    3619                         SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
    3620 
    3621                         //initialize st
    3622                         Int4* st = new Int4[nbt*3];
    3623                         for (i=0;i<nbt*3;i++) st[i]=-1;
    3624 
    3625                         //check number of edges
    3626                         Int4 kk =0;
    3627                         for (i=0;i<nbe;i++){
    3628                                 kk=kk+(i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
    3629                         }
    3630                         if (kk != nbe) {
    3631                                 throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i",kk-nbe));
    3632                         }
    3633 
    3634                         //
    3635                         for (i=0;i<nbt;i++){
    3636                                 for (int j=0;j<3;j++) {
    3637                                         Int4 k =edge4->addtrie(Number(triangles[i][VerticesOfTriangularEdge[j][0]]),
    3638                                                                 Number(triangles[i][VerticesOfTriangularEdge[j][1]]));
    3639                                         Int4 invisible = triangles[i].Hidden(j);
    3640                                         if(st[k]==-1){
    3641                                                 st[k]=3*i+j;
    3642                                         }
    3643                                         else if(st[k]>=0) {
    3644                                                 if (triangles[i].TriangleAdj(j) || triangles[st[k] / 3].TriangleAdj((int) (st[k]%3))){
    3645                                                         throw ErrorException(__FUNCT__,exprintf("(triangles[i].TriangleAdj(j) || triangles[st[k] / 3].TriangleAdj((int) (st[k]%3)))"));
    3646                                                 }
    3647 
    3648                                                 triangles[i].SetAdj2(j,triangles + st[k] / 3,(int) (st[k]%3));
    3649                                                 if (invisible)  triangles[i].SetHidden(j);
    3650                                                 if (k<nbe) {
    3651                                                         triangles[i].SetLocked(j);
    3652                                                 }
    3653                                                 st[k]=-2-st[k];
    3654                                         }
    3655                                         else {
    3656                                                 throw ErrorException(__FUNCT__,exprintf("The edge (%i , %i) belongs to more than 2 triangles",
    3657                                                                                 Number(triangles[i][VerticesOfTriangularEdge[j][0]]),Number(triangles[i][VerticesOfTriangularEdge[j][1]])));
    3658                                         }
    3659                                 }
    3660                         }
    3661                         if(verbosity>5) {
    3662                                 printf("         info on Mesh %s:\n",name);
    3663                                 printf("            - number of vertices    = %i \n",nbv);
    3664                                 printf("            - number of triangles   = %i \n",nbt);
    3665                                 printf("            - number of given edges = %i \n",nbe);
    3666                                 printf("            - number of all edges   = %i \n"  ,edge4->nb());
    3667                                 printf("            - Euler number 1 - nb of holes = %i \n"  ,nbt-edge4->nb()+nbv);
    3668                         }
    3669 
    3670                         // check the consistant of edge[].adj and the geometrical required  vertex
    3671                         Int4 k=0;
    3672                         for (i=0;i<edge4->nb();i++){
    3673                                 if (st[i] >=0){ // edge alone
    3674                                         if (i < nbe) {
    3675                                                 Int4 i0=edge4->i(i);
    3676                                                 ordre[i0] = vertices+i0;
    3677                                                 Int4 i1=edge4->j(i);
    3678                                                 ordre[i1] = vertices+i1;
    3679                                         }
    3680                                         else {
    3681                                                 k=k+1;
    3682                                                 if (k <20) {
    3683                                                         throw ErrorException(__FUNCT__,exprintf("Lost boundary edges %i : %i %i",i,edge4->i(i),edge4->j(i)));
    3684                                                 }
    3685                                         }
    3686                                 }
    3687                         }
    3688                         if(k != 0) {
    3689                                 throw ErrorException(__FUNCT__,exprintf("%i boundary edges  are not defined as edges",k));
    3690                         }
    3691 
    3692                         /* mesh generation with boundary points*/
    3693                         Int4 nbvb = 0;
    3694                         for (i=0;i<nbv;i++){
    3695                                 vertices[i].t=0;
    3696                                 vertices[i].vint=0;
    3697                                 if (ordre[i]){
    3698                                         ordre[nbvb++] = ordre[i];
    3699                                 }
    3700                         }
    3701 
    3702                         Triangle* savetriangles= triangles;
    3703                         Int4 savenbt=nbt;
    3704                         Int4 savenbtx=nbtx;
    3705                         SubDomain * savesubdomains = subdomains;
    3706                         subdomains = 0;
    3707 
    3708                         Int4  Nbtriafillhole = 2*nbvb;
    3709                         Triangle* triafillhole =new Triangle[Nbtriafillhole];
    3710                         triangles =  triafillhole;
    3711 
    3712                         nbt=2;
    3713                         nbtx= Nbtriafillhole;
    3714 
    3715                         for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;)
    3716                          if  ( ++i >= nbvb) {
    3717                                  throw ErrorException(__FUNCT__,exprintf("FillHoleInMesh: All the vertices are aligned"));
    3718                          }
    3719                         Exchange( ordre[2], ordre[i]);
    3720 
    3721                                  Vertex *  v0=ordre[0], *v1=ordre[1];
    3722 
    3723 
    3724                                  triangles[0](0) = 0; // sommet pour infini
    3725                                  triangles[0](1) = v0;
    3726                                  triangles[0](2) = v1;
    3727 
    3728                                  triangles[1](0) = 0;// sommet pour infini
    3729                                  triangles[1](2) = v0;
    3730                                  triangles[1](1) = v1;
    3731                                  const int e0 = OppositeEdge[0];
    3732                                  const int e1 = NextEdge[e0];
    3733                                  const int e2 = PreviousEdge[e0];
    3734                                  triangles[0].SetAdj2(e0, &triangles[1] ,e0);
    3735                                  triangles[0].SetAdj2(e1, &triangles[1] ,e2);
    3736                                  triangles[0].SetAdj2(e2, &triangles[1] ,e1);
    3737 
    3738                                  triangles[0].det = -1;  // faux triangles
    3739                                  triangles[1].det = -1;  // faux triangles
    3740 
    3741                                  triangles[0].SetTriangleContainingTheVertex();
    3742                                  triangles[1].SetTriangleContainingTheVertex();
    3743 
    3744                                  triangles[0].link=&triangles[1];
    3745                                  triangles[1].link=&triangles[0];
    3746 
    3747                                  if (!quadtree )
    3748                                   delete  quadtree; // ->ReInitialise();
    3749 
    3750                                  quadtree = new QuadTree(this,0);
    3751                                  quadtree->Add(*v0);
    3752                                  quadtree->Add(*v1);
    3753 
    3754                                  // We add the vertices one by one
    3755                                  Int4 NbSwap=0;
    3756                                  for (Int4 icount=2; icount<nbvb; icount++) {
    3757                                          Vertex *vi  = ordre[icount];
    3758                                          Icoor2 dete[3];
    3759                                          Triangle *tcvi = FindTriangleContening(vi->i,dete);
    3760                                          quadtree->Add(*vi);
    3761                                          Add(*vi,tcvi,dete);
    3762                                          NbSwap += vi->Optim(1,1);
    3763                                  }
    3764 
    3765                                  // inforce the boundary
    3766                                  TriangleAdjacent ta(0,0);
    3767                                  Int4 nbloss = 0,knbe=0;
    3768                                  for ( i = 0; i < nbe; i++){
    3769                                          if (st[i] >=0){  // edge alone => on border ...  FH oct 2009
    3770                                                  Vertex & a=edges[i][0], & b =    edges[i][1];
    3771                                                  if (a.t && b.t) // le bug est la si maillage avec des bod non raffine 1.
    3772                                                         {
    3773                                                          knbe++;
    3774                                                          if (ForceEdge(a,b,ta)<0)
    3775                                                           nbloss++;
    3776                                                         }
    3777                                          }
    3778                                  }
    3779                                  if(nbloss) {
    3780                                          throw ErrorException(__FUNCT__,exprintf("we lost(?) %i edges other %i",nbloss,knbe));
    3781                                  }
    3782 
    3783                                  FindSubDomain(1);
    3784                                  // remove all the hole
    3785                                  // remove all the good sub domain
    3786                                  Int4 krm =0;
    3787                                  for (i=0;i<nbt;i++){
    3788                                          if (triangles[i].link){ // remove triangles
    3789                                                  krm++;
    3790                                                  for (int j=0;j<3;j++)
    3791                                                         {
    3792                                                          TriangleAdjacent ta =  triangles[i].Adj(j);
    3793                                                          Triangle & tta = * (Triangle *) ta;
    3794                                                          if(! tta.link) // edge between remove and not remove
    3795                                                                 { // change the link of ta;
    3796                                                                  int ja = ta;
    3797                                                                  Vertex *v0= ta.EdgeVertex(0);
    3798                                                                  Vertex *v1= ta.EdgeVertex(1);
    3799                                                                  Int4 k =edge4->addtrie(v0?Number(v0):nbv,v1? Number(v1):nbv);
    3800                                                                  if (st[k]<0){
    3801                                                                          throw ErrorException(__FUNCT__,exprintf("st[k]<0"));
    3802                                                                  }
    3803                                                                  tta.SetAdj2(ja,savetriangles + st[k] / 3,(int) (st[k]%3));
    3804                                                                  ta.SetLock();
    3805                                                                  st[k]=-2-st[k];
    3806                                                                 }
    3807                                                         }
    3808                                          }
    3809                                  }
    3810                                  Int4 NbTfillHoll =0;
    3811                                  for (i=0;i<nbt;i++){
    3812                                          if (triangles[i].link) {
    3813                                                  triangles[i]=Triangle((Vertex *) NULL,(Vertex *) NULL,(Vertex *) NULL);
    3814                                                  triangles[i].color=-1;
    3815                                          }
    3816                                          else
    3817                                                 {
    3818                                                  triangles[i].color= savenbt+ NbTfillHoll++;
    3819                                                 }
    3820                                  }
    3821                                  if (savenbt+NbTfillHoll>savenbtx ){
    3822                                          throw ErrorException(__FUNCT__,exprintf("savenbt+NbTfillHoll>savenbtx"));
    3823                                  }
    3824                                  // copy of the outside triangles in saveTriangles
    3825                                  for (i=0;i<nbt;i++){
    3826                                          if(triangles[i].color>=0) {
    3827                                                  savetriangles[savenbt]=triangles[i];
    3828                                                  savetriangles[savenbt].link=0;
    3829                                                  savenbt++;
    3830                                          }
    3831                                  }
    3832                                  // gestion of the adj
    3833                                  k =0;
    3834                                  Triangle * tmax = triangles + nbt;
    3835                                  for (i=0;i<savenbt;i++) 
    3836                                         {
    3837                                          Triangle & ti = savetriangles[i];
     2878                        for ( iv=0,k=0; iv<nbv; iv++,k+=n )
     2879                         dxdx[iv]=dxdy[iv]=dydy[iv]=0;
     2880                        for (i=0;i<nbt;i++)
     2881                         if(triangles[i].link)
     2882                                {// for real all triangles
     2883                                 // coor of 3 vertices
     2884                                 R2 A=triangles[i][0];
     2885                                 R2 B=triangles[i][1];
     2886                                 R2 C=triangles[i][2];
     2887
     2888
     2889                                 // warning the normal is internal and the
     2890                                 //   size is the length of the edge
     2891                                 R2 nAB = Orthogonal(B-A);
     2892                                 R2 nBC = Orthogonal(C-B);
     2893                                 R2 nCA = Orthogonal(A-C);
     2894                                 // remark :  nAB + nBC + nCA == 0
     2895
     2896                                 // number of the 3 vertices
     2897                                 iA = Number(triangles[i][0]);
     2898                                 iB = Number(triangles[i][1]);
     2899                                 iC = Number(triangles[i][2]);
     2900
     2901                                 // for the test of  boundary edge
     2902                                 // the 3 adj triangles
     2903                                 Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
     2904                                 Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
     2905                                 Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
     2906
     2907                                 // value of the P1 fonction on 3 vertices
     2908                                 sA = ss[iA*n];
     2909                                 sB = ss[iB*n];
     2910                                 sC = ss[iC*n];
     2911
     2912                                 R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ;
     2913                                 if(choice)
     2914                                        {
     2915                                         int nbb = 0;
     2916                                         Real8 dd = detT[i];
     2917                                         Real8 lla,llb,llc,llf;
     2918                                         Real8  taa[3][3],bb[3];
     2919                                         // construction of the trans of lin system
    38382920                                         for (int j=0;j<3;j++)
    38392921                                                {
    3840                                                  Triangle * ta = ti.TriangleAdj(j);
    3841                                                  int aa = ti.NuEdgeTriangleAdj(j);
    3842                                                  int lck = ti.Locked(j);
    3843                                                  if (!ta) k++; // bug
    3844                                                  else if ( ta >= triangles && ta < tmax)
     2922                                                 int ie = OppositeEdge[j];
     2923                                                 TriangleAdjacent ta = triangles[i].Adj(ie);
     2924                                                 Triangle *tt = ta;
     2925                                                 if (tt && tt->link)
    38452926                                                        {
    3846                                                          ta= savetriangles + ta->color;
    3847                                                          ti.SetAdj2(j,ta,aa);
    3848                                                          if(lck) ti.SetLocked(j);
     2927                                                         Vertex &v = *ta.OppositeVertex();
     2928                                                         R2 V = v;
     2929                                                         Int4 iV = Number(v);
     2930                                                         Real8 lA  = bamg::Area2(V,B,C)/dd;
     2931                                                         Real8 lB  = bamg::Area2(A,V,C)/dd;
     2932                                                         Real8 lC  = bamg::Area2(A,B,V)/dd;
     2933                                                         taa[0][j] =  lB*lC;
     2934                                                         taa[1][j] =  lC*lA;
     2935                                                         taa[2][j] =  lA*lB;
     2936                                                         lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ;
     2937
     2938                                                         bb[j]     =  ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ;
     2939                                                        }
     2940                                                 else
     2941                                                        {
     2942                                                         nbb++;
     2943                                                         taa[0][j]=0;
     2944                                                         taa[1][j]=0;
     2945                                                         taa[2][j]=0;
     2946                                                         taa[j][j]=1;
     2947                                                         bb[j]=0;
    38492948                                                        }
    38502949                                                }
     2950
     2951                                         // resolution of 3x3 lineaire system transpose
     2952                                         Real8 det33 =  det3x3(taa[0],taa[1],taa[2]);           
     2953                                         Real8 cBC   =  det3x3(bb,taa[1],taa[2]);
     2954                                         Real8 cCA   =  det3x3(taa[0],bb,taa[2]);
     2955                                         Real8 cAB   =  det3x3(taa[0],taa[1],bb);
     2956
     2957                                         if (!det33){
     2958                                                 throw ErrorException(__FUNCT__,exprintf("!det33"));
     2959                                         }
     2960                                         // computation of the gradient in the element
     2961
     2962                                         // H( li*lj) = grad li grad lj + grad lj grad lj
     2963                                         // grad li = njk  / detT ; with i j k =(A,B,C)
     2964                                         Real8 Hxx = cAB * ( nBC.x*nCA.x) +  cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x);
     2965                                         Real8 Hyy = cAB * ( nBC.y*nCA.y) +  cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y);
     2966                                         Real8 Hxy = cAB * ( nBC.y*nCA.x) +  cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x)
     2967                                                + cAB * ( nBC.x*nCA.y) +  cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y);
     2968                                         Real8 coef = 1.0/(3*dd*det33);
     2969                                         Real8 coef2 = 2*coef;
     2970                                         Hxx *= coef2;
     2971                                         Hyy *= coef2;
     2972                                         Hxy *= coef2;
     2973                                         if(nbb==0)
     2974                                                {
     2975                                                 dxdx[iA] += Hxx;
     2976                                                 dydy[iA] += Hyy;
     2977                                                 dxdy[iA] += Hxy;
     2978
     2979                                                 dxdx[iB] += Hxx;
     2980                                                 dydy[iB] += Hyy;
     2981                                                 dxdy[iB] += Hxy;
     2982
     2983                                                 dxdx[iC] += Hxx;
     2984                                                 dydy[iC] += Hyy;
     2985                                                 dxdy[iC] += Hxy;
     2986                                                }
     2987
    38512988                                        }
    3852                                  //      OutSidesTriangles = triangles;
    3853                                  //     Int4 NbOutSidesTriangles = nbt;
    3854 
    3855                                  // restore triangles;
    3856                                  nbt=savenbt;
    3857                                  nbtx=savenbtx;
    3858                                  delete [] triangles;
    3859                                  delete [] subdomains;
    3860                                  triangles = savetriangles;
    3861                                  subdomains = savesubdomains;
    3862                                  if (k) {
    3863                                          throw ErrorException(__FUNCT__,exprintf("number of triangles edges alone = %i",k));
    3864                                  }
    3865                                  FindSubDomain();
    3866 
    3867                                  delete edge4;
    3868                                  delete [] st;
    3869                                  for (i=0;i<nbv;i++)
    3870                                   quadtree->Add(vertices[i]);
    3871 
    3872                                  SetVertexFieldOn();
    3873 
    3874                                  for (i=0;i<nbe;i++)
    3875                                   if(edges[i].on)
    3876                                         for(int j=0;j<2;j++)
    3877                                          if (!edges[i].adj[j])
    3878                                           if(!edges[i][j].on->IsRequiredVertex()) {
    3879                                                   throw ErrorException(__FUNCT__,exprintf("adj and vertex required esge(?)"));
    3880                                           }
     2989                                 else
     2990                                        {
     2991
     2992                                         // if edge on boundary no contribution  => normal = 0
     2993                                         if ( ! tBC || ! tBC->link ) nBC = O;
     2994                                         if ( ! tCA || ! tCA->link ) nCA = O;
     2995                                         if ( ! tAB || ! tAB->link ) nAB = O;
     2996
     2997                                         // remark we forgot a 1/2 because
     2998                                         //       $\\int_{edge} w_i = 1/2 $ if $i$ is in edge
     2999                                         //                          0  if not
     3000                                         // if we don't take the  boundary
     3001                                         // dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
     3002
     3003                                         dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
     3004                                         dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
     3005                                         dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
     3006
     3007                                         // warning optimization (1) the divide by 2 is done on the metrix construction
     3008                                         dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
     3009                                         dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
     3010                                         dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ;
     3011
     3012                                         dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
     3013                                         dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
     3014                                         dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
     3015                                        }
     3016
     3017                                } // for real all triangles
     3018                        Int4 kk=0;
     3019                        for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
     3020                         if(Mmassxx[iv]>0)
     3021                                {
     3022                                 dxdx[iv] /= 2*Mmassxx[iv];
     3023                                 // warning optimization (1) on term dxdy[iv]*ci/2
     3024                                 dxdy[iv] /= 4*Mmassxx[iv];
     3025                                 dydy[iv] /= 2*Mmassxx[iv];
     3026                                 // Compute the matrix with abs(eigen value)
     3027                                 Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
     3028                                 MatVVP2x2 Vp(M);
     3029                                 Vp.Abs();
     3030                                 M = Vp;
     3031                                 dxdx[iv] = M.a11;
     3032                                 dxdy[iv] = M.a21;
     3033                                 dydy[iv] = M.a22;
     3034                                }
     3035                         else kk++;
     3036
     3037
     3038                        // correction of second derivate
     3039                        // by a laplacien
     3040
     3041                        Real8 *d2[3] = { dxdx, dxdy, dydy};
     3042                        Real8 *dd;
     3043                        for (int xy = 0;xy<3;xy++)
     3044                          {
     3045                                dd = d2[xy];
     3046                                // do leat 2 iteration for boundary problem
     3047                                for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++)
     3048                                  {
     3049                                        for (i=0;i<nbt;i++)
     3050                                         if(triangles[i].link) // the real triangles
     3051                                                {
     3052                                                 // number of the 3 vertices
     3053                                                 iA = Number(triangles[i][0]);
     3054                                                 iB = Number(triangles[i][1]);
     3055                                                 iC = Number(triangles[i][2]);
     3056                                                 Real8 cc=3;
     3057                                                 if(ijacobi==0)
     3058                                                  cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
     3059                                                 workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
     3060                                                }
     3061                                        for (iv=0;iv<nbv;iv++)
     3062                                         workV[iv]=0;
     3063
     3064                                        for (i=0;i<nbt;i++)
     3065                                         if(triangles[i].link) // the real triangles
     3066                                                {
     3067                                                 // number of the 3 vertices
     3068                                                 iA = Number(triangles[i][0]);
     3069                                                 iB = Number(triangles[i][1]);
     3070                                                 iC = Number(triangles[i][2]);
     3071                                                 Real8 cc =  workT[i]*detT[i];
     3072                                                 workV[iA] += cc;
     3073                                                 workV[iB] += cc;
     3074                                                 workV[iC] += cc;
     3075                                                }
     3076
     3077                                        for (iv=0;iv<nbv;iv++)
     3078                                         if( ijacobi<NbJacobi || OnBoundary[iv])
     3079                                          dd[iv] = workV[iv]/(Mmass[iv]*6);
     3080
     3081
     3082                                  }
     3083
     3084
     3085                          }
     3086
     3087                        // constuction  of the metrix from the Hessian dxdx. dxdy,dydy
     3088
     3089                        Real8 rCutOff=CutOff*absmax;// relative cut off
     3090
     3091                        for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
     3092                          { // for all vertices
     3093                                MetricIso Miso;
     3094                                Real8 ci ;
     3095                                if (RelativeMetric)
     3096                                  { //   compute the norm of the solution
     3097                                        double xx =0,*sfk=sf+k;
     3098                                        for (int ifield=0;ifield<nbfield;ifield++,sfk++)
     3099                                         xx += *sfk* *sfk;             
     3100                                        xx=sqrt(xx);
     3101                                        ci = coef2/Max(xx,rCutOff);
     3102                                  }
     3103                                else ci = cnorm;
     3104
     3105                                Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci,  dydy[iv]*ci);
     3106                                MatVVP2x2 Vp(Miv);
     3107
     3108                                Vp.Abs();
     3109                                if(power!=1.0)
     3110                                 Vp.pow(power);
     3111
     3112
     3113
     3114                                h1=Min(h1,Vp.lmin());
     3115                                h2=Max(h2,Vp.lmax());
     3116
     3117                                Vp.Maxh(hmin);
     3118                                Vp.Minh(hmax);
     3119
     3120                                rx = Max(rx,Vp.Aniso2());
     3121
     3122                                Vp.BoundAniso2(coef);
     3123
     3124                                hn1=Min(hn1,Vp.lmin());
     3125                                hn2=Max(hn2,Vp.lmax());
     3126                                rnx = Max(rnx,Vp.Aniso2());
     3127
     3128                                Metric MVp(Vp);
     3129                                vertices[iv].m.IntersectWith(MVp);
     3130                          }// for all vertices
     3131                        if (verbosity>2) {
     3132                                printf("      Field %i of solution %i\n",nufield,nusol);
     3133                                printf("         before bounding : Hmin = %g, Hmax = %g, factor of anisotropy max = %g\n",pow(h2,-0.5), pow(h1,-0.5), pow(rx,0.5));
     3134                                printf("         after  bounding : Hmin = %g, Hmax = %g, factor of anisotropy max = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
     3135                        }
     3136                  } //  end of for all field
     3137          }// end for all solution
     3138
     3139        delete [] detT;
     3140        delete [] Mmass;
     3141        delete [] dxdx;
     3142        delete [] dxdy;
     3143        delete [] dydy;
     3144        delete []  workT;
     3145        delete [] workV;
     3146        delete [] Mmassxx;
     3147        delete []  OnBoundary;
     3148
     3149}
     3150/*}}}1*/
     3151/*FUNCTION Triangles::IntersectGeomMetric{{{1*/
     3152void Triangles::IntersectGeomMetric(const Real8 err=1,const int iso=0){
     3153        long int verbosity=0;
     3154        Real8 ss[2]={0.00001,0.99999};
     3155        Real8 errC = 2*sqrt(2*err);
     3156        Real8 hmax = Gh.MaximalHmax();
     3157        Real8 hmin = Gh.MinimalHmin();
     3158        Real8 maxaniso = 1e6;
     3159        if (hmax<=0){
     3160                throw ErrorException(__FUNCT__,exprintf("hmax<=0"));
     3161        }
     3162        SetVertexFieldOn();
     3163        if (errC > 1) errC = 1;
     3164        for (Int4  i=0;i<nbe;i++)
     3165         for (int j=0;j<2;j++)
     3166                {
     3167
     3168                 Vertex V;
     3169                 VertexOnGeom GV;
     3170                 Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
     3171                        {
     3172                         GeometricalEdge * eg = GV;
     3173                         Real8 s = GV;
     3174                         R2 tg;
     3175                         Real8  R1= eg->R1tg(s,tg);
     3176                         Real8 ht = hmax;
     3177                         if (R1>1.0e-20) {  // err relative to the length of the edge
     3178                                 ht = Min(Max(errC/R1,hmin),hmax);
     3179                         }
     3180                         Real8 hn = iso? ht : Min(hmax,ht*maxaniso);
     3181                         if (ht<=0 || hn<=0){
     3182                                 throw ErrorException(__FUNCT__,exprintf("ht<=0 || hn<=0"));
     3183                         }
     3184                         MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
     3185                         Metric MVp(Vp);
     3186                         edges[i][j].m.IntersectWith(MVp);
     3187                        }
     3188
     3189                }
     3190        // the problem is for the vertex on vertex
     3191}
     3192/*}}}1*/
     3193        /*FUNCTION Triangles::Insert{{{1*/
     3194        void Triangles::Insert() {
     3195                long int verbosity=2;
     3196                if (verbosity>2) printf("   Insert initial %i vertices\n",nbv);
     3197                Triangles * OldCurrentTh =CurrentTh;
     3198
     3199                CurrentTh=this;
     3200                SetIntCoor();
     3201                Int4 i;
     3202                for (i=0;i<nbv;i++) ordre[i]= &vertices[i] ;
     3203
     3204                // construction d'un ordre aleatoire
     3205                const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv) ;
     3206                Int4 k3 = rand()%nbv ;
     3207                for (int is3=0; is3<nbv; is3++)
     3208                 ordre[is3]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
     3209
     3210                for (i=2 ; det( ordre[0]->i, ordre[1]->i, ordre[i]->i ) == 0;){
     3211                        if  ( ++i >= nbv) {
     3212                                throw ErrorException(__FUNCT__,exprintf("all the vertices are aligned"));
     3213                        }
     3214                }
     3215                // echange i et 2 dans ordre afin
     3216                // que les 3 premiers ne soit pas aligne
     3217                Exchange( ordre[2], ordre[i]);
     3218
     3219                // on ajoute un point a l'infini pour construire le maillage
     3220                // afin d'avoir une definition simple des aretes frontieres
     3221                nbt = 2;
     3222
     3223                // on construit un maillage trivale forme
     3224                // d'une arete et de 2 triangles
     3225                // construit avec le 2 aretes orientes et
     3226                Vertex *  v0=ordre[0], *v1=ordre[1];
     3227
     3228                triangles[0](0) = 0; // sommet pour infini
     3229                triangles[0](1) = v0;
     3230                triangles[0](2) = v1;
     3231
     3232                triangles[1](0) = 0;// sommet pour infini
     3233                triangles[1](2) = v0;
     3234                triangles[1](1) = v1;
     3235                const int e0 = OppositeEdge[0];
     3236                const int e1 = NextEdge[e0];
     3237                const int e2 = PreviousEdge[e0];
     3238                triangles[0].SetAdj2(e0, &triangles[1] ,e0);
     3239                triangles[0].SetAdj2(e1, &triangles[1] ,e2);
     3240                triangles[0].SetAdj2(e2, &triangles[1] ,e1);
     3241
     3242                triangles[0].det = -1;  // faux triangles
     3243                triangles[1].det = -1;  // faux triangles
     3244
     3245                triangles[0].SetTriangleContainingTheVertex();
     3246                triangles[1].SetTriangleContainingTheVertex();
     3247
     3248                triangles[0].link=&triangles[1];
     3249                triangles[1].link=&triangles[0];
     3250
     3251                //  nbtf = 2;
     3252                if (  !quadtree )  quadtree = new QuadTree(this,0);
     3253                quadtree->Add(*v0);
     3254                quadtree->Add(*v1);
     3255
     3256                //the vertices are added one by one
     3257                Int4 NbSwap=0;
     3258
     3259
     3260                if (verbosity>3) printf("   Begining of insertion process...\n");
     3261
     3262                for (Int4 icount=2; icount<nbv; icount++) {
     3263                        Vertex *vi  = ordre[icount];
     3264                        Icoor2 dete[3];
     3265                        Triangle *tcvi = FindTriangleContening(vi->i,dete);
     3266                        quadtree->Add(*vi);
     3267                        Add(*vi,tcvi,dete);
     3268                        NbSwap += vi->Optim(1,0);
     3269                }
     3270                if (verbosity>3) {
     3271                        printf("      NbSwap of insertion: %i\n",NbSwap);
     3272                        printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
     3273                        printf("      NbUnSwap:            %i\n",NbUnSwap);
     3274                        printf("      NbUnSwap/nbv         %i\n",NbUnSwap/nbv);
     3275                }
     3276                NbUnSwap = 0;
     3277                // construction d'un ordre aleatoire
     3278                //  const int PrimeNumber= (nbv % 999983) ? 1000003: 999983 ;
     3279#ifdef NBLOOPOPTIM
     3280
     3281                k3 = rand()%nbv ;
     3282                for (int is4=0; is4<nbv; is4++)
     3283                 ordre[is4]= &vertices[k3 = (k3 + PrimeNumber)% nbv];
     3284
     3285                for(int Nbloop=0;Nbloop<NBLOOPOPTIM;Nbloop++)
     3286                  {
     3287                        Int4  NbSwap = 0;
     3288                        for (int is1=0; is1<nbv; is1++)
     3289                         NbSwap += ordre[is1]->Optim(0,0);
     3290                        if (verbosity>3) {
     3291                                printf("      Optim Loop: %i\n",Nbloop);
     3292                                printf("      NbSwap/nbv:          %i\n",NbSwap/nbv);
     3293                                printf("      NbUnSwap:            %i\n",NbUnSwap);
     3294                                printf("      NbUnSwap/nbv         %i\n",NbUnSwap/nbv);
     3295                        }
     3296                        NbUnSwap = 0;
     3297                        if(!NbSwap) break;
    38813298                  }
     3299                ReMakeTriangleContainingTheVertex();
     3300                // because we break the TriangleContainingTheVertex
     3301#endif
    38823302                CurrentTh=OldCurrentTh;
    38833303        }
    38843304        /*}}}1*/
    3885         /*FUNCTION Triangles::Optim{{{1*/
    3886         Int4  Triangle::Optim(Int2 i,int koption) {
    3887                 // turne around in positif sens
    3888                 Int4 NbSwap =0;
    3889                 Triangle  *t = this;
    3890                 int k=0,j =OppositeEdge[i];
    3891                 int jp = PreviousEdge[j];
    3892                 // initialise   tp, jp the previous triangle & edge
    3893                 Triangle *tp= at[jp];
    3894                 jp = aa[jp]&3;
     3305        /*FUNCTION Triangles::InsertNewPoints{{{1*/
     3306        Int4 Triangles::InsertNewPoints(Int4 nbvold,Int4 & NbTSwap) {
     3307                long int verbosity=2;
     3308                Real8 seuil= 1.414/2 ;// for two close point
     3309                Int4 i;
     3310                // insertion part ---
     3311
     3312                const Int4 nbvnew = nbv-nbvold;
     3313                if (verbosity>5) printf("      Try to Insert the %i new points\n",nbvnew);
     3314                Int4 NbSwap=0;
     3315                Icoor2 dete[3];
     3316
     3317                // construction d'un ordre aleatoire
     3318                if (! nbvnew)
     3319                 return 0;
     3320                if (nbvnew) {
     3321                        const Int4 PrimeNumber= AGoodNumberPrimeWith(nbv)  ;
     3322                        Int4 k3 = rand()%nbvnew ;
     3323                        for (Int4 is3=0; is3<nbvnew; is3++) {
     3324                                register Int4 j = nbvold +(k3 = (k3 + PrimeNumber)% nbvnew);
     3325                                register Int4 i = nbvold+is3;
     3326                                ordre[i]= vertices + j;
     3327                                ordre[i]->ReferenceNumber=i;
     3328                        }
     3329                        // be carefull
     3330                        Int4  iv = nbvold;
     3331                        for (i=nbvold;i<nbv;i++)
     3332                          {// for all the new point
     3333                                Vertex & vi = *ordre[i];
     3334                                vi.i = toI2(vi.r);
     3335                                vi.r = toR2(vi.i);
     3336                                Real4 hx,hy;
     3337                                vi.m.Box(hx,hy);
     3338                                Icoor1 hi=(Icoor1) (hx*coefIcoor),hj=(Icoor1) (hy*coefIcoor);
     3339                                if (!quadtree->ToClose(vi,seuil,hi,hj))
     3340                                  {
     3341                                        // a good new point
     3342                                        Vertex & vj = vertices[iv];
     3343                                        Int4 j = vj.ReferenceNumber;
     3344                                        if ( &vj!= ordre[j]){
     3345                                                throw ErrorException(__FUNCT__,exprintf("&vj!= ordre[j]"));
     3346                                        }
     3347                                        if(i!=j)
     3348                                          { //  for valgring
     3349                                                Exchange(vi,vj);
     3350                                                Exchange(ordre[j],ordre[i]);
     3351                                          }
     3352                                        vj.ReferenceNumber=0;
     3353                                        Triangle *tcvj = FindTriangleContening(vj.i,dete);
     3354                                        if (tcvj && !tcvj->link){
     3355                                                throw ErrorException(__FUNCT__,exprintf("problem inserting point"));
     3356                                        }
     3357                                        quadtree->Add(vj);
     3358                                        Add(vj,tcvj,dete);
     3359                                        NbSwap += vj.Optim(1);         
     3360                                        iv++;
     3361                                  }
     3362                          }
     3363                        if (verbosity>3) {
     3364                                printf("   number of new points: %i\n",iv);
     3365                                printf("   number of to close (?) points: %i\n",nbv-iv);
     3366                                printf("   number of swap after: %i\n",NbSwap);
     3367                        }
     3368                        nbv = iv;
     3369                }
     3370
     3371                for (i=nbvold;i<nbv;i++) NbSwap += vertices[i].Optim(1); 
     3372                if (verbosity>3) printf("   NbSwap=%i\n",NbSwap);
     3373
     3374                NbTSwap +=  NbSwap ;
     3375                return nbv-nbvold;
     3376        }
     3377        /*}}}1*/
     3378/*FUNCTION Triangles::MakeGeometricalEdgeToEdge{{{1*/
     3379Edge** Triangles::MakeGeometricalEdgeToEdge() {
     3380        if (!Gh.nbe){
     3381                throw ErrorException(__FUNCT__,exprintf("!Gh.nbe"));
     3382        }
     3383        Edge **e= new (Edge* [Gh.nbe]);
     3384
     3385        Int4 i;
     3386        for ( i=0;i<Gh.nbe ; i++)
     3387         e[i]=NULL;
     3388        for ( i=0;i<nbe ; i++)
     3389          {
     3390                Edge * ei = edges+i;
     3391                GeometricalEdge *on = ei->on;
     3392                e[Gh.Number(on)] = ei;   
     3393          }
     3394        for ( i=0;i<nbe ; i++)
     3395         for (int ii=0;ii<2;ii++) {
     3396                 Edge * ei = edges+i;
     3397                 GeometricalEdge *on = ei->on;
     3398                 int j= ii;
     3399                 while (!(*on)[j].Required()) {
     3400                         Adj(on,j); // next geom edge
     3401                         j=1-j;
     3402                         if (e[Gh.Number(on)])  break; // optimisation     
     3403                         e[Gh.Number(on)] = ei;
     3404                 }
     3405         }
     3406
     3407        int kk=0;
     3408        for ( i=0;i<Gh.nbe ; i++){
     3409                if (!e[i]){
     3410                        kk++;
     3411                        if(kk<10) printf("BUG: the geometrical edge %i is on no edge curve\n",i);
     3412                }
     3413        }
     3414        if(kk) throw ErrorException(__FUNCT__,exprintf("See above"));
     3415
     3416        return e;
     3417}
     3418/*}}}1*/
     3419        /*FUNCTION Triangles::MakeQuadrangles{{{1*/
     3420        void Triangles::MakeQuadrangles(double costheta){
     3421                long int verbosity=0;
     3422
     3423                if (verbosity>2) printf("MakeQuadrangles costheta = %g\n",costheta);
     3424
     3425                if (costheta >1) {
     3426                        if (verbosity>5) printf("   do nothing: costheta > 1\n");
     3427                }
     3428
     3429
     3430                        Int4 nbqq = (nbt*3)/2;
     3431                        DoubleAndInt4  *qq = new DoubleAndInt4[nbqq];
     3432
     3433                        Int4 i,ij;
     3434                        int j;
     3435                        Int4 k=0;
     3436                        for (i=0;i<nbt;i++)
     3437                         for (j=0;j<3;j++)
     3438                          if ((qq[k].q=triangles[i].QualityQuad(j))>=costheta)
     3439                                qq[k++].i3j=i*3+j;
     3440                        //  sort  qq
     3441                        HeapSort(qq,k);
     3442
     3443                        Int4 kk=0;
     3444                        for (ij=0;ij<k;ij++) {
     3445                                i=qq[ij].i3j/3;
     3446                                j=(int) (qq[ij].i3j%3);
     3447                                // optisamition no float computation 
     3448                                if (triangles[i].QualityQuad(j,0) >=costheta)
     3449                                 triangles[i].SetHidden(j),kk++;
     3450                          }
     3451                        NbOfQuad = kk;
     3452                        if (verbosity>2){
     3453                                printf("   number of quadrilaterals    = %i\n",NbOfQuad);
     3454                                printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
     3455                                printf("   number of outside triangles = %i\n",NbOutT);
     3456                        }
     3457                        delete [] qq;
     3458        }
     3459        /*}}}1*/
     3460/*FUNCTION Triangles::MakeQuadTree{{{1*/
     3461void Triangles::MakeQuadTree() { 
     3462        long int verbosity=0;
     3463        if (  !quadtree )  quadtree = new QuadTree(this);
     3464
     3465}
     3466/*}}}1*/
     3467/*FUNCTION Triangles::MaxSubDivision{{{1*/
     3468void  Triangles::MaxSubDivision(Real8 maxsubdiv) {
     3469        long int verbosity=0;
     3470
     3471        const  Real8 maxsubdiv2 = maxsubdiv*maxsubdiv;
     3472        if(verbosity>1) printf("   Limit the subdivision of a edges in the new mesh by %g\n",maxsubdiv);
     3473        // for all the edges
     3474        // if the len of the edge is to long
     3475        Int4 it,nbchange=0;   
     3476        Real8 lmax=0;
     3477        for (it=0;it<nbt;it++)
     3478          {
     3479                Triangle &t=triangles[it];
     3480                for (int j=0;j<3;j++)
     3481                  {
     3482                        Triangle &tt = *t.TriangleAdj(j);
     3483                        if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link))
     3484                          {
     3485                                Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
     3486                                Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
     3487                                R2 AB= (R2) v1-(R2) v0;
     3488                                Metric M = v0;
     3489                                Real8 l = M(AB,AB);
     3490                                lmax = Max(lmax,l);
     3491                                if(l> maxsubdiv2)
     3492                                  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
     3493                                        Real8 lc = M(AC,AC);
     3494                                        D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
     3495                                        D2xD2 Rt1(Rt.inv());
     3496                                        D2xD2 D(maxsubdiv2,0,0,lc);
     3497                                        D2xD2 MM = Rt1*D*Rt1.t();
     3498                                        v0.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
     3499                                        nbchange++;
     3500                                  }
     3501                                M = v1;
     3502                                l = M(AB,AB);
     3503                                lmax = Max(lmax,l);
     3504                                if(l> maxsubdiv2)
     3505                                  { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
     3506                                        Real8 lc = M(AC,AC);
     3507                                        D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
     3508                                        D2xD2 Rt1(Rt.inv());
     3509                                        D2xD2 D(maxsubdiv2,0,0,lc);
     3510                                        D2xD2  MM = Rt1*D*Rt1.t();
     3511                                        v1.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
     3512                                        nbchange++;
     3513                                  }
     3514
     3515
     3516                          }
     3517                  }
     3518          }
     3519        if(verbosity>3){
     3520                printf("      number of metric changes = %i, maximum number of subdivision of a edges before change = %g\n",nbchange,pow(lmax,0.5));
     3521        }
     3522}
     3523/*}}}1*/
     3524        /*FUNCTION Triangles::MetricAt{{{1*/
     3525        Metric Triangles::MetricAt(const R2 & A) const {
     3526                I2 a = toI2(A);
     3527                Icoor2 deta[3];
     3528                Triangle * t =FindTriangleContening(a,deta);
     3529                if (t->det <0) { // outside
     3530                        double ba,bb;
     3531                        TriangleAdjacent edge= CloseBoundaryEdge(a,t,ba,bb) ;
     3532                        return Metric(ba,*edge.EdgeVertex(0),bb,*edge.EdgeVertex(1));}
     3533                else { // inside
     3534                        Real8   aa[3];
     3535                        Real8 s = deta[0]+deta[1]+deta[2];
     3536                        aa[0]=deta[0]/s;
     3537                        aa[1]=deta[1]/s;
     3538                        aa[2]=deta[2]/s;
     3539                        return Metric(aa,(*t)[0],(*t)[1],(*t)[2]);
     3540                }
     3541        }
     3542        /*}}}1*/
     3543/*FUNCTION Triangles::NearestVertex{{{1*/
     3544Vertex * Triangles::NearestVertex(Icoor1 i,Icoor1 j) {
     3545        return  quadtree->NearestVertex(i,j);
     3546}
     3547/*}}}1*/
     3548        /*FUNCTION Triangles::NewPoints{{{1*/
     3549        void  Triangles::NewPoints(Triangles & Bh,int KeepBackVertex) {
     3550                long int verbosity=2;
     3551                Int4 nbtold(nbt),nbvold(nbv);
     3552                if (verbosity>2)  printf("   Triangles::NewPoints\n");
     3553                Int4 i,k;
     3554                int j;
     3555                Int4 *first_np_or_next_t = new Int4[nbtx];
     3556                Int4 NbTSwap =0;
     3557                //    insert old point
     3558                nbtold = nbt;
     3559
     3560                if (KeepBackVertex && (&Bh != this) && (nbv+Bh.nbv< nbvx)){
     3561                        //   Bh.SetVertexFieldOn();
     3562                        for (i=0;i<Bh.nbv;i++)
     3563                          {
     3564                                Vertex & bv = Bh[i];
     3565                                if (!bv.on) {
     3566                                        vertices[nbv].r = bv.r;
     3567                                        vertices[nbv++].m = bv.m;}
     3568                          }
     3569                        int nbv1=nbv;
     3570                        Bh.ReMakeTriangleContainingTheVertex();     
     3571                        InsertNewPoints(nbvold,NbTSwap)   ;           
     3572                } 
     3573                else
     3574                 Bh.ReMakeTriangleContainingTheVertex();     
     3575
     3576                Triangle *t;
     3577                // generation of the list of next Triangle
     3578                // at 1 time we test all the triangles
     3579                Int4 Headt =0,next_t;
     3580                for(i=0;i<nbt;i++)
     3581                 first_np_or_next_t[i]=-(i+1);
     3582                // end list i >= nbt
     3583                // the list of test triangle is
     3584                // the next traingle on i is  -first_np_or_next_t[i]
     3585                int iter=0;
     3586                // Big loop
    38953587                do {
    3896                         while (t->swap(j,koption))
    3897                           {
    3898                                 NbSwap++;
    3899                                 k++;
    3900                                 if (k>=20000){
    3901                                         throw ErrorException(__FUNCT__,exprintf("k>=20000"));
     3588                        iter++;
     3589                        nbtold = nbt;
     3590                        nbvold = nbv;
     3591
     3592                        // default size of  IntersectionTriangle
     3593
     3594                        i=Headt;
     3595                        next_t=-first_np_or_next_t[i];
     3596                        for(t=&triangles[i];i<nbt;t=&triangles[i=next_t],next_t=-first_np_or_next_t[i])
     3597                          { // for each triangle  t
     3598                                // we can change first_np_or_next_t[i]
     3599                                if (i<0 || i>=nbt ){
     3600                                        throw ErrorException(__FUNCT__,exprintf("i<0 || i>=nbt"));
    39023601                                }
    3903                                 t=  tp->at[jp];      // set unchange t qnd j for previous triangles
    3904                                 j=  NextEdge[tp->aa[jp]&3];
    3905                           }
    3906                         // end on this  Triangle
    3907                         tp = t;
    3908                         jp = NextEdge[j];
    3909 
     3602                                first_np_or_next_t[i] = iter;
     3603                                for(j=0;j<3;j++)
     3604                                  { // for each edge
     3605                                        TriangleAdjacent tj(t,j);
     3606                                        Vertex & vA = * tj.EdgeVertex(0);
     3607                                        Vertex & vB = * tj.EdgeVertex(1);
     3608
     3609                                        if (!t->link) continue;// boundary
     3610                                        if (t->det <0) continue;
     3611                                        if (t->Locked(j)) continue;
     3612
     3613                                        TriangleAdjacent tadjj = t->Adj(j);       
     3614                                        Triangle * ta= tadjj;
     3615
     3616                                        if (ta->det <0) continue;         
     3617
     3618                                        R2 A = vA;
     3619                                        R2 B = vB;
     3620
     3621                                        k=Number(ta);
     3622
     3623                                        if(first_np_or_next_t[k]==iter)  // this edge is done before
     3624                                         continue; // next edge of the triangle
     3625
     3626                                        //const Int4 NbvOld = nbv;
     3627                                        lIntTria.SplitEdge(Bh,A,B);
     3628                                        lIntTria.NewPoints(vertices,nbv,nbvx);
     3629                                  } // end loop for each edge
     3630
     3631                          }// for triangle   
     3632
     3633                        if (!InsertNewPoints(nbvold,NbTSwap))
     3634                         break;
     3635
     3636                        for (i=nbtold;i<nbt;i++)
     3637                         first_np_or_next_t[i]=iter;
     3638
     3639                        Headt = nbt; // empty list
     3640                        for (i=nbvold;i<nbv;i++)
     3641                          { // for all the triangle contening the vertex i
     3642                                Vertex * s  = vertices + i;
     3643                                TriangleAdjacent ta(s->t, EdgesVertexTriangle[s->vint][1]);
     3644                                Triangle * tbegin= (Triangle*) ta;
     3645                                Int4 kt;
     3646                                do {
     3647                                        kt = Number((Triangle*) ta);
     3648                                        if (first_np_or_next_t[kt]>0)
     3649                                         first_np_or_next_t[kt]=-Headt,Headt=kt;
     3650                                        if (ta.EdgeVertex(0)!=s){
     3651                                                throw ErrorException(__FUNCT__,exprintf("ta.EdgeVertex(0)!=s"));
     3652                                        }
     3653                                        ta = Next(Adj(ta));
     3654                                } while ( (tbegin != (Triangle*) ta));
     3655                          }   
     3656
     3657                } while (nbv!=nbvold);
     3658
     3659                delete []  first_np_or_next_t;
     3660
     3661                Int4 NbSwapf =0,NbSwp;
     3662
     3663                // bofbof
     3664
     3665
     3666                NbSwp = NbSwapf;
     3667                for (i=0;i<nbv;i++)
     3668                 NbSwapf += vertices[i].Optim(0);
     3669                /*
     3670                        for (i=0;i<nbv;i++)
     3671                        NbSwapf += vertices[i].Optim(0);
     3672                        for (i=0;i<nbv;i++)
     3673                        NbSwapf += vertices[i].Optim(0);
     3674                        for (i=0;i<nbv;i++)
     3675                        NbSwapf += vertices[i].Optim(0);
     3676                        for (i=0;i<nbv;i++)
     3677                        NbSwapf += vertices[i].Optim(0);
     3678                        */
     3679                NbTSwap +=  NbSwapf ;
     3680        }
     3681        /*}}}1*/
     3682/*FUNCTION Triangles::Optim{{{1*/
     3683Int4  Triangle::Optim(Int2 i,int koption) {
     3684        // turne around in positif sens
     3685        Int4 NbSwap =0;
     3686        Triangle  *t = this;
     3687        int k=0,j =OppositeEdge[i];
     3688        int jp = PreviousEdge[j];
     3689        // initialise   tp, jp the previous triangle & edge
     3690        Triangle *tp= at[jp];
     3691        jp = aa[jp]&3;
     3692        do {
     3693                while (t->swap(j,koption))
     3694                  {
     3695                        NbSwap++;
     3696                        k++;
     3697                        if (k>=20000){
     3698                                throw ErrorException(__FUNCT__,exprintf("k>=20000"));
     3699                        }
    39103700                        t=  tp->at[jp];      // set unchange t qnd j for previous triangles
    39113701                        j=  NextEdge[tp->aa[jp]&3];
    3912 
    3913                 } while( t != this);
    3914                 return NbSwap;
     3702                  }
     3703                // end on this  Triangle
     3704                tp = t;
     3705                jp = NextEdge[j];
     3706
     3707                t=  tp->at[jp];      // set unchange t qnd j for previous triangles
     3708                j=  NextEdge[tp->aa[jp]&3];
     3709
     3710        } while( t != this);
     3711        return NbSwap;
     3712}
     3713/*}}}1*/
     3714/*FUNCTION Triangles::PreInit{{{1*/
     3715void Triangles::PreInit(Int4 inbvx,char *fname) {
     3716        long int verbosity=0;
     3717
     3718        srand(19999999);
     3719        NbRef=0;
     3720        //  allocGeometry=0;
     3721        identity=0;
     3722        NbOfTriangleSearchFind =0;
     3723        NbOfSwapTriangle =0;
     3724        nbiv=0;
     3725        nbv=0;
     3726        nbvx=inbvx;
     3727        nbt=0;
     3728        NbOfQuad = 0;
     3729        nbtx=2*inbvx-2;
     3730        NbSubDomains=0;
     3731        NbVertexOnBThVertex=0;
     3732        NbVertexOnBThEdge=0;
     3733        VertexOnBThVertex=0;
     3734        VertexOnBThEdge=0;
     3735
     3736        NbCrackedVertices=0;
     3737        NbCrackedEdges =0;
     3738        CrackedEdges  =0; 
     3739        nbe = 0;
     3740        name = fname ;
     3741
     3742        if (inbvx) {
     3743                vertices=new Vertex[nbvx];
     3744                if (!vertices){
     3745                        throw ErrorException(__FUNCT__,exprintf("!vertices"));
     3746                }
     3747                ordre=new (Vertex* [nbvx]);
     3748                if (!ordre){
     3749                        throw ErrorException(__FUNCT__,exprintf("!ordre"));
     3750                }
     3751                triangles=new Triangle[nbtx];
     3752                if (!triangles){
     3753                        throw ErrorException(__FUNCT__,exprintf("!triangles"));
     3754                }
     3755        }
     3756        else {
     3757                vertices=0;
     3758                ordre=0;
     3759                triangles=0;
     3760                nbtx=0;
     3761        }
     3762        if ( name || inbvx) {
     3763                time_t timer =time(0);
     3764                char buf[70];     
     3765                strftime(buf ,70,", Date: %y/%m/%d %H:%M %Ss",localtime(&timer));
     3766                counter++;
     3767                char countbuf[30];   
     3768                sprintf(countbuf,"%d",counter);
     3769                int lg =0 ;
     3770                if (&BTh != this && BTh.name)
     3771                 lg = strlen(BTh.name)+4;
     3772                identity = new char[ lg + strlen(buf) + strlen(countbuf)+ 2  + 10 + ( Gh.name ? strlen(Gh.name) + 4 : 0)];
     3773                identity[0]=0;
     3774                if (lg)
     3775                 strcat(strcat(strcat(identity,"B="),BTh.name),", ");
     3776
     3777                if (Gh.name)
     3778                 strcat(strcat(identity,"G="),Gh.name);
     3779                strcat(strcat(identity,";"),countbuf);
     3780                strcat(identity,buf);
     3781        }
     3782
     3783        quadtree=0;
     3784        edges=0;
     3785        VerticesOnGeomVertex=0;
     3786        VerticesOnGeomEdge=0;
     3787        NbVerticesOnGeomVertex=0;
     3788        NbVerticesOnGeomEdge=0;
     3789        subdomains=0;
     3790        NbSubDomains=0;
     3791}
     3792/*}}}1*/
     3793        /*FUNCTION Triangles::ProjectOnCurve{{{1*/
     3794        GeometricalEdge*   Triangles::ProjectOnCurve( Edge & BhAB, Vertex &  vA, Vertex & vB,
     3795                                Real8 theta,Vertex & R,VertexOnEdge &  BR,VertexOnGeom & GR) {
     3796                void *pA=0,*pB=0;
     3797                Real8 tA=0,tB=0;
     3798                R2 A=vA,B=vB;
     3799                Vertex * pvA=&vA, * pvB=&vB;
     3800                if (vA.vint == IsVertexOnVertex){
     3801                        pA=vA.onbv;
     3802                }
     3803                else if (vA.vint == IsVertexOnEdge){
     3804                        pA=vA.onbe->be;
     3805                        tA=vA.onbe->abcisse;
     3806                }
     3807                else {
     3808                        throw ErrorException(__FUNCT__,exprintf("ProjectOnCurve On Vertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vA)));
     3809                }
     3810
     3811                if (vB.vint == IsVertexOnVertex){
     3812                        pB=vB.onbv;
     3813                }
     3814                else if(vB.vint == IsVertexOnEdge){
     3815                        pB=vB.onbe->be;
     3816                        tB=vB.onbe->abcisse;
     3817                }
     3818                else {
     3819                        throw ErrorException(__FUNCT__,exprintf("ProjectOnCurve On Vertex %i forget call to SetVertexFieldOnBTh",BTh.Number(vB)));
     3820                }
     3821                Edge * e = &BhAB;
     3822                if (!pA || !pB || !e){
     3823                        throw ErrorException(__FUNCT__,exprintf("!pA || !pB || !e"));
     3824                }
     3825                // be carefull the back ground edge e is on same geom edge
     3826                // of the initiale edge def by the 2 vertex A B;
     3827                //check Is a background Mesh;   
     3828                if (e<BTh.edges || e>=BTh.edges+BTh.nbe){
     3829                        throw ErrorException(__FUNCT__,exprintf("e<BTh.edges || e>=BTh.edges+BTh.nbe"));
     3830                }
     3831                // walk on BTh edge
     3832                //not finish ProjectOnCurve with BackGround Mesh);
     3833                // 1 first find a back ground edge contening the vertex A
     3834                // 2 walk n back gound boundary to find the final vertex B
     3835
     3836                if( vA.vint == IsVertexOnEdge)
     3837                  { // find the start edge
     3838                        e = vA.onbe->be;         
     3839
     3840                  }
     3841                else if (vB.vint == IsVertexOnEdge)
     3842                  {
     3843                        theta = 1-theta;
     3844                        Exchange(tA,tB);
     3845                        Exchange(pA,pB);
     3846                        Exchange(pvA,pvB);
     3847                        Exchange(A,B);
     3848                        e =  vB.onbe->be;
     3849
     3850                  }
     3851                else{ // do the search by walking
     3852                        throw ErrorException(__FUNCT__,exprintf("case not supported yet"));
     3853                  }
     3854
     3855                // find the direction of walking with sens of edge and pA,PB;
     3856                R2 AB=B-A;
     3857
     3858                Real8 cosE01AB = (( (R2) (*e)[1] - (R2) (*e)[0] ) , AB);
     3859                int kkk=0;
     3860                int sens = (cosE01AB>0) ? 1 : 0;
     3861
     3862                //   Real8 l=0; // length of the edge AB
     3863                Real8 abscisse = -1;
     3864
     3865                for (int cas=0;cas<2;cas++){
     3866                        // 2 times algo:
     3867                        //    1 for computing the length l
     3868                        //    2 for find the vertex
     3869                        int  iii;
     3870                        Vertex  *v0=pvA,*v1;
     3871                        Edge *neee,*eee;
     3872                        Real8 lg =0; // length of the curve
     3873                        Real8 te0;
     3874                        // we suppose take the curve's abcisse
     3875                        for ( eee=e,iii=sens,te0=tA;
     3876                                                eee && ((( void*) eee) != pB) && (( void*) (v1=&((*eee)[iii]))) != pB ;
     3877                                                neee = eee->adj[iii],iii = 1-neee->Intersection(*eee),eee = neee,v0=v1,te0=1-iii ) {
     3878
     3879                                kkk=kkk+1;
     3880                                if (kkk>=100){
     3881                                        throw ErrorException(__FUNCT__,exprintf("kkk>=100"));
     3882                                }
     3883                                if (!eee){
     3884                                        throw ErrorException(__FUNCT__,exprintf("!eee"));
     3885                                }
     3886                                Real8 lg0 = lg;
     3887                                Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
     3888                                lg += dp;
     3889                                if (cas && abscisse <= lg) { // ok we find the geom edge
     3890                                        Real8 sss  =   (abscisse-lg0)/dp;
     3891                                        Real8 thetab = te0*(1-sss)+ sss*iii;
     3892                                        if (thetab<0 || thetab>1){
     3893                                                throw ErrorException(__FUNCT__,exprintf("thetab<0 || thetab>1"));
     3894                                        }
     3895                                        BR = VertexOnEdge(&R,eee,thetab);
     3896                                        return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
     3897                                  }
     3898                          }
     3899                        // we find the end
     3900                        if (v1 != pvB){
     3901                                if (( void*) v1 == pB)
     3902                                 tB = iii;
     3903
     3904                                Real8 lg0 = lg;
     3905                                if (!eee){
     3906                                        throw ErrorException(__FUNCT__,exprintf("!eee"));
     3907                                }
     3908                                v1 = pvB;
     3909                                Real8 dp = LengthInterpole(v0->m,v1->m,(R2) *v1 - (R2) *v0);
     3910                                lg += dp;       
     3911                                abscisse = lg*theta;
     3912                                if (abscisse <= lg && abscisse >= lg0 ) // small optimisation we know the lenght because end
     3913                                  { // ok we find the geom edge
     3914                                        Real8 sss  =   (abscisse-lg0)/dp;
     3915                                        Real8 thetab = te0*(1-sss)+ sss*tB;
     3916                                        if (thetab<0 || thetab>1){
     3917                                                throw ErrorException(__FUNCT__,exprintf("thetab<0 || thetab>1"));
     3918                                        }
     3919                                        BR = VertexOnEdge(&R,eee,thetab);
     3920                                        return  Gh.ProjectOnCurve(*eee,thetab,R,GR);
     3921                                  }
     3922                          }
     3923                        abscisse = lg*theta;
     3924
     3925                  }
     3926                throw ErrorException(__FUNCT__,exprintf("Big bug..."));
     3927                return 0; // just for the compiler
     3928        }                 
     3929        /*}}}1*/
     3930        /*FUNCTION Triangles::ReNumberingTheTriangleBySubDomain{{{1*/
     3931        void Triangles::ReNumberingTheTriangleBySubDomain(bool justcompress) {
     3932                long int verbosity=0;
     3933                Int4 *renu= new Int4[nbt];
     3934                register Triangle *t0,*t,*te=triangles+nbt;
     3935                register Int4 k=0,it,i,j;
     3936
     3937                for ( it=0;it<nbt;it++)
     3938                 renu[it]=-1; // outside triangle
     3939                for ( i=0;i<NbSubDomains;i++)
     3940                  {
     3941                        t=t0=subdomains[i].head;
     3942                        if (!t0){ // not empty sub domain
     3943                                throw ErrorException(__FUNCT__,exprintf("!t0"));
     3944                        }
     3945                        do {
     3946                                Int4 kt = Number(t);
     3947                                if (kt<0 || kt >= nbt ){
     3948                                        throw ErrorException(__FUNCT__,exprintf("kt<0 || kt >= nbt"));
     3949                                }
     3950                                if (renu[kt]!=-1){
     3951                                        throw ErrorException(__FUNCT__,exprintf("renu[kt]!=-1"));
     3952                                }
     3953                                renu[kt]=k++;
     3954                        }
     3955                        while (t0 != (t=t->link));
     3956                  }
     3957                // take is same numbering if possible   
     3958                if(justcompress)
     3959                 for ( k=0,it=0;it<nbt;it++)
     3960                  if(renu[it] >=0 )
     3961                        renu[it]=k++;
     3962
     3963                // put the outside triangles at the end
     3964                for ( it=0;it<nbt;it++){
     3965                        if (renu[it]==-1) renu[it]=k++;
     3966                }
     3967                if (k != nbt){
     3968                        throw ErrorException(__FUNCT__,exprintf("k != nbt"));
     3969                }
     3970                // do the change on all the pointeur
     3971                for ( it=0;it<nbt;it++)
     3972                 triangles[it].ReNumbering(triangles,te,renu);
     3973
     3974                for ( i=0;i<NbSubDomains;i++)
     3975                 subdomains[i].head=triangles+renu[Number(subdomains[i].head)];
     3976
     3977                // move the Triangles  without a copy of the array
     3978                // be carefull not trivial code
     3979                for ( it=0;it<nbt;it++) // for all sub cycles of the permutation renu
     3980                 if (renu[it] >= 0) // a new sub cycle
     3981                        {
     3982                         i=it;
     3983                         Triangle ti=triangles[i],tj;
     3984                         while ( (j=renu[i]) >= 0)
     3985                                { // i is old, and j is new
     3986                                 renu[i] = -1; // mark
     3987                                 tj = triangles[j]; // save new
     3988                                 triangles[j]= ti; // new <- old
     3989                                 i=j;     // next
     3990                                 ti = tj;
     3991                                } 
     3992                        }
     3993                delete [] renu;
     3994                nt = nbt - NbOutT;
     3995
    39153996        }
    39163997        /*}}}1*/
    3917         /*FUNCTION Triangles::SmoothingVertex{{{1*/
    3918         void Triangles::SmoothingVertex(int nbiter,Real8 omega ) {
    3919                 long int verbosity=0;
    3920                 //  if quatree exist remove it end reconstruct
    3921                 if (quadtree) delete quadtree;
    3922                 quadtree=0;
    3923                 ReMakeTriangleContainingTheVertex();
    3924                 Triangle vide; // a triangle to mark the boundary vertex
    3925                 Triangle   ** tstart= new Triangle* [nbv];
    3926                 Int4 i,j,k;
    3927                 //   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide
    3928                 if ( this == & BTh)
    3929                  for ( i=0;i<nbv;i++)
    3930                   tstart[i]=vertices[i].t;     
    3931                 else
    3932                  for ( i=0;i<nbv;i++)
    3933                   tstart[i]=0;
    3934                 for ( j=0;j<NbVerticesOnGeomVertex;j++ )
    3935                  tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
    3936                 for ( k=0;k<NbVerticesOnGeomEdge;k++ )
    3937                  tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
    3938                 if(verbosity>2) printf("   SmoothingVertex: nb Iteration = %i, Omega=%g\n",nbiter,omega);
    3939                 for (k=0;k<nbiter;k++)
     3998        /*FUNCTION Triangles::ReNumberingVertex{{{1*/
     3999        void Triangles::ReNumberingVertex(Int4 * renu) {
     4000                // warning be carfull because pointeur
     4001                // from on mesh to over mesh
     4002                //  --  so do ReNumbering a the beginning
     4003                Vertex * ve = vertices+nbv;
     4004                Int4 it,ie,i;
     4005
     4006                for ( it=0;it<nbt;it++)
     4007                 triangles[it].ReNumbering(vertices,ve,renu);
     4008
     4009                for ( ie=0;ie<nbe;ie++)
     4010                 edges[ie].ReNumbering(vertices,ve,renu);
     4011
     4012                for (i=0;i< NbVerticesOnGeomVertex;i++)
    39404013                  {
    3941                         Int4 i,NbSwap =0;
    3942                         Real8 delta =0;
    3943                         for ( i=0;i<nbv;i++)
    3944                          if (tstart[i] != &vide) // not a boundary vertex
    3945                           delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
    3946                         if (!NbOfQuad)
    3947                          for ( i=0;i<nbv;i++)
    3948                           if (tstart[i] != &vide) // not a boundary vertex
    3949                                 NbSwap += vertices[i].Optim(1);
    3950                         if (verbosity>3) printf("      move max = %g, iteration = %i, nb of swap = %i\n",pow(delta,0.5),k,NbSwap);
     4014                        Vertex *v = VerticesOnGeomVertex[i].mv;
     4015                        if (v>=vertices && v < ve)
     4016                         VerticesOnGeomVertex[i].mv=vertices+renu[Number(v)];
    39514017                  }
    39524018
    3953                 delete [] tstart;
    3954                 if (quadtree) quadtree= new QuadTree(this);
     4019                for (i=0;i< NbVerticesOnGeomEdge;i++)
     4020                  {
     4021                        Vertex *v =VerticesOnGeomEdge[i].mv;
     4022                        if (v>=vertices && v < ve)
     4023                         VerticesOnGeomEdge[i].mv=vertices+renu[Number(v)];
     4024                  }
     4025
     4026                for (i=0;i< NbVertexOnBThVertex;i++)
     4027                  {
     4028                        Vertex *v=VertexOnBThVertex[i].v;
     4029                        if (v>=vertices && v < ve)
     4030                         VertexOnBThVertex[i].v=vertices+renu[Number(v)];
     4031                  }
     4032
     4033                for (i=0;i< NbVertexOnBThEdge;i++)
     4034                  {
     4035                        Vertex *v=VertexOnBThEdge[i].v;
     4036                        if (v>=vertices && v < ve)
     4037                         VertexOnBThEdge[i].v=vertices+renu[Number(v)];
     4038                  }
     4039
     4040                // move the Vertices without a copy of the array
     4041                // be carefull not trivial code
     4042                Int4 j;
     4043                for ( it=0;it<nbv;it++) // for all sub cycles of the permutation renu
     4044                 if (renu[it] >= 0) // a new sub cycle
     4045                        {
     4046                         i=it;
     4047                         Vertex ti=vertices[i],tj;
     4048                         while ( (j=renu[i]) >= 0)
     4049                                { // i is old, and j is new
     4050                                 renu[i] = -1-renu[i]; // mark
     4051                                 tj = vertices[j]; // save new
     4052                                 vertices[j]= ti; // new <- old
     4053                                 i=j;     // next
     4054                                 ti = tj;
     4055                                } 
     4056                        }
     4057                if (quadtree)
     4058                  {  delete quadtree;
     4059                        quadtree = new QuadTree(this);
     4060                  }
     4061                for ( it=0;it<nbv;it++)
     4062                 renu[i]= -renu[i]-1;
     4063
    39554064        }
    39564065        /*}}}1*/
    3957         /*FUNCTION Triangles::MakeQuadTree{{{1*/
    3958         void Triangles::MakeQuadTree() { 
     4066/*FUNCTION Triangles::SetIntCoor{{{1*/
     4067void Triangles::SetIntCoor(const char * strfrom) {
     4068        pmin =  vertices[0].r;
     4069        pmax =  vertices[0].r;
     4070
     4071        // recherche des extrema des vertices pmin,pmax
     4072        Int4 i;
     4073        for (i=0;i<nbv;i++) {
     4074                pmin.x = Min(pmin.x,vertices[i].r.x);
     4075                pmin.y = Min(pmin.y,vertices[i].r.y);
     4076                pmax.x = Max(pmax.x,vertices[i].r.x);
     4077                pmax.y = Max(pmax.y,vertices[i].r.y);
     4078        }
     4079        R2 DD = (pmax-pmin)*0.05;
     4080        pmin = pmin-DD;
     4081        pmax = pmax+DD;
     4082        coefIcoor= (MaxICoor)/(Max(pmax.x-pmin.x,pmax.y-pmin.y));
     4083        if (coefIcoor<=0){
     4084                throw ErrorException(__FUNCT__,exprintf("coefIcoor<=0"));
     4085        }
     4086
     4087        // generation of integer coord 
     4088        for (i=0;i<nbv;i++) {
     4089                vertices[i].i = toI2(vertices[i].r);   
     4090        }
     4091
     4092        // computation of the det
     4093        int Nberr=0;
     4094        for (i=0;i<nbt;i++) {
     4095                Vertex & v0 = triangles[i][0];
     4096                Vertex & v1 = triangles[i][1];
     4097                Vertex & v2 = triangles[i][2];
     4098                if ( &v0 && &v1 &&  &v2 ) // a good triangles;
     4099                  {
     4100                        triangles[i].det= det(v0,v1,v2);
     4101                        if (triangles[i].det <=0 && Nberr++ <10){
     4102                                if(Nberr==1)
     4103                                 if (strfrom){
     4104                                         throw ErrorException(__FUNCT__,exprintf("Fatal error %s (SetInCoor) : area of Triangle %i < 0",strfrom,i));
     4105                                 }
     4106                                 else{
     4107                                         throw ErrorException(__FUNCT__,exprintf("Fatal error (SetInCoor) : area of Triangle %i < 0",i));
     4108                                 }
     4109                        }
     4110                  }
     4111                else triangles[i].det= -1; // Null triangle;
     4112        }
     4113}
     4114/*}}}1*/
     4115/*FUNCTION Triangles::ShowRegulaty{{{1*/
     4116void  Triangles::ShowRegulaty() const {
     4117        const  Real8  sqrt32=sqrt(3.)*0.5;
     4118        const Real8  aireKh=sqrt32*0.5;
     4119        D2  Beq(1,0),Heq(0.5,sqrt32);
     4120        D2xD2 Br(D2xD2(Beq,Heq).t());
     4121        D2xD2 B1r(Br.inv());
     4122        double gammamn=1e100,hmin=1e100;
     4123        double gammamx=0,hmax=0;
     4124        double beta=1e100;
     4125        double beta0=0;
     4126        double  alpha2=0;
     4127        double area=0,Marea=0;
     4128        // Real8 cf= Real8(coefIcoor);
     4129        // Real8 cf2= 6.*cf*cf;
     4130        int nt=0;
     4131        for (int it=0;it<nbt;it++)
     4132         if ( triangles[it].link)
     4133                {
     4134                 nt++;
     4135                 Triangle &K=triangles[it];
     4136                 Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
     4137                 area+= area3;
     4138                 D2xD2 B_Kt(K[0],K[1],K[2]);
     4139                 D2xD2 B_K(B_Kt.t());
     4140                 D2xD2 B1K = Br*B_K.inv();
     4141                 D2xD2 BK =  B_K*B1r;
     4142                 D2xD2 B1B1 = B1K.t()*B1K;
     4143                 MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
     4144                 MatVVP2x2 VMK(MK);
     4145                 alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
     4146                 Real8 betaK=0;
     4147
     4148                 for (int j=0;j<3;j++)
     4149                        {
     4150                         Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
     4151                         hmin=Min(hmin,he);
     4152                         hmax=Max(hmax,he);
     4153                         Vertex & v=K[j];
     4154                         D2xD2 M((MetricAnIso)v);
     4155                         betaK += sqrt(M.det());
     4156
     4157                         D2xD2 BMB = BK.t()*M*BK;
     4158                         MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
     4159                         MatVVP2x2 VM1(M1);
     4160                         gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
     4161                         gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);         
     4162                        }
     4163                 betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
     4164                 Marea+= betaK;
     4165                 beta=min(beta,betaK);
     4166                 beta0=max(beta0,betaK);
     4167                }   
     4168        area*=3;
     4169        gammamn=sqrt(gammamn);
     4170        gammamx=sqrt(gammamx);   
     4171        printf("   Adaptmesh info:\n");
     4172        printf("      number of triangles = %i\n",nt);
     4173        printf("      hmin = %g, hmax=%g\n",hmin,hmax);
     4174        printf("      area = %g, M area = %g, M area/( |Khat| nt) = %g\n",area,Marea, Marea/(aireKh*nt));
     4175        printf("      infinite-regularity(?): min = %g, max = %g\n",gammamn,gammamx);
     4176        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));
     4177}
     4178/*}}}1*/
     4179/*FUNCTION Triangles::ShowHistogram{{{1*/
     4180void  Triangles::ShowHistogram() const {
     4181
     4182        const Int4 kmax=10;
     4183        const Real8 llmin = 0.5,llmax=2;
     4184        const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
     4185        Int4 histo[kmax+1];
     4186        Int4 i,it,k, nbedges =0;
     4187        for (i=0;i<=kmax;i++) histo[i]=0;
     4188        for (it=0;it<nbt;it++)
     4189         if ( triangles[it].link)
     4190                {
     4191
     4192                 for (int j=0;j<3;j++)
     4193                        {
     4194                         Triangle *ta = triangles[it].TriangleAdj(j);
     4195                         if ( !ta || !ta->link || Number(ta) >= it)
     4196                                {
     4197                                 Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
     4198                                 Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
     4199                                 if ( !& vP || !&vQ) continue;
     4200                                 R2 PQ = vQ.r - vP.r;
     4201                                 Real8 l = log(LengthInterpole(vP,vQ,PQ));
     4202                                 nbedges++;
     4203                                 k = (int) ((l - lmin)*delta);
     4204                                 k = Min(Max(k,0L),kmax);
     4205                                 histo[k]++;
     4206                                }
     4207                        }
     4208                } 
     4209        printf(" --- Histogram of the unit mesh,  nb of edges = %i\n",nbedges);
     4210        printf("      length of edge in   | %% of edge  | Nb of edges \n");
     4211        printf("      --------------------+-------------+-------------\n");
     4212        for   (i=0;i<=kmax;i++){
     4213                if (i==0) printf("      %10i",0);
     4214                else      printf("      %10g",exp(lmin+i/delta));
     4215                if (i==kmax) printf("          +inf   ");
     4216                else printf("      %10g",exp(lmin+(i+1)/delta));
     4217                printf("|  %10g |\n",((long)  ((10000.0 * histo[i])/ nbedges))/100.0);
     4218                printf("  %g\n",histo[i]);
     4219        }
     4220        printf("      --------------------+-------------+-------------\n");
     4221}
     4222/*}}}1*/
     4223/*FUNCTION Triangles::SmoothingVertex{{{1*/
     4224void Triangles::SmoothingVertex(int nbiter,Real8 omega ) {
     4225        long int verbosity=0;
     4226        //  if quatree exist remove it end reconstruct
     4227        if (quadtree) delete quadtree;
     4228        quadtree=0;
     4229        ReMakeTriangleContainingTheVertex();
     4230        Triangle vide; // a triangle to mark the boundary vertex
     4231        Triangle   ** tstart= new Triangle* [nbv];
     4232        Int4 i,j,k;
     4233        //   attention si Background == Triangle alors on ne peut pas utiliser la rechech rapide
     4234        if ( this == & BTh)
     4235         for ( i=0;i<nbv;i++)
     4236          tstart[i]=vertices[i].t;     
     4237        else
     4238         for ( i=0;i<nbv;i++)
     4239          tstart[i]=0;
     4240        for ( j=0;j<NbVerticesOnGeomVertex;j++ )
     4241         tstart[ Number(VerticesOnGeomVertex[j].mv)]=&vide;
     4242        for ( k=0;k<NbVerticesOnGeomEdge;k++ )
     4243         tstart[ Number(VerticesOnGeomEdge[k].mv)]=&vide;
     4244        if(verbosity>2) printf("   SmoothingVertex: nb Iteration = %i, Omega=%g\n",nbiter,omega);
     4245        for (k=0;k<nbiter;k++)
     4246          {
     4247                Int4 i,NbSwap =0;
     4248                Real8 delta =0;
     4249                for ( i=0;i<nbv;i++)
     4250                 if (tstart[i] != &vide) // not a boundary vertex
     4251                  delta=Max(delta,vertices[i].Smoothing(*this,BTh,tstart[i],omega));
     4252                if (!NbOfQuad)
     4253                 for ( i=0;i<nbv;i++)
     4254                  if (tstart[i] != &vide) // not a boundary vertex
     4255                        NbSwap += vertices[i].Optim(1);
     4256                if (verbosity>3) printf("      move max = %g, iteration = %i, nb of swap = %i\n",pow(delta,0.5),k,NbSwap);
     4257          }
     4258
     4259        delete [] tstart;
     4260        if (quadtree) quadtree= new QuadTree(this);
     4261}
     4262/*}}}1*/
     4263/*FUNCTION Triangles::SmoothMetric{{{1*/
     4264void Triangles::SmoothMetric(Real8 raisonmax) {
     4265        long int verbosity=0;
     4266
     4267        if(raisonmax<1.1) return;
     4268        if(verbosity > 1) printf("   Triangles::SmoothMetric raisonmax = %g\n",raisonmax);
     4269        ReMakeTriangleContainingTheVertex();
     4270        Int4 i,j,kch,kk,ip;
     4271        Int4 *first_np_or_next_t0 = new Int4[nbv];
     4272        Int4 *first_np_or_next_t1 = new Int4[nbv];
     4273        Int4 Head0 =0,Head1=-1;
     4274        Real8 logseuil= log(raisonmax);
     4275
     4276        for(i=0;i<nbv-1;i++)
     4277         first_np_or_next_t0[i]=i+1;
     4278        first_np_or_next_t0[nbv-1]=-1;// end;
     4279        for(i=0;i<nbv;i++)
     4280         first_np_or_next_t1[i]=-1;
     4281        kk=0;
     4282        while (Head0>=0&& kk++<100) {
     4283                kch=0;
     4284                for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1) {
     4285                        //  pour tous les triangles autour du sommet s
     4286                        register Triangle* t= vertices[i].t;
     4287                        if (!t){
     4288                                throw ErrorException(__FUNCT__,exprintf("!t"));
     4289                        }
     4290                        Vertex & vi = vertices[i];
     4291                        TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
     4292                        Vertex *pvj0 = ta.EdgeVertex(0);
     4293                        while (1) {
     4294                                ta=Previous(Adj(ta));
     4295                                if (vertices+i != ta.EdgeVertex(1)){
     4296                                        throw ErrorException(__FUNCT__,exprintf("vertices+i != ta.EdgeVertex(1)"));
     4297                                }
     4298                                Vertex & vj = *(ta.EdgeVertex(0));
     4299                                if ( &vj ) {
     4300                                        j= &vj-vertices;
     4301                                        if (j<0 || j >= nbv){
     4302                                                throw ErrorException(__FUNCT__,exprintf("j<0 || j >= nbv"));
     4303                                        }
     4304                                        R2 Aij = (R2) vj - (R2) vi;
     4305                                        Real8 ll =  Norme2(Aij);
     4306                                        if (0) { 
     4307                                                Real8 hi = ll/vi.m(Aij);
     4308                                                Real8 hj = ll/vj.m(Aij);
     4309                                                if(hi < hj)
     4310                                                  {
     4311                                                        Real8 dh=(hj-hi)/ll;
     4312                                                        if (dh>logseuil) {
     4313                                                                vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
     4314                                                                if(first_np_or_next_t1[j]<0)
     4315                                                                 kch++,first_np_or_next_t1[j]=Head1,Head1=j;
     4316                                                        }
     4317                                                  }
     4318                                        }
     4319                                        else
     4320                                          {
     4321                                                Real8 li = vi.m(Aij);
     4322                                                if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
     4323                                                 if(first_np_or_next_t1[j]<0) // if the metrix change
     4324                                                  kch++,first_np_or_next_t1[j]=Head1,Head1=j;
     4325                                          }
     4326                                }
     4327                                if  ( &vj ==  pvj0 ) break;
     4328                        }
     4329                }
     4330                Head0 = Head1;
     4331                Head1 = -1;
     4332                Exchange(first_np_or_next_t0,first_np_or_next_t1);
     4333        }
     4334        if(verbosity>2) printf("      number of iterations = %i\n",kch);
     4335        delete [] first_np_or_next_t0;
     4336        delete [] first_np_or_next_t1;
     4337}
     4338/*}}}1*/
     4339        /*FUNCTION Triangles::SplitElement{{{1*/
     4340        int  Triangles::SplitElement(int choice){
    39594341                long int verbosity=0;
    3960                 if (  !quadtree )  quadtree = new QuadTree(this);
    3961 
     4342
     4343                Direction NoDirOfSearch;
     4344                const  int withBackground = &BTh != this && &BTh;
     4345
     4346                ReNumberingTheTriangleBySubDomain();
     4347                //int nswap =0;
     4348                const Int4 nfortria( choice ? 4 : 6);
     4349                if(withBackground)
     4350                  {
     4351                        BTh.SetVertexFieldOn();
     4352                        SetVertexFieldOnBTh();
     4353                  }
     4354                else
     4355                 BTh.SetVertexFieldOn();
     4356
     4357                Int4 newnbt=0,newnbv=0;
     4358                Int4 * kedge = 0;
     4359                Int4 newNbOfQuad=NbOfQuad;
     4360                Int4 * ksplit= 0, * ksplitarray=0;
     4361                Int4 kkk=0;
     4362                int ret =0;
     4363                if (nbvx<nbv+nbe) return 1;//   
     4364                Triangles *  OCurrentTh= CurrentTh;
     4365                CurrentTh = this;
     4366                // 1) create  the new points by spliting the internal edges
     4367                // set the
     4368                Int4 nbvold = nbv;
     4369                Int4 nbtold = nbt;
     4370                Int4 NbOutTold  = NbOutT;
     4371                Int4  NbEdgeOnGeom=0;
     4372                Int4 i;
     4373
     4374                nbt = nbt - NbOutT; // remove all the  the ouside triangles
     4375                Int4 nbtsave = nbt;
     4376                Triangle * lastT = triangles + nbt;
     4377                for (i=0;i<nbe;i++)
     4378                 if(edges[i].on) NbEdgeOnGeom++;
     4379                Int4 newnbe=nbe+nbe;
     4380                //  Int4 newNbVerticesOnGeomVertex=NbVerticesOnGeomVertex;
     4381                Int4 newNbVerticesOnGeomEdge=NbVerticesOnGeomEdge+NbEdgeOnGeom;
     4382                // Int4 newNbVertexOnBThVertex=NbVertexOnBThVertex;
     4383                Int4 newNbVertexOnBThEdge=withBackground ? NbVertexOnBThEdge+NbEdgeOnGeom:0;
     4384
     4385                // do allocation for pointeur to the geometry and background
     4386                VertexOnGeom * newVerticesOnGeomEdge = new VertexOnGeom[newNbVerticesOnGeomEdge];
     4387                VertexOnEdge *newVertexOnBThEdge = newNbVertexOnBThEdge ?  new VertexOnEdge[newNbVertexOnBThEdge]:0;
     4388                if (NbVerticesOnGeomEdge)
     4389                 memcpy(newVerticesOnGeomEdge,VerticesOnGeomEdge,sizeof(VertexOnGeom)*NbVerticesOnGeomEdge);
     4390                if (NbVertexOnBThEdge)
     4391                 memcpy(newVertexOnBThEdge,VertexOnBThEdge,sizeof(VertexOnEdge)*NbVertexOnBThEdge);
     4392                Edge *newedges = new Edge [newnbe];
     4393                //  memcpy(newedges,edges,sizeof(Edge)*nbe);
     4394                SetOfEdges4 * edge4= new SetOfEdges4(nbe,nbv);
     4395                Int4 k=nbv;
     4396                Int4 kk=0;
     4397                Int4 kvb = NbVertexOnBThEdge;
     4398                Int4 kvg = NbVerticesOnGeomEdge;
     4399                Int4 ie =0;
     4400                Edge ** edgesGtoB=0;
     4401                if (withBackground)
     4402                 edgesGtoB= BTh.MakeGeometricalEdgeToEdge();
     4403                Int4 ferr=0;
     4404                for (i=0;i<nbe;i++)
     4405                 newedges[ie].on=0;
     4406
     4407                for (i=0;i<nbe;i++)
     4408                  {
     4409                        GeometricalEdge *ong =  edges[i].on;
     4410
     4411                        newedges[ie]=edges[i];
     4412                        newedges[ie].adj[0]=newedges+(edges[i].adj[0]-edges) ;
     4413                        newedges[ie].adj[1]=newedges + ie +1;
     4414                        R2 A = edges[i][0],B = edges[i][1];
     4415
     4416
     4417                        kk += (i == edge4->addtrie(Number(edges[i][0]),Number(edges[i][1])));
     4418                        if (ong) // a geometrical edges
     4419                          {
     4420                                if (withBackground){
     4421                                        // walk on back ground mesh
     4422                                        //  newVertexOnBThEdge[ibe++] = VertexOnEdge(vertices[k],bedge,absicsseonBedge);
     4423                                        // a faire -- difficile
     4424                                        // the first PB is to now a background edge between the 2 vertices
     4425                                        if (!edgesGtoB){
     4426                                                throw ErrorException(__FUNCT__,exprintf("!edgesGtoB"));
     4427                                        }
     4428                                        ong= ProjectOnCurve(*edgesGtoB[Gh.Number(edges[i].on)],
     4429                                                                edges[i][0],edges[i][1],0.5,vertices[k],
     4430                                                                newVertexOnBThEdge[kvb],
     4431                                                                newVerticesOnGeomEdge[kvg++]);
     4432                                        vertices[k].ReferenceNumber= edges[i].ref;
     4433                                        vertices[k].DirOfSearch =   NoDirOfSearch;       
     4434                                        ;
     4435                                        // get the Info on background mesh
     4436                                        Real8 s =        newVertexOnBThEdge[kvb];
     4437                                        Vertex &  bv0  = newVertexOnBThEdge[kvb][0];
     4438                                        Vertex &  bv1  = newVertexOnBThEdge[kvb][1];
     4439                                        // compute the metrix of the new points
     4440                                        vertices[k].m =  Metric(1-s,bv0,s,bv1);
     4441                                        kvb++;
     4442                                  }
     4443                                else
     4444                                  {
     4445                                        ong=Gh.ProjectOnCurve(edges[i],
     4446                                                                0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);
     4447                                        // vertices[k].i = toI2( vertices[k].r);
     4448                                        vertices[k].ReferenceNumber = edges[i].ref;
     4449                                        vertices[k].DirOfSearch = NoDirOfSearch;
     4450                                        vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);             
     4451                                  } 
     4452                          }
     4453                        else // straigth line edge ---
     4454                          {
     4455                                vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;
     4456                                vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);
     4457                                vertices[k].on = 0;
     4458                          }
     4459                        //vertices[k].i = toI2( vertices[k].r);
     4460                        R2 AB =  vertices[k].r;
     4461                        R2 AA = (A+AB)*0.5;
     4462                        R2 BB = (AB+B)*0.5;
     4463                        vertices[k].ReferenceNumber = edges[i].ref;
     4464                        vertices[k].DirOfSearch = NoDirOfSearch;
     4465
     4466                        newedges[ie].on = Gh.Contening(AA,ong);
     4467                        newedges[ie++].v[1]=vertices+k;
     4468
     4469                        newedges[ie]=edges[i];
     4470                        newedges[ie].adj[0]=newedges + ie -1;
     4471                        newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;
     4472                        newedges[ie].on =  Gh.Contening(BB,ong);
     4473                        newedges[ie++].v[0]=vertices+k;
     4474                        k++;
     4475                  }
     4476                if (edgesGtoB) delete [] edgesGtoB;
     4477                edgesGtoB=0;
     4478
     4479                newnbv=k;
     4480                newNbVerticesOnGeomEdge=kvg;
     4481                if (newnbv> nbvx) goto Error;// bug
     4482
     4483                nbv = k;
     4484
     4485
     4486                kedge = new Int4[3*nbt+1];
     4487                ksplitarray = new Int4[nbt+1];
     4488                ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]
     4489
     4490                for (i=0;i<3*nbt;i++)
     4491                 kedge[i]=-1;
     4492
     4493                // 
     4494
     4495                for (i=0;i<nbt;i++) {
     4496                        Triangle & t = triangles[i];
     4497                        if (!t.link){
     4498                                throw ErrorException(__FUNCT__,exprintf("!t.link"));
     4499                        }
     4500                        for(int j=0;j<3;j++)
     4501                          {
     4502                                const TriangleAdjacent ta = t.Adj(j);
     4503                                const Triangle & tt = ta;
     4504                                if (&tt >= lastT)
     4505                                 t.SetAdj2(j,0,0);// unset adj
     4506                                const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
     4507                                const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
     4508                                Int4  ke =edge4->findtrie(Number(v0),Number(v1));
     4509                                if (ke>0)
     4510                                  {
     4511                                        Int4 ii = Number(tt);
     4512                                        int  jj = ta;
     4513                                        Int4 ks = ke + nbvold;
     4514                                        kedge[3*i+j] = ks;
     4515                                        if (ii<nbt) // good triangle
     4516                                         kedge[3*ii+jj] = ks;
     4517                                        Vertex &A=vertices[ks];
     4518                                        Real8 aa,bb,cc,dd;
     4519                                        if ((dd=Area2(v0.r,v1.r,A.r)) >=0){
     4520                                                // warning PB roundoff error
     4521                                                if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0
     4522                                                                                ||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0 
     4523                                                                                ||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0)){
     4524                                                        printf("%i not in triangle %i In= %i %i %i %i %i\n",ke + nbvold,i,!!t.link,aa,bb,cc,dd);
     4525                                                        throw ErrorException(__FUNCT__,exprintf("Number of triangles with P2 interpolation Problem"));
     4526                                                }
     4527                                        }
     4528                                        else {
     4529                                                if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0
     4530                                                                                ||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0
     4531                                                                                ||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)){
     4532                                                        printf("%i not in triangle %i In= %i %i %i %i %i\n",ke + nbvold,ii,!!tt.link,aa,bb,cc,dd);
     4533                                                        throw ErrorException(__FUNCT__,exprintf("Number of triangles with P2 interpolation Problem"));
     4534                                                }
     4535                                        }
     4536                                  }
     4537                          }
     4538                }
     4539
     4540                for (i=0;i<nbt;i++){
     4541                        ksplit[i]=1; // no split by default
     4542                        const Triangle & t = triangles[ i];
     4543                        int nbsplitedge =0;
     4544                        int nbinvisible =0;
     4545                        int invisibleedge=0;
     4546                        int kkk[3];     
     4547                        for (int j=0;j<3;j++)
     4548                          {
     4549                                if (t.Hidden(j)) invisibleedge=j,nbinvisible++;
     4550
     4551                                const TriangleAdjacent ta = t.Adj(j);
     4552                                const Triangle & tt = ta;
     4553
     4554
     4555                                const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];
     4556                                const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];
     4557                                if ( kedge[3*i+j] < 0)
     4558                                  {
     4559                                        Int4  ke =edge4->findtrie(Number(v0),Number(v1));
     4560                                        if (ke<0) // new
     4561                                          {
     4562                                                if (&tt) // internal triangles all the boundary
     4563                                                  { // new internal edges
     4564                                                        Int4 ii = Number(tt);
     4565                                                        int  jj = ta;
     4566
     4567                                                        kedge[3*i+j]=k;// save the vertex number
     4568                                                        kedge[3*ii+jj]=k;
     4569                                                        if (k<nbvx)
     4570                                                          {
     4571                                                                vertices[k].r = ((R2) v0+(R2) v1 )/2;
     4572                                                                //vertices[k].i = toI2( vertices[k].r);
     4573                                                                vertices[k].ReferenceNumber=0;
     4574                                                                vertices[k].DirOfSearch =NoDirOfSearch;
     4575                                                                vertices[k].m =  Metric(0.5,v0,0.5,v1);
     4576                                                          }
     4577                                                        k++;
     4578                                                        kkk[nbsplitedge++]=j;                 
     4579                                                  } // tt
     4580                                                else
     4581                                                 throw ErrorException(__FUNCT__,exprintf("Bug..."));
     4582                                          } // ke<0           
     4583                                        else
     4584                                          { // ke >=0
     4585                                                kedge[3*i+j]=nbvold+ke;
     4586                                                kkk[nbsplitedge++]=j;// previously splited
     4587                                          }
     4588                                  }
     4589                                else
     4590                                 kkk[nbsplitedge++]=j;// previously splited
     4591
     4592                          }
     4593                        if (nbinvisible>=2){
     4594                                throw ErrorException(__FUNCT__,exprintf("nbinvisible>=2"));
     4595                        }
     4596                        switch (nbsplitedge) {
     4597                                case 0: ksplit[i]=10; newnbt++; break;   // nosplit
     4598                                case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2
     4599                                case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3
     4600                                case 3:
     4601                                                  if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;
     4602                                                  else   ksplit[i]=10*nfortria,newnbt+=nfortria;
     4603                                                  break;
     4604                        }
     4605                        if (ksplit[i]<40){
     4606                                throw ErrorException(__FUNCT__,exprintf("ksplit[i]<40"));
     4607                        }
     4608                  }
     4609                //  now do the element split
     4610                newNbOfQuad = 4*NbOfQuad;
     4611                nbv = k;
     4612                kkk = nbt;
     4613                ksplit[-1] = nbt;
     4614                // look on  old true  triangles
     4615
     4616                for (i=0;i<nbtsave;i++){
     4617                        int  nbmkadj=0;
     4618                        Int4 mkadj [100];
     4619                        mkadj[0]=i;
     4620                        Int4 kk=ksplit[i]/10;
     4621                        int  ke=(int) (ksplit[i]%10);
     4622                        if (kk>=7 || kk<=0){
     4623                                throw ErrorException(__FUNCT__,exprintf("kk>=7 || kk<=0"));
     4624                        }
     4625
     4626                        // def the numbering   k (edge) i vertex
     4627                        int k0 = ke;
     4628                        int k1 = NextEdge[k0];
     4629                        int k2 = PreviousEdge[k0];
     4630                        int i0 = OppositeVertex[k0];
     4631                        int i1 = OppositeVertex[k1];
     4632                        int i2 = OppositeVertex[k2];
     4633
     4634                        Triangle &t0=triangles[i];
     4635                        Vertex * v0=t0(i0);           
     4636                        Vertex * v1=t0(i1);           
     4637                        Vertex * v2=t0(i2);
     4638
     4639                        if (nbmkadj>=10){
     4640                                throw ErrorException(__FUNCT__,exprintf("nbmkadj>=10"));
     4641                        }
     4642                        // --------------------------
     4643                        TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));
     4644                        // save the flag Hidden
     4645                        int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};
     4646                        // un set all adj -- save Hidden flag --
     4647                        t0.SetAdj2(0,0,hid[0]);
     4648                        t0.SetAdj2(1,0,hid[1]);
     4649                        t0.SetAdj2(2,0,hid[2]);
     4650                        // --  remake
     4651                        switch  (kk) {
     4652                                case 1: break;// nothing
     4653                                case 2: //
     4654                                                  {
     4655                                                        Triangle &t1=triangles[kkk++];
     4656                                                        t1=t0;
     4657                                                        if (kedge[3*i+i0]<0){
     4658                                                                throw ErrorException(__FUNCT__,exprintf("kedge[3*i+i0]<0"));
     4659                                                        }
     4660                                                        Vertex * v3 = vertices + kedge[3*i+k0];
     4661
     4662                                                        t0(i2) = v3;
     4663                                                        t1(i1) = v3;
     4664                                                        t0.SetAllFlag(k2,0);
     4665                                                        t1.SetAllFlag(k1,0);
     4666                                                  }
     4667                                                break;
     4668                                case 3: //
     4669                                                  {
     4670                                                        Triangle &t1=triangles[kkk++];
     4671                                                        Triangle &t2=triangles[kkk++];
     4672                                                        t2=t1=t0;
     4673                                                        if (kedge[3*i+k1]<0){
     4674                                                                throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k1]<0"));
     4675                                                        }
     4676                                                        if (kedge[3*i+k2]<0){
     4677                                                                throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k2]<0"));
     4678                                                        }
     4679
     4680                                                        Vertex * v01 = vertices + kedge[3*i+k2];
     4681                                                        Vertex * v02 = vertices + kedge[3*i+k1];
     4682                                                        t0(i1) = v01;
     4683                                                        t0(i2) = v02;
     4684                                                        t1(i2) = v02;
     4685                                                        t1(i0) = v01;
     4686                                                        t2(i0) = v02;
     4687                                                        t0.SetAllFlag(k0,0);
     4688                                                        t1.SetAllFlag(k1,0);
     4689                                                        t1.SetAllFlag(k0,0);
     4690                                                        t2.SetAllFlag(k2,0);
     4691                                                  }
     4692                                                break;
     4693                                case 4: //
     4694                                case 6: // split in 4
     4695                                                  {
     4696                                                        Triangle &t1=triangles[kkk++];
     4697                                                        Triangle &t2=triangles[kkk++];
     4698                                                        Triangle &t3=triangles[kkk++];
     4699                                                        t3=t2=t1=t0;
     4700                                                        if (kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0){
     4701                                                                throw ErrorException(__FUNCT__,exprintf("kedge[3*i+k0] <0 || kedge[3*i+k1]<0 || kedge[3*i+k2]<0"));
     4702                                                        }
     4703                                                        Vertex * v12 = vertices + kedge[3*i+k0];
     4704                                                        Vertex * v02 = vertices + kedge[3*i+k1];
     4705                                                        Vertex * v01 = vertices + kedge[3*i+k2];
     4706                                                        t0(i1) = v01;
     4707                                                        t0(i2) = v02;
     4708                                                        t0.SetAllFlag(k0,hid[k0]);
     4709
     4710                                                        t1(i0) = v01;
     4711                                                        t1(i2) = v12;
     4712                                                        t0.SetAllFlag(k1,hid[k1]);
     4713
     4714                                                        t2(i0) = v02;
     4715                                                        t2(i1) = v12;
     4716                                                        t2.SetAllFlag(k2,hid[k2]);
     4717
     4718                                                        t3(i0) = v12;
     4719                                                        t3(i1) = v02;
     4720                                                        t3(i2) = v01;
     4721
     4722                                                        t3.SetAllFlag(0,hid[0]);           
     4723                                                        t3.SetAllFlag(1,hid[1]);           
     4724                                                        t3.SetAllFlag(2,hid[2]);
     4725
     4726                                                        if ( kk == 6)
     4727                                                          {
     4728
     4729                                                                Triangle &t4=triangles[kkk++];
     4730                                                                Triangle &t5=triangles[kkk++];
     4731
     4732                                                                t4 = t3;
     4733                                                                t5 = t3;
     4734
     4735                                                                t0.SetHidden(k0);
     4736                                                                t1.SetHidden(k1);
     4737                                                                t2.SetHidden(k2);
     4738                                                                t3.SetHidden(0);
     4739                                                                t4.SetHidden(1);
     4740                                                                t5.SetHidden(2);
     4741
     4742                                                                if (nbv < nbvx )
     4743                                                                  {
     4744                                                                        vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;
     4745                                                                        vertices[nbv].ReferenceNumber =0;
     4746                                                                        vertices[nbv].DirOfSearch =NoDirOfSearch;
     4747                                                                        //vertices[nbv].i = toI2(vertices[nbv].r);
     4748                                                                        Real8 a3[]={1./3.,1./3.,1./3.};
     4749                                                                        vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);
     4750                                                                        Vertex * vc =  vertices +nbv++;
     4751                                                                        t3(i0) = vc;
     4752                                                                        t4(i1) = vc;
     4753                                                                        t5(i2) = vc;
     4754
     4755                                                                  }
     4756                                                                else
     4757                                                                 goto Error;
     4758                                                          }
     4759
     4760                                                  }
     4761                                                break;         
     4762                        }
     4763
     4764                        // save all the new triangles
     4765                        mkadj[nbmkadj++]=i;
     4766                        Int4 jj;
     4767                        if (t0.link)
     4768                         for (jj=nbt;jj<kkk;jj++)
     4769                                {
     4770                                 triangles[jj].link=t0.link;
     4771                                 t0.link= triangles+jj;
     4772                                 mkadj[nbmkadj++]=jj;
     4773                                }
     4774                        if (nbmkadj>13){// 13 = 6 + 4 +
     4775                                throw ErrorException(__FUNCT__,exprintf("nbmkadj>13"));
     4776                        }
     4777
     4778                        if (kk==6)  newNbOfQuad+=3;
     4779                        for (jj=ksplit[i-1];jj<kkk;jj++) nbt = kkk;
     4780                        ksplit[i]= nbt; // save last adresse of the new triangles
     4781                        kkk = nbt;
     4782                  }
     4783
     4784                for (i=0;i<nbv;i++) vertices[i].m = vertices[i].m*2.;
     4785
     4786                if(withBackground)
     4787                 for (i=0;i<BTh.nbv;i++)
     4788                  BTh.vertices[i].m =  BTh.vertices[i].m*2.;
     4789
     4790
     4791                ret = 2;
     4792                if (nbt>= nbtx) goto Error; // bug
     4793                if (nbv>= nbvx) goto Error; // bug
     4794                // generation of the new triangles
     4795
     4796                SetIntCoor("In SplitElement");
     4797
     4798                ReMakeTriangleContainingTheVertex();
     4799                if(withBackground)
     4800                 BTh.ReMakeTriangleContainingTheVertex();
     4801
     4802                delete [] edges;
     4803                edges = newedges;
     4804                nbe = newnbe;
     4805                NbOfQuad = newNbOfQuad;
     4806
     4807                for (i=0;i<NbSubDomains;i++)
     4808                  {
     4809                        Int4 k = subdomains[i].edge- edges;
     4810                        subdomains[i].edge =  edges+2*k; // spilt all edge in 2
     4811                  }
     4812
     4813                if (ksplitarray) delete [] ksplitarray;
     4814                if (kedge) delete [] kedge;
     4815                if (edge4) delete edge4;
     4816                if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
     4817                VerticesOnGeomEdge= newVerticesOnGeomEdge;
     4818                if(VertexOnBThEdge) delete []  VertexOnBThEdge;
     4819                VertexOnBThEdge = newVertexOnBThEdge;
     4820                NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;
     4821                NbVertexOnBThEdge=newNbVertexOnBThEdge;
     4822                //  ReMakeTriangleContainingTheVertex();
     4823
     4824                FillHoleInMesh();
     4825
     4826                if (verbosity>2){
     4827                        printf("   number of quadrilaterals    = %i\n",NbOfQuad);
     4828                        printf("   number of triangles         = %i\n",nbt-NbOutT- NbOfQuad*2);
     4829                        printf("   number of outside triangles = %i\n",NbOutT);
     4830                }
     4831
     4832                CurrentTh=OCurrentTh;
     4833                return 0; //ok
     4834
     4835Error:
     4836                nbv = nbvold;
     4837                nbt = nbtold;
     4838                NbOutT = NbOutTold;
     4839                // cleaning memory ---
     4840                delete newedges;
     4841                if (ksplitarray) delete [] ksplitarray;
     4842                if (kedge) delete [] kedge;
     4843                if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;
     4844                if (edge4) delete edge4;
     4845                if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;
     4846
     4847
     4848                CurrentTh= OCurrentTh;
     4849                return ret; // ok
    39624850        }
    39634851        /*}}}1*/
    3964         /*FUNCTION Triangles::ShowRegulaty{{{1*/
    3965         void  Triangles::ShowRegulaty() const {
    3966                 const  Real8  sqrt32=sqrt(3.)*0.5;
    3967                 const Real8  aireKh=sqrt32*0.5;
    3968                 D2  Beq(1,0),Heq(0.5,sqrt32);
    3969                 D2xD2 Br(D2xD2(Beq,Heq).t());
    3970                 D2xD2 B1r(Br.inv());
    3971                 double gammamn=1e100,hmin=1e100;
    3972                 double gammamx=0,hmax=0;
    3973                 double beta=1e100;
    3974                 double beta0=0;
    3975                 double  alpha2=0;
    3976                 double area=0,Marea=0;
    3977                 // Real8 cf= Real8(coefIcoor);
    3978                 // Real8 cf2= 6.*cf*cf;
    3979                 int nt=0;
    3980                 for (int it=0;it<nbt;it++)
    3981                  if ( triangles[it].link)
    3982                         {
    3983                          nt++;
    3984                          Triangle &K=triangles[it];
    3985                          Real8  area3= Area2((R2) K[0],(R2) K[1],(R2) K[2])/6.;
    3986                          area+= area3;
    3987                          D2xD2 B_Kt(K[0],K[1],K[2]);
    3988                          D2xD2 B_K(B_Kt.t());
    3989                          D2xD2 B1K = Br*B_K.inv();
    3990                          D2xD2 BK =  B_K*B1r;
    3991                          D2xD2 B1B1 = B1K.t()*B1K;
    3992                          MetricAnIso MK(B1B1.x.x,B1B1.x.y,B1B1.y.y);
    3993                          MatVVP2x2 VMK(MK);
    3994                          alpha2 = Max(alpha2,Max(VMK.lambda1/VMK.lambda2,VMK.lambda2/VMK.lambda1));
    3995                          Real8 betaK=0;
    3996 
    3997                          for (int j=0;j<3;j++)
    3998                                 {
    3999                                  Real8 he= Norme2(R2(K[j],K[(j+1)%3]));
    4000                                  hmin=Min(hmin,he);
    4001                                  hmax=Max(hmax,he);
    4002                                  Vertex & v=K[j];
    4003                                  D2xD2 M((MetricAnIso)v);
    4004                                  betaK += sqrt(M.det());
    4005 
    4006                                  D2xD2 BMB = BK.t()*M*BK;
    4007                                  MetricAnIso M1(BMB.x.x,BMB.x.y,BMB.y.y);
    4008                                  MatVVP2x2 VM1(M1);
    4009                                  gammamn=Min3(gammamn,VM1.lambda1,VM1.lambda2);
    4010                                  gammamx=Max3(gammamx,VM1.lambda1,VM1.lambda2);         
    4011                                 }
    4012                          betaK *= area3;//  1/2 (somme sqrt(det))* area(K)
    4013                          Marea+= betaK;
    4014                          beta=min(beta,betaK);
    4015                          beta0=max(beta0,betaK);
    4016                         }   
    4017                 area*=3;
    4018                 gammamn=sqrt(gammamn);
    4019                 gammamx=sqrt(gammamx);   
    4020                 printf("   Adaptmesh info:\n");
    4021                 printf("      number of triangles = %i\n",nt);
    4022                 printf("      hmin = %g, hmax=%g\n",hmin,hmax);
    4023                 printf("      area = %g, M area = %g, M area/( |Khat| nt) = %g\n",area,Marea, Marea/(aireKh*nt));
    4024                 printf("      infinite-regularity(?): min = %g, max = %g\n",gammamn,gammamx);
    4025                 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));
     4852/*FUNCTION Triangles::SplitInternalEdgeWithBorderVertices{{{1*/
     4853Int4  Triangles::SplitInternalEdgeWithBorderVertices(){
     4854        Int4 NbSplitEdge=0;
     4855        SetVertexFieldOn(); 
     4856        Int4 it;
     4857        Int4 nbvold=nbv;
     4858        long int verbosity=2;
     4859        for (it=0;it<nbt;it++){
     4860                Triangle &t=triangles[it];
     4861                if (t.link)
     4862                 for (int j=0;j<3;j++)
     4863                  if(!t.Locked(j) && !t.Hidden(j)){
     4864                          Triangle &tt = *t.TriangleAdj(j);
     4865                          if ( &tt && tt.link && it < Number(tt))
     4866                                 { // an internal edge
     4867                                  Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
     4868                                  Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
     4869                                  if (v0.on && v1.on){
     4870                                          R2 P= ((R2) v0 + (R2) v1)*0.5;
     4871                                          if ( nbv<nbvx) {
     4872                                                  vertices[nbv].r = P;
     4873                                                  vertices[nbv++].m = Metric(0.5,v0.m,0.5,v1.m);
     4874                                                  vertices[nbv].ReferenceNumber=0;
     4875                                                  vertices[nbv].DirOfSearch = NoDirOfSearch ;
     4876                                          }
     4877                                          NbSplitEdge++;
     4878                                  }
     4879                                 }
     4880                  }
     4881        }
     4882        ReMakeTriangleContainingTheVertex();   
     4883        if (nbvold!=nbv){
     4884                Int4  iv = nbvold;
     4885                Int4 NbSwap = 0;
     4886                Icoor2 dete[3]; 
     4887                for (Int4 i=nbvold;i<nbv;i++) {// for all the new point
     4888                        Vertex & vi = vertices[i];
     4889                        vi.i = toI2(vi.r);
     4890                        vi.r = toR2(vi.i);
     4891
     4892                        // a good new point
     4893                        vi.ReferenceNumber=0;
     4894                        vi.DirOfSearch =NoDirOfSearch;
     4895                        Triangle *tcvi = FindTriangleContening(vi.i,dete);
     4896                        if (tcvi && !tcvi->link) {
     4897                                printf("problem inserting point\n");
     4898                        }
     4899
     4900                        quadtree->Add(vi);
     4901                        if (!tcvi || tcvi->det<0){// internal
     4902                                throw ErrorException(__FUNCT__,exprintf("!tcvi || tcvi->det < 0"));
     4903                        }
     4904                        Add(vi,tcvi,dete);
     4905                        NbSwap += vi.Optim(1);         
     4906                        iv++;
     4907                        //      }
     4908        }
     4909        if (verbosity>3) {
     4910                printf("   number of points: %i\n",iv);
     4911                printf("   number of swap to  split internal edges with border vertices: %i\n",NbSwap);
     4912                nbv = iv;
     4913        }
     4914}
     4915if (NbSplitEdge>nbv-nbvold) printf("WARNING: not enough vertices  to split all internal edges, we lost %i edges...\n",NbSplitEdge - ( nbv-nbvold));
     4916if (verbosity>2) printf("SplitInternalEdgeWithBorderVertices: Number of splited edge %i\n",NbSplitEdge);
     4917
     4918return  NbSplitEdge;
     4919}
     4920/*}}}1*/
     4921        /*FUNCTION Triangles::swap{{{1*/
     4922        int Triangle::swap(Int2 a,int koption){
     4923                if(a/4 !=0) return 0;// arete lock or MarkUnSwap
     4924
     4925                register Triangle *t1=this,*t2=at[a];// les 2 triangles adjacent
     4926                register Int1 a1=a,a2=aa[a];// les 2 numero de l arete dans les 2 triangles
     4927                if(a2/4 !=0) return 0; // arete lock or MarkUnSwap
     4928
     4929                register Vertex  *sa=t1->ns[VerticesOfTriangularEdge[a1][0]];
     4930                register Vertex  *sb=t1->ns[VerticesOfTriangularEdge[a1][1]];
     4931                register Vertex  *s1=t1->ns[OppositeVertex[a1]];
     4932                register Vertex  *s2=t2->ns[OppositeVertex[a2]];
     4933
     4934                Icoor2 det1=t1->det , det2=t2->det ;
     4935                Icoor2 detT = det1+det2;
     4936                Icoor2 detA = Abs(det1) + Abs(det2);
     4937                Icoor2 detMin = Min(det1,det2);
     4938
     4939                int OnSwap = 0;       
     4940                // si 2 triangle infini (bord) => detT = -2;
     4941                if (sa == 0) {// les deux triangles sont frontieres
     4942                        det2=bamg::det(s2->i,sb->i,s1->i);
     4943                        OnSwap = det2 >0;}
     4944                else if (sb == 0) { // les deux triangles sont frontieres
     4945                        det1=bamg::det(s1->i,sa->i,s2->i);
     4946                        OnSwap = det1 >0;}
     4947                else if(( s1 != 0) && (s2 != 0) ) {
     4948                        det1 = bamg::det(s1->i,sa->i,s2->i);
     4949                        det2 = detT - det1;
     4950                        OnSwap = (Abs(det1) + Abs(det2)) < detA;
     4951
     4952                        Icoor2 detMinNew=Min(det1,det2);
     4953                        //     if (detMin<0 && (Abs(det1) + Abs(det2) == detA)) OnSwap=BinaryRand();// just for test   
     4954                        if (! OnSwap &&(detMinNew>0)) {
     4955                                OnSwap = detMin ==0;
     4956                                if (! OnSwap) {
     4957                                        int  kopt = koption;
     4958                                        while (1)
     4959                                         if(kopt) {
     4960                                                 // critere de Delaunay pure isotrope
     4961                                                 register Icoor2 xb1 = sb->i.x - s1->i.x,
     4962                                                                         x21 = s2->i.x - s1->i.x,
     4963                                                                         yb1 = sb->i.y - s1->i.y,
     4964                                                                         y21 = s2->i.y - s1->i.y,
     4965                                                                         xba = sb->i.x - sa->i.x,
     4966                                                                         x2a = s2->i.x - sa->i.x,
     4967                                                                         yba = sb->i.y - sa->i.y,
     4968                                                                         y2a = s2->i.y - sa->i.y;
     4969                                                 register double
     4970                                                        cosb12 =  double(xb1*x21 + yb1*y21),
     4971                                                                         cosba2 =  double(xba*x2a + yba*y2a) ,
     4972                                                                         sinb12 = double(det2),
     4973                                                                         sinba2 = double(t2->det);
     4974
     4975
     4976                                                 // angle b12 > angle ba2 => cotg(angle b12) < cotg(angle ba2)
     4977                                                 OnSwap =  ((double) cosb12 * (double)  sinba2) <  ((double) cosba2 * (double) sinb12);
     4978                                                 break;
     4979                                         }
     4980                                         else
     4981                                                {       
     4982                                                 // critere de Delaunay anisotrope
     4983                                                 Real8 som;
     4984                                                 I2 AB=(I2) *sb - (I2) *sa;
     4985                                                 I2 MAB2=((I2) *sb + (I2) *sa);
     4986                                                 R2 MAB(MAB2.x*0.5,MAB2.y*0.5);
     4987                                                 I2 A1=(I2) *s1 - (I2) *sa;
     4988                                                 I2 D = (I2) * s1 - (I2) * sb ;
     4989                                                 R2 S2(s2->i.x,s2->i.y);
     4990                                                 R2 S1(s1->i.x,s1->i.y);
     4991                                                        {
     4992                                                         Metric M=s1->m;
     4993                                                         R2 ABo = M.Orthogonal(AB);
     4994                                                         R2 A1o = M.Orthogonal(A1);
     4995                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
     4996                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
     4997                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
     4998                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
     4999                                                         if (Abs(d) > dd*1.e-3) {
     5000                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
     5001                                                                 som  = M(C - S2)/M(C - S1);
     5002                                                         } else
     5003                                                                {kopt=1;continue;}
     5004
     5005                                                        }
     5006                                                        {
     5007                                                         Metric M=s2->m;
     5008                                                         R2 ABo = M.Orthogonal(AB);
     5009                                                         R2 A1o = M.Orthogonal(A1);
     5010                                                         // (A+B)+ x ABo = (S1+B)/2+ y A1
     5011                                                         // ABo x - A1o y =  (S1+B)/2-(A+B)/2 = (S1-B)/2 = D/2
     5012                                                         double dd = Abs(ABo.x*A1o.y)+Abs(ABo.y*A1o.x);
     5013                                                         double d = (ABo.x*A1o.y - ABo.y*A1o.x)*2; // because D/2
     5014                                                         if(Abs(d) > dd*1.e-3) {
     5015                                                                 R2 C(MAB+ABo*((D.x*A1o.y - D.y*A1o.x)/d));
     5016                                                                 som  += M(C - S2)/M(C -  S1);
     5017                                                         } else
     5018                                                                {kopt=1;continue;}
     5019                                                        }
     5020                                                 OnSwap = som < 2;
     5021                                                 break;
     5022                                                }
     5023
     5024                                } // OnSwap
     5025                        } // (! OnSwap &&(det1 > 0) && (det2 > 0) )
     5026                }
     5027                if( OnSwap )
     5028                 bamg::swap(t1,a1,t2,a2,s1,s2,det1,det2);
     5029                else {
     5030                        NbUnSwap ++;
     5031                        t1->SetMarkUnSwap(a1);     
     5032                }
     5033                return OnSwap;
    40265034        }
    40275035        /*}}}1*/
    4028         /*FUNCTION Triangles::ShowHistogram{{{1*/
    4029         void  Triangles::ShowHistogram() const {
    4030 
    4031                 const Int4 kmax=10;
    4032                 const Real8 llmin = 0.5,llmax=2;
    4033                 const Real8 lmin=log(llmin),lmax=log(llmax),delta= kmax/(lmax-lmin);
    4034                 Int4 histo[kmax+1];
    4035                 Int4 i,it,k, nbedges =0;
    4036                 for (i=0;i<=kmax;i++) histo[i]=0;
    4037                 for (it=0;it<nbt;it++)
    4038                  if ( triangles[it].link)
    4039                         {
    4040 
    4041                          for (int j=0;j<3;j++)
    4042                                 {
    4043                                  Triangle *ta = triangles[it].TriangleAdj(j);
    4044                                  if ( !ta || !ta->link || Number(ta) >= it)
    4045                                         {
    4046                                          Vertex & vP = triangles[it][VerticesOfTriangularEdge[j][0]];
    4047                                          Vertex & vQ = triangles[it][VerticesOfTriangularEdge[j][1]];
    4048                                          if ( !& vP || !&vQ) continue;
    4049                                          R2 PQ = vQ.r - vP.r;
    4050                                          Real8 l = log(LengthInterpole(vP,vQ,PQ));
    4051                                          nbedges++;
    4052                                          k = (int) ((l - lmin)*delta);
    4053                                          k = Min(Max(k,0L),kmax);
    4054                                          histo[k]++;
    4055                                         }
    4056                                 }
    4057                         } 
    4058                 printf(" --- Histogram of the unit mesh,  nb of edges = %i\n",nbedges);
    4059                 printf("      length of edge in   | %% of edge  | Nb of edges \n");
    4060                 printf("      --------------------+-------------+-------------\n");
    4061                 for   (i=0;i<=kmax;i++){
    4062                         if (i==0) printf("      %10i",0);
    4063                         else      printf("      %10g",exp(lmin+i/delta));
    4064                         if (i==kmax) printf("          +inf   ");
    4065                         else printf("      %10g",exp(lmin+(i+1)/delta));
    4066                         printf("|  %10g |\n",((long)  ((10000.0 * histo[i])/ nbedges))/100.0);
    4067                         printf("  %g\n",histo[i]);
    4068                   }
    4069                 printf("      --------------------+-------------+-------------\n");
     5036/*FUNCTION Triangles::UnCrack{{{1*/
     5037int Triangles::UnCrack() {
     5038        if (NbCrackedEdges!=0 && NbCrackedVertices<=0);{
     5039                throw ErrorException(__FUNCT__,exprintf("NbCrackedEdges ==0 || NbCrackedVertices >0"));
    40705040        }
    4071         /*}}}1*/
    4072         /*FUNCTION Triangles::Crack{{{1*/
    4073         int  Triangles::Crack() {
    4074                 if (NbCrackedEdges!=0 && NbCrackedVertices<=0);{
    4075                         throw ErrorException(__FUNCT__,exprintf("NbCrackedEdges!=0 && NbCrackedVertices<=0"));
    4076                 }
    4077                 for (int i=0;i<NbCrackedEdges;i++) CrackedEdges[i].Crack();
    4078                 return NbCrackedEdges;
    4079         }
    4080         /*}}}1*/
    4081         /*FUNCTION Triangles::UnCrack{{{1*/
    4082         int Triangles::UnCrack() {
    4083                 if (NbCrackedEdges!=0 && NbCrackedVertices<=0);{
    4084                         throw ErrorException(__FUNCT__,exprintf("NbCrackedEdges ==0 || NbCrackedVertices >0"));
    4085                 }
    4086                 for (int i=0;i<NbCrackedEdges;i++)
    4087                  CrackedEdges[i].UnCrack();
    4088                 return NbCrackedEdges;
    4089         }
    4090         /*}}}1*/
    4091         /*FUNCTION Triangles::CrackMesh{{{1*/
    4092         int Triangles::CrackMesh() {
    4093                 long int verbosity=0;
    4094                 Triangles *CurrentThOld = CurrentTh;
    4095                 //  computed the number of cracked edge
    4096                 int i,k;
    4097                 for (k=i=0;i<nbe;i++)
    4098                  if(edges[i].on->Cracked()) k++;
    4099                 if( k==0) return 0;
    4100                 CurrentTh = this;
    4101                 printf("      number of Cracked Edges = %i\n",k);
    4102                 NbCrackedEdges =k;
    4103                 CrackedEdges = new  CrackedEdge[k];
    4104                 //  new edge
    4105                 Edge * e = new Edge[ nbe + k];
    4106 
    4107                 // copy
    4108                 for (i=0;i<nbe;i++)
    4109                  e[i] = edges[i];
    4110                 delete edges;
    4111                 edges = e;
    4112 
    4113                 const int  nbe0  = nbe;
    4114                 for (k=i=0;i<nbe0;i++) // on double les arete cracked
    4115                  if(edges[i].on->Cracked())
    4116                         {
    4117                          e[nbe] = e[i];
    4118                          //  return the edge
    4119                          e[nbe].v[0] =  e[i].v[1];
    4120                          e[nbe].v[1] =  e[i].v[0];
    4121                          e[nbe].on = e[i].on->link ; // fqux
    4122                          CrackedEdges[k++]=CrackedEdge(edges,i,nbe);
    4123                          nbe++;
    4124                         }
    4125                 ReMakeTriangleContainingTheVertex() ;
    4126                 // 
    4127                 int nbcrakev  =0;
    4128                 Vertex *vlast = vertices + nbv;
    4129                 Vertex *vend = vertices + nbvx; // end of array
    4130                 for (int iv=0;iv<nbv;iv++) // vertex
    4131                   {
    4132                         Vertex & v= vertices[iv];
    4133                         Vertex * vv = & v; 
    4134                         int kk=0; // nb cracked
    4135                         int kc=0;
    4136                         int kkk =0; // nb triangle  with same number
    4137                         Triangle * tbegin = v.t;
    4138                         int i  = v.vint;       
    4139                         if (!tbegin || (i<0) || (i>=3)){
    4140                                 throw ErrorException(__FUNCT__,exprintf("!tbegin || (i<0) || (i>=3)"));
    4141                         }
    4142                         // turn around the vertex v
    4143                         TriangleAdjacent ta(tbegin,EdgesVertexTriangle[i][0]);// previous edge
    4144                         int k=0;
    4145                         do {
    4146                                 int kv = VerticesOfTriangularEdge[ta][1];
    4147                                 k++;
    4148                                 Triangle * tt (ta);
    4149                                 if ( ta.Cracked() )
    4150                                   {   
    4151                                         TriangleAdjacent tta=(ta.Adj());
    4152                                         if (!tta.Cracked()){
    4153                                                 throw ErrorException(__FUNCT__,exprintf("!tta.Cracked()"));
    4154                                         }
    4155                                         if ( kk == 0) tbegin=ta,kkk=0;  //  begin by a cracked edge  => restart               
    4156                                         if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
    4157                                         kk++;// number of cracked edge view                 
    4158                                   }
    4159                                 if ( tt->link ) { // if good triangles store the value
    4160                                         int it = Number(tt);
    4161                                         if (it>=nt){
    4162                                                 throw ErrorException(__FUNCT__,exprintf("(it>=nt)"));
    4163                                         }
    4164                                         (*tt)(kv)= vv; //   Change the vertex of triangle
    4165                                         if(vv<vend) {*vv= v;vv->ReferenceNumber=iv;} // copy the vertex value + store the old vertex number in ref
    4166                                         //        tt->SetTriangleContainingTheVertex();
    4167                                         kkk++;
    4168                                 } else if (kk) { // crack + boundary
    4169                                         if (  kkk ) { kc =1;vv = vlast++;  kkk = 0; } // new vertex if use
    4170                                 }
    4171 
    4172                                 ta = Next(ta).Adj();
    4173                         } while ( (tbegin != ta));
    4174                         if (!k){
    4175                                 throw ErrorException(__FUNCT__,exprintf("!k"));
    4176                         }
    4177                         if (kc)  nbcrakev++;
    4178                   }
    4179 
    4180                 if ( nbcrakev )
    4181                  for (int iec =0;iec < NbCrackedEdges; iec ++)
    4182                   CrackedEdges[iec].Set();
    4183 
    4184                 //  set the ref
    4185                 NbCrackedVertices =   nbcrakev;
    4186                 // int nbvo = nbv;
    4187                 nbv = vlast - vertices;
    4188                 int nbnewv =  nbv - nbv; // nb of new vrtices
    4189                 if (nbcrakev && verbosity > 1 ) printf("      number of Cracked vertices = %i, number of created vertices = %i\n",nbcrakev,nbnewv);
    4190                 // all the new vertices are on geometry
    4191                 if (nbnewv)
    4192                   { //
    4193                         Int4 n = nbnewv+NbVerticesOnGeomVertex;
    4194                         Int4 i,j,k;
    4195                         VertexOnGeom * vog = new VertexOnGeom[n];
    4196                         for ( i =0; i<NbVerticesOnGeomVertex;i++)
    4197                          vog[i]=VerticesOnGeomVertex[i];
    4198                         delete [] VerticesOnGeomVertex;
    4199                         VerticesOnGeomVertex = vog;
    4200                         // loop on cracked edge
    4201                         Vertex * LastOld = vertices + nbv - nbnewv;
    4202                         for (int iec =0;iec < NbCrackedEdges; iec ++)
    4203                          for (k=0;k<2;k++)
    4204                                 {
    4205                                  Edge & e = *( k ? CrackedEdges[iec].a.edge : CrackedEdges[iec].b.edge);
    4206                                  for (j=0;j<2;j++)
    4207                                         {
    4208                                          Vertex * v = e(j);
    4209                                          if ( v >=  LastOld)
    4210                                                 { // a new vertex
    4211                                                  Int4 old = v->ReferenceNumber ; // the old same vertex
    4212                                                  Int4 i  = ( v - LastOld);
    4213                                                  //  if the old is on vertex => warning
    4214                                                  // else the old is on edge => ok
    4215                                                  vog[i] = vog[old];
    4216                                                  //                 vog[i].mv = v;
    4217                                                  //g[i].ge = ;
    4218                                                  //og[i].abcisse = ;
    4219                                                 }
    4220 
    4221                                         }
    4222                                 }
    4223 
    4224                         NbVerticesOnGeomVertex = n;
    4225                   }
    4226                 SetVertexFieldOn();
    4227 
    4228                 if (vlast >= vend) { 
    4229                         throw ErrorException(__FUNCT__,exprintf("Not enougth vertices: to crack the mesh we need %i vertices",nbv));
    4230                   }
    4231                 CurrentTh = CurrentThOld;
    4232                 return  NbCrackedVertices;
    4233         }
    4234         /*}}}1*/
    4235         /*FUNCTION Triangles::FindTriangleContening{{{1*/
    4236         Triangle * Triangles::FindTriangleContening(const I2 & B,Icoor2 dete[3], Triangle *tstart) const {
    4237                 Triangle * t=0;
    4238                 int j,jp,jn,jj;
    4239                 if (tstart) t=tstart;
    4240                 else {
    4241                         if (!quadtree){
    4242                                 throw ErrorException(__FUNCT__,exprintf("!quadtree"));
    4243                         }
    4244                         Vertex *a = quadtree->NearestVertex(B.x,B.y) ;
    4245 
    4246                         if (! a || !a->t ) {
    4247                                 if (a) {
    4248                                         printf("TriangleConteningTheVertex vertex number %i, another call to ReMakeTriangleContainingTheVertex was required\n", Number(a));
    4249                                 }
    4250                                 throw ErrorException(__FUNCT__,exprintf("problem in Triangles::FindTriangleContening"));
    4251                         }
    4252                         if (a<vertices || a>=vertices+nbv){
    4253                                 throw ErrorException(__FUNCT__,exprintf("a<vertices || a>=vertices+nbv"));
    4254                         }
    4255                         t = a->t;
    4256                         if (t<triangles || t>=triangles+nbt){
    4257                                 throw ErrorException(__FUNCT__,exprintf("t<triangles || t>=triangles+nbt"));
    4258                         }
    4259                 }
    4260                 Icoor2  detop ;
    4261                 int kkkk =0; // number of test triangle
    4262 
    4263                 while ( t->det < 0){ // the initial triangles is outside 
    4264                         int k0=(*t)(0) ?  ((  (*t)(1) ? ( (*t)(2) ? -1 : 2) : 1  )) : 0;
    4265                         if (k0<0){ // k0 the NULL  vertex
    4266                                 throw ErrorException(__FUNCT__,exprintf("k0<0"));
    4267                         }
    4268                         int k1=NextVertex[k0],k2=PreviousVertex[k0];
    4269                         dete[k0]=det(B,(*t)[k1],(*t)[k2]);
    4270                         dete[k1]=dete[k2]=-1;     
    4271                         if (dete[k0] > 0) // outside B
    4272                          return t;
    4273                         t = t->TriangleAdj(OppositeEdge[k0]);
    4274                         kkkk++;
    4275                         if (kkkk>=2){
    4276                                 throw ErrorException(__FUNCT__,exprintf("kkkk>=2"));
    4277                         }
    4278                   }
    4279 
    4280                 jj=0;
    4281                 detop = det(*(*t)(VerticesOfTriangularEdge[jj][0]),*(*t)(VerticesOfTriangularEdge[jj][1]),B);
    4282 
    4283                 while(t->det  > 0 ) {
    4284                         kkkk++;
    4285                         if (kkkk>=2000){
    4286                                 throw ErrorException(__FUNCT__,exprintf("kkkk>=2000"));
    4287                         }
    4288                         j= OppositeVertex[jj];
    4289                         dete[j] = detop;  //det(*b,*s1,*s2);
    4290                         jn = NextVertex[j];
    4291                         jp = PreviousVertex[j];
    4292                         dete[jp]= det(*(*t)(j),*(*t)(jn),B);
    4293                         dete[jn] = t->det-dete[j] -dete[jp];
    4294 
    4295                         // count the number k of  dete <0
    4296                         int k=0,ii[3];
    4297                         if (dete[0] < 0 ) ii[k++]=0;
    4298                         if (dete[1] < 0 ) ii[k++]=1;
    4299                         if (dete[2] < 0 ) ii[k++]=2;
    4300                         // 0 => ok
    4301                         // 1 => go in way 1
    4302                         // 2 => two way go in way 1 or 2 randomly
    4303 
    4304                         if (k==0) break;
    4305                         if (k == 2 && BinaryRand()) Exchange(ii[0],ii[1]);
    4306                         if ( k>=3){
    4307                                 throw ErrorException(__FUNCT__,exprintf("k>=3"));
    4308                         }
    4309                         TriangleAdjacent t1 = t->Adj(jj=ii[0]);
    4310                         if ((t1.det() < 0 ) && (k == 2))
    4311                          t1 = t->Adj(jj=ii[1]);
    4312                         t=t1;
    4313                         j=t1;// for optimisation we now the -det[OppositeVertex[j]];
    4314                         detop = -dete[OppositeVertex[jj]];
    4315                         jj = j;
    4316                   }
    4317 
    4318                 if (t->det<0) // outside triangle
    4319                  dete[0]=dete[1]=dete[2]=-1,dete[OppositeVertex[jj]]=detop;
    4320                 //  NbOfTriangleSearchFind += kkkk; 
    4321                 return t;
    4322         }
    4323         /*}}}1*/
    4324         /*FUNCTION Triangles::IntersectGeomMetric{{{1*/
    4325         void Triangles::IntersectGeomMetric(const Real8 err=1,const int iso=0){
    4326                 long int verbosity=0;
    4327                 Real8 ss[2]={0.00001,0.99999};
    4328                 Real8 errC = 2*sqrt(2*err);
    4329                 Real8 hmax = Gh.MaximalHmax();
    4330                 Real8 hmin = Gh.MinimalHmin();
    4331                 Real8 maxaniso = 1e6;
    4332                 if (hmax<=0){
    4333                         throw ErrorException(__FUNCT__,exprintf("hmax<=0"));
    4334                 }
    4335                 SetVertexFieldOn();
    4336                 if (errC > 1) errC = 1;
    4337                 for (Int4  i=0;i<nbe;i++)
    4338                  for (int j=0;j<2;j++)
    4339                         {
    4340 
    4341                          Vertex V;
    4342                          VertexOnGeom GV;
    4343                          Gh.ProjectOnCurve(edges[i],ss[j],V,GV);
    4344                                 {
    4345                                  GeometricalEdge * eg = GV;
    4346                                  Real8 s = GV;
    4347                                  R2 tg;
    4348                                  Real8  R1= eg->R1tg(s,tg);
    4349                                  Real8 ht = hmax;
    4350                                  if (R1>1.0e-20) {  // err relative to the length of the edge
    4351                                          ht = Min(Max(errC/R1,hmin),hmax);
    4352                                         }
    4353                                  Real8 hn = iso? ht : Min(hmax,ht*maxaniso);
    4354                                  if (ht<=0 || hn<=0){
    4355                                          throw ErrorException(__FUNCT__,exprintf("ht<=0 || hn<=0"));
    4356                                  }
    4357                                  MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg);
    4358                                  Metric MVp(Vp);
    4359                                  edges[i][j].m.IntersectWith(MVp);
    4360                                 }
    4361 
    4362                         }
    4363                 // the problem is for the vertex on vertex
    4364         }
    4365         /*}}}1*/
    4366         /*FUNCTION Triangles::BoundAnisotropy{{{1*/
    4367         void  Triangles::BoundAnisotropy(Real8 anisomax,Real8 hminaniso) {
    4368                 long int verbosity=0;
    4369 
    4370                 double lminaniso = 1/ (Max(hminaniso*hminaniso,1e-100));
    4371                 if (verbosity > 1)  printf("   BoundAnisotropy by %g\n",anisomax);
    4372                 Real8 h1=1.e30,h2=1e-30,rx=0;
    4373                 Real8 coef = 1./(anisomax*anisomax);
    4374                 Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
    4375                 for (Int4 i=0;i<nbv;i++)
    4376                   {
    4377 
    4378                         MatVVP2x2 Vp(vertices[i]);
    4379                         double lmax=Vp.lmax();
    4380                         h1=Min(h1,Vp.lmin());
    4381                         h2=Max(h2,Vp.lmax());
    4382                         rx = Max(rx,Vp.Aniso2());
    4383 
    4384                         Vp *= Min(lminaniso,lmax)/lmax;
    4385 
    4386                         Vp.BoundAniso2(coef);
    4387 
    4388                         hn1=Min(hn1,Vp.lmin());
    4389                         hn2=Max(hn2,Vp.lmax());
    4390                         rnx = Max(rnx,Vp.Aniso2());
    4391 
    4392 
    4393                         vertices[i].m = Vp;
    4394 
    4395                   }
    4396 
    4397                 if (verbosity>2){
    4398                         printf("      input:  Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(h2,-0.5),pow(h1,-0.5),pow(rx,0.5));
    4399                         printf("      output: Hmin = %g, Hmax = %g, factor of anisotropy max  = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
    4400                   }
    4401         }
    4402         /*}}}1*/
    4403         /*FUNCTION Triangles::IntersectConsMetric{{{1*/
    4404         void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols,
    4405                                 const  Real8 hmin1,const Real8 hmax1,const Real8 coef,
    4406                                 const Real8 anisomax ,const Real8 CutOff,const int NbJacobi,
    4407                                 const int DoNormalisation,const double power,const int choice)
    4408           { //  the array of solution s is store   
    4409                 // sol0,sol1,...,soln    on vertex 0
    4410                 //  sol0,sol1,...,soln   on vertex 1
    4411                 //  etc.
    4412                 //  choise = 0 =>  H is computed with green formule
    4413                 //   otherwise  => H is computed from P2 on 4T
    4414                 const int dim = 2;
    4415 
    4416                 long int verbosity=0;
    4417 
    4418                 int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ;
    4419 
    4420                 // computation of the nb of field
    4421                 Int4 ntmp = 0;
    4422                 if (typsols)
    4423                   {
    4424                         for (Int4 i=0;i<nbsol;i++)
    4425                          ntmp += sizeoftype[typsols[i]];
    4426                   }
    4427                 else
    4428                  ntmp = nbsol;
    4429 
    4430                 // n is the total number of fields
    4431 
    4432                 const Int4 n = ntmp;
    4433 
    4434                 Int4 i,k,iA,iB,iC,iv;
    4435                 R2 O(0,0);
    4436                 int RelativeMetric = CutOff>1e-30;
    4437                 Real8 hmin = Max(hmin1,MinimalHmin());
    4438                 Real8 hmax = Min(hmax1,MaximalHmax());
    4439                 Real8 coef2 = 1/(coef*coef);
    4440 
    4441                 if(verbosity>1) {
    4442                         printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",n,nbt,nbv);
    4443                         printf("      coef = %g\n",coef);
    4444                         printf("      hmin = %g hmax = %g\n",hmin,hmax);
    4445                         printf("      anisomax = %g nb Jacobi = %i, power = %i\n",anisomax,NbJacobi,power);
    4446                         if (RelativeMetric) printf("      RelativeErr with CutOff= %g\n",CutOff);
    4447                         else printf("      Absolute error\n");
    4448                   }
    4449                 double *ss=(double*)s;
    4450 
    4451                 double sA,sB,sC;
    4452 
    4453                 Real8 *detT = new Real8[nbt];
    4454                 Real8 *Mmass= new Real8[nbv];
    4455                 Real8 *Mmassxx= new Real8[nbv];
    4456                 Real8 *dxdx= new Real8[nbv];
    4457                 Real8 *dxdy= new Real8[nbv];
    4458                 Real8 *dydy= new Real8[nbv];
    4459                 Real8 *workT= new Real8[nbt];
    4460                 Real8 *workV= new Real8[nbv];
    4461                 int *OnBoundary = new int[nbv];
    4462                 for (iv=0;iv<nbv;iv++)
    4463                   {
    4464                         Mmass[iv]=0;
    4465                         OnBoundary[iv]=0;
    4466                         Mmassxx[iv]=0;
    4467                   }
    4468 
    4469                 for (i=0;i<nbt;i++)
    4470                  if(triangles[i].link) // the real triangles
    4471                         {
    4472                          const Triangle &t=triangles[i];
    4473                          // coor of 3 vertices
    4474                          R2 A=t[0];
    4475                          R2 B=t[1];
    4476                          R2 C=t[2];
    4477 
    4478 
    4479                          // number of the 3 vertices
    4480                          iA = Number(t[0]);
    4481                          iB = Number(t[1]);
    4482                          iC = Number(t[2]);
    4483 
    4484                          Real8 dett = bamg::Area2(A,B,C);
    4485                          detT[i]=dett;
    4486                          dett /= 6;
    4487 
    4488                          // construction of on boundary
    4489                          int nbb =0;
    4490                          for(int j=0;j<3;j++)
    4491                                 {
    4492                                  Triangle *ta=t.Adj(j);
    4493                                  if ( ! ta || !ta->link) // no adj triangle => edge on boundary
    4494                                   OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1,
    4495                                          OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1,
    4496                                          nbb++;
    4497                                 }
    4498 
    4499                          workT[i] = nbb;
    4500                          Mmass[iA] += dett;
    4501                          Mmass[iB] += dett;
    4502                          Mmass[iC] += dett;
    4503 
    4504                          if((nbb==0)|| !choice)
    4505                                 {
    4506                                  Mmassxx[iA] += dett;
    4507                                  Mmassxx[iB] += dett;
    4508                                  Mmassxx[iC] += dett;
    4509                                 }
    4510                         }
    4511                  else
    4512                   workT[i]=-1;
    4513 
    4514                 for (Int4 nusol=0;nusol<nbsol;nusol++)
    4515                   { //for all Solution 
    4516 
    4517                         Real8 smin=ss[0],smax=ss[0];
    4518 
    4519                         Real8 h1=1.e30,h2=1e-30,rx=0;
    4520                         Real8 coef = 1./(anisomax*anisomax);
    4521                         Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
    4522                         int nbfield = typsols? sizeoftype[typsols[nusol]] : 1;
    4523                         if (nbfield == 1)
    4524                          for ( iv=0,k=0; iv<nbv; iv++,k+=n )
    4525                                 {
    4526                                  dxdx[iv]=dxdy[iv]=dydy[iv]=0;
    4527                                  smin=Min(smin,ss[k]);
    4528                                  smax=Max(smax,ss[k]);
    4529                                 }
    4530                         else
    4531                           {
    4532                                 //  cas vectoriel
    4533                                 for ( iv=0,k=0; iv<nbv; iv++,k+=n )
    4534                                   {     
    4535                                         double v=0;                 
    4536                                         for (int i=0;i<nbfield;i++)
    4537                                          v += ss[k+i]*ss[k+i];
    4538                                         v = sqrt(v);
    4539                                         smin=Min(smin,v);
    4540                                         smax=Max(smax,v);
    4541                                   }
    4542                           }
    4543                         Real8 sdelta = smax-smin;
    4544                         Real8 absmax=Max(Abs(smin),Abs(smax));
    4545                         Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2;
    4546 
    4547                         if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, cnorm = %g, number of fields = %i\n",nusol,smin,smax,sdelta,cnorm,nbfield);
    4548 
    4549                         if ( sdelta < 1.0e-10*Max(absmax,1e-20) && (nbfield ==1)) {
    4550                                 if (verbosity>2) printf("      Solution %i is constant, skipping...\n");
    4551                                 continue;
    4552                           }
    4553 
    4554                         double *sf  = ss;
    4555                         for (Int4 nufield=0;nufield<nbfield;nufield++,ss++)
    4556                           {
    4557                                 for ( iv=0,k=0; iv<nbv; iv++,k+=n )
    4558                                  dxdx[iv]=dxdy[iv]=dydy[iv]=0;
    4559                                 for (i=0;i<nbt;i++)
    4560                                  if(triangles[i].link)
    4561                                         {// for real all triangles
    4562                                          // coor of 3 vertices
    4563                                          R2 A=triangles[i][0];
    4564                                          R2 B=triangles[i][1];
    4565                                          R2 C=triangles[i][2];
    4566 
    4567 
    4568                                          // warning the normal is internal and the
    4569                                          //   size is the length of the edge
    4570                                          R2 nAB = Orthogonal(B-A);
    4571                                          R2 nBC = Orthogonal(C-B);
    4572                                          R2 nCA = Orthogonal(A-C);
    4573                                          // remark :  nAB + nBC + nCA == 0
    4574 
    4575                                          // number of the 3 vertices
    4576                                          iA = Number(triangles[i][0]);
    4577                                          iB = Number(triangles[i][1]);
    4578                                          iC = Number(triangles[i][2]);
    4579 
    4580                                          // for the test of  boundary edge
    4581                                          // the 3 adj triangles
    4582                                          Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
    4583                                          Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
    4584                                          Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
    4585 
    4586                                          // value of the P1 fonction on 3 vertices
    4587                                          sA = ss[iA*n];
    4588                                          sB = ss[iB*n];
    4589                                          sC = ss[iC*n];
    4590 
    4591                                          R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ;
    4592                                          if(choice)
    4593                                                 {
    4594                                                  int nbb = 0;
    4595                                                  Real8 dd = detT[i];
    4596                                                  Real8 lla,llb,llc,llf;
    4597                                                  Real8  taa[3][3],bb[3];
    4598                                                  // construction of the trans of lin system
    4599                                                  for (int j=0;j<3;j++)
    4600                                                         {
    4601                                                          int ie = OppositeEdge[j];
    4602                                                          TriangleAdjacent ta = triangles[i].Adj(ie);
    4603                                                          Triangle *tt = ta;
    4604                                                          if (tt && tt->link)
    4605                                                                 {
    4606                                                                  Vertex &v = *ta.OppositeVertex();
    4607                                                                  R2 V = v;
    4608                                                                  Int4 iV = Number(v);
    4609                                                                  Real8 lA  = bamg::Area2(V,B,C)/dd;
    4610                                                                  Real8 lB  = bamg::Area2(A,V,C)/dd;
    4611                                                                  Real8 lC  = bamg::Area2(A,B,V)/dd;
    4612                                                                  taa[0][j] =  lB*lC;
    4613                                                                  taa[1][j] =  lC*lA;
    4614                                                                  taa[2][j] =  lA*lB;
    4615                                                                  lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ;
    4616 
    4617                                                                  bb[j]     =  ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ;
    4618                                                                 }
    4619                                                          else
    4620                                                                 {
    4621                                                                  nbb++;
    4622                                                                  taa[0][j]=0;
    4623                                                                  taa[1][j]=0;
    4624                                                                  taa[2][j]=0;
    4625                                                                  taa[j][j]=1;
    4626                                                                  bb[j]=0;
    4627                                                                 }
    4628                                                         }
    4629 
    4630                                                  // resolution of 3x3 lineaire system transpose
    4631                                                  Real8 det33 =  det3x3(taa[0],taa[1],taa[2]);           
    4632                                                  Real8 cBC   =  det3x3(bb,taa[1],taa[2]);
    4633                                                  Real8 cCA   =  det3x3(taa[0],bb,taa[2]);
    4634                                                  Real8 cAB   =  det3x3(taa[0],taa[1],bb);
    4635 
    4636                                                  if (!det33){
    4637                                                          throw ErrorException(__FUNCT__,exprintf("!det33"));
    4638                                                  }
    4639                                                  // computation of the gradient in the element
    4640 
    4641                                                  // H( li*lj) = grad li grad lj + grad lj grad lj
    4642                                                  // grad li = njk  / detT ; with i j k =(A,B,C)
    4643                                                  Real8 Hxx = cAB * ( nBC.x*nCA.x) +  cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x);
    4644                                                  Real8 Hyy = cAB * ( nBC.y*nCA.y) +  cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y);
    4645                                                  Real8 Hxy = cAB * ( nBC.y*nCA.x) +  cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x)
    4646                                                         + cAB * ( nBC.x*nCA.y) +  cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y);
    4647                                                  Real8 coef = 1.0/(3*dd*det33);
    4648                                                  Real8 coef2 = 2*coef;
    4649                                                  Hxx *= coef2;
    4650                                                  Hyy *= coef2;
    4651                                                  Hxy *= coef2;
    4652                                                  if(nbb==0)
    4653                                                         {
    4654                                                          dxdx[iA] += Hxx;
    4655                                                          dydy[iA] += Hyy;
    4656                                                          dxdy[iA] += Hxy;
    4657 
    4658                                                          dxdx[iB] += Hxx;
    4659                                                          dydy[iB] += Hyy;
    4660                                                          dxdy[iB] += Hxy;
    4661 
    4662                                                          dxdx[iC] += Hxx;
    4663                                                          dydy[iC] += Hyy;
    4664                                                          dxdy[iC] += Hxy;
    4665                                                         }
    4666 
    4667                                                 }
    4668                                          else
    4669                                                 {
    4670 
    4671                                                  // if edge on boundary no contribution  => normal = 0
    4672                                                  if ( ! tBC || ! tBC->link ) nBC = O;
    4673                                                  if ( ! tCA || ! tCA->link ) nCA = O;
    4674                                                  if ( ! tAB || ! tAB->link ) nAB = O;
    4675 
    4676                                                  // remark we forgot a 1/2 because
    4677                                                  //       $\\int_{edge} w_i = 1/2 $ if $i$ is in edge
    4678                                                  //                          0  if not
    4679                                                  // if we don't take the  boundary
    4680                                                  // dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
    4681 
    4682                                                  dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
    4683                                                  dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
    4684                                                  dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
    4685 
    4686                                                  // warning optimization (1) the divide by 2 is done on the metrix construction
    4687                                                  dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
    4688                                                  dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
    4689                                                  dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ;
    4690 
    4691                                                  dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
    4692                                                  dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
    4693                                                  dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
    4694                                                 }
    4695 
    4696                                         } // for real all triangles
    4697                                 Int4 kk=0;
    4698                                 for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
    4699                                  if(Mmassxx[iv]>0)
    4700                                         {
    4701                                          dxdx[iv] /= 2*Mmassxx[iv];
    4702                                          // warning optimization (1) on term dxdy[iv]*ci/2
    4703                                          dxdy[iv] /= 4*Mmassxx[iv];
    4704                                          dydy[iv] /= 2*Mmassxx[iv];
    4705                                          // Compute the matrix with abs(eigen value)
    4706                                          Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
    4707                                          MatVVP2x2 Vp(M);
    4708                                          Vp.Abs();
    4709                                          M = Vp;
    4710                                          dxdx[iv] = M.a11;
    4711                                          dxdy[iv] = M.a21;
    4712                                          dydy[iv] = M.a22;
    4713                                         }
    4714                                  else kk++;
    4715 
    4716 
    4717                                 // correction of second derivate
    4718                                 // by a laplacien
    4719 
    4720                                 Real8 *d2[3] = { dxdx, dxdy, dydy};
    4721                                 Real8 *dd;
    4722                                 for (int xy = 0;xy<3;xy++)
    4723                                   {
    4724                                         dd = d2[xy];
    4725                                         // do leat 2 iteration for boundary problem
    4726                                         for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++)
    4727                                           {
    4728                                                 for (i=0;i<nbt;i++)
    4729                                                  if(triangles[i].link) // the real triangles
    4730                                                         {
    4731                                                          // number of the 3 vertices
    4732                                                          iA = Number(triangles[i][0]);
    4733                                                          iB = Number(triangles[i][1]);
    4734                                                          iC = Number(triangles[i][2]);
    4735                                                          Real8 cc=3;
    4736                                                          if(ijacobi==0)
    4737                                                           cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
    4738                                                          workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
    4739                                                         }
    4740                                                 for (iv=0;iv<nbv;iv++)
    4741                                                  workV[iv]=0;
    4742 
    4743                                                 for (i=0;i<nbt;i++)
    4744                                                  if(triangles[i].link) // the real triangles
    4745                                                         {
    4746                                                          // number of the 3 vertices
    4747                                                          iA = Number(triangles[i][0]);
    4748                                                          iB = Number(triangles[i][1]);
    4749                                                          iC = Number(triangles[i][2]);
    4750                                                          Real8 cc =  workT[i]*detT[i];
    4751                                                          workV[iA] += cc;
    4752                                                          workV[iB] += cc;
    4753                                                          workV[iC] += cc;
    4754                                                         }
    4755 
    4756                                                 for (iv=0;iv<nbv;iv++)
    4757                                                  if( ijacobi<NbJacobi || OnBoundary[iv])
    4758                                                   dd[iv] = workV[iv]/(Mmass[iv]*6);
    4759 
    4760 
    4761                                           }
    4762 
    4763 
    4764                                   }
    4765 
    4766                                 // constuction  of the metrix from the Hessian dxdx. dxdy,dydy
    4767 
    4768                                 Real8 rCutOff=CutOff*absmax;// relative cut off
    4769 
    4770                                 for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
    4771                                   { // for all vertices
    4772                                         MetricIso Miso;
    4773                                         Real8 ci ;
    4774                                         if (RelativeMetric)
    4775                                           { //   compute the norm of the solution
    4776                                                 double xx =0,*sfk=sf+k;
    4777                                                 for (int ifield=0;ifield<nbfield;ifield++,sfk++)
    4778                                                  xx += *sfk* *sfk;             
    4779                                                 xx=sqrt(xx);
    4780                                                 ci = coef2/Max(xx,rCutOff);
    4781                                           }
    4782                                         else ci = cnorm;
    4783 
    4784                                         Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci,  dydy[iv]*ci);
    4785                                         MatVVP2x2 Vp(Miv);
    4786 
    4787                                         Vp.Abs();
    4788                                         if(power!=1.0)
    4789                                          Vp.pow(power);
    4790 
    4791 
    4792 
    4793                                         h1=Min(h1,Vp.lmin());
    4794                                         h2=Max(h2,Vp.lmax());
    4795 
    4796                                         Vp.Maxh(hmin);
    4797                                         Vp.Minh(hmax);
    4798 
    4799                                         rx = Max(rx,Vp.Aniso2());
    4800 
    4801                                         Vp.BoundAniso2(coef);
    4802 
    4803                                         hn1=Min(hn1,Vp.lmin());
    4804                                         hn2=Max(hn2,Vp.lmax());
    4805                                         rnx = Max(rnx,Vp.Aniso2());
    4806 
    4807                                         Metric MVp(Vp);
    4808                                         vertices[iv].m.IntersectWith(MVp);
    4809                                   }// for all vertices
    4810                                 if (verbosity>2) {
    4811                                         printf("      Field %i of solution %i\n",nufield,nusol);
    4812                                         printf("         before bounding : Hmin = %g, Hmax = %g, factor of anisotropy max = %g\n",pow(h2,-0.5), pow(h1,-0.5), pow(rx,0.5));
    4813                                         printf("         after  bounding : Hmin = %g, Hmax = %g, factor of anisotropy max = %g\n",pow(hn2,-0.5),pow(hn1,-0.5),pow(rnx,0.5));
    4814                                   }
    4815                           } //  end of for all field
    4816                   }// end for all solution
    4817 
    4818                 delete [] detT;
    4819                 delete [] Mmass;
    4820                 delete [] dxdx;
    4821                 delete [] dxdy;
    4822                 delete [] dydy;
    4823                 delete []  workT;
    4824                 delete [] workV;
    4825                 delete [] Mmassxx;
    4826                 delete []  OnBoundary;
    4827 
    4828           }
    4829         /*}}}1*/
    4830         /*FUNCTION Triangles::MaxSubDivision{{{1*/
    4831         void  Triangles::MaxSubDivision(Real8 maxsubdiv) {
    4832                 long int verbosity=0;
    4833 
    4834                 const  Real8 maxsubdiv2 = maxsubdiv*maxsubdiv;
    4835                 if(verbosity>1) printf("   Limit the subdivision of a edges in the new mesh by %g\n",maxsubdiv);
    4836                 // for all the edges
    4837                 // if the len of the edge is to long
    4838                 Int4 it,nbchange=0;   
    4839                 Real8 lmax=0;
    4840                 for (it=0;it<nbt;it++)
    4841                   {
    4842                         Triangle &t=triangles[it];
    4843                         for (int j=0;j<3;j++)
    4844                           {
    4845                                 Triangle &tt = *t.TriangleAdj(j);
    4846                                 if ( ! &tt ||  it < Number(tt) && ( tt.link || t.link))
    4847                                   {
    4848                                         Vertex &v0 = t[VerticesOfTriangularEdge[j][0]];
    4849                                         Vertex &v1 = t[VerticesOfTriangularEdge[j][1]];
    4850                                         R2 AB= (R2) v1-(R2) v0;
    4851                                         Metric M = v0;
    4852                                         Real8 l = M(AB,AB);
    4853                                         lmax = Max(lmax,l);
    4854                                         if(l> maxsubdiv2)
    4855                                           { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
    4856                                                 Real8 lc = M(AC,AC);
    4857                                                 D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
    4858                                                 D2xD2 Rt1(Rt.inv());
    4859                                                 D2xD2 D(maxsubdiv2,0,0,lc);
    4860                                                 D2xD2 MM = Rt1*D*Rt1.t();
    4861                                                 v0.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
    4862                                                 nbchange++;
    4863                                           }
    4864                                         M = v1;
    4865                                         l = M(AB,AB);
    4866                                         lmax = Max(lmax,l);
    4867                                         if(l> maxsubdiv2)
    4868                                           { R2 AC = M.Orthogonal(AB);// the ortogonal vector of AB in M
    4869                                                 Real8 lc = M(AC,AC);
    4870                                                 D2xD2 Rt(AB,AC);// Rt.x = AB , Rt.y = AC;
    4871                                                 D2xD2 Rt1(Rt.inv());
    4872                                                 D2xD2 D(maxsubdiv2,0,0,lc);
    4873                                                 D2xD2  MM = Rt1*D*Rt1.t();
    4874                                                 v1.m =  M = MetricAnIso(MM.x.x,MM.y.x,MM.y.y);
    4875                                                 nbchange++;
    4876                                           }
    4877 
    4878 
    4879                                   }
    4880                           }
    4881                   }
    4882                 if(verbosity>3){
    4883                         printf("      number of metric changes = %i, maximum number of subdivision of a edges before change = %g\n",nbchange,pow(lmax,0.5));
    4884                 }
    4885         }
    4886         /*}}}1*/
    4887         /*FUNCTION Triangles::SmoothMetric{{{1*/
    4888         void Triangles::SmoothMetric(Real8 raisonmax) {
    4889                 long int verbosity=0;
    4890 
    4891                 if(raisonmax<1.1) return;
    4892                 if(verbosity > 1) printf("   Triangles::SmoothMetric raisonmax = %g\n",raisonmax);
    4893                 ReMakeTriangleContainingTheVertex();
    4894                 Int4 i,j,kch,kk,ip;
    4895                 Int4 *first_np_or_next_t0 = new Int4[nbv];
    4896                 Int4 *first_np_or_next_t1 = new Int4[nbv];
    4897                 Int4 Head0 =0,Head1=-1;
    4898                 Real8 logseuil= log(raisonmax);
    4899 
    4900                 for(i=0;i<nbv-1;i++)
    4901                  first_np_or_next_t0[i]=i+1;
    4902                 first_np_or_next_t0[nbv-1]=-1;// end;
    4903                 for(i=0;i<nbv;i++)
    4904                  first_np_or_next_t1[i]=-1;
    4905                 kk=0;
    4906                 while (Head0>=0&& kk++<100) {
    4907                         kch=0;
    4908                         for (i=Head0;i>=0;i=first_np_or_next_t0[ip=i],first_np_or_next_t0[ip]=-1) {
    4909                                 //  pour tous les triangles autour du sommet s
    4910                                 register Triangle* t= vertices[i].t;
    4911                                 if (!t){
    4912                                         throw ErrorException(__FUNCT__,exprintf("!t"));
    4913                                 }
    4914                                 Vertex & vi = vertices[i];
    4915                                 TriangleAdjacent ta(t,EdgesVertexTriangle[vertices[i].vint][0]);
    4916                                 Vertex *pvj0 = ta.EdgeVertex(0);
    4917                                 while (1) {
    4918                                         ta=Previous(Adj(ta));
    4919                                         if (vertices+i != ta.EdgeVertex(1)){
    4920                                                 throw ErrorException(__FUNCT__,exprintf("vertices+i != ta.EdgeVertex(1)"));
    4921                                         }
    4922                                         Vertex & vj = *(ta.EdgeVertex(0));
    4923                                         if ( &vj ) {
    4924                                                 j= &vj-vertices;
    4925                                                 if (j<0 || j >= nbv){
    4926                                                         throw ErrorException(__FUNCT__,exprintf("j<0 || j >= nbv"));
    4927                                                 }
    4928                                                 R2 Aij = (R2) vj - (R2) vi;
    4929                                                 Real8 ll =  Norme2(Aij);
    4930                                                 if (0) { 
    4931                                                         Real8 hi = ll/vi.m(Aij);
    4932                                                         Real8 hj = ll/vj.m(Aij);
    4933                                                         if(hi < hj)
    4934                                                           {
    4935                                                                 Real8 dh=(hj-hi)/ll;
    4936                                                                 if (dh>logseuil) {
    4937                                                                         vj.m.IntersectWith(vi.m/(1 +logseuil*ll/hi));
    4938                                                                         if(first_np_or_next_t1[j]<0)
    4939                                                                          kch++,first_np_or_next_t1[j]=Head1,Head1=j;
    4940                                                                 }
    4941                                                           }
    4942                                                 }
    4943                                                 else
    4944                                                   {
    4945                                                         Real8 li = vi.m(Aij);
    4946                                                         if( vj.m.IntersectWith(vi.m/(1 +logseuil*li)) )
    4947                                                          if(first_np_or_next_t1[j]<0) // if the metrix change
    4948                                                           kch++,first_np_or_next_t1[j]=Head1,Head1=j;
    4949                                                   }
    4950                                         }
    4951                                         if  ( &vj ==  pvj0 ) break;
    4952                                 }
    4953                           }
    4954                         Head0 = Head1;
    4955                         Head1 = -1;
    4956                         Exchange(first_np_or_next_t0,first_np_or_next_t1);
    4957                 }
    4958                 if(verbosity>2) printf("      number of iterations = %i\n",kch);
    4959                 delete [] first_np_or_next_t0;
    4960                 delete [] first_np_or_next_t1;
    4961         }
    4962         /*}}}1*/
    4963         /*FUNCTION Triangles::NearestVertex{{{1*/
    4964         Vertex * Triangles::NearestVertex(Icoor1 i,Icoor1 j) {
    4965                 return  quadtree->NearestVertex(i,j);
    4966         }
    4967         /*}}}1*/
    4968         /*FUNCTION Triangles::PreInit{{{1*/
    4969         void Triangles::PreInit(Int4 inbvx,char *fname) {
    4970                 long int verbosity=0;
    4971 
    4972                 srand(19999999);
    4973                 OnDisk =0;
    4974                 NbRef=0;
    4975                 //  allocGeometry=0;
    4976                 identity=0;
    4977                 NbOfTriangleSearchFind =0;
    4978                 NbOfSwapTriangle =0;
    4979                 nbiv=0;
    4980                 nbv=0;
    4981                 nbvx=inbvx;
    4982                 nbt=0;
    4983                 NbOfQuad = 0;
    4984                 nbtx=2*inbvx-2;
    4985                 NbSubDomains=0;
    4986                 NbVertexOnBThVertex=0;
    4987                 NbVertexOnBThEdge=0;
    4988                 VertexOnBThVertex=0;
    4989                 VertexOnBThEdge=0;
    4990 
    4991                 NbCrackedVertices=0;
    4992                 NbCrackedEdges =0;
    4993                 CrackedEdges  =0; 
    4994                 nbe = 0;
    4995                 name = fname ;
    4996 
    4997                 if (inbvx) {
    4998                         vertices=new Vertex[nbvx];
    4999                         if (!vertices){
    5000                                 throw ErrorException(__FUNCT__,exprintf("!vertices"));
    5001                         }
    5002                         ordre=new (Vertex* [nbvx]);
    5003                         if (!ordre){
    5004                                 throw ErrorException(__FUNCT__,exprintf("!ordre"));
    5005                         }
    5006                         triangles=new Triangle[nbtx];
    5007                         if (!triangles){
    5008                                 throw ErrorException(__FUNCT__,exprintf("!triangles"));
    5009                         }
    5010                 }
    5011                 else {
    5012                         vertices=0;
    5013                         ordre=0;
    5014                         triangles=0;
    5015                         nbtx=0;
    5016                 }
    5017                 if ( name || inbvx) {
    5018                         time_t timer =time(0);
    5019                         char buf[70];     
    5020                         strftime(buf ,70,", Date: %y/%m/%d %H:%M %Ss",localtime(&timer));
    5021                         counter++;
    5022                         char countbuf[30];   
    5023                         sprintf(countbuf,"%d",counter);
    5024                         int lg =0 ;
    5025                         if (&BTh != this && BTh.name)
    5026                          lg = strlen(BTh.name)+4;
    5027                         identity = new char[ lg + strlen(buf) + strlen(countbuf)+ 2  + 10 + ( Gh.name ? strlen(Gh.name) + 4 : 0)];
    5028                         identity[0]=0;
    5029                         if (lg)
    5030                          strcat(strcat(strcat(identity,"B="),BTh.name),", ");
    5031 
    5032                         if (Gh.name)
    5033                          strcat(strcat(identity,"G="),Gh.name);
    5034                         strcat(strcat(identity,";"),countbuf);
    5035                         strcat(identity,buf);
    5036                   }
    5037 
    5038                 quadtree=0;
    5039                 edges=0;
    5040                 VerticesOnGeomVertex=0;
    5041                 VerticesOnGeomEdge=0;
    5042                 NbVerticesOnGeomVertex=0;
    5043                 NbVerticesOnGeomEdge=0;
    5044                 subdomains=0;
    5045                 NbSubDomains=0;
    5046         }
    5047         /*}}}1*/
     5041        for (int i=0;i<NbCrackedEdges;i++)
     5042         CrackedEdges[i].UnCrack();
     5043        return NbCrackedEdges;
     5044}
     5045/*}}}1*/
    50485046
    50495047        /*Intermediary*/
Note: See TracChangeset for help on using the changeset viewer.