Changeset 2957


Ignore:
Timestamp:
02/04/10 08:32:31 (15 years ago)
Author:
Mathieu Morlighem
Message:

minor

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

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/Bamgx/Mesh2.h

    r2955 r2957  
    660660                        Int4 NbOfTriangleSearchFind;
    661661                        Int4 NbOfSwapTriangle;
    662                         char * name, *identity;
    663662                        Vertex * vertices;   // data of vertices des sommets
    664663
     
    710709
    711710                        Triangles(Triangles &,Geometry * pGh=0,Triangles* pBTh=0,Int4 nbvxx=0 ); // COPY OPERATEUR
    712                         Triangles(const Triangles &,const int *flag,const int *bb); // truncature
     711                        Triangles(const Triangles &,const int *flag,const int *bb,BamgOpts* bamgopts); // truncature
    713712
    714713                        void SetIntCoor(const char * from =0);
     
    786785                        int UnCrack();
    787786
    788                         void ConsGeometry(Real8 =-1.0,int *equiedges=0); // construct a geometry if no geo
     787                        void BuildGeometryFromMesh(BamgOpts* bamgopts);
    789788                        void FillHoleInMesh() ;
    790789                        int  CrackMesh();
     
    792791                        void GeomToTriangles1(Int4 nbvx,int KeepVertices=1);// the real constructor mesh adaption
    793792                        void GeomToTriangles0(Int4 nbvx);                   // the real constructor mesh generator
    794                         void PreInit(Int4,char* =NULL );
     793                        void PreInit(Int4);
    795794
    796795        };
     
    801800                        Int4 NbRef; // counter of ref on the this class if 0 we can delete
    802801
    803                         char *name;
    804802                        Int4 nbvx,nbtx; // nombre max  de sommets , de  Geometry
    805803                        Int4 nbv,nbt,nbiv,nbe; // nombre de sommets, de Geometry, de sommets initiaux,
  • issm/trunk/src/c/Bamgx/objects/Geometry.cpp

    r2945 r2957  
    2626                NbRef =0;
    2727                quadtree=0;
    28                 name = new char[strlen(Gh.name)+4];
    29                 strcpy(name,"cp:");
    30                 strcat(name,Gh.name);
    3128                vertices = nbv ? new GeometricalVertex[nbv] : NULL;
    3229                triangles = nbt ? new  Triangle[nbt]:NULL;
     
    6057                if(quadtree)  delete  quadtree;quadtree=0;
    6158                if(curves)  delete  []curves;curves=0;NbOfCurves=0;
    62                 if(name) delete [] name;name=0;
    6359                if(subdomains) delete [] subdomains;subdomains=0;
    6460                //  if(ordre)     delete [] ordre;
     
    877873
    878874                printf("Geometry:\n");
    879                 printf("   name: %s\n",name);
    880875                printf("   nbvx (maximum number of vertices) : %i\n",nbvx);
    881876                printf("   nbtx (maximum number of triangles): %i\n",nbtx);
     
    905900        void Geometry::EmptyGeometry() {
    906901                NbRef=0;
    907                 name =0;
    908902                quadtree=0;
    909903                curves=0;
  • issm/trunk/src/c/Bamgx/objects/Triangles.cpp

    r2955 r2957  
    2626        Triangles::Triangles(BamgMesh* bamgmesh, BamgOpts* bamgopts):Gh(*(new Geometry())),BTh(*this){
    2727
    28                 PreInit(0,"none");
     28                PreInit(0);
    2929                ReadMesh(bamgmesh,bamgopts);
    3030                SetIntCoor();
     
    3333        /*}}}1*/
    3434        /*FUNCTION Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb){{{1*/
    35         Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb) : Gh(*(new Geometry())), BTh(*this) {
    36 
    37                   char cname[] = "trunc";
     35        Triangles::Triangles(const Triangles & Tho,const int *flag ,const int *bb,BamgOpts* bamgopts) : Gh(*(new Geometry())), BTh(*this) {
    3836
    3937                  int i,k,itadj;
     
    8381                  printf("   number of New boundary edge %i\n",nbNewBedge);
    8482                  Int4 inbvx =k;
    85                   PreInit(inbvx,cname);
     83                  PreInit(inbvx);
    8684                  for (i=0;i<Tho.nbv;i++)
    8785                        if (kk[i]>=0)
     
    121119                  delete [] reft;
    122120                  delete [] refv;
    123                   double cutoffradian = 10.0/180.0*Pi;
    124                   ConsGeometry(cutoffradian);
     121                  //double cutoffradian = 10.0/180.0*Pi;
     122                  BuildGeometryFromMesh(bamgopts);
    125123                  Gh.AfterRead();
    126124                  SetIntCoor();
     
    148146                if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;
    149147                if (VerticesOnGeomVertex) delete [] VerticesOnGeomVertex;
    150                 //if (name) delete [] name; //TEST crash if not commented
    151                 if (identity) delete [] identity;
    152148                if (VertexOnBThVertex) delete [] VertexOnBThVertex;
    153149                if (VertexOnBThEdge) delete [] VertexOnBThEdge;
     
    172168                  // do all the allocation to be sure all the pointer existe
    173169
    174                   char * cname = 0;
    175                   if (Th.name)
    176                          {
    177                           cname = new char[strlen(Th.name)+1];
    178                           strcpy(cname,Th.name);
    179                          }
    180                   PreInit(nbvxx,cname);// to make the allocation
     170                  PreInit(nbvxx);// to make the allocation
    181171                  // copy of triangles
    182172                  nt=Th.nt;
     
    302292                        triangles =new Triangle[nbt];
    303293                        for (i=0;i<bamgmesh->NumQuadrilaterals;i++){
     294                                //divide the quad into two triangles
    304295                                Triangle & t1 = triangles[2*i];
    305296                                Triangle & t2 = triangles[2*i+1];
     
    466457                        printf("WARNING: mesh present but no geometry found. Reconstructing...\n");
    467458                        /*Recreate geometry: */
    468                         ConsGeometry(bamgopts->MaximalAngleOfCorner*Pi/180);
     459                        BuildGeometryFromMesh(bamgopts);
    469460                        Gh.AfterRead();
    470461                }
     
    885876        }
    886877        /*}}}1*/
    887         /*FUNCTION Triangles::BuildMetric0 (double P2 projection){{{1*/
    888         void Triangles::BuildMetric0(BamgOpts* bamgopts){
    889 
    890                 /*Options*/
    891                 const int dim = 2;
    892                 double* s=NULL;
    893                 Int4    nbsol;
    894                 int     verbosity;
    895 
    896                 int   i,j,k,iA,iB,iC;
    897                 int   iv;
     878        /*FUNCTION Triangles::BuildGeometryFromMesh{{{1*/
     879        void Triangles::BuildGeometryFromMesh(BamgOpts* bamgopts){
     880                /*Reconstruct Geometry from Mesh*/
     881
     882                /*Intermediary*/
     883                int i,j,k;
    898884
    899885                /*Recover options*/
    900                 verbosity=bamgopts->verbose;
    901 
    902                 /*Get and process fields*/
    903                 s=bamgopts->field;
    904                 nbsol=bamgopts->numfields;
    905 
    906                 //initialization of some variables
    907                 double* ss=(double*)s;
    908                 double  sA,sB,sC;
    909                 Real8*  detT = new Real8[nbt];
    910                 Real8*  sumareas = new Real8[nbv];
    911                 Real8*  alpha= new Real8[nbt*3];
    912                 Real8*  beta = new Real8[nbt*3];
    913                 Real8*  dx_elem    = new Real8[nbt];
    914                 Real8*  dy_elem    = new Real8[nbt];
    915                 Real8*  dx_vertex  = new Real8[nbv];
    916                 Real8*  dy_vertex  = new Real8[nbv];
    917                 Real8*  dxdx_elem  = new Real8[nbt];
    918                 Real8*  dxdy_elem  = new Real8[nbt];
    919                 Real8*  dydy_elem  = new Real8[nbt];
    920                 Real8*  dxdx_vertex= new Real8[nbv];
    921                 Real8*  dxdy_vertex= new Real8[nbv];
    922                 Real8*  dydy_vertex= new Real8[nbv];
    923 
    924                 //display infos
    925                 if(verbosity>1) {
    926                         printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
    927                 }
    928 
    929                 //first, build the chains that will be used for the Hessian computation, as weel as the area of each element
    930                 int head_s[nbv];
    931                 int next_p[3*nbt];
    932                 int  p=0;
    933                 //initialization
    934                 for(i=0;i<nbv;i++){
    935                         sumareas[i]=0;
    936                         head_s[i]=-1;
    937                 }
    938                 for(i=0;i<nbt;i++){
    939 
    940                         //lopp over the real triangles (no boundary elements)
    941                         if(triangles[i].link){
    942 
    943                                 //get current triangle t
    944                                 const Triangle &t=triangles[i];
    945 
    946                                 // coor of 3 vertices
    947                                 R2 A=t[0];
    948                                 R2 B=t[1];
    949                                 R2 C=t[2];
    950 
    951                                 //compute triangle determinant (2*Area)
    952                                 Real8 dett = bamg::Area2(A,B,C);
    953                                 detT[i]=dett;
    954 
    955                                 /*The nodal functions are such that for a vertex A:
    956                                  *    N_A(x,y)=alphaA x + beta_A y +gamma_A
    957                                  *    N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
    958                                  * solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
    959                                  * leads to:
    960                                  *    N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
    961                                  * and this gives:
    962                                  *    alpha_A = (yB-yC)/(2*Area(T))*/
    963                                 alpha[i*3+0]=(B.y-C.y)/dett;
    964                                 alpha[i*3+1]=(C.y-A.y)/dett;
    965                                 alpha[i*3+2]=(A.y-B.y)/dett;
    966                                 beta[ i*3+0]=(C.x-B.x)/dett;
    967                                 beta[ i*3+1]=(A.x-C.x)/dett;
    968                                 beta[ i*3+2]=(B.x-A.x)/dett;
    969 
    970                                 //compute chains
    971                                 for(j=0;j<3;j++){
    972                                         k=Number(triangles[i][j]);
    973                                         next_p[p]=head_s[k];
    974                                         head_s[k]=p++;
    975 
    976                                         //add area to sumareas
    977                                         sumareas[k]+=dett;
    978                                 }
    979 
    980                         }
    981                 }
    982 
    983                 //for all Solutions
    984                 for (Int4 nusol=0;nusol<nbsol;nusol++) {
    985                         Real8 smin=ss[nusol],smax=ss[nusol];
    986 
    987                         //get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
    988                         for ( iv=0,k=0; iv<nbv; iv++){
    989                                 smin=Min(smin,ss[iv*nbsol+nusol]);
    990                                 smax=Max(smax,ss[iv*nbsol+nusol]);
    991                         }
    992                         Real8 sdelta=smax-smin;
    993                         Real8 absmax=Max(Abs(smin),Abs(smax));
    994 
    995                         //display info
    996                         if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g\n",nusol,smin,smax,sdelta);
    997 
    998                         //skip constant field
    999                         if (sdelta < 1.0e-10*Max(absmax,1e-20)){
    1000                                 printf("      Solution %i is constant, skipping...\n",nusol);
    1001                                 continue;
    1002                         }
    1003 
    1004                         //initialize the hessian and gradient matrices
    1005                         for ( iv=0,k=0; iv<nbv; iv++) dxdx_vertex[iv]=dxdy_vertex[iv]=dydy_vertex[iv]=dx_vertex[iv]=dy_vertex[iv]=0;
    1006 
    1007                         //1: Compute gradient for each element (exact)
    1008                         for (i=0;i<nbt;i++){
    1009                                 if(triangles[i].link){
    1010                                         // number of the 3 vertices
    1011                                         iA = Number(triangles[i][0]);
    1012                                         iB = Number(triangles[i][1]);
    1013                                         iC = Number(triangles[i][2]);
    1014 
    1015                                         // value of the P1 fonction on 3 vertices
    1016                                         sA = ss[iA*nbsol+nusol];
    1017                                         sB = ss[iB*nbsol+nusol];
    1018                                         sC = ss[iC*nbsol+nusol];
    1019 
    1020                                         //gradient = (sum alpha_i s_i, sum_i beta_i s_i)
    1021                                         dx_elem[i]=sA*alpha[3*i+0]+sB*alpha[3*i+1]+sC*alpha[3*i+2];
    1022                                         dy_elem[i]=sA*beta[ 3*i+0]+sB*beta[ 3*i+1]+sC*beta[ 3*i+2];
    1023                                 }
    1024                         }
    1025 
    1026                         //2: then compute a gradient for each vertex using a P2 projection
    1027                         for(i=0;i<nbv;i++){
    1028                                 for(p=head_s[i];p!=-1;p=next_p[p]){
    1029                                         //Get triangle number
    1030                                         k=(Int4)(p/3);
    1031                                         dx_vertex[i]+=dx_elem[k]*detT[k]/sumareas[i];
    1032                                         dy_vertex[i]+=dy_elem[k]*detT[k]/sumareas[i];
    1033                                 }
    1034                         }
    1035 
    1036                         //3: compute Hessian matrix on each element
    1037                         for (i=0;i<nbt;i++){
    1038                                 if(triangles[i].link){
    1039                                         // number of the 3 vertices
    1040                                         iA = Number(triangles[i][0]);
    1041                                         iB = Number(triangles[i][1]);
    1042                                         iC = Number(triangles[i][2]);
    1043 
    1044                                         //Hessian
    1045                                         dxdx_elem[i]=dx_vertex[iA]*alpha[3*i+0]+dx_vertex[iB]*alpha[3*i+1]+dx_vertex[iC]*alpha[3*i+2];
    1046                                         dxdy_elem[i]=dy_vertex[iA]*alpha[3*i+0]+dy_vertex[iB]*alpha[3*i+1]+dy_vertex[iC]*alpha[3*i+2];
    1047                                         dydy_elem[i]=dy_vertex[iA]*beta[3*i+0]+dy_vertex[iB]*beta[3*i+1]+dy_vertex[iC]*beta[3*i+2];
    1048                                 }
    1049                         }
    1050 
    1051                         //4: finaly compute Hessian on each vertex using the second P2 projection
    1052                         for(i=0;i<nbv;i++){
    1053                                 for(p=head_s[i];p!=-1;p=next_p[p]){
    1054                                         //Get triangle number
    1055                                         k=(Int4)(p/3);
    1056                                         dxdx_vertex[i]+=dxdx_elem[k]*detT[k]/sumareas[i];
    1057                                         dxdy_vertex[i]+=dxdy_elem[k]*detT[k]/sumareas[i];
    1058                                         dydy_vertex[i]+=dydy_elem[k]*detT[k]/sumareas[i];
    1059                                 }
    1060                         }
    1061 
    1062                         /*Compute Metric from Hessian*/
    1063                         for ( iv=0;iv<nbv;iv++){
    1064                                 vertices[iv].MetricFromHessian(dxdx_vertex[iv],dxdy_vertex[iv],dydy_vertex[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
    1065                         }
    1066 
    1067                 }//for all solutions
    1068 
    1069                 //clean up
    1070                 delete [] detT;
    1071                 delete [] alpha;
    1072                 delete [] beta;
    1073                 delete [] sumareas;
    1074                 delete [] dx_elem;
    1075                 delete [] dy_elem;
    1076                 delete [] dx_vertex;
    1077                 delete [] dy_vertex;
    1078                 delete [] dxdx_elem;
    1079                 delete [] dxdy_elem;
    1080                 delete [] dydy_elem;
    1081                 delete [] dxdx_vertex;
    1082                 delete [] dxdy_vertex;
    1083                 delete [] dydy_vertex;
    1084         }
    1085         /*}}}1*/
    1086         /*FUNCTION Triangles::BuildMetric1 (Green formula){{{1*/
    1087         void Triangles::BuildMetric1(BamgOpts* bamgopts){
    1088 
    1089                 /*Options*/
    1090                 const int dim = 2;
    1091                 double* s=NULL;
    1092                 Int4 nbsol;
    1093                 int NbJacobi;
    1094                 int verbosity;
    1095 
    1096                 /*Recover options*/
    1097                 verbosity=bamgopts->verbose;
    1098                 NbJacobi=bamgopts->nbjacobi;
    1099 
    1100                 /*Get and process fields*/
    1101                 s=bamgopts->field;
    1102                 nbsol=bamgopts->numfields;
    1103 
    1104                 //initialization of some variables
    1105                 Int4    i,k,iA,iB,iC,iv;
    1106                 R2      O(0,0);
    1107                 double* ss=(double*)s;
    1108                 double  sA,sB,sC;
    1109                 Real8*  detT = new Real8[nbt];
    1110                 Real8*  Mmass= new Real8[nbv];
    1111                 Real8*  Mmassxx= new Real8[nbv];
    1112                 Real8*  dxdx= new Real8[nbv];
    1113                 Real8*  dxdy= new Real8[nbv];
    1114                 Real8*  dydy= new Real8[nbv];
    1115                 Real8*  workT= new Real8[nbt];
    1116                 Real8*  workV= new Real8[nbv];
    1117                 int*    OnBoundary = new int[nbv];
    1118 
    1119                 //display infos
    1120                 if(verbosity>1) {
    1121                         printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
    1122                 }
    1123 
    1124                 //initialize Mmass, OnBoundary and Massxx by zero
    1125                 for (iv=0;iv<nbv;iv++){
    1126                         Mmass[iv]=0;
    1127                         OnBoundary[iv]=0;
    1128                         Mmassxx[iv]=0;
    1129                 }
    1130 
    1131                 //Build detT Mmas Mmassxx workT and OnBoundary
    1132                 for (i=0;i<nbt;i++){
    1133 
    1134                         //lopp over the real triangles (no boundary elements)
    1135                         if(triangles[i].link){
    1136 
    1137                                 //get current triangle t
    1138                                 const Triangle &t=triangles[i];
    1139 
    1140                                 // coor of 3 vertices
    1141                                 R2 A=t[0];
    1142                                 R2 B=t[1];
    1143                                 R2 C=t[2];
    1144 
    1145                                 // number of the 3 vertices
    1146                                 iA = Number(t[0]);
    1147                                 iB = Number(t[1]);
    1148                                 iC = Number(t[2]);
    1149 
    1150                                 //compute triangle determinant (2*Area)
    1151                                 Real8 dett = bamg::Area2(A,B,C);
    1152                                 detT[i]=dett;
    1153                                 dett /= 6;
    1154 
    1155                                 // construction of OnBoundary (flag=1 if on boundary, else 0)
    1156                                 int nbb=0;
    1157                                 for(int j=0;j<3;j++){
    1158                                         //get adjacent triangle
    1159                                         Triangle *ta=t.Adj(j);
    1160                                         //if there is no adjacent triangle, the edge of the triangle t is on boundary
    1161                                         if ( !ta || !ta->link){
    1162                                                 //mark the two vertices of the edge as OnBoundary
    1163                                                 OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1;
    1164                                                 OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1;
    1165                                                 nbb++;
    1166                                         }
    1167                                 }
    1168 
    1169                                 //number of vertices on boundary for current triangle t
    1170                                 workT[i] = nbb;
    1171 
    1172                                 //Build Mmass Mmass[i] = Mmass[i] + Area/3
    1173                                 Mmass[iA] += dett;
    1174                                 Mmass[iB] += dett;
    1175                                 Mmass[iC] += dett;
    1176 
    1177                                 //Build Massxx = Mmass
    1178                                 Mmassxx[iA] += dett;
    1179                                 Mmassxx[iB] += dett;
    1180                                 Mmassxx[iC] += dett;
    1181                         }
    1182 
    1183                         //else: the triangle is a boundary triangle -> workT=-1
    1184                         else workT[i]=-1;
    1185                 }
    1186 
    1187                 //for all Solution 
    1188                 for (Int4 nusol=0;nusol<nbsol;nusol++) {
    1189 
    1190                         Real8 smin=ss[nusol],smax=ss[nusol];
    1191                         Real8 h1=1.e30,h2=1e-30,rx=0;
    1192                         Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
    1193 
    1194                         //get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
    1195                         for ( iv=0,k=0; iv<nbv; iv++ ){
    1196                                 dxdx[iv]=dxdy[iv]=dydy[iv]=0;
    1197                                 smin=Min(smin,ss[iv*nbsol+nusol]);
    1198                                 smax=Max(smax,ss[iv*nbsol+nusol]);
    1199                         }
    1200                         Real8 sdelta=smax-smin;
    1201                         Real8 absmax=Max(Abs(smin),Abs(smax));
    1202 
    1203                         //display info
    1204                         if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, number of fields = %i\n",nusol,smin,smax,sdelta,nbsol);
    1205 
    1206                         //skip constant field
    1207                         if (sdelta < 1.0e-10*Max(absmax,1e-20) ){
    1208                                 if (verbosity>2) printf("      Solution %i is constant, skipping...\n");
    1209                                 continue;
    1210                         }
    1211 
    1212                         //pointer toward ss that is also a pointer toward s (solutions)
    1213                         double* sf=ss;
    1214 
    1215                                 //initialize the hessian matrix
    1216                                 for ( iv=0,k=0; iv<nbv; iv++) dxdx[iv]=dxdy[iv]=dydy[iv]=0;
    1217 
    1218                                 //loop over the triangles
    1219                                 for (i=0;i<nbt;i++){
    1220 
    1221                                         //for real all triangles
    1222                                         if(triangles[i].link){
    1223 
    1224                                                 // coor of 3 vertices
    1225                                                 R2 A=triangles[i][0];
    1226                                                 R2 B=triangles[i][1];
    1227                                                 R2 C=triangles[i][2];
    1228 
    1229                                                 //warning: the normal is internal and the size is the length of the edge
    1230                                                 R2 nAB = Orthogonal(B-A);
    1231                                                 R2 nBC = Orthogonal(C-B);
    1232                                                 R2 nCA = Orthogonal(A-C);
    1233                                                 //note that :  nAB + nBC + nCA == 0
    1234 
    1235                                                 // number of the 3 vertices
    1236                                                 iA = Number(triangles[i][0]);
    1237                                                 iB = Number(triangles[i][1]);
    1238                                                 iC = Number(triangles[i][2]);
    1239 
    1240                                                 // for the test of  boundary edge
    1241                                                 // the 3 adj triangles
    1242                                                 Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
    1243                                                 Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
    1244                                                 Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
    1245 
    1246                                                 // value of the P1 fonction on 3 vertices
    1247                                                 sA = ss[iA*nbsol+nusol];
    1248                                                 sB = ss[iB*nbsol+nusol];
    1249                                                 sC = ss[iC*nbsol+nusol];
    1250 
    1251                                                 /*The nodal functions are such that for a vertex A:
    1252                                                   N_A(x,y)=alphaA x + beta_A y +gamma_A
    1253                                                   N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
    1254                                                   solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
    1255                                                   leads to:
    1256                                                   N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
    1257                                                   and this gives:
    1258                                                   alpha_A = (yB-yC)/(2*Area(T))
    1259                                                   beta_A = (xC-xB)/(2*Area(T))
    1260                                                   and therefore:
    1261                                                   grad N_A = nA / detT
    1262                                                   for an interpolation of a solution s:
    1263                                                   grad(s) = s * sum_{i=A,B,C} grad(N_i) */
    1264 
    1265                                                 R2 Grads=(nAB*sC+nBC*sA+nCA*sB)/detT[i];
    1266 
    1267                                                 //Use Green to compute Hessian Matrix
    1268 
    1269                                                 // if edge on boundary no contribution  => normal = 0
    1270                                                 if ( !tBC || !tBC->link ) nBC=O;
    1271                                                 if ( !tCA || !tCA->link ) nCA=O;
    1272                                                 if ( !tAB || !tAB->link ) nAB=O;
    1273 
    1274                                                 // remark we forgot a 1/2 because
    1275                                                 //       int_{edge} w_i = 1/2 if i is in edge
    1276                                                 //                         0  if not
    1277                                                 // if we don't take the  boundary
    1278                                                 dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
    1279                                                 dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
    1280                                                 dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
    1281 
    1282                                                 //warning optimization (1) the division by 2 is done on the metric construction
    1283                                                 dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
    1284                                                 dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
    1285                                                 dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ;
    1286 
    1287                                                 dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
    1288                                                 dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
    1289                                                 dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
    1290 
    1291                                         } // for real all triangles
    1292                                 }
    1293 
    1294                                 Int4 kk=0;
    1295                                 for ( iv=0,k=0 ; iv<nbv; iv++){
    1296                                         if(Mmassxx[iv]>0){
    1297                                                 dxdx[iv] /= 2*Mmassxx[iv];
    1298                                                 // warning optimization (1) on term dxdy[iv]*ci/2
    1299                                                 dxdy[iv] /= 4*Mmassxx[iv];
    1300                                                 dydy[iv] /= 2*Mmassxx[iv];
    1301                                                 // Compute the matrix with abs(eigen value)
    1302                                                 Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
    1303                                                 MatVVP2x2 Vp(M);
    1304                                                 Vp.Abs();
    1305                                                 M = Vp;
    1306                                                 dxdx[iv] = M.a11;
    1307                                                 dxdy[iv] = M.a21;
    1308                                                 dydy[iv] = M.a22;
    1309                                         }
    1310                                         else kk++;
    1311                                 }
    1312 
    1313                                 // correction of second derivative
    1314                                 // by a laplacien
    1315                                 Real8* d2[3] = {dxdx, dxdy, dydy};
    1316                                 Real8* dd;
    1317                                 for (int xy = 0;xy<3;xy++) {
    1318                                         dd = d2[xy];
    1319                                         // do leat 2 iteration for boundary problem
    1320                                         for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++){
    1321                                                 for (i=0;i<nbt;i++)
    1322                                                  if(triangles[i].link){// the real triangles
    1323                                                          // number of the 3 vertices
    1324                                                          iA = Number(triangles[i][0]);
    1325                                                          iB = Number(triangles[i][1]);
    1326                                                          iC = Number(triangles[i][2]);
    1327                                                          Real8 cc=3;
    1328                                                          if(ijacobi==0)
    1329                                                           cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
    1330                                                          workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
    1331                                                  }
    1332                                                 for (iv=0;iv<nbv;iv++) workV[iv]=0;
    1333 
    1334                                                 for (i=0;i<nbt;i++){
    1335                                                         if(triangles[i].link){ // the real triangles
    1336                                                                 // number of the 3 vertices
    1337                                                                 iA = Number(triangles[i][0]);
    1338                                                                 iB = Number(triangles[i][1]);
    1339                                                                 iC = Number(triangles[i][2]);
    1340                                                                 Real8 cc =  workT[i]*detT[i];
    1341                                                                 workV[iA] += cc;
    1342                                                                 workV[iB] += cc;
    1343                                                                 workV[iC] += cc;
    1344                                                         }
    1345                                                 }
    1346 
    1347                                                 for (iv=0;iv<nbv;iv++){
    1348                                                         if( ijacobi<NbJacobi || OnBoundary[iv]){
    1349                                                                 dd[iv] = workV[iv]/(Mmass[iv]*6);
    1350                                                         }
    1351                                                 }
    1352                                         }
    1353                                 }
    1354 
    1355                                 /*Compute Metric from Hessian*/
    1356                                 for ( iv=0;iv<nbv;iv++){
    1357                                         vertices[iv].MetricFromHessian(dxdx[iv],dxdy[iv],dydy[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
    1358                                 }
    1359 
    1360                 }// end for all solution
    1361 
    1362                 delete [] detT;
    1363                 delete [] Mmass;
    1364                 delete [] dxdx;
    1365                 delete [] dxdy;
    1366                 delete [] dydy;
    1367                 delete []  workT;
    1368                 delete [] workV;
    1369                 delete [] Mmassxx;
    1370                 delete []  OnBoundary;
    1371 
    1372         }
    1373         /*}}}1*/
    1374         /*FUNCTION Triangles::ConsGeometry{{{1*/
    1375         void Triangles::ConsGeometry(Real8 cutoffradian,int *equiedges){
    1376                 //  if equiedges existe taille nbe
    1377                 //   equiedges[i]/2 == i  original
    1378                 //   equiedges[i]/2 = j  =>   equivalence entre i et j => meme maillage
    1379                 //   equiedges[i]%2   : 0 meme sens , 1 pas meme sens
    1380                 //       
    1381                 // --------------------------
    1382                 long int verbosity=0;
     886                int    verbosity=bamgopts->verbose;
     887                double cutoffradian=bamgopts->MaximalAngleOfCorner*Pi/180;
     888                CurrentTh=this;
     889
     890                //display info
    1383891                if (verbosity>1) printf("   construction of the geometry from the 2d mesh\n");
     892
     893                //check that the mesh is not empty
    1384894                if (nbt<=0 || nbv <=0 ) {
    1385                         throw ErrorException(__FUNCT__,exprintf("nbt or nbv is negative"));
    1386                 }
    1387 
    1388                 // construction of the edges
    1389                 //  Triangles * OldCurrentTh =CurrentTh;
    1390                 CurrentTh=this;
    1391                 //  Int4 NbTold = nbt;
    1392                 // generation of the integer coor
    1393                 // generation of the adjacence of the triangles
    1394                 if (cutoffradian>=0)
    1395                  Gh.MaximalAngleOfCorner = cutoffradian;
    1396                 SetOfEdges4 * edge4= new SetOfEdges4(nbt*3,nbv);
    1397                 Int4 * st = new Int4[nbt*3];
    1398                 Int4 i,k;
    1399                 int j;
    1400                 if (Gh.name) delete Gh.name;
    1401                 Gh.name = new char [ name ? strlen(name) + 15 : 50 ];
    1402                 Gh.name[0]=0;
    1403                 strcat(Gh.name,"cons from: ");
    1404                 if (name) strcat(Gh.name,name);
    1405                 else strcat(Gh.name," a mesh with no name");
     895                        throw ErrorException(__FUNCT__,exprintf("nbt or nbv is negative (Mesh empty?)"));
     896                }
     897
     898                //Gh is the geometry of the mesh (this), initialize MaximalAngleOfCorner
     899                if (cutoffradian>=0) Gh.MaximalAngleOfCorner = cutoffradian;
     900
     901                //Construction of the edges
     902                SetOfEdges4* edge4= new SetOfEdges4(nbt*3,nbv);
     903                Int4*        st   = new Int4[nbt*3];
    1406904                for (i=0;i<nbt*3;i++)
    1407905                 st[i]=-1;
     
    1445943
    1446944                if(verbosity>5) {
    1447                         printf("         info on Mesh %s:\n",name);
     945                        printf("         info on Meshs:\n");
    1448946                        printf("            - number of vertices    = %i \n",nbv);
    1449947                        printf("            - number of triangles   = %i \n",nbt);
     
    16971195                        if(requis) kreq++;
    16981196                        edges[i].onGeometry =  Gh.edges + i;
    1699                         if(equiedges && i < nbeold ) {
    1700                                 int j=equiedges[i]/2;
    1701                                 int sens=equiedges[i]%2;
    1702                                 if(i!=j && equiedges[i]>=0) {
    1703                                         if( sens==0)
    1704                                          Gh.edges[i].SetEqui();
    1705                                         else
    1706                                          Gh.edges[i].SetReverseEqui();
    1707                                         Gh.edges[i].link= & Gh.edges[j];
    1708                                 }
    1709 
    1710                         }
    17111197                        if(requis)  {  // correction fevr 2009 JYU ...
    17121198                                Gh.edges[i].v[0]->SetRequired();
     
    17661252                  triangles[i].SetAdj2(j,0,triangles[i].GetAllflag(j));
    17671253
    1768           }
     1254        }
     1255        /*}}}1*/
     1256        /*FUNCTION Triangles::BuildMetric0 (double P2 projection){{{1*/
     1257        void Triangles::BuildMetric0(BamgOpts* bamgopts){
     1258
     1259                /*Options*/
     1260                const int dim = 2;
     1261                double* s=NULL;
     1262                Int4    nbsol;
     1263                int     verbosity;
     1264
     1265                int   i,j,k,iA,iB,iC;
     1266                int   iv;
     1267
     1268                /*Recover options*/
     1269                verbosity=bamgopts->verbose;
     1270
     1271                /*Get and process fields*/
     1272                s=bamgopts->field;
     1273                nbsol=bamgopts->numfields;
     1274
     1275                //initialization of some variables
     1276                double* ss=(double*)s;
     1277                double  sA,sB,sC;
     1278                Real8*  detT = new Real8[nbt];
     1279                Real8*  sumareas = new Real8[nbv];
     1280                Real8*  alpha= new Real8[nbt*3];
     1281                Real8*  beta = new Real8[nbt*3];
     1282                Real8*  dx_elem    = new Real8[nbt];
     1283                Real8*  dy_elem    = new Real8[nbt];
     1284                Real8*  dx_vertex  = new Real8[nbv];
     1285                Real8*  dy_vertex  = new Real8[nbv];
     1286                Real8*  dxdx_elem  = new Real8[nbt];
     1287                Real8*  dxdy_elem  = new Real8[nbt];
     1288                Real8*  dydy_elem  = new Real8[nbt];
     1289                Real8*  dxdx_vertex= new Real8[nbv];
     1290                Real8*  dxdy_vertex= new Real8[nbv];
     1291                Real8*  dydy_vertex= new Real8[nbv];
     1292
     1293                //display infos
     1294                if(verbosity>1) {
     1295                        printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
     1296                }
     1297
     1298                //first, build the chains that will be used for the Hessian computation, as weel as the area of each element
     1299                int head_s[nbv];
     1300                int next_p[3*nbt];
     1301                int  p=0;
     1302                //initialization
     1303                for(i=0;i<nbv;i++){
     1304                        sumareas[i]=0;
     1305                        head_s[i]=-1;
     1306                }
     1307                for(i=0;i<nbt;i++){
     1308
     1309                        //lopp over the real triangles (no boundary elements)
     1310                        if(triangles[i].link){
     1311
     1312                                //get current triangle t
     1313                                const Triangle &t=triangles[i];
     1314
     1315                                // coor of 3 vertices
     1316                                R2 A=t[0];
     1317                                R2 B=t[1];
     1318                                R2 C=t[2];
     1319
     1320                                //compute triangle determinant (2*Area)
     1321                                Real8 dett = bamg::Area2(A,B,C);
     1322                                detT[i]=dett;
     1323
     1324                                /*The nodal functions are such that for a vertex A:
     1325                                 *    N_A(x,y)=alphaA x + beta_A y +gamma_A
     1326                                 *    N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
     1327                                 * solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
     1328                                 * leads to:
     1329                                 *    N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
     1330                                 * and this gives:
     1331                                 *    alpha_A = (yB-yC)/(2*Area(T))*/
     1332                                alpha[i*3+0]=(B.y-C.y)/dett;
     1333                                alpha[i*3+1]=(C.y-A.y)/dett;
     1334                                alpha[i*3+2]=(A.y-B.y)/dett;
     1335                                beta[ i*3+0]=(C.x-B.x)/dett;
     1336                                beta[ i*3+1]=(A.x-C.x)/dett;
     1337                                beta[ i*3+2]=(B.x-A.x)/dett;
     1338
     1339                                //compute chains
     1340                                for(j=0;j<3;j++){
     1341                                        k=Number(triangles[i][j]);
     1342                                        next_p[p]=head_s[k];
     1343                                        head_s[k]=p++;
     1344
     1345                                        //add area to sumareas
     1346                                        sumareas[k]+=dett;
     1347                                }
     1348
     1349                        }
     1350                }
     1351
     1352                //for all Solutions
     1353                for (Int4 nusol=0;nusol<nbsol;nusol++) {
     1354                        Real8 smin=ss[nusol],smax=ss[nusol];
     1355
     1356                        //get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
     1357                        for ( iv=0,k=0; iv<nbv; iv++){
     1358                                smin=Min(smin,ss[iv*nbsol+nusol]);
     1359                                smax=Max(smax,ss[iv*nbsol+nusol]);
     1360                        }
     1361                        Real8 sdelta=smax-smin;
     1362                        Real8 absmax=Max(Abs(smin),Abs(smax));
     1363
     1364                        //display info
     1365                        if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g\n",nusol,smin,smax,sdelta);
     1366
     1367                        //skip constant field
     1368                        if (sdelta < 1.0e-10*Max(absmax,1e-20)){
     1369                                printf("      Solution %i is constant, skipping...\n",nusol);
     1370                                continue;
     1371                        }
     1372
     1373                        //initialize the hessian and gradient matrices
     1374                        for ( iv=0,k=0; iv<nbv; iv++) dxdx_vertex[iv]=dxdy_vertex[iv]=dydy_vertex[iv]=dx_vertex[iv]=dy_vertex[iv]=0;
     1375
     1376                        //1: Compute gradient for each element (exact)
     1377                        for (i=0;i<nbt;i++){
     1378                                if(triangles[i].link){
     1379                                        // number of the 3 vertices
     1380                                        iA = Number(triangles[i][0]);
     1381                                        iB = Number(triangles[i][1]);
     1382                                        iC = Number(triangles[i][2]);
     1383
     1384                                        // value of the P1 fonction on 3 vertices
     1385                                        sA = ss[iA*nbsol+nusol];
     1386                                        sB = ss[iB*nbsol+nusol];
     1387                                        sC = ss[iC*nbsol+nusol];
     1388
     1389                                        //gradient = (sum alpha_i s_i, sum_i beta_i s_i)
     1390                                        dx_elem[i]=sA*alpha[3*i+0]+sB*alpha[3*i+1]+sC*alpha[3*i+2];
     1391                                        dy_elem[i]=sA*beta[ 3*i+0]+sB*beta[ 3*i+1]+sC*beta[ 3*i+2];
     1392                                }
     1393                        }
     1394
     1395                        //2: then compute a gradient for each vertex using a P2 projection
     1396                        for(i=0;i<nbv;i++){
     1397                                for(p=head_s[i];p!=-1;p=next_p[p]){
     1398                                        //Get triangle number
     1399                                        k=(Int4)(p/3);
     1400                                        dx_vertex[i]+=dx_elem[k]*detT[k]/sumareas[i];
     1401                                        dy_vertex[i]+=dy_elem[k]*detT[k]/sumareas[i];
     1402                                }
     1403                        }
     1404
     1405                        //3: compute Hessian matrix on each element
     1406                        for (i=0;i<nbt;i++){
     1407                                if(triangles[i].link){
     1408                                        // number of the 3 vertices
     1409                                        iA = Number(triangles[i][0]);
     1410                                        iB = Number(triangles[i][1]);
     1411                                        iC = Number(triangles[i][2]);
     1412
     1413                                        //Hessian
     1414                                        dxdx_elem[i]=dx_vertex[iA]*alpha[3*i+0]+dx_vertex[iB]*alpha[3*i+1]+dx_vertex[iC]*alpha[3*i+2];
     1415                                        dxdy_elem[i]=dy_vertex[iA]*alpha[3*i+0]+dy_vertex[iB]*alpha[3*i+1]+dy_vertex[iC]*alpha[3*i+2];
     1416                                        dydy_elem[i]=dy_vertex[iA]*beta[3*i+0]+dy_vertex[iB]*beta[3*i+1]+dy_vertex[iC]*beta[3*i+2];
     1417                                }
     1418                        }
     1419
     1420                        //4: finaly compute Hessian on each vertex using the second P2 projection
     1421                        for(i=0;i<nbv;i++){
     1422                                for(p=head_s[i];p!=-1;p=next_p[p]){
     1423                                        //Get triangle number
     1424                                        k=(Int4)(p/3);
     1425                                        dxdx_vertex[i]+=dxdx_elem[k]*detT[k]/sumareas[i];
     1426                                        dxdy_vertex[i]+=dxdy_elem[k]*detT[k]/sumareas[i];
     1427                                        dydy_vertex[i]+=dydy_elem[k]*detT[k]/sumareas[i];
     1428                                }
     1429                        }
     1430
     1431                        /*Compute Metric from Hessian*/
     1432                        for ( iv=0;iv<nbv;iv++){
     1433                                vertices[iv].MetricFromHessian(dxdx_vertex[iv],dxdy_vertex[iv],dydy_vertex[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
     1434                        }
     1435
     1436                }//for all solutions
     1437
     1438                //clean up
     1439                delete [] detT;
     1440                delete [] alpha;
     1441                delete [] beta;
     1442                delete [] sumareas;
     1443                delete [] dx_elem;
     1444                delete [] dy_elem;
     1445                delete [] dx_vertex;
     1446                delete [] dy_vertex;
     1447                delete [] dxdx_elem;
     1448                delete [] dxdy_elem;
     1449                delete [] dydy_elem;
     1450                delete [] dxdx_vertex;
     1451                delete [] dxdy_vertex;
     1452                delete [] dydy_vertex;
     1453        }
     1454        /*}}}1*/
     1455        /*FUNCTION Triangles::BuildMetric1 (Green formula){{{1*/
     1456        void Triangles::BuildMetric1(BamgOpts* bamgopts){
     1457
     1458                /*Options*/
     1459                const int dim = 2;
     1460                double* s=NULL;
     1461                Int4 nbsol;
     1462                int NbJacobi;
     1463                int verbosity;
     1464
     1465                /*Recover options*/
     1466                verbosity=bamgopts->verbose;
     1467                NbJacobi=bamgopts->nbjacobi;
     1468
     1469                /*Get and process fields*/
     1470                s=bamgopts->field;
     1471                nbsol=bamgopts->numfields;
     1472
     1473                //initialization of some variables
     1474                Int4    i,k,iA,iB,iC,iv;
     1475                R2      O(0,0);
     1476                double* ss=(double*)s;
     1477                double  sA,sB,sC;
     1478                Real8*  detT = new Real8[nbt];
     1479                Real8*  Mmass= new Real8[nbv];
     1480                Real8*  Mmassxx= new Real8[nbv];
     1481                Real8*  dxdx= new Real8[nbv];
     1482                Real8*  dxdy= new Real8[nbv];
     1483                Real8*  dydy= new Real8[nbv];
     1484                Real8*  workT= new Real8[nbt];
     1485                Real8*  workV= new Real8[nbv];
     1486                int*    OnBoundary = new int[nbv];
     1487
     1488                //display infos
     1489                if(verbosity>1) {
     1490                        printf("   Construction of Metric: number of field: %i (nbt=%i, nbv=%i)\n",nbsol,nbt,nbv);
     1491                }
     1492
     1493                //initialize Mmass, OnBoundary and Massxx by zero
     1494                for (iv=0;iv<nbv;iv++){
     1495                        Mmass[iv]=0;
     1496                        OnBoundary[iv]=0;
     1497                        Mmassxx[iv]=0;
     1498                }
     1499
     1500                //Build detT Mmas Mmassxx workT and OnBoundary
     1501                for (i=0;i<nbt;i++){
     1502
     1503                        //lopp over the real triangles (no boundary elements)
     1504                        if(triangles[i].link){
     1505
     1506                                //get current triangle t
     1507                                const Triangle &t=triangles[i];
     1508
     1509                                // coor of 3 vertices
     1510                                R2 A=t[0];
     1511                                R2 B=t[1];
     1512                                R2 C=t[2];
     1513
     1514                                // number of the 3 vertices
     1515                                iA = Number(t[0]);
     1516                                iB = Number(t[1]);
     1517                                iC = Number(t[2]);
     1518
     1519                                //compute triangle determinant (2*Area)
     1520                                Real8 dett = bamg::Area2(A,B,C);
     1521                                detT[i]=dett;
     1522                                dett /= 6;
     1523
     1524                                // construction of OnBoundary (flag=1 if on boundary, else 0)
     1525                                int nbb=0;
     1526                                for(int j=0;j<3;j++){
     1527                                        //get adjacent triangle
     1528                                        Triangle *ta=t.Adj(j);
     1529                                        //if there is no adjacent triangle, the edge of the triangle t is on boundary
     1530                                        if ( !ta || !ta->link){
     1531                                                //mark the two vertices of the edge as OnBoundary
     1532                                                OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1;
     1533                                                OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1;
     1534                                                nbb++;
     1535                                        }
     1536                                }
     1537
     1538                                //number of vertices on boundary for current triangle t
     1539                                workT[i] = nbb;
     1540
     1541                                //Build Mmass Mmass[i] = Mmass[i] + Area/3
     1542                                Mmass[iA] += dett;
     1543                                Mmass[iB] += dett;
     1544                                Mmass[iC] += dett;
     1545
     1546                                //Build Massxx = Mmass
     1547                                Mmassxx[iA] += dett;
     1548                                Mmassxx[iB] += dett;
     1549                                Mmassxx[iC] += dett;
     1550                        }
     1551
     1552                        //else: the triangle is a boundary triangle -> workT=-1
     1553                        else workT[i]=-1;
     1554                }
     1555
     1556                //for all Solution 
     1557                for (Int4 nusol=0;nusol<nbsol;nusol++) {
     1558
     1559                        Real8 smin=ss[nusol],smax=ss[nusol];
     1560                        Real8 h1=1.e30,h2=1e-30,rx=0;
     1561                        Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; 
     1562
     1563                        //get min(s), max(s) and initialize Hessian (dxdx,dxdy,dydy)
     1564                        for ( iv=0,k=0; iv<nbv; iv++ ){
     1565                                dxdx[iv]=dxdy[iv]=dydy[iv]=0;
     1566                                smin=Min(smin,ss[iv*nbsol+nusol]);
     1567                                smax=Max(smax,ss[iv*nbsol+nusol]);
     1568                        }
     1569                        Real8 sdelta=smax-smin;
     1570                        Real8 absmax=Max(Abs(smin),Abs(smax));
     1571
     1572                        //display info
     1573                        if(verbosity>2) printf("      Solution %i, Min = %g, Max = %g, Delta = %g, number of fields = %i\n",nusol,smin,smax,sdelta,nbsol);
     1574
     1575                        //skip constant field
     1576                        if (sdelta < 1.0e-10*Max(absmax,1e-20) ){
     1577                                if (verbosity>2) printf("      Solution %i is constant, skipping...\n");
     1578                                continue;
     1579                        }
     1580
     1581                        //pointer toward ss that is also a pointer toward s (solutions)
     1582                        double* sf=ss;
     1583
     1584                                //initialize the hessian matrix
     1585                                for ( iv=0,k=0; iv<nbv; iv++) dxdx[iv]=dxdy[iv]=dydy[iv]=0;
     1586
     1587                                //loop over the triangles
     1588                                for (i=0;i<nbt;i++){
     1589
     1590                                        //for real all triangles
     1591                                        if(triangles[i].link){
     1592
     1593                                                // coor of 3 vertices
     1594                                                R2 A=triangles[i][0];
     1595                                                R2 B=triangles[i][1];
     1596                                                R2 C=triangles[i][2];
     1597
     1598                                                //warning: the normal is internal and the size is the length of the edge
     1599                                                R2 nAB = Orthogonal(B-A);
     1600                                                R2 nBC = Orthogonal(C-B);
     1601                                                R2 nCA = Orthogonal(A-C);
     1602                                                //note that :  nAB + nBC + nCA == 0
     1603
     1604                                                // number of the 3 vertices
     1605                                                iA = Number(triangles[i][0]);
     1606                                                iB = Number(triangles[i][1]);
     1607                                                iC = Number(triangles[i][2]);
     1608
     1609                                                // for the test of  boundary edge
     1610                                                // the 3 adj triangles
     1611                                                Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
     1612                                                Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
     1613                                                Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);
     1614
     1615                                                // value of the P1 fonction on 3 vertices
     1616                                                sA = ss[iA*nbsol+nusol];
     1617                                                sB = ss[iB*nbsol+nusol];
     1618                                                sC = ss[iC*nbsol+nusol];
     1619
     1620                                                /*The nodal functions are such that for a vertex A:
     1621                                                  N_A(x,y)=alphaA x + beta_A y +gamma_A
     1622                                                  N_A(A) = 1,   N_A(B) = 0,   N_A(C) = 0
     1623                                                  solving this system of equation (determinant = 2Area(T) != 0 if A,B and C are not inlined)
     1624                                                  leads to:
     1625                                                  N_A = (xB yC - xC yB + x(yB-yC) +y(xC-xB))/(2*Area(T))
     1626                                                  and this gives:
     1627                                                  alpha_A = (yB-yC)/(2*Area(T))
     1628                                                  beta_A = (xC-xB)/(2*Area(T))
     1629                                                  and therefore:
     1630                                                  grad N_A = nA / detT
     1631                                                  for an interpolation of a solution s:
     1632                                                  grad(s) = s * sum_{i=A,B,C} grad(N_i) */
     1633
     1634                                                R2 Grads=(nAB*sC+nBC*sA+nCA*sB)/detT[i];
     1635
     1636                                                //Use Green to compute Hessian Matrix
     1637
     1638                                                // if edge on boundary no contribution  => normal = 0
     1639                                                if ( !tBC || !tBC->link ) nBC=O;
     1640                                                if ( !tCA || !tCA->link ) nCA=O;
     1641                                                if ( !tAB || !tAB->link ) nAB=O;
     1642
     1643                                                // remark we forgot a 1/2 because
     1644                                                //       int_{edge} w_i = 1/2 if i is in edge
     1645                                                //                         0  if not
     1646                                                // if we don't take the  boundary
     1647                                                dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
     1648                                                dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
     1649                                                dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
     1650
     1651                                                //warning optimization (1) the division by 2 is done on the metric construction
     1652                                                dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
     1653                                                dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
     1654                                                dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ;
     1655
     1656                                                dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
     1657                                                dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
     1658                                                dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
     1659
     1660                                        } // for real all triangles
     1661                                }
     1662
     1663                                Int4 kk=0;
     1664                                for ( iv=0,k=0 ; iv<nbv; iv++){
     1665                                        if(Mmassxx[iv]>0){
     1666                                                dxdx[iv] /= 2*Mmassxx[iv];
     1667                                                // warning optimization (1) on term dxdy[iv]*ci/2
     1668                                                dxdy[iv] /= 4*Mmassxx[iv];
     1669                                                dydy[iv] /= 2*Mmassxx[iv];
     1670                                                // Compute the matrix with abs(eigen value)
     1671                                                Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
     1672                                                MatVVP2x2 Vp(M);
     1673                                                Vp.Abs();
     1674                                                M = Vp;
     1675                                                dxdx[iv] = M.a11;
     1676                                                dxdy[iv] = M.a21;
     1677                                                dydy[iv] = M.a22;
     1678                                        }
     1679                                        else kk++;
     1680                                }
     1681
     1682                                // correction of second derivative
     1683                                // by a laplacien
     1684                                Real8* d2[3] = {dxdx, dxdy, dydy};
     1685                                Real8* dd;
     1686                                for (int xy = 0;xy<3;xy++) {
     1687                                        dd = d2[xy];
     1688                                        // do leat 2 iteration for boundary problem
     1689                                        for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++){
     1690                                                for (i=0;i<nbt;i++)
     1691                                                 if(triangles[i].link){// the real triangles
     1692                                                         // number of the 3 vertices
     1693                                                         iA = Number(triangles[i][0]);
     1694                                                         iB = Number(triangles[i][1]);
     1695                                                         iC = Number(triangles[i][2]);
     1696                                                         Real8 cc=3;
     1697                                                         if(ijacobi==0)
     1698                                                          cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
     1699                                                         workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
     1700                                                 }
     1701                                                for (iv=0;iv<nbv;iv++) workV[iv]=0;
     1702
     1703                                                for (i=0;i<nbt;i++){
     1704                                                        if(triangles[i].link){ // the real triangles
     1705                                                                // number of the 3 vertices
     1706                                                                iA = Number(triangles[i][0]);
     1707                                                                iB = Number(triangles[i][1]);
     1708                                                                iC = Number(triangles[i][2]);
     1709                                                                Real8 cc =  workT[i]*detT[i];
     1710                                                                workV[iA] += cc;
     1711                                                                workV[iB] += cc;
     1712                                                                workV[iC] += cc;
     1713                                                        }
     1714                                                }
     1715
     1716                                                for (iv=0;iv<nbv;iv++){
     1717                                                        if( ijacobi<NbJacobi || OnBoundary[iv]){
     1718                                                                dd[iv] = workV[iv]/(Mmass[iv]*6);
     1719                                                        }
     1720                                                }
     1721                                        }
     1722                                }
     1723
     1724                                /*Compute Metric from Hessian*/
     1725                                for ( iv=0;iv<nbv;iv++){
     1726                                        vertices[iv].MetricFromHessian(dxdx[iv],dxdy[iv],dydy[iv],smin,smax,ss[iv*nbsol+nusol],bamgopts->err[nusol],bamgopts);
     1727                                }
     1728
     1729                }// end for all solution
     1730
     1731                delete [] detT;
     1732                delete [] Mmass;
     1733                delete [] dxdx;
     1734                delete [] dxdy;
     1735                delete [] dydy;
     1736                delete []  workT;
     1737                delete [] workV;
     1738                delete [] Mmassxx;
     1739                delete []  OnBoundary;
     1740
     1741        }
    17691742        /*}}}1*/
    17701743        /*FUNCTION Triangles::ConsRefTriangle{{{1*/
     
    20672040                        }
    20682041                        if(verbosity>5) {
    2069                                 printf("         info on Mesh %s:\n",name);
     2042                                printf("         info on Mesh\n");
    20702043                                printf("            - number of vertices    = %i \n",nbv);
    20712044                                printf("            - number of triangles   = %i \n",nbt);
     
    38513824/*}}}1*/
    38523825/*FUNCTION Triangles::PreInit{{{1*/
    3853 void Triangles::PreInit(Int4 inbvx,char *fname) {
     3826void Triangles::PreInit(Int4 inbvx) {
    38543827        long int verbosity=0;
    38553828
     
    38573830        NbRef=0;
    38583831        //  allocGeometry=0;
    3859         identity=0;
    38603832        NbOfTriangleSearchFind =0;
    38613833        NbOfSwapTriangle =0;
     
    38763848        CrackedEdges  =0; 
    38773849        nbe = 0;
    3878         name = fname ;
    38793850
    38803851        if (inbvx) {
Note: See TracChangeset for help on using the changeset viewer.