Changeset 2932


Ignore:
Timestamp:
01/29/10 09:49:13 (15 years ago)
Author:
Mathieu Morlighem
Message:

fixed Simultaneous reduction

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

Legend:

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

    r2928 r2932  
    149149
    150150                BTh.IntersectGeomMetric(errg,iso);
     151                if (verbosity>1) printf("   Smoothing Metric...");
    151152                if(bamgopts->gradation) BTh.SmoothMetric(bamgopts->gradation);
     153                if (verbosity>1) printf(" done\n");
    152154                BTh.MaxSubDivision(maxsubdiv);
    153155                BTh.BoundAnisotropy(anisomax,hminaniso);
  • issm/trunk/src/c/Bamgx/Metric.h

    r2928 r2932  
    6464                                        Real8  b,const  MetricAnIso mb);
    6565                int  IntersectWith(const MetricAnIso M2);
    66                 int  IntersectWith_new(const MetricAnIso M2);
    6766                MetricAnIso operator*(Real8 c) const {Real8 c2=c*c;return  MetricAnIso(a11*c2,a21*c2,a22*c2);}
    6867                MetricAnIso operator/(Real8 c) const {Real8 c2=1/(c*c);return  MetricAnIso(a11*c2,a21*c2,a22*c2);}
     
    123122        }
    124123
    125         void SimultaneousMatrixReduction(const MetricAnIso M1,const MetricAnIso M2, MetricAnIso* M);
    126         void  SimultaneousMatrixReduction_bamg( MetricAnIso M1,  MetricAnIso M2,double & l1,double & l2, D2xD2 & V);
    127         void eigen2(double* M,double lambda[2],double vp[2][2]);;
     124        void  SimultaneousMatrixReduction( MetricAnIso M1,  MetricAnIso M2,double & l1,double & l2, D2xD2 & V);
    128125
    129126        inline MetricAnIso::MetricAnIso(const MatVVP2x2 M) {
  • issm/trunk/src/c/Bamgx/R2.h

    r2924 r2932  
    88                          R x,y;
    99                          void Echo(){
     10                                  printf("Member of P2:\n");
    1011                                  printf("   x: %g\n",x);
    1112                                  printf("   y: %g\n",y);
     
    3536                  public:
    3637                  P2<R,RR> x,y;
     38                  void Echo(){
     39                          printf("Member of P2xP2:\n");
     40                          printf("   x.x: %g   x.y: %g\n",x.x,x.y);
     41                          printf("   y.x: %g   y.x: %g\n",y.x,y.y);
     42                  }
    3743                  P2xP2 (): x(),y()  {}
    3844                  P2xP2 (P2<R,RR> a,P2<R,RR> b): x(a),y(b) {}
  • issm/trunk/src/c/Bamgx/objects/MetricAnIso.cpp

    r2928 r2932  
    6969        }
    7070        /*}}}*/
    71         /*FUNCTION MetricAnIso::IntersectWith_new{{{1*/
    72         int MetricAnIso::IntersectWith_new(MetricAnIso M2) {
    73                 /*Get a new metric from an existing metric (M1=this)
    74                  * and a new metric given in input M2 using a
    75                  * Simultaneous Matrix Reduction
    76                  * */
    77 
    78                 MetricAnIso M;
    79 
    80                 //Compute M intersection of M1 and M2
    81                 SimultaneousMatrixReduction(*this,M2,&M);
    82 
    83                 //check wether something has been done
    84                 if(M.a11!=a11 || M.a21!=a21 || M.a22!=a22){
    85 
    86                         //update this with M
    87                         a11=M.a11;
    88                         a21=M.a21;
    89                         a22=M.a22;
    90 
    91                         //return 1 -> something has been done
    92                         return 1;
    93                 }
    94                 else{
    95 
    96                         //nothing has changed, return 0
    97                         return 0;
    98                 }
    99         }
    100         /*}}}1*/
    10171        /*FUNCTION MetricAnIso::IntersectWith{{{1*/
    10272        int MetricAnIso::IntersectWith(const MetricAnIso M2) {
     
    11181                double l1,l2;
    11282
    113                 SimultaneousMatrixReduction_bamg(*this,M2,l1,l2,M);
     83                SimultaneousMatrixReduction(*this,M2,l1,l2,M);
    11484
    11585                R2 v1(M.x.x,M.y.x);
     
    12797                        a11=Mi.x.x;
    12898                        a21=0.5*(Mi.x.y+Mi.y.x);
    129                         a22=Mi.y.y; }
    130                         return r;
     99                        a22=Mi.y.y;
     100                }
     101                return r;
    131102        }
    132103        /*}}}1*/
    133104
    134105        /*Intermediary*/
    135         /*FUNCTION eigen2{{{1*/
    136         void eigen2(double* M,double* lambda,double vp[2][2]) {
    137                 /*m=[a b]
    138                  *  [c d] */
    139 
    140                 double normM,detM,trM;
    141                 double norm;
    142                 const double a=M[2*0+0];
    143                 const double b=M[2*0+1];
    144                 const double c=M[2*1+0];
    145                 const double d=M[2*1+1];
    146 
    147                 //compute norm(M)
    148                 normM=pow(pow(a,2.0)+pow(b,2.0)+pow(c,2.0)+pow(d,2.0),0.5);
    149 
    150                 //if normM<10-30, M=zeros(2,2)
    151                 if (normM<1.0e-30){
    152                         lambda[0]=0.0;
    153                         lambda[1]=0.0;
    154                         vp[0][0]=vp[0][1]=vp[1][0]=vp[1][1]=0.0;
    155                         return;
    156                 }
    157 
    158                 //check that matrix is already diagonal if det(M)=0
    159                 if(Abs(b)<(1.0e-12*normM) & Abs(c)<(1.0e-12*normM)){
    160                         lambda[0]=a;
    161                         lambda[1]=d;
    162                         vp[0][0]=1;
    163                         vp[0][1]=0;
    164                         vp[1][0]=0;
    165                         vp[1][1]=1;
    166                         return;
    167                 }
    168 
    169                 //compute det(M)
    170                 detM=a*d-c*b;
    171 
    172                 //not symetrical and still det<10^-30
    173                 if (Abs(detM)<1.0e-30){
    174                         throw ErrorException(__FUNCT__,exprintf("Cannot find eigen values of a non invertible matrix"));
    175                 }
    176 
    177                 //See http://www.math.harvard.edu/archive/21b_fall_04/exhibits/2dmatrices/index.html
    178                 trM=a+d;
    179 
    180                 //general case
    181                 lambda[0] = 0.5*(trM + pow( trM*trM - 4.0*detM ,0.5));
    182                 lambda[1] = 0.5*(trM - pow( trM*trM - 4.0*detM ,0.5));
    183 
    184                 if(Abs(b)>1.0e-30){ //if b!=0
    185                         norm=pow(b*b+pow(lambda[0]-a,2.0),0.5);
    186                         vp[0][0]=b/norm;
    187                         vp[1][0]=(lambda[0]-a)/norm;
    188                         norm=pow(b*b+pow(lambda[1]-a,2.0),0.5);
    189                         vp[0][1]=b/norm;
    190                         vp[1][1]=(lambda[1]-a)/norm;
    191                 }
    192                 else{
    193                         norm=pow(c*c+pow(lambda[0]-d,2.0),0.5);
    194                         vp[0][0]=(lambda[0]-d)/norm;
    195                         vp[1][0]=c/norm;
    196                         norm=pow(c*c+pow(lambda[1]-d,2.0),0.5);
    197                         vp[0][1]=(lambda[1]-d)/norm;
    198                         vp[1][1]=c/norm;
    199                 }
    200         }
    201         /*}}}1*/
    202106        /*FUNCTION LengthInterpole{{{1*/
    203107        Real8 LengthInterpole(const MetricAnIso Ma,const  MetricAnIso Mb, R2 AB) {
     
    267171        /*}}}1*/
    268172        /*FUNCTION SimultaneousMatrixReduction{{{1*/
    269         void SimultaneousMatrixReduction(MetricAnIso M1,MetricAnIso M2,MetricAnIso* pM) {
    270 
    271                 /*intermediary*/
    272                 double a11,a21,a22;
    273                 double b11,b21,b22;
    274                 double mu1,mu2;
    275                 double lambda1,lambda2;
    276                 double detM1,detP;
    277                 double N[2][2];
    278                 double lambda[2];
    279                 double vp[2][2];
    280                 double invP[2][2];
    281                 MetricAnIso M;
    282 
    283                 //get components of both metrics
    284                 a11=M1.a11; a21=M1.a21; a22=M1.a22;
    285                 b11=M2.a11; b21=M2.a21; b22=M2.a22;
    286 
    287                 //check diagnonal matrices (easy)
    288                 if (Abs(a21)< 1.0e-20 && Abs(b21)< 1.0e-20){
    289                         M.a11=Max(a11,b11);
    290                         M.a22=Max(a22,b22);
    291                         M.a21=0;
    292                         *pM=M;
    293                         return;
    294                 }
    295 
    296                 //Build N=M1^-1 M2 (Alauzet2003 p16)
    297                 detM1=a11*a22-a21*a21;
    298                 if (!detM1){
    299                         printf("a11 a21 a22 = %g %g %g\n",a11,a21,a22);
    300                         throw ErrorException(__FUNCT__,exprintf("One of the metric has a zero eigen value or cannot be inverted... (detP=%g)",detP));
    301                 }
    302                 N[0][0]= 1.0/detM1 * ( a22*b11-a21*b21);
    303                 N[0][1]= 1.0/detM1 * ( a22*b21-a21*b22);
    304                 N[1][0]= 1.0/detM1 * (-a21*b11+a11*b21);
    305                 N[1][1]= 1.0/detM1 * (-a21*b21+a11*b22);
    306 
    307                 //now, we must find the eigen values and vectors of N
    308                 eigen2(&N[0][0],lambda,vp);
    309 
    310                 //Now that we have P=vp, we can recompute M = M1 inter M2
    311                 //
    312                 //      -T [ max(lambda1, mu1)          0         ]  -1
    313                 // M = P   [                                      ] P
    314                 //         [        0            max(lambda2, mu2)]
    315 
    316                 //get det(P)
    317                 detP=vp[0][0]*vp[1][1]-vp[0][1]*vp[1][0];
    318                 if (!detP){
    319                         printf("vp= [%g %g ; %g %g]\n",vp[0][0],vp[0][1],vp[1][0],vp[1][1]);
    320                         throw ErrorException(__FUNCT__,exprintf("One of the metric has a zero eigen value or cannot be inverted... (detP=%g)",detM1));
    321                 }
    322                 invP[0][0]= 1.0/detP * ( vp[1][1]);
    323                 invP[0][1]= 1.0/detP * (-vp[0][1]);
    324                 invP[1][0]= 1.0/detP * (-vp[1][0]);
    325                 invP[1][1]= 1.0/detP * ( vp[0][0]);
    326 
    327                 //Compute lambdai and mui using Rayleigh formula: lambdai = ei' M1 ei
    328                 lambda1=vp[0][0]*(a11*vp[0][0]+a21*vp[1][0]) + vp[1][0]*(a21*vp[0][0]+a22*vp[1][0]);
    329                 lambda2=vp[0][1]*(a11*vp[0][1]+a21*vp[1][1]) + vp[1][1]*(a21*vp[0][1]+a22*vp[1][1]);
    330                 mu1    =vp[0][0]*(b11*vp[0][0]+b21*vp[1][0]) + vp[1][0]*(b21*vp[0][0]+b22*vp[1][0]);
    331                 mu2    =vp[0][1]*(b11*vp[0][1]+b21*vp[1][1]) + vp[1][1]*(b21*vp[0][1]+b22*vp[1][1]);
    332 
    333                 //finally compute M
    334                 M.a11=invP[0][0]*Max(lambda1,mu1)*invP[0][0] + invP[1][0]*Max(lambda2,mu2)*invP[1][0];
    335                 M.a21=invP[0][0]*Max(lambda1,mu1)*invP[0][1] + invP[1][0]*Max(lambda2,mu2)*invP[1][1];
    336                 M.a22=invP[0][1]*Max(lambda1,mu1)*invP[0][1] + invP[1][1]*Max(lambda2,mu2)*invP[1][1];
    337                 *pM=M;
    338         }
    339         /*}}}1*/
    340         /*FUNCTION SimultaneousMatrixReduction_bamg{{{1*/
    341         void SimultaneousMatrixReduction_bamg( MetricAnIso M1,  MetricAnIso M2,double & l1,double & l2, D2xD2 & V) {
     173        void SimultaneousMatrixReduction( MetricAnIso M1,  MetricAnIso M2,double & l1,double & l2, D2xD2 & V) {
    342174                double a11=M1.a11,a21=M1.a21,a22=M1.a22;
    343175                double b11=M2.a11,b21=M2.a21,b22=M2.a22;
     
    353185                const double c=-c21+a11*a22;
    354186                const double bb = b*b,ac= a*c;
     187                const double b2a = b/(2*a);
    355188                const double delta = bb - 4 * ac;
    356                 if (bb + Abs(ac) < 1.0e-20 || (delta< 1.0E-4 * bb ) ){
     189                if ( (bb + Abs(ac) < 1.0e-34 ) ||  (delta < 1.0e-6*bb) ){
    357190                        // racine double;
    358191                        if (Abs(a) < 1.e-30 )
  • issm/trunk/src/c/Bamgx/objects/Triangles.cpp

    r2929 r2932  
    20082008                                }
    20092009
    2010 
    20112010                                /*Compute Metric from Hessian*/
    20122011
     
    20332032
    20342033                                        //Apply Metric to vertex
    2035                                         vertices[iv].m.IntersectWith_new(MVp);
     2034                                        vertices[iv].m.IntersectWith(MVp);
    20362035                                }
    20372036                        }//for all fields
Note: See TracChangeset for help on using the changeset viewer.