MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/mpm/jacobirot.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso                                *
00004  *                                                                      *
00005  * This program is free software: you can redistribute it and/or modify *
00006  * it under the terms of the GNU General Public License as published by *
00007  * the Free Software Foundation, either version 3 of the License, or    *
00008  * any later version.                                                   *
00009  *                                                                      *
00010  * This program is distributed in the hope that it will be useful,      *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00013  * GNU General Public License for more details.                         *
00014  *                                                                      *
00015  * You should have received a copy of the GNU General Public License    *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00017  ************************************************************************/
00018 
00019 /* JacobiRot - Copyright (C) 2007 Dorival de Moraes Pedroso */
00020 
00023 #ifndef MPM_JACOBIROT_H
00024 #define MPM_JACOBIROT_H
00025 
00026 // STL
00027 #include <cmath>  // for sqrt ...
00028 #include <cfloat> // for DBL_EPSILON
00029 
00030 // MechSys
00031 #include <mechsys/util/fatal.h>
00032 
00033 // Local
00034 #include <mechsys/mpm/defs.h>
00035 
00036 namespace MPM {
00037 
00038 inline int JacobiRot(STensor2 const & T, double L[3])
00039 {
00040     const double maxIt  = 30;              // Max number of iterations
00041     const double tol    = DBL_EPSILON*100; // Erro: Tolerance
00042     const double zero   = DBL_EPSILON;     // Zero
00043     
00044     double UT[3];  // Values of the Upper Triangle part of symmetric matrix A
00045     double th;     // theta = (Aii-Ajj)/2Aij
00046     double c;      // Cossine
00047     double s;      // Sine
00048     double cc;     // Cossine squared
00049     double ss;     // Sine squared
00050     double t;      // Tangent
00051     double tmp;    // Auxiliar variable
00052     double sumUT;  // Sum of upper triangle of abs(A) that measures the error
00053     int    it;     // Iteration number
00054     double h;      // Difference L[i]-L[j]
00055     
00056     // Initialize eigenvalues which correnspond to the diagonal part of A
00057     L[0]=T(0); L[1]=T(1); L[2]=T(2);
00058 
00059     // Initialize Upper Triangle part of A matrix (array[3])
00060     UT[0]=T(3)/SQ2; UT[1]=T(4)/SQ2; UT[2]=T(5)/SQ2;
00061 
00062     // Iterations
00063     for (it=1; it<=maxIt; ++it)
00064     {
00065         // Check error
00066         sumUT = fabs(UT[0])+fabs(UT[1])+fabs(UT[2]);
00067         if (sumUT<=tol) return it;
00068         
00069         // i=0, j=1 ,r=2 (p=3)
00070         h=L[0]-L[1];
00071         if (fabs(h)<zero) t=1.0;
00072         else
00073         {
00074             th=0.5*h/UT[0];
00075             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00076             if (th<0.0) t=-t;
00077         }
00078         c  = 1.0/sqrt(1.0+t*t);
00079         s  = c*t;
00080         cc = c*c;
00081         ss = s*s;
00082         // Zeroes term UT[0]
00083         tmp   = cc*L[0] + 2.0*c*s*UT[0] + ss*L[1];
00084         L[1]  = ss*L[0] - 2.0*c*s*UT[0] + cc*L[1];
00085         L[0]  = tmp;
00086         UT[0] = 0.0;
00087         tmp   = c*UT[2] + s*UT[1];
00088         UT[1] = c*UT[1] - s*UT[2];
00089         UT[2] = tmp;
00090         
00091         // i=1, j=2 ,r=0 (p=4)
00092         h = L[1]-L[2];
00093         if (fabs(h)<zero) t=1.0;
00094         else
00095         {
00096             th=0.5*h/UT[1];
00097             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00098             if (th<0.0) t=-t;
00099         }
00100         c  = 1.0/sqrt(1.0+t*t);
00101         s  = c*t;
00102         cc = c*c;
00103         ss = s*s;
00104         // Zeroes term UT[1]
00105         tmp   = cc*L[1] + 2.0*c*s*UT[1] + ss*L[2];
00106         L[2]  = ss*L[1] - 2.0*c*s*UT[1] + cc*L[2];
00107         L[1]  = tmp;
00108         UT[1] = 0.0;
00109         tmp   = c*UT[0] + s*UT[2];
00110         UT[2] = c*UT[2] - s*UT[0];
00111         UT[0] = tmp;
00112 
00113         // i=0, j=2 ,r=1 (p=5)
00114         h = L[0]-L[2];
00115         if (fabs(h)<zero) t=1.0;
00116         else
00117         {
00118             th=0.5*h/UT[2];
00119             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00120             if (th<0.0) t=-t;
00121         }
00122         c  = 1.0/sqrt(1.0+t*t);
00123         s  = c*t;
00124         cc = c*c;
00125         ss = s*s;
00126         // Zeroes term UT[2]
00127         tmp   = cc*L[0] + 2.0*c*s*UT[2] + ss*L[2];
00128         L[2]  = ss*L[0] - 2.0*c*s*UT[2] + cc*L[2];
00129         L[0]  = tmp;
00130         UT[2] = 0.0;
00131         tmp   = c*UT[0] + s*UT[1];
00132         UT[1] = c*UT[1] - s*UT[0];
00133         UT[0] = tmp;
00134     }
00135     throw new Fatal("JacobiRot dit not converge for %d iterations",it);
00136 }
00137 
00138 inline int JacobiRot (STensor2 const & T, double V0[3], double V1[3], double V2[3], double L[3]) 
00139 {
00140     const double maxIt  = 30;              // Max number of iterations
00141     const double tol    = DBL_EPSILON*100; // Erro: Tolerance
00142     const double zero   = DBL_EPSILON;     // Zero
00143     
00144     double UT[3];  // Values of the Upper Triangle part of symmetric matrix A
00145     double th;     // theta = (Aii-Ajj)/2Aij
00146     double c;      // Cossine
00147     double s;      // Sine
00148     double cc;     // Cossine squared
00149     double ss;     // Sine squared
00150     double t;      // Tangent
00151     double tmp;    // Auxiliar variable
00152     double TM[3];  // Auxiliar array
00153     double sumUT;  // Sum of upper triangle of abs(A) that measures the error
00154     int    it;     // Iteration number
00155     double h;      // Difference L[i]-L[j]
00156     
00157     // Initialize eigenvalues which correnspond to the diagonal part of A
00158     L[0]=T(0); L[1]=T(1); L[2]=T(2);
00159 
00160     // Initialize Upper Triangle part of A matrix (array[3])
00161     UT[0]=T(3)/SQ2; UT[1]=T(4)/SQ2; UT[2]=T(5)/SQ2;
00162 
00163     // Initialize eigenvectors
00164     V0[0]=1.0; V1[0]=0.0; V2[0]=0.0;
00165     V0[1]=0.0; V1[1]=1.0; V2[1]=0.0;
00166     V0[2]=0.0; V1[2]=0.0; V2[2]=1.0;
00167 
00168     // Iterations
00169     for (it=1; it<=maxIt; ++it)
00170     {
00171         // Check error
00172         sumUT = fabs(UT[0])+fabs(UT[1])+fabs(UT[2]);
00173         if (sumUT<=tol) return it;
00174         
00175         // i=0, j=1 ,r=2 (p=3)
00176         h=L[0]-L[1];
00177         if (fabs(h)<zero) t=1.0;
00178         else
00179         {
00180             th=0.5*h/UT[0];
00181             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00182             if (th<0.0) t=-t;
00183         }
00184         c  = 1.0/sqrt(1.0+t*t);
00185         s  = c*t;
00186         cc = c*c;
00187         ss = s*s;
00188         // Zeroes term UT[0]
00189         tmp   = cc*L[0] + 2.0*c*s*UT[0] + ss*L[1];
00190         L[1]  = ss*L[0] - 2.0*c*s*UT[0] + cc*L[1];
00191         L[0]  = tmp;
00192         UT[0] = 0.0;
00193         tmp   = c*UT[2] + s*UT[1];
00194         UT[1] = c*UT[1] - s*UT[2];
00195         UT[2] = tmp;
00196         // Actualize eigenvectors
00197         TM[0] = s*V1[0] + c*V0[0];
00198         TM[1] = s*V1[1] + c*V0[1];
00199         TM[2] = s*V1[2] + c*V0[2];
00200         V1[0] = c*V1[0] - s*V0[0];
00201         V1[1] = c*V1[1] - s*V0[1];
00202         V1[2] = c*V1[2] - s*V0[2];
00203         V0[0] = TM[0];
00204         V0[1] = TM[1];
00205         V0[2] = TM[2];
00206         
00207         // i=1, j=2 ,r=0 (p=4)
00208         h = L[1]-L[2];
00209         if (fabs(h)<zero) t=1.0;
00210         else
00211         {
00212             th=0.5*h/UT[1];
00213             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00214             if (th<0.0) t=-t;
00215         }
00216         c  = 1.0/sqrt(1.0+t*t);
00217         s  = c*t;
00218         cc = c*c;
00219         ss = s*s;
00220         // Zeroes term UT[1]
00221         tmp   = cc*L[1] + 2.0*c*s*UT[1] + ss*L[2];
00222         L[2]  = ss*L[1] - 2.0*c*s*UT[1] + cc*L[2];
00223         L[1]  = tmp;
00224         UT[1] = 0.0;
00225         tmp   = c*UT[0] + s*UT[2];
00226         UT[2] = c*UT[2] - s*UT[0];
00227         UT[0] = tmp;
00228         // Actualize eigenvectors
00229         TM[1] = s*V2[1] + c*V1[1];
00230         TM[2] = s*V2[2] + c*V1[2];
00231         TM[0] = s*V2[0] + c*V1[0];
00232         V2[1] = c*V2[1] - s*V1[1];
00233         V2[2] = c*V2[2] - s*V1[2];
00234         V2[0] = c*V2[0] - s*V1[0];
00235         V1[1] = TM[1];
00236         V1[2] = TM[2];
00237         V1[0] = TM[0];
00238 
00239         // i=0, j=2 ,r=1 (p=5)
00240         h = L[0]-L[2];
00241         if (fabs(h)<zero) t=1.0;
00242         else
00243         {
00244             th=0.5*h/UT[2];
00245             t=1.0/(fabs(th)+sqrt(th*th+1.0));
00246             if (th<0.0) t=-t;
00247         }
00248         c  = 1.0/sqrt(1.0+t*t);
00249         s  = c*t;
00250         cc = c*c;
00251         ss = s*s;
00252         // Zeroes term UT[2]
00253         tmp   = cc*L[0] + 2.0*c*s*UT[2] + ss*L[2];
00254         L[2]  = ss*L[0] - 2.0*c*s*UT[2] + cc*L[2];
00255         L[0]  = tmp;
00256         UT[2] = 0.0;
00257         tmp   = c*UT[0] + s*UT[1];
00258         UT[1] = c*UT[1] - s*UT[0];
00259         UT[0] = tmp;
00260         // Actualize eigenvectors
00261         TM[0] = s*V2[0] + c*V0[0];
00262         TM[2] = s*V2[2] + c*V0[2];
00263         TM[1] = s*V2[1] + c*V0[1];
00264         V2[0] = c*V2[0] - s*V0[0];
00265         V2[2] = c*V2[2] - s*V0[2];
00266         V2[1] = c*V2[1] - s*V0[1];
00267         V0[0] = TM[0];
00268         V0[2] = TM[2];
00269         V0[1] = TM[1];
00270     }
00271     throw new Fatal("JacobiRot dit not converge for %d iterations",it);
00272 }
00273 
00274 }; // namespace MPM
00275 
00276 #endif // MPM_JACOBIROT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines