Changeset 2877
- Timestamp:
- 01/20/10 16:10:17 (15 years ago)
- Location:
- issm/trunk/src/c/Bamgx
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/Bamgx/Bamgx.cpp
r2865 r2877 84 84 //build metric if not given in input 85 85 if (verbosity>1) printf(" Generating Metric...\n"); 86 for(i=0;i<Gh.nbv;i++) 87 { 86 for(i=0;i<Gh.nbv;i++){ 88 87 MetricAnIso M=Gh[i]; 89 88 MatVVP2x2 Vp(M/coef); … … 91 90 Vp.Minh(hmax); 92 91 Gh.vertices[i].m = Vp; 93 92 } 94 93 95 94 //generate mesh -
issm/trunk/src/c/Bamgx/Mesh2.h
r2870 r2877 219 219 int cas; 220 220 friend class Geometry; 221 GeometricalVertex 221 GeometricalVertex* link; // link all the same GeometricalVertex circular (Crack) 222 222 public: 223 223 int Corner() const {return cas&4;} … … 228 228 GeometricalVertex() :cas(0), link(this) {}; 229 229 230 GeometricalVertex 230 GeometricalVertex* The() { 231 231 if (!link){ 232 232 throw ErrorException(__FUNCT__,exprintf("!link")); 233 233 } 234 234 return link; 235 }// return a unique vert ices235 }// return a unique vertex 236 236 237 237 int IsThe() const { return link == this;} … … 249 249 // if tg[0] =0 => no continuite 250 250 GeometricalEdge * Adj [2]; 251 int SensAdj[2];251 int DirAdj[2]; 252 252 // private: 253 253 int flag ; … … 656 656 657 657 int static counter; // to kown the number of mesh in memory 658 int OnDisk; // true if on disk659 658 Geometry & Gh; // Geometry 660 659 Triangles & BTh; // Background Mesh Bth==*this =>no background … … 713 712 Triangles(BamgMesh* bamgmesh,BamgOpts* bamgopts); 714 713 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 726 726 727 727 void SetIntCoor(const char * from =0); … … 746 746 void ForceBoundary(); 747 747 void Heap(); 748 void FindSubDomain(int );748 void FindSubDomain(int OutSide=0); 749 749 Int4 ConsRefTriangle(Int4 *) const; 750 750 void ShowHistogram() const; … … 820 820 class Geometry { 821 821 public: 822 int OnDisk;823 822 Int4 NbRef; // counter of ref on the this class if 0 we can delete 824 823 … … 832 831 Int4 NbOfCurves; 833 832 int empty(){return (nbv ==0) && (nbt==0) && (nbe==0) && (NbSubDomains==0); } 834 GeometricalVertex * vertices; // data of vertices des sommets833 GeometricalVertex* vertices; 835 834 Triangle * triangles; 836 835 GeometricalEdge * edges; … … 859 858 Geometry() {EmptyGeometry();}// empty Geometry 860 859 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();} 862 861 863 862 const GeometricalVertex & operator[] (Int4 i) const { return vertices[i];}; … … 1143 1142 1144 1143 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];} 1146 1145 1147 1146 inline Real4 qualite(const Vertex &va,const Vertex &vb,const Vertex &vc) -
issm/trunk/src/c/Bamgx/QuadTree.h
r2862 r2877 9 9 const IntQuad MaxISize = ( 1L << MaxDeep); 10 10 11 12 11 class Triangles; 13 12 class Vertex; … … 15 14 class QuadTree { 16 15 public: 17 18 16 class QuadTreeBox { 19 17 public: 20 21 18 long n; // if n < 4 => Vertex else => QuadTreeBox; 22 19 union { … … 24 21 Vertex * v[4]; 25 22 }; 26 27 28 }; // end class QuadTreeBox ///////////////// 29 23 }; // end class 30 24 class StorageQuadTreeBox { 31 25 public: … … 41 35 return len*sizeof(QuadTreeBox)+sizeof(StorageQuadTreeBox)+ (n?n->SizeOf():0); 42 36 } 43 }; // end class StorageQuadTreeBox 44 37 }; // end class 45 38 StorageQuadTreeBox * sb; 46 47 48 39 long lenStorageQuadTreeBox; 49 40 50 41 public: 51 QuadTreeBox 52 Triangles *th;42 QuadTreeBox* root; 43 Triangles* th; 53 44 long NbQuadTreeBox,NbVertices; 54 45 long NbQuadTreeBoxSearch,NbVerticesSearch; 55 Vertex 56 Vertex * NearestVertexWithNormal(Icoor1 i,Icoor1 j); // new version57 Vertex 46 Vertex* NearestVertex(Icoor1 i,Icoor1 j); 47 Vertex* NearestVertexWithNormal(Icoor1 i,Icoor1 j); 48 Vertex* ToClose(Vertex & ,Real8 ,Icoor1,Icoor1); 58 49 long SizeOf() const {return sizeof(QuadTree)+sb->SizeOf();} 59 60 61 50 void Add( Vertex & w); 62 63 51 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); 67 53 if (!sb || (sb->bc->n != 0)){ 68 54 throw ErrorException(__FUNCT__,exprintf("!sb || (sb->bc->n != 0)")); -
issm/trunk/src/c/Bamgx/objects/Geometry.cpp
r2865 r2877 314 314 edges[i].tg[0]=zero2; 315 315 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; 317 317 edges[i].Adj[0] = edges[i].Adj[1] = 0; 318 318 edges[i].flag = 0; … … 483 483 484 484 /*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 geometry511 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 else528 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 edge633 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*/662 485 /*FUNCTION Geometry::AfterRead(){{{1*/ 663 void Geometry::AfterRead() 486 void Geometry::AfterRead(){ 664 487 long int verbosity=0; 665 488 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; 672 495 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; 687 512 if ( v != &(Vertex &) vertices[j]){ 688 513 throw ErrorException(__FUNCT__,exprintf(" v != &(Vertex &) vertices[j]")); … … 690 515 vertices[i].link = vertices + j; 691 516 k++; 692 517 } 693 518 else quadtree.Add(vertices[i]); 694 519 } 695 520 if (k) { 696 521 printf("number of distinct vertices= %i, over %i\n",nbv - k,nbv); … … 702 527 } 703 528 704 // verification of cracked edge 529 // verification of cracked edge (to be completed) 705 530 for (i=0;i<nbe;i++){ 706 531 if (edges[i].Cracked() ) { … … 710 535 if ( e1[0].The() == e2[0].The() && e1[1].The() == e2[1].The() ) 711 536 { 537 //nothing 712 538 } 713 539 else … … 722 548 } 723 549 550 //build hv and ev 724 551 for (i=0;i<nbv;i++) hv[i]=-1;// empty list 725 726 552 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; 728 554 Real8 lv10 = Norme2(v10); 729 555 if(lv10 == 0) { … … 731 557 } 732 558 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++; 738 563 } 739 564 } … … 804 629 } 805 630 edges[i1].Adj[j1] = edges + i; 806 edges[i1]. SensAdj[j1] = jj;631 edges[i1].DirAdj[j1] = jj; 807 632 } 808 633 … … 819 644 if( ! edges[i].v[jj]->Corner()) { // not a Corner 820 645 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; 822 647 ltg = Norme2(tg); 823 648 tg = tg *(lAB/ltg),ltg=lAB; … … 838 663 } // for (i=0;i<nbe;i++) 839 664 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(); 844 667 845 668 NbOfCurves = 0; … … 872 695 GeometricalVertex *b=(*e)(k1); 873 696 if (a == b || b->Required() ) break; 874 k0 = e-> SensAdj[k1];// vertex in next edge697 k0 = e->DirAdj[k1];// vertex in next edge 875 698 e = e->Adj[k1]; // next edge 876 699 … … 887 710 } 888 711 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++){ 895 717 GeometricalEdge * be=curves[i].be, *eqbe=be->link; 896 718 //GeometricalEdge * ee=curves[i].ee, *eqee=be->link; … … 909 731 if(be->ReverseEqui()) 910 732 curves[i].Reverse(); 911 912 733 } 734 } 913 735 914 736 delete []ev; … … 918 740 } 919 741 /*}}}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; 793 retry: 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*/ 920 918 921 919 } -
issm/trunk/src/c/Bamgx/objects/QuadTree.cpp
r2865 r2877 51 51 NbVertices(0), 52 52 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 } 58 57 /*}}}1*/ 59 58 /*FUNCTION QuadTree::~QuadTree(){{{1*/ … … 65 64 66 65 /*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*/ 67 109 /*FUNCTION QuadTree::NearestVertex{{{1*/ 68 110 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]; 72 114 register int l=0; // level 73 115 register QuadTreeBox * b; … … 80 122 Vertex *vn=0; 81 123 82 // init for optimi sation ---124 // init for optimization 83 125 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){ 90 131 // search the non empty 91 132 // QuadTreeBox containing the point (i,j) … … 93 134 register int k = IJ(iplus,jplus,hb2);// QuadTreeBox number of size hb2 contening i;j 94 135 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 97 137 NbQuadTreeBoxSearch++; 98 138 b=b0; … … 100 140 j0 += J_IJ(k,hb2); // j orign of QuadTreeBox 101 141 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++){ 109 146 I2 i2 = b->v[k]->i; 110 147 h0 = NORM(iplus,i2.x,jplus,i2.y); … … 113 150 vn = b->v[k];} 114 151 NbVerticesSearch++; 115 152 } 116 153 return vn; 117 } 118 // general case ----- 154 } 155 156 // general case 119 157 pb[0]= b; 120 158 pi[0]=b->n>0 ?(int) b->n : 4 ; … … 124 162 do { 125 163 b= pb[l]; 126 while (pi[l]--) 127 { 164 while (pi[l]--){ 128 165 register int k = pi[l]; 129 166 130 if (b->n>0) // Vertex QuadTreeBox none empty 131 { 167 if (b->n>0){ // Vertex QuadTreeBox none empty 132 168 NbVerticesSearch++; 133 169 I2 i2 = b->v[k]->i; … … 138 174 vn = b->v[k]; 139 175 } 140 } 141 else // Pointer QuadTreeBox 142 { 176 } 177 else{ // Pointer QuadTreeBox 143 178 register QuadTreeBox *b0=b; 144 179 NbQuadTreeBoxSearch++; 145 if ((b=b->b[k])) 146 { 180 if ((b=b->b[k])){ 147 181 hb >>=1 ; // div by 2 148 182 register Icoor1 iii = ii[l]+I_IJ(k,hb); 149 183 register Icoor1 jjj = jj[l]+J_IJ(k,hb); 150 184 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)){ 153 186 pb[++l]= b; 154 187 pi[l]= b->n>0 ?(int) b->n : 4 ; … … 156 189 jj[l]= jjj; 157 190 158 159 else 160 161 162 else163 b=b0;164 165 191 } 192 else{ 193 b=b0, hb <<=1 ; 194 } 195 } 196 else b=b0; 197 } 198 } 166 199 hb <<= 1; // mul by 2 167 200 } while (l--); 168 169 201 return vn; 170 202 } … … 280 312 } 281 313 /*}}}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*/ 282 328 /*FUNCTION QuadTree::ToClose {{{1*/ 283 329 Vertex * QuadTree::ToClose(Vertex & v,Real8 seuil,Icoor1 hx,Icoor1 hy){ … … 357 403 } 358 404 /*}}}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 full380 {381 Vertex *v4[4]; // copy of the QuadTreeBox vertices382 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 QuadTreeBox388 b->b[0]=b->b[1]=b->b[2]=b->b[3]=0; // set empty QuadTreeBox ptr389 l >>= 1; // div the size by 2390 for (register int k=0;k<4;k++) // for the 4 vertices find the sub QuadTreeBox ij391 {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 QuadTreeBox396 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 QuadTreeBox402 b->v[b->n++]=&w; // we add the vertex403 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*/420 405 421 406 } -
issm/trunk/src/c/Bamgx/objects/Triangles.cpp
r2870 r2877 27 27 28 28 PreInit(0,"none"); 29 OnDisk = 1;30 31 29 ReadMesh(bamgmesh,bamgopts); 32 30 SetIntCoor(); … … 35 33 /*}}}1*/ 36 34 /*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) { 39 36 40 37 char cname[] = "trunc"; … … 729 726 730 727 /*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*/ 731 886 /*FUNCTION Triangles::ConsGeometry{{{1*/ 732 887 void Triangles::ConsGeometry(Real8 cutoffradian,int *equiedges) // construct a geometry if no geo … … 772 927 if (nbe != edge4->nb()){ 773 928 throw ErrorException(__FUNCT__,exprintf("Some Double edge in the mesh, the number is %i, nbe4=%i",nbe,edge4->nb())); 774 929 } 775 930 for (i=0;i<nbt;i++){ 776 931 for (j=0;j<3;j++) { … … 810 965 printf(" - Euler number 1 - nb of holes = %i \n" ,nbt-edge4->nb()+nbv); 811 966 } 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 } 813 1110 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]); 873 1167 } 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; 875 1269 } 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)); 1125 1280 1126 1281 } 1127 1282 /*}}}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")); 1217 1299 } 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++; 1220 1349 } 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 1229 1395 } 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++; 1233 1403 } 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 1493 1446 } 1494 1447 } 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; 1504 1450 } 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*/ 2462 1460 /*FUNCTION Triangles::ForceBoundary{{{1*/ 2463 1461 void Triangles::ForceBoundary() { … … 2497 1495 } 2498 1496 /*}}}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*/ 2499 1788 /*FUNCTION Triangles::FindSubDomain{{{1*/ 2500 void Triangles::FindSubDomain(int OutSide =0) {1789 void Triangles::FindSubDomain(int OutSide) { 2501 1790 long int verbosity=0; 2502 1791 … … 2747 2036 } 2748 2037 /*}}}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; 2815 2125 } 2816 2126 /*}}}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 } 2836 2351 } 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")); 2839 2356 } 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")); 2901 2359 } 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; 2907 2381 } 2908 2382 /*}}}1*/ … … 3248 2722 } 3249 2723 /*}}}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*/ 2725 void 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"); 3502 2769 } 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 } 3519 2863 } 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++) 3603 2877 { 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 3838 2920 for (int j=0;j<3;j++) 3839 2921 { 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) 3845 2926 { 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; 3849 2948 } 3850 2949 } 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 3851 2988 } 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*/ 3152 void 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; 3881 3298 } 3299 ReMakeTriangleContainingTheVertex(); 3300 // because we break the TriangleContainingTheVertex 3301 #endif 3882 3302 CurrentTh=OldCurrentTh; 3883 3303 } 3884 3304 /*}}}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*/ 3379 Edge** 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*/ 3461 void Triangles::MakeQuadTree() { 3462 long int verbosity=0; 3463 if ( !quadtree ) quadtree = new QuadTree(this); 3464 3465 } 3466 /*}}}1*/ 3467 /*FUNCTION Triangles::MaxSubDivision{{{1*/ 3468 void 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*/ 3544 Vertex * 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 3895 3587 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")); 3902 3601 } 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*/ 3683 Int4 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 } 3910 3700 t= tp->at[jp]; // set unchange t qnd j for previous triangles 3911 3701 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*/ 3715 void 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 3915 3996 } 3916 3997 /*}}}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++) 3940 4013 { 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)]; 3951 4017 } 3952 4018 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 3955 4064 } 3956 4065 /*}}}1*/ 3957 /*FUNCTION Triangles::MakeQuadTree{{{1*/ 3958 void Triangles::MakeQuadTree() { 4066 /*FUNCTION Triangles::SetIntCoor{{{1*/ 4067 void 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*/ 4116 void 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*/ 4180 void 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*/ 4224 void 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*/ 4264 void 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){ 3959 4341 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 4835 Error: 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 3962 4850 } 3963 4851 /*}}}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*/ 4853 Int4 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 } 4915 if (NbSplitEdge>nbv-nbvold) printf("WARNING: not enough vertices to split all internal edges, we lost %i edges...\n",NbSplitEdge - ( nbv-nbvold)); 4916 if (verbosity>2) printf("SplitInternalEdgeWithBorderVertices: Number of splited edge %i\n",NbSplitEdge); 4917 4918 return 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; 4026 5034 } 4027 5035 /*}}}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*/ 5037 int Triangles::UnCrack() { 5038 if (NbCrackedEdges!=0 && NbCrackedVertices<=0);{ 5039 throw ErrorException(__FUNCT__,exprintf("NbCrackedEdges ==0 || NbCrackedVertices >0")); 4070 5040 } 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*/ 5048 5046 5049 5047 /*Intermediary*/
Note:
See TracChangeset
for help on using the changeset viewer.