00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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>
00034 #include <cmath>
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);
00221
00223 inline void Hid2Sig_(REAL const & SX, REAL const & SY, REAL const & p,
00224 REAL & SI, REAL & SII, REAL & SIII);
00225
00227
00228
00230
00231
00232
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
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
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
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
00288 inline bool Eigenvals(Tensor2 const & T, REAL L[3])
00289 {
00290
00291 if (JacobiRot(T,L)==-1) return false;
00292
00293 return true;
00294 }
00295
00296
00297 inline bool Eigenvp(Tensor2 const & T, REAL L[3], Tensor2 P[3])
00298 {
00299 REAL V0[3];
00300 REAL V1[3];
00301 REAL V2[3];
00302
00303
00304 if (JacobiRot(T,V0,V1,V2,L)==-1) return false;
00305
00306 REAL sq2 = sqrt(2.0);
00307
00308
00309
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
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
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
00335 inline bool Sqrt(Tensor2 const & T, Tensor2 & R)
00336 {
00337 REAL L[3];
00338 Tensor2 P[3];
00339
00340
00341 if (!Eigenvp(T,L,P)) return false;
00342
00343
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;
00352
00353 return true;
00354 }
00355
00356
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;
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;
00424
00425 REAL s = I[0]*I[1]*I[2]-9.0*I[2]*I[2];
00426 if (s<0.0) return false;
00427
00428 tn = 3.0*I[2]/I[1];
00429 if (tn<ZERO) return false;
00430
00431 ts = sqrt(s)/I[1];
00432 if (ts!=ts) return false;
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;
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
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
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
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
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
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
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 };
00560
00561 #endif // MECHSYS_TENSORS_FUNCTIONS_H
00562
00563