functions.h

00001 /*************************************************************************************
00002  * MechSys - A C++ library to simulate (Continuum) Mechanical Systems                *
00003  * Copyright (C) 2005 Dorival de Moraes Pedroso <dorival.pedroso at gmail.com>       *
00004  * Copyright (C) 2005 Raul Dario Durand Farfan  <raul.durand at gmail.com>           *
00005  *                                                                                   *
00006  * This file is part of MechSys.                                                     *
00007  *                                                                                   *
00008  * MechSys is free software; you can redistribute it and/or modify it under the      *
00009  * terms of the GNU General Public License as published by the Free Software         *
00010  * Foundation; either version 2 of the License, or (at your option) any later        *
00011  * version.                                                                          *
00012  *                                                                                   *
00013  * MechSys is distributed in the hope that it will be useful, but WITHOUT ANY        *
00014  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   *
00015  * PARTICULAR PURPOSE. See the GNU General Public License for more details.          *
00016  *                                                                                   *
00017  * You should have received a copy of the GNU General Public License along with      *
00018  * MechSys; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, *
00019  * Fifth Floor, Boston, MA 02110-1301, USA                                           *
00020  *************************************************************************************/
00021 
00022 #ifndef MECHSYS_TENSORS_FUNCTIONS_H
00023 #define MECHSYS_TENSORS_FUNCTIONS_H
00024 
00025 #ifdef HAVE_CONFIG_H
00026   #include "config.h"
00027 #else
00028   #ifndef REAL
00029     #define REAL double
00030   #endif
00031 #endif
00032 
00033 #include <cassert> // for assert()
00034 #include <cmath>   // for sqrt()
00035 
00036 #include "tensors/tensors.h"
00037 #include "tensors/jacobirot.h"
00038 #include "util/exception.h"
00039 
00040 namespace Tensors
00041 {
00042 
00047 
00048 
00055 void Mult(Tensor2 const & S,  
00056           Tensor2 const & T,  
00057           Tensor2       & R   
00058 );
00059 
00061 
00062 REAL Norm(Tensor2 const & T 
00063 );
00064 
00066 REAL Det(Tensor2 const & T);
00067 
00069 
00070 bool Inv(Tensor2 const & T,  
00071          Tensor2       & R   
00072 );
00073 
00075 
00076 bool Eigenvals(Tensor2 const & T,    
00077                REAL            L[3]  
00078 );
00079 
00081 // {{{
00110 // }}}
00111 bool Eigenvp(Tensor2 const & T,    
00112              REAL            L[3], 
00113              Tensor2         P[3]  
00114 );
00115 
00117 
00118 bool Sqrt(Tensor2 const & T, 
00119           Tensor2       & R  
00120 );
00121 
00123 void CharInvs(Tensor2 const & T,   
00124               REAL            I[3] 
00125 );
00126 
00128 
00132 void Strain_Ev_Ed(Tensor2 const & Eps, 
00133                   REAL          & Ev,  
00134                   REAL          & Ed   
00135 );
00136 
00138 
00142 void Stress_p_q(Tensor2 const & Sig, 
00143                 REAL          & p,   
00144                 REAL          & q    
00145 );
00146 
00148 
00149 inline REAL Stress_q(Tensor2 const & Sig 
00150 );
00151 
00153 
00172 inline REAL Sin3ThDev(Tensor2 const & S);
00173 
00175 void Stress_p_q_S_sin3th(Tensor2 const & Sig   ,
00176                          REAL          & p     ,
00177                          REAL          & q     ,
00178                          Tensor2       & S     , 
00179                          REAL          & sin3th  
00180 );
00181 
00183 
00188 bool Stress_tn_ts(Tensor2 const & Sig, 
00189                   REAL          & tn,  
00190                   REAL          & ts   
00191 );
00192 
00194 
00198 void Stress_P_Q(Tensor2 const & Sig, 
00199                 REAL          & P,   
00200                 REAL          & Q    
00201 );
00202 
00204 void Stress_P_Q_S_sin3th(Tensor2 const & Sig   , 
00205                          REAL          & P     , 
00206                          REAL          & Q     , 
00207                          Tensor2       & S     , 
00208                          REAL          & sin3th
00209 );
00210 
00212 inline REAL Sin3Th(REAL SI, REAL SII, REAL SIII);
00213 
00215 inline void Hid2Sig(REAL const &    p, REAL const &    q, REAL const &   th,
00216                     REAL       & Sig1, REAL       & Sig2, REAL       & Sig3);
00217 
00219 inline void Hid2Sig(REAL const *  P, REAL const *   Q, REAL const *    T,
00220                     REAL       * SI, REAL       * SII, REAL       * SIII, int Size); // S# must be already allocated !!!
00221 
00223 inline void Hid2Sig_(REAL const & SX, REAL const &  SY, REAL const &    p,
00224                      REAL       & SI, REAL       & SII, REAL       & SIII);
00225  // end of group TensorFunctions
00227 
00228 
00230 
00231 
00232 // Tensor multiplication:  R = S*T
00233 inline void Mult(Tensor2 const & S, Tensor2 const & T, Tensor2 & R)  // {{{
00234 {
00235     REAL sq2 = sqrt(2.0);
00236 
00237     R(0) = S(0)*T(0)     + S(3)*T(3)/2.0 + S(5)*T(5)/2.0;
00238     R(1) = S(3)*T(3)/2.0 + S(1)*T(1)     + S(4)*T(4)/2.0;
00239     R(2) = S(5)*T(5)/2.0 + S(4)*T(4)/2.0 + S(2)*T(2);
00240 
00241     R(3) = S(0)*T(3)     + S(3)*T(1)     + S(5)*T(4)/sq2;
00242     R(4) = S(3)*T(5)/sq2 + S(1)*T(4)     + S(4)*T(2);
00243     R(5) = S(0)*T(5)     + S(3)*T(4)/sq2 + S(5)*T(2);
00244 
00245 #ifndef NDEBUG
00246     REAL A = S(3)*T(0)     + S(1)*T(3)     + S(4)*T(5)/sq2;
00247     REAL B = S(5)*T(3)/sq2 + S(4)*T(1)     + S(2)*T(4);
00248     REAL C = S(5)*T(0)     + S(4)*T(3)/sq2 + S(2)*T(5);
00249     //std::cout << _15_8 R(3)-A << " | " << _15_8 R(4)-B << " | " << _15_8 R(5)-C << std::endl;
00250     const REAL ZERO=1.0e-10;
00251     if (!(fabs(R(3)-A)<ZERO && fabs(R(4)-B)<ZERO && fabs(R(5)-C)<ZERO))
00252         throw new Fatal("Tensors::Mult: Result of matrix multiplication is NOT symmetric. assert(fabs(R(3)-A)<ZERO & fabs(R(4)-B)<ZERO & fabs(R(5)-C)<ZERO) failed)");
00253 #endif
00254 } // }}}
00255 
00257 inline REAL Norm(Tensor2 const & T)  // {{{
00258 {
00259     return sqrt(T(0)*T(0) + T(1)*T(1) + T(2)*T(2) + T(3)*T(3) + T(4)*T(4) + T(5)*T(5));
00260 } // }}}
00261     
00262 // Determinant of T
00263 inline REAL Det(Tensor2 const & T)  // {{{
00264 {
00265     return T(0)*T(1)*T(2) + T(3)*T(4)*T(5)/sqrt(2.0) - T(0)*T(4)*T(4)/2.0 - T(1)*T(5)*T(5)/2.0 - T(2)*T(3)*T(3)/2.0;
00266 } // }}}
00267 
00268 // Inverse of a tensor T:  R = T^(-1)
00269 inline bool Inv(Tensor2 const & T, Tensor2 & R)  // {{{
00270 {
00271     REAL sq2 = sqrt(2.0);
00272     REAL det = Det(T);
00273     
00274     const REAL ZERO=1.0e-10;
00275     if (fabs(det)<ZERO) return false;
00276 
00277     R(0) =     ( T(1)*T(2)     - T(4)*T(4)/2.0 )/det;
00278     R(1) =     ( T(2)*T(0)     - T(5)*T(5)/2.0 )/det;
00279     R(2) =     ( T(0)*T(1)     - T(3)*T(3)/2.0 )/det;
00280     R(3) = sq2*( T(4)*T(5)/2.0 - T(2)*T(3)/sq2 )/det;
00281     R(4) = sq2*( T(5)*T(3)/2.0 - T(0)*T(4)/sq2 )/det;
00282     R(5) = sq2*( T(3)*T(4)/2.0 - T(1)*T(5)/sq2 )/det;
00283 
00284     return true;
00285 } // }}}
00286 
00287 // Eigenvalues (L) of a tensor T
00288 inline bool Eigenvals(Tensor2 const & T, REAL L[3])  // {{{
00289 {
00290     // Calculate eigenvalues and eigenvectors
00291     if (JacobiRot(T,L)==-1) return false;
00292 
00293     return true;
00294 } // }}}
00295 
00296 // Eigenvalues (L) and Eigenprojectors (P) of a tensor T
00297 inline bool Eigenvp(Tensor2 const & T, REAL L[3], Tensor2 P[3])  // {{{
00298 {
00299     REAL V0[3]; // eigenvector
00300     REAL V1[3]; // eigenvector
00301     REAL V2[3]; // eigenvector
00302 
00303     // Calculate eigenvalues and eigenvectors
00304     if (JacobiRot(T,V0,V1,V2,L)==-1) return false;
00305 
00306     REAL sq2 = sqrt(2.0);
00307 
00308     // Calculate eigenprojectors (Pi = Vi dyad Vi)
00309     // Eigenprojector 0
00310     P[0](0) = V0[0] * V0[0];
00311     P[0](1) = V0[1] * V0[1];
00312     P[0](2) = V0[2] * V0[2];
00313     P[0](3) = V0[0] * V0[1] * sq2;
00314     P[0](4) = V0[1] * V0[2] * sq2;
00315     P[0](5) = V0[0] * V0[2] * sq2;
00316     // Eigenprojector 1
00317     P[1](0) = V1[0] * V1[0];
00318     P[1](1) = V1[1] * V1[1];
00319     P[1](2) = V1[2] * V1[2];
00320     P[1](3) = V1[0] * V1[1] * sq2;
00321     P[1](4) = V1[1] * V1[2] * sq2;
00322     P[1](5) = V1[0] * V1[2] * sq2;
00323     // Eigenprojector 2
00324     P[2](0) = V2[0] * V2[0];
00325     P[2](1) = V2[1] * V2[1];
00326     P[2](2) = V2[2] * V2[2];
00327     P[2](3) = V2[0] * V2[1] * sq2;
00328     P[2](4) = V2[1] * V2[2] * sq2;
00329     P[2](5) = V2[0] * V2[2] * sq2;
00330 
00331     return true;
00332 } // }}}
00333 
00334 // Square root of a tensor T:  R = T^(0.5)
00335 inline bool Sqrt(Tensor2 const & T, Tensor2 & R)  // {{{
00336 {
00337     REAL    L[3]; // Eigenvalues
00338     Tensor2 P[3]; // Eigenprojectors
00339 
00340     // Calculate eigenvalues and eigenprojectors
00341     if (!Eigenvp(T,L,P)) return false;
00342     
00343     // Calculate R = sqrt(T)
00344     R(0)=0.0;
00345     R(1)=0.0;
00346     R(2)=0.0;
00347     R(3)=0.0;
00348     R(4)=0.0;
00349     R(5)=0.0;
00350     for (int i=0; i<3; ++i)
00351         R = sqrt(L[i])*P[i] + R; // R <- sqrt(L[i])*P[i] + R
00352 
00353     return true;
00354 } // }}}
00355 
00356 // Characteristic invariants of a symmetric second order tensor
00357 inline void CharInvs(Tensor2 const & T, REAL I[3])  // {{{
00358 {
00359     I[0] = T(0)+T(1)+T(2);
00360     I[1] = T(0)*T(1) + T(1)*T(2) + T(2)*T(0) - (T(3)*T(3) + T(4)*T(4) + T(5)*T(5))/2.0;
00361     I[2] = T(0)*T(1)*T(2) + T(3)*T(4)*T(5)/sqrt(2.0) - (T(0)*T(4)*T(4) + T(1)*T(5)*T(5) + T(2)*T(3)*T(3))/2.0;
00362 } // }}}
00363 
00365 inline void Strain_Ev_Ed (Tensor2 const & Eps, REAL & Ev, REAL & Ed)  // {{{
00366 {
00367     Ev = Eps(0)+Eps(1)+Eps(2);
00368     Ed = sqrt(2.0*(   (Eps(0)-Eps(1))*(Eps(0)-Eps(1))
00369                     + (Eps(1)-Eps(2))*(Eps(1)-Eps(2))
00370                     + (Eps(2)-Eps(0))*(Eps(2)-Eps(0)) + 3.0*(Eps(3)*Eps(3) + Eps(4)*Eps(4) + Eps(5)*Eps(5)) ))/3.0;
00371 } // }}}
00372 
00374 inline void Stress_p_q(Tensor2 const & Sig, REAL & p, REAL & q)  // {{{
00375 {
00376     p = (Sig(0)+Sig(1)+Sig(2))/3.0;
00377     q = sqrt((   (Sig(0)-Sig(1))*(Sig(0)-Sig(1))
00378                + (Sig(1)-Sig(2))*(Sig(1)-Sig(2))
00379                + (Sig(2)-Sig(0))*(Sig(2)-Sig(0)) + 3.0*(Sig(3)*Sig(3) + Sig(4)*Sig(4) + Sig(5)*Sig(5)) )/2.0);
00380 } // }}}
00381 
00383 inline REAL Stress_q(Tensor2 const & Sig) // {{{
00384 {
00385     return sqrt((   (Sig(0)-Sig(1))*(Sig(0)-Sig(1))
00386                   + (Sig(1)-Sig(2))*(Sig(1)-Sig(2))
00387                   + (Sig(2)-Sig(0))*(Sig(2)-Sig(0)) + 3.0*(Sig(3)*Sig(3) + Sig(4)*Sig(4) + Sig(5)*Sig(5)) )/2.0);
00388 } // }}}
00389 
00391 inline REAL Sin3ThDev(Tensor2 const & S) // {{{
00392 {
00393     const REAL ZZERO = 1.0e-5;
00394     REAL normS = Norm(S);
00395     if (normS<=ZZERO) return -1.0;
00396     else
00397     {
00398         REAL     L = 9.0*sqrt(2.0)*Det(S)/(sqrt(3.0)*pow(normS,3.0));
00399         if      (L>= 1.0) return  1.0;
00400         else if (L<=-1.0) return -1.0;
00401         else              return  L;
00402     }
00403 } // }}}
00404 
00406 inline void Stress_p_q_S_sin3th(Tensor2 const & Sig, REAL & p,  REAL & q, Tensor2 & S, REAL & sin3th) // {{{
00407 {
00408     Stress_p_q(Sig,p,q);
00409     S = Sig - I * p;
00410     const REAL    ZZERO  = 1.0e-7;
00411     if (q<=ZZERO) sin3th = -1.0; // 3th==-90 => th=30
00412     else          sin3th = 27.0*Det(S)/(2.0*pow(q,3.0));
00413     if (sin3th>= 1.0) sin3th =  1.0;
00414     if (sin3th<=-1.0) sin3th = -1.0;
00415 } // }}}
00416 
00418 inline bool Stress_tn_ts(Tensor2 const & Sig, REAL & tn, REAL & ts)  // {{{
00419 {
00420     REAL I[3];
00421     CharInvs(Sig,I);
00422     const REAL ZERO=1.0e-10;
00423     if (fabs(I[1])<=ZERO) return false; // Second invariant equal zero
00424 
00425     REAL s = I[0]*I[1]*I[2]-9.0*I[2]*I[2];
00426     if (s<0.0) return false; // in ts, avoid sqrt(s) NaN
00427 
00428     tn = 3.0*I[2]/I[1];
00429     if (tn<ZERO) return false; // tn must be >= 0
00430 
00431     ts = sqrt(s)/I[1];
00432     if (ts!=ts) return false;  // NaN values
00433 
00434     return true;
00435 } // }}}
00436 
00438 inline void Stress_P_Q(Tensor2 const & Sig, REAL & P,  REAL & Q) // {{{
00439 {
00440     P = (Sig(0)+Sig(1)+Sig(2))/sqrt(3.0);
00441     Q = sqrt( ((Sig(0)-Sig(1))*(Sig(0)-Sig(1))
00442              + (Sig(1)-Sig(2))*(Sig(1)-Sig(2))
00443              + (Sig(2)-Sig(0))*(Sig(2)-Sig(0)))/3.0 + Sig(3)*Sig(3) + Sig(4)*Sig(4) + Sig(5)*Sig(5) );
00444 } // }}}
00445 
00447 inline void Stress_P_Q_S_sin3th(Tensor2 const & Sig, REAL & P, REAL & Q, Tensor2 & S, REAL & sin3th) // {{{
00448 {
00449     Stress_P_Q(Sig,P,Q);
00450     S = Sig - I * (P/sqrt(3.0));
00451     const REAL    ZZERO  = 1.0e-7;
00452     if (Q<=ZZERO) sin3th = -1.0; // 3th==-90 => th=30
00453     else          sin3th = 27.0*Det(S)/(2.0*pow(sqrt(3.0)*Q/sqrt(2.0),3.0));
00454     if (sin3th>= 1.0) sin3th =  1.0;
00455     if (sin3th<=-1.0) sin3th = -1.0;
00456 } // }}}
00457 
00459 inline REAL Sin3Th(REAL SI, REAL SII, REAL SIII)  // {{{
00460 {
00461     /*       \->T   | S1  
00462      *        \  A<-|   
00463      *         \    |     
00464      *     -30  \   |         
00465      *       ',  \  |
00466      *         '. \ |
00467      *           '.\|
00468      *            .' -.                
00469      *          .'     '.
00470      *        .'         '.
00471      *   S2 .'             '. S3    */
00472 
00473     REAL       p = (SI+SII+SIII)/3.0;
00474     REAL devS[3] = {SI-p, SII-p, SIII-p};
00475     REAL    det  = devS[0]*devS[1]*devS[2];
00476     REAL    norm = sqrt(devS[0]*devS[0] + devS[1]*devS[1] + devS[2]*devS[2]);
00477     if (norm<=1.0e-5) return -1.0;
00478     else
00479     {
00480         REAL     L = 9.0*sqrt(2.0)*det/(sqrt(3.0)*pow(norm,3.0));
00481         if      (L>= 1.0) return  1.0;
00482         else if (L<=-1.0) return -1.0;
00483         else              return  L;
00484     }
00485 } // }}}
00486 
00488 inline void Hid2Sig(REAL const &    p, REAL const &    q, REAL const &   th, // {{{
00489                     REAL       & Sig1, REAL       & Sig2, REAL       & Sig3)
00490 {
00491     /*  Converts hidrostatic coordinates to sigma (principal) coord (T in radians)
00492 
00493                    SI|      r = (Sx^2+Sy^2)^0.5
00494                      |Sy    z = Sz
00495                  \ T |
00496                   \  |
00497                    \ |
00498                     \|
00499                    .' -.--------> Sx
00500                  .'     '.
00501                .'         '.
00502          SII .'             '. SIII      */
00503 
00504     // Constants
00505     REAL sq2    = sqrt(2.0);
00506     REAL sq6    = sqrt(6.0);
00507     REAL sq2by3 = sq2/sqrt(3.0);
00508     REAL     r  = q*sq2by3;
00509     REAL     Sx = -r*sin(th);
00510     REAL     Sy =  r*cos(th);
00511            Sig1 = p + 2.0*Sy/sq6;
00512            Sig2 = p -     Sy/sq6 - Sx/sq2;
00513            Sig3 = p -     Sy/sq6 + Sx/sq2;
00514 } // }}}
00515 
00517 inline void Hid2Sig(REAL const *  P, REAL const *   Q, REAL const *    T, // {{{
00518                     REAL       * SI, REAL       * SII, REAL       * SIII, int Size)
00519 {
00520     /*  Converts hidrostatic coordinates to sigma (principal) coord (T in radians)
00521 
00522                    SI|      r = (Sx^2+Sy^2)^0.5
00523                      |Sy    z = Sz
00524                  \ T |
00525                   \  |
00526                    \ |
00527                     \|
00528                    .' -.--------> Sx
00529                  .'     '.
00530                .'         '.
00531          SII .'             '. SIII      */
00532 
00533     // Constants
00534     REAL sq2    = sqrt(2.0);
00535     REAL sq6    = sqrt(6.0);
00536     REAL sq2by3 = sq2/sqrt(3.0);
00537     for (int i=0; i<Size; ++i)
00538     {
00539         REAL r  = Q[i]*sq2by3;
00540         REAL Sx = -r*sin(T[i]);
00541         REAL Sy =  r*cos(T[i]);
00542         SI  [i] = P[i] + 2.0*Sy/sq6;
00543         SII [i] = P[i] -     Sy/sq6 - Sx/sq2;
00544         SIII[i] = P[i] -     Sy/sq6 + Sx/sq2;
00545     }
00546 } // }}}
00547 
00549 inline void Hid2Sig_(REAL const & SX, REAL const &  SY, REAL const &    p, // {{{
00550                      REAL       & SI, REAL       & SII, REAL       & SIII)
00551 {
00552     REAL sq2  = sqrt(2.0);
00553     REAL sq6  = sqrt(6.0);
00554          SI   = p + 2.0*SY/sq6;
00555          SII  = p -     SY/sq6 - SX/sq2;
00556          SIII = p -     SY/sq6 + SX/sq2;
00557 } // }}}
00558 
00559 }; // namespace Tensors
00560 
00561 #endif // MECHSYS_TENSORS_FUNCTIONS_H
00562 
00563 // vim:fdm=marker

Generated on Wed Jan 24 15:56:27 2007 for MechSys by  doxygen 1.4.7