elast_tst.cpp

Go to the documentation of this file.
00001 
00002 //################################################################################
00003 //# COPY-YES  (C):     :-))                                                      #
00004 //# PROJECT:           Object Oriented Finite Element Program                    #
00005 //# PURPOSE:                                                                     #
00006 //# CLASS:                                                                       #
00007 //#                                                                              #
00008 //# VERSION:                                                                     #
00009 //# LANGUAGE:          C++.ver >= 2.0                                            #
00010 //# TARGET OS:         DOS || UNIX || . . .                                      #
00011 //# DESIGNER(S):       Boris Jeremic                                             #
00012 //# PROGRAMMER(S):     Boris Jeremic                                             #
00013 //#                                                                              #
00014 //#                                                                              #
00015 //# DATE:              April 2001                                                #
00016 //# UPDATE HISTORY:                                                              #
00017 //#                                                                              #
00018 //#                                                                              #
00019 //################################################################################
00020 //*/
00021 #include "time.h"
00022 #include "limits.h"
00023 #include "math.h"
00024 #include "float.h"
00025 // nDarray tools
00026 #include "BJtensor.h"
00027 #include "stresst.h"
00028 #include "straint.h"
00029 #include "BJvector.h"
00030 #include "BJmatrix.h"
00031 #include "iostream.h"
00032 
00033 int main(int argc, char *argv[])
00034 {
00035   if (argc != 2)
00036     {
00037       puts("\a\n usage: elast_tst test01.std\n");
00038       exit( 1 );
00039     }
00040 ::printf("\n\n-------------  MACHINE (CPU) DEPENDENT THINGS  --------------\n\n");
00041 
00042 // defining machine epsilon for different built in data types supported by C++
00043 float        float_eps       = f_macheps();  // or use float.h values FLT_EPSILON
00044 double       double_eps      = d_macheps();  // or use float.h values DBL_EPSILON
00045 //long double  long_double_eps = ld_macheps(); // or use float.h values LDBL_EPSILON
00046 
00047 ::printf("\n float macheps = %.20e \n",float_eps);
00048 ::printf(" double macheps = %.20e \n",double_eps);
00049 //::printf(" long double macheps = %.20Le \n\n\n",long_double_eps);
00050 
00051 
00052 // Usual tolerance is defined as square root of machine epsilon
00053 float        sqrt_f_eps       = sqrt(f_macheps());
00054 double       sqrt_d_eps       = sqrt(d_macheps());
00055 //long double  sqrt_ld_eps      = sqrt(ld_macheps());
00056 
00057 ::printf("\n sqrt float macheps = %.20e \n",sqrt_f_eps);
00058 ::printf(" sqrt double macheps = %.20e \n",sqrt_d_eps);
00059 //::printf(" sqrt long double macheps = %.20Le \n",sqrt_ld_eps);
00060 
00061 
00062 double one = 1.0;
00063 double onepmc = 1.0+double_eps;
00064 ::printf("\n one = %.32e \n",one);
00065 ::printf("onepmc = %.32e \n",onepmc);
00066 if (one == onepmc) 
00067   {
00068     printf("1.0 == 1.0+double_eps -->>  OK \n");
00069   }
00070 else 
00071   {
00072     printf("1.0 == 1.0+double_eps -->>  NOT OK \n");
00073   }   
00074 
00075 
00076 
00077 double one2 = 10e20;
00078 double onepmc2 = 10e20*(1.0+double_eps);
00079 ::printf("\n one2 = %.32e \n",one2);
00080 ::printf("onepmc2 = %.32e \n",onepmc2);
00081 if (one2 == onepmc2) 
00082   {
00083     printf("10e20 == 10e20*(1.0+double_eps) -->>  OK \n");
00084   }
00085 else 
00086   {
00087     printf("10e20 == 10e20*(1.0+double_eps) -->>  NOT OK \n");
00088   }   
00089 
00090 
00091 
00092 double one3 = 1.0;
00093 double onepmc3 = 1.0+double_eps*10000.0;
00094 ::printf("\n one3 = %.32e \n",one3);
00095 ::printf("onepmc3 = %.32e\n",onepmc3);
00096 if (one3 == onepmc3) 
00097   {
00098     printf("1.0 == 1.0+double_eps*10.0 -->>  OK \n");
00099   }
00100 else 
00101   {
00102     printf("1.0 == 1.0+double_eps*10.0 -->>  NOT OK \n");
00103   }   
00104 
00105 
00106 ::printf("\n\n----------------  MATRIX  -----------------\n\n");
00107 
00108 // New data type MATRIX is defined in such a way that it can be regarded
00109 // as concrete data type.
00110 // default constructor:
00111   BJmatrix matrix1;
00112   matrix1.print("m1","matrix1");
00113 
00114   static double initvalue[] = {1.0, 2.0,
00115                                3.0, 4.0};
00116 // constructor with matrix initialization
00117   BJmatrix matrix2(2,2,initvalue);
00118   matrix2.print("m2","matrix2");
00119 
00120 // unit matrix initialization ( third order )
00121   BJmatrix matrix3("I",3);
00122   matrix3.print("m3","matrix3");
00123 
00124 // matrix initialization from the file that is in predefined format!
00125   BJmatrix  m(argv[1]);
00126   m.print("m","m is");
00127 //====
00128 // matrix assignment
00129   BJmatrix first_matrix = m;
00130   first_matrix.print("fm","first_matrix is");
00131 
00132 
00133 // ---------------------------------
00134 ::printf("\n\n--------EIGENVECTORS and EIGENVALUES-----------\n");
00135   static double symm_initvalue[] = {1.0, 0.0,
00136                                     0.0, 0.0};
00137 // constructor with matrix initialization
00138   BJmatrix sym_matrix(2,2,symm_initvalue);
00139   sym_matrix.print("m","Sym_matrix");
00140 
00141 // Eigenvalues
00142   BJvector eval = sym_matrix.eigenvalues();
00143   eval.print("ev","Eigenvalues of sym_matrix");
00144 // Eigenvectors
00145   BJmatrix evect = sym_matrix.eigenvectors();
00146   evect.print("ev","Eigenvectors of sym_matrix");
00147 
00148 // matrix to file "test.dat"
00149   m.write_standard("test.dat", "this is a test");
00150 
00151 // equivalence of two matrices ( within tolerance sqrt(macheps) )
00152   if ( first_matrix == m ) ::printf("\n first_matrix == m  TRUE \n");
00153   else ::printf("\a\n first_matrix == m  NOTTRUE \n");
00154 
00155 // matrix addition
00156   BJmatrix m2 =m+m;
00157   m2.print("m2","\nm+m = \n");
00158 
00159 // equivalence of two matrices ( within tolerance sqrt(macheps) )
00160   if ( m2 == m ) ::printf("\a\n m2 == m  TRUE \n");
00161   else ::printf("\n m2 == m  NOTTRUE \n");
00162 // matrix substraction
00163   BJmatrix m3 =m-m;
00164   m3.print("m3","\nm-m = \n");
00165 
00166 // matrix multiplication
00167   BJmatrix m4 = m*m;
00168   m4.print("m4","\n m*m = \n");
00169 
00170 // matrix transposition
00171   BJmatrix mtran = m.transpose();
00172   mtran.print("mt","transpose of m is");
00173 
00174 // determinant of matrix
00175 
00176   printf("determinant = %6.6f \n",m.determinant());
00177 
00178 //  exit(0);
00179 // matrix inversion
00180   BJmatrix minv = m.inverse();
00181   minv.print("mi","inverse of m is");
00182 // check matrix inversion
00183   ( m * minv ).print("1"," m * m.inverse() ");
00184 
00185 // minima, maxima, mean and variance values for matrix:
00186   printf("min = %6.6f \n", m.mmin() );
00187   printf("max = %6.6f \n", m.mmax() );
00188   printf("mean = %6.6f \n", m.mean() );
00189   printf("variance = %6.6f \n", m.variance() );
00190 
00191 //====//===printf("\n\n-----------------  SKY MATRIX ----------------------\n\n");
00192 //====//===
00193 //====//===// skymatrix as defined by K.J. Bathe in "FE procedures in Engineering Analysis"
00194 //====//===// The example is from that book too!
00195 //====//===
00196 //====//===int maxa[] = { 1,   2,         4,          6,          8,                  13};
00197 //====//===double a[] = {2.0, 3.0, -2.0, 5.0, -2.0, 10.0, -3.0, 10.0, 4.0, 0.0, 0.0, -1.0};
00198 //====//===double rhs[] = { 0.0, 1.0, 0.0, 0.0, 0.0 };
00199 //====//===
00200 //====//===// skymatrix constructor
00201 //====//===  skymatrix first( 5, maxa, a);
00202 //====//===
00203 //====//===// simple print functions:
00204 //====//===  first.full_print("\nfirst Sparse Skyline Matrix as FULL :\n ");
00205 //====//===  first.lower_print("\nfirst Sparse Skyline Matrix :\n ");
00206 //====//===  first.upper_print("\nfirst Sparse Skyline Matrix :\n ");
00207 //====//===
00208 //====//===// skymatrix assignment
00209 //====//===  skymatrix second = first;
00210 //====//===  second.full_print("\nsecond Sparse Skyline Matrix as FULL :\n ");
00211 //====//===
00212 //====//===//  skymatrix third; // not defined !
00213 //====//===// assignments:
00214 //====//===  skymatrix third = second = first;
00215 //====//===
00216 //====//===// LDL factorization ( see K.J. Bathe's book! )
00217 //====//===  first = first.v_ldl_factorize();
00218 //====//===
00219 //====//===// simple print functions:
00220 //====//===  first.lower_print("\n lower first but factorized :\n ");
00221 //====//===  first.full_print("\nfirst but factorized Sparse Skyline Matrix as FULL :\n ");
00222 //====//===  first.upper_print("\n upper first but factorized :\n ");
00223 //====//===
00224 //====//===// right hand side reduction ( see K.J. Bathe's book! ) ( vetor of unknowns is rhs )
00225 //====//===  first.d_reduce_r_h_s_l_v( rhs );
00226 //====//===  int i=0;
00227 //====//===  for( i=0 ; i<5 ; i++ )
00228 //====//===    {
00229 //====//===      printf("intermediate_rhs[%d] = %8.4f\n",i, rhs[i]);
00230 //====//===    }
00231 //====//===
00232 //====//===// backsubstitution
00233 //====//===  first.d_back_substitute ( rhs );
00234 //====//===  for( i=0 ; i<5 ; i++ )
00235 //====//===    {
00236 //====//===      printf("solution_rhs[%d] = %8.4f\n",i, rhs[i]);
00237 //====//===    }
00238 //====//===
00239 //====//===// minima, maxima and mean values for skymatrix:
00240 //====//===  printf("min = %6.6f \n", first.mmin() );
00241 //====//===  printf("max = %6.6f \n", first.mmax() );
00242 //====//===  printf("mean = %6.6f \n", first.mean() );
00243 //====//===//
00244 //====//===//
00245 //====//===
00246 //====//===printf("\n\n-----------------  PROFILE MATRIX ----------------------\n");
00247 //====//===printf("-----------------  EXAMPLE 1 ----------------------\n\n");
00248 //====//===
00249 //====//===// profilematrix as defined by O.C. Zienkiewicz and R.L. Taylor
00250 //====//===// in "The FEM  - fourth edition"
00251 //====//===// The example is from: K.J. Bathe: "FE procedures in Engineering Analysis"
00252 //====//===
00253 //====//===int jp[]    = { 0,    1,    2,    3,                   7};
00254 //====//===double au[] = {    -2.0, -2.0, -3.0, -1.0, 0.0, 0.0, 4.0};
00255 //====//===double ad[] = { 2.0, 3.0, 5.0, 10.0, 10.0 };
00256 //====//===double* al  = au;
00257 //====//===double b[] = { 0.0, 1.0, 0.0, 0.0, 0.0 };
00258 //====//===
00259 //====//===// profile matrix constructor
00260 //====//===  profilematrix first_profile( 5, jp, 'S', au, al, ad);
00261 //====//===
00262 //====//===// simple print function
00263 //====//===  first_profile.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
00264 //====//===
00265 //====//===// asignment operetor
00266 //====//===  profilematrix second_profile = first_profile;
00267 //====//===  second_profile.full_print("\nsecond_profile Sparse Profile Matrix as FULL :\n ");
00268 //====//===
00269 //====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
00270 //====//===// "The FEM - fourth edition"
00271 //====//===  first_profile = first_profile.datri();
00272 //====//===  first_profile.full_print("\nfirst but factorized Sparse Profile Matrix as FULL :\n ");
00273 //====//===  ::printf("\n\n");
00274 //====//===
00275 //====//===// right hand side reduction and backsubstitution ( vector of unknowns is b )
00276 //====//===  first_profile.dasol(b);
00277 //====//===  for( i=0 ; i<5 ; i++ )
00278 //====//===    {
00279 //====//===      printf("solution_b[%d] = %8.4f\n",i, b[i]);
00280 //====//===    }
00281 //====//===
00282 //====//===  printf("\n\nmin = %6.6f \n", first_profile.mmin() );
00283 //====//===  printf("max = %6.6f \n", first_profile.mmax() );
00284 //====//===  printf("mean = %6.6f \n", first_profile.mean() );
00285 //====//===
00286 //====//===
00287 //====//===printf("\n-----------------  EXAMPLE 2 ----------------------\n\n");
00288 //====//===
00289 //====//===// The example is from: O.C. Zienkiewicz and R.L. Taylor:
00290 //====//===// "The FEM - fourth edition"
00291 //====//===int jp2[]    = { 0,    1,    3};
00292 //====//===double au2[] = {    2.0, 1.0, 2.0};
00293 //====//===double ad2[] = { 4.0, 4.0, 4.0};
00294 //====//===double* al2  = au2;
00295 //====//===double b2[] = { 0.0, 0.0, 1.0 };
00296 //====//===
00297 //====//===// profile matrix constructor
00298 //====//===  profilematrix first_profile2( 3, jp2, 'S', au2, al2, ad2);
00299 //====//===
00300 //====//===// simple print function
00301 //====//===  first_profile2.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
00302 //====//===
00303 //====//===// asignment operetor
00304 //====//===  profilematrix second_profile2 = first_profile2;
00305 //====//===  second_profile2.full_print("\nsecond_profile Sparse Profile Matrix as FULL :\n ");
00306 //====//===
00307 //====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
00308 //====//===// "The FEM - fourth edition"
00309 //====//===  profilematrix first_profile2TRI = first_profile2.datri();
00310 //====//===  first_profile2TRI.full_print("\nfirst but factorized Sparse Profile Matrix as FULL :\n ");
00311 //====//===  ::printf("\n\n");
00312 //====//===
00313 //====//===// right hand side reduction and backsubstitution ( vector of unknowns is b2 )
00314 //====//===  first_profile2TRI.dasol( b2 );
00315 //====//===  for( i=0 ; i<3 ; i++ )
00316 //====//===    {
00317 //====//===      printf("solution_b[%d] = %8.4f\n",i, b2[i]);
00318 //====//===    }
00319 //====//===
00320 //====//===  printf("\n\nmin = %6.6f \n", first_profile2.mmin() );
00321 //====//===  printf("max = %6.6f \n", first_profile2.mmax() );
00322 //====//===  printf("mean = %6.6f \n", first_profile2.mean() );
00323 //====//===
00324 //====//===
00325 //====//===printf("\n-----------------  EXAMPLE 3 ----------------------\n\n");
00326 //====//===
00327 //====//===// The main advantage of profile solver as described in
00328 //====//===// O.C. Zienkiewicz and R.L. Taylor: "The FEM - fourth edition"
00329 //====//===// is that it supports nonsymetric matrices stored in profile format.
00330 //====//===
00331 //====//===int jp3[]    = { 0,    1,    3};
00332 //====//===double au3[] = { 2.0, 3.0, 2.0};
00333 //====//===double ad3[] = { 4.0, 4.0, 4.0};
00334 //====//===double al3[] = { 2.0, 1.0, 2.0};
00335 //====//===double  b3[] = { 1.0, 1.0, 1.0 };
00336 //====//===
00337 //====//===// nonsymetric profile matrix constructor
00338 //====//===  profilematrix first_profile3( 3, jp3, 'N', au3, al3, ad3);
00339 //====//===
00340 //====//===// print out
00341 //====//===  first_profile3.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
00342 //====//===
00343 //====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
00344 //====//===// "The FEM - fourth edition"
00345 //====//===  profilematrix first_profile3TRI = first_profile3.datri();
00346 //====//===  first_profile3TRI.full_print("\nfirst but factorized \
00347 //====//===  Sparse Profile Matrix as FULL :\n ");
00348 //====//===  ::printf("\n\n");
00349 //====//===
00350 //====//===// right hand side reduction and backsubstitution ( vector of unknowns is b3 )
00351 //====//===  first_profile3TRI.dasol( b3 );
00352 //====//===  for( i=0 ; i<3 ; i++ )
00353 //====//===    {
00354 //====//===      printf("solution_b[%d] = %8.4f\n",i, b3
00355 //====//===      [i]);
00356 //====//===    }
00357 //====//===
00358 //====//===  printf("\n\nmin = %6.6f \n", first_profile3.mmin() );
00359 //====//===  printf("max = %6.6f \n", first_profile3.mmax() );
00360 //====//===  printf("mean = %6.6f \n", first_profile3.mean() );
00361 //====//===
00362 //====//===
00363 //====printf("\n\n------------  VECTOR  -------------------\n\n");
00364 
00365 static double vect1[] = {2.0, 3.0, -2.0, 5.0, -2.0};
00366 static double vect2[] = {1.0, 1.0, 1.0, 1.0, 1.0};
00367 
00368 // vector constructor
00369   BJvector first_vector( 5, vect1);
00370   first_vector.print("f","\n\nfirst_vector vector\n");
00371 
00372 // vector constructor
00373   BJvector second_vector ( 5, vect2);
00374   second_vector.print("s","\n\nsecond_vector vector\n");
00375 
00376 // default constructor for vector
00377   BJvector third_vector;
00378 // vector assignment
00379   third_vector = first_vector + second_vector;
00380   third_vector.print("t","\nfirst_vector + second_vector = \n");
00381 
00382   BJvector dot_product = first_vector.transpose() * second_vector; 
00383 //  vector dot product;
00384 //  dot_product = first_vector.transpose() * second_vector;
00385 //====  dot_product.print("d","\nfirst_vector * second_vector \n");
00386 //====
00387       
00388 printf("\n\n------------VECTOR AND MATRIX -----------------\n\n");
00389 static double vect3[] = {1.0, 2.0, 3.0, 4.0, 5.0};
00390 
00391 //default construcotrs
00392 BJmatrix res1;
00393 BJmatrix res2;
00394 
00395 // matrix constructor
00396 BJmatrix vect_as_matrix(5, 1, vect3);
00397 BJvector vect(5, vect3);
00398 
00399 first_matrix.print("f","\n first matrix");
00400 
00401 // vector and matrix are quite similar !
00402 vect_as_matrix.print("vm","\n vector as matrix");
00403 vect.print("v","\n vector");
00404 
00405 // this should give the same answer! ( vector multiplication with matrix
00406 res1 = vect_as_matrix.transpose() * first_matrix;
00407 res2 = vect.transpose() * first_matrix;
00408 
00409 res1.print("r1","\n result");
00410 res2.print("r2","\n result");
00411 
00412 
00413 
00414 ::printf("\n\n----------------- TENSOR --------------------\n\n");
00415   
00416 //  Tensor t0();
00417 //  Tensor *ta = new Tensor;
00418   
00419 // tensor default construcotr
00420   tensor t1;
00421   t1.print("t1","\n tensor t1");
00422 
00423   static double t2values[] = {  1,2,3,
00424                                 4,5,6,
00425                                 7,8,9  };
00426 // tensor constructor with values assignments ( order 2 ; like matrix )
00427   tensor t2( 2, def_dim_2, t2values);
00428   t2.print("t2","\ntensor t2 (2nd-order with values assignement)");
00429 
00430   cerr << "rank of t2: " << t2.rank() << endl;
00431   for (int ii=1; ii<=t2.rank(); ii++) {
00432     cerr << "dimension of t2 in " << ii << " is " << t2.dim(ii) << endl;
00433   }
00434 
00435 
00436   tensor tst( 2, def_dim_2, t2values); 
00437 //  t2 = t2*2.0;
00438 //  t2.print("t2x2","\ntensor t2 x 2.0");
00439   t2.print("t2","\noriginal tensor t2 ");
00440   tst.print("tst","\ntst ");
00441 
00442   tensor t2xt2 = t2("ij")*t2("jk");
00443   t2xt2.print("t2xt2","\ntensor t2 x t2");
00444 
00445   tensor t2xtst = t2("ij")*tst("jk");
00446   t2xtst.print("t2xtst","\ntensor t2 x tst");
00447 //  exit(0);
00448   t2.print("t2","\noriginal tensor t2 ");
00449 
00450 // tensor constructor with 0.0 assignment ( order 4 ; 4D array )
00451   tensor ZERO(4,def_dim_4,0.0);
00452   ZERO.print("z","\ntensor ZERO (4-th order with value assignment)");
00453 
00454   static double t4val[] =
00455 { 11.100,  12.300,  13.100,   15.230,  16.450,   14.450,  17.450,  18.657,  19.340,
00456  110.020, 111.000, 112.030,  114.034, 115.043,  113.450, 116.670, 117.009, 118.060,
00457  128.400, 129.500, 130.060,  132.560, 133.000,  131.680, 134.100, 135.030, 136.700,
00458  119.003, 120.400, 121.004,  123.045, 124.023,  122.546, 125.023, 126.043, 127.000,
00459  137.500, 138.600, 139.000,  141.067, 142.230,  140.120, 143.250, 144.030, 145.900,
00460  146.060, 147.700, 148.990,  150.870, 151.000,  149.780, 152.310, 153.200, 154.700,
00461  164.050, 165.900, 166.003,  168.450, 169.023,  167.067, 170.500, 171.567, 172.500,
00462  155.070, 156.800, 157.067,  159.000, 160.230,  158.234, 161.470, 162.234, 163.800,
00463  173.090, 174.030, 175.340,  177.060, 178.500,  176.000, 179.070, 180.088, 181.200};
00464 
00465 // tensor constructor with values assignment ( order 4 ; 4D array )
00466   tensor t4(4, def_dim_4, t4val);
00467   t4.print("t4","\ntensor t4 (4th-order with values assignment)");
00468 
00469 //  Some relevant notes from the Dec. 96 Draft (as pointed out by KAI folks):
00470 //  
00471 //  "A binary operator shall be implemented either by a  non-static  member
00472 //    function (_class.mfct_) with one parameter or by a non-member function
00473 //    with two parameters.  Thus, for any binary  operator  @,  x@y  can  be
00474 //    interpreted as either x.operator@(y) or operator@(x,y)." [13.5.2]
00475 //  
00476 //  "The order of evaluation of arguments [of a function call] is
00477 //  unspecified."  [5.2.2 paragraph 9]
00478 //  
00479 //  
00480 // SO THAT IS WHY I NEED THIS temp
00481 // It is not evident which operator will be called up first: operator() or operator* .
00482 // 
00483 //% ////////////////////////////////////////////////////////////////////////
00484 // testing the multi products using indicial notation:
00485   tensor tst1;
00486   tensor temp = t2("ij") *  t4("ijkl");
00487   tst1 = temp("kl")  * t4("klpq")  * t2("pq");
00488   tst1.print("tst1","\ntensor tst1 = t2(\"ij\")*t4(\"ijkl\")*t4(\"klpq\")*t2(\"pq\");");
00489 
00490 
00491 // testing inverse function for 4. order tensor. Inverse for 4. order tensor
00492 // is done by converting that tensor to matrix, inverting that matrix
00493 // and finally converting matrix back to tensor
00494   tensor t4inv_2 = t4.inverse_2();
00495   t4inv_2.print("t4i","\ntensor t4 inverted_2");
00496   tensor unity_2 = t4("ijkl")*t4inv_2("klpq");
00497   unity_2.print("uno2","\ntensor unity_2");
00498 
00499 //....................................................................
00500 // There  are several built in tensor types. One of them is:
00501 // Levi-Civita permutation tensor
00502   tensor e("e",3,def_dim_3);
00503   e.print("e","\nLevi-Civita permutation tensor e");
00504 
00505 // The other one is:
00506 // Kronecker delta tensor
00507   tensor I2("I", 2, def_dim_2);
00508   I2.print("I2","\ntensor I2 (2nd order unit tensor: Kronecker Delta -> d_ij)");
00509 
00510 
00511 
00512          tensor Ipmnq = I2("pm") * I2("nq");
00513   tensor Imnpq = I2("mn") * I2("pq");
00514 
00515 
00516 
00518 //  tensor X  = (1.0/3.0) * Imnpq ;// - Apqmn * (1.0/3.0);
00519 //       X.print();
00520 
00521 
00522 // tensor multiplications 
00523   tensor I2I2 = I2("ij")*I2("ij");
00524   I2I2.print("I2I2","\ntensor I2 * I2");
00525 
00526 // tensor multiplications ( from right)
00527   tensor I2PI = I2*PI;
00528   I2PI.print("I2PI","\ntensor I2 * PI");
00529 
00531 //  tensor PII2 = PI*I2;
00532 //  PII2.print("PII2","\ntensor PI * I2");
00533 
00535 //  tensor mPII2 = -PII2;
00536 //  mPII2.print("mPII2","\ntensor -PI * I2");
00537 
00538 // trace function
00539   double deltatrace = I2.trace();
00540   ::printf("\ntrace of Kronecker delta is %f \n",deltatrace);
00541 
00542 // determinant of 2. order tensor only!
00543   double deltadet = I2.determinant();
00544   ::printf("\ndeterminant of Kronecker delta is %f \n",deltadet);
00545 
00546 // comparison  of tensor ( again within sqrt(macheps) tolerance )
00547   tensor I2again = I2;
00548   if ( I2again == I2 ) ::printf("\n I2again == I2  TRUE (OK)\n");
00549   else ::printf("\a\n\n\n I2again == I2  NOTTRUE \n\n\n");
00550 
00551 //....................................................................
00552 // some of the 4. order tensor used in conituum mechanics:
00553 // the most general representation of the fourth order isotropic tensor
00554 // includes the following fourth orther unit isotropic tensors:
00555   tensor I_ijkl( 4, def_dim_4, 0.0 );
00556   I_ijkl = I2("ij")*I2("kl");
00557 //  I_ijkl.print("ijkl","\ntensor I_ijkl = d_ij d_kl)");
00558   tensor I_ikjl( 4, def_dim_4, 0.0 );
00559 //  I_ikjl = I2("ij")*I2("kl");
00560   I_ikjl = I_ijkl.transpose0110();
00561 //  I_ikjl.print("ikjl","\ntensor I_ikjl) ");
00562   tensor I_ikjl_inv_2 = I_ikjl.inverse_2();
00563 //  I_ikjl_inv_2.print("I_ikjl","\ntensor I_ikjl_inverse_2)");
00564   if ( I_ikjl == I_ikjl_inv_2 ) ::printf("\n\n I_ikjl == I_ikjl_inv_2 !\n");
00565   else ::printf("\a\n\n           I_ikjl != I_ikjl_inv_2 !\n");
00566 
00567   tensor I_iljk( 4, def_dim_4, 0.0 );
00568 //  I_ikjl = I2("ij")*I2("kl");
00569 //..  I_iljk = I_ikjl.transpose0101();
00570   I_iljk = I_ijkl.transpose0111();
00571 //  I_iljk.print("iljk","\ntensor I_iljk) ");
00572 // To check out this three fourth-order isotropic tensor please see
00573 // W.Michael Lai, David Rubin, Erhard Krempl
00574 // " Introduction to Continuum Mechanics"
00575 // QA808.2
00576 // ISBN 0-08-022699-X
00577 
00578 //....................................................................
00579 // Multiplications between 4. order tensors
00580   ::printf("\n\n intermultiplications \n");
00581 //  tensor I_ijkl_I_ikjl = I_ijkl("ijkl")*I_ikjl("ikjl");
00582   tensor I_ijkl_I_ikjl = I_ijkl("ijkl")*I_ikjl("ijkl");
00583   I_ijkl_I_ikjl.print("i","\n\n I_ijkl*I_ikjl \n");
00584 
00585 //  tensor I_ijkl_I_iljk = I_ijkl("ijkl")*I_iljk("iljk");
00586   tensor I_ijkl_I_iljk = I_ijkl("ijkl")*I_iljk("ijkl");
00587   I_ijkl_I_iljk.print("i","\n\n I_ijkl*I_iljk \n");
00588 
00589 //  tensor I_ikjl_I_iljk = I_ikjl("ikjl")*I_iljk("iljk");
00590   tensor I_ikjl_I_iljk = I_ikjl("ijkl")*I_iljk("ijkl");
00591  I_ikjl_I_iljk.print("i","\n\n I_ikjl*I_iljk \n");
00592 
00593 //....................................................................
00594 // More multiplications between 4. order tensors
00595   ::printf("\n\n   intermultiplications same with same \n");
00596   tensor I_ijkl_I_ijkl = I_ijkl("ijkl")*I_ijkl("ijkl");
00597   I_ijkl_I_ijkl.print("i","\n\n I_ijkl*I_ijkl \n");
00598 
00599   tensor I_ikjl_I_ikjl = I_ikjl("ikjl")*I_ikjl("ikjl");
00600   I_ikjl_I_ikjl.print("i","\n\n I_ikjl*I_ikjl \n");
00601 
00602   tensor I_iljk_I_iljk = I_iljk("iljk")*I_iljk("iljk");
00603   I_iljk_I_iljk.print("i","\n\n I_iljk*I_iljk \n");
00604 
00605 
00606 // tensor additions ans scalar multiplications
00607 // symmetric part of fourth oder unit isotropic tensor
00608   tensor I4s = (I_ikjl+I_iljk)*0.5;
00609 //  tensor I4s = 0.5*(I_ikjl+I_iljk);
00610   I4s.print("I4s","\n symmetric tensor I4s = (I_ikjl+I_iljk)*0.5 ");
00611 // skew-symmetric part of fourth oder unit isotropic tensor
00612   tensor I4sk = (I_ikjl-I_iljk)*0.5;
00613   I4sk.print("I4sk","\n skew-symmetric tensor I4sk = (I_ikjl-I_iljk)*0.5 ");
00614 
00615 // equvalence check ( they should be different )
00616   if ( I4s == I4sk ) ::printf("\n\n I4s == I4sk !\n");
00617   else ::printf("\a\n\n           I4s != I4sk !\n");
00618 
00619 
00620 //....................................................................
00621 // e-delta identity  ( see Lubliner ( QA931 .L939 1990) page 2.
00622 // and Lai ( QA808.2 L3 1978) page 12 )
00623   tensor ee = e("ijm")*e("klm");
00624   ee.print("ee","\ntensor e_ijm*e_klm");
00625   tensor id = ee - (I_ikjl - I_iljk);
00626   if ( id == ZERO ) ::printf("\n\n e-delta identity HOLDS !! \n\n");
00627   tensor ee1 = e("ilm")*e("jlm");
00628   ee1.print("ee1","\n\n e(\"ilm\")*e(\"jlm\") \n");
00629   tensor ee2 = e("ijk")*e("ijk");
00630   ee2.print("ee2","\n\n e(\"ijk\")*e(\"ijk\") \n");
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 //....................................................................
00641 // Linear Isotropic Elasticity Tensor
00642 // building elasticity tensor
00643   double Ey = 20000;
00644   double nu = 0.2;
00645 // building stiffness tensor in one command line
00646   tensor E1 = (I_ijkl*((Ey*nu*2.0)/(2.0*(1.0+nu)*(1-2.0*nu)))) +
00647               ( (I_ikjl+I_iljk)*(Ey/(2.0*(1.0+nu))));
00648 // building compliance tensor in one command line
00649   tensor D1= (I_ijkl * (-nu/Ey)) + ( (I_ikjl+I_iljk) * ((1.0+nu)/(2.0*Ey)));
00650 
00651 // multiplication between them
00652   tensor test = E1("ijkl")*D1("klpq");
00653   test.print("t","\n\n\n test =  E1(\"ijkl\")*D1(\"klpq\") \n");
00654 // and this should be equal to the symmetric part of 4. order unit tensor
00655   if ( test == I4s ) ::printf("\n test == I4s  TRUE  ( up to sqrt(macheps())) \n");
00656   else ::printf("\a\n\n\n   test == I4s    NOTTRUE  ( up to sqrt(macheps())) \n\n\n");
00657 
00658 //............Different Way...........................................
00659 // Linear Isotropic Elasticity Tensor
00660   double lambda = nu * Ey / (1. + nu) / (1. - 2. * nu);
00661   double mu = Ey / (2. * (1. + nu));
00662   ::printf("\n  lambda = %.12e\n",lambda);
00663   ::printf("      mu = %.12e\n",mu);
00664 
00665   ::printf("\nYoung Modulus = %.4e",Ey);
00666   ::printf("\nPoisson ratio = %.4e\n",nu);
00667   ::printf(  "    lambda + 2 mu = %.4e\n", (lambda + 2 * mu));
00668 
00669 // building elasticity tensor
00670   tensor E2 = (I_ijkl * lambda) + (I4s * (2. * mu));
00671   E2.print("E2","tensor E2: elastic moduli Tensor = lambda*I2*I2+2*mu*I4s");
00672 
00673   tensor E2inv = E2.inverse();
00674 
00675 // building compliance tensor
00676   tensor D2= (I_ijkl * (-nu/Ey)) + (I4s * (1./(2.*mu)));
00677   D2.print("D2","tensor D2: compliance Tensor (I_ijkl * (-nu/Ey)) + (I4s * (1./2./mu))");
00678 
00679   if ( E2inv == D2 ) ::printf("\n E2inv == D2   TRUE \n");
00680   else ::printf("\a\n\n\n  E2inv == D2   NOTTRUE \n\n\n");
00681 
00682   if ( E1 == E2 ) ::printf("\n E1 == E2  TRUE \n");
00683   else ::printf("\a\n\n\n  E1 == E2  NOTTRUE \n\n\n");
00684 
00685   if ( D1 == D2 ) ::printf("\n D1 == D2  TRUE \n");
00686   else ::printf("\a\n\n\n  D1 == D2  NOTTRUE \n\n\n");
00687 
00688 
00689  
00690 //::printf("stack length is : %u \n",_stklen);
00691 double PIo3 = PI/3.0;
00692 //::printf("Pi/3.0 = %f \n",PIo3);
00693 //-------------------------------------------
00694   double p_start     = 5000.000;
00695   double q_start     = 2000.0;
00696   double theta_start = PIo3;
00697 //..//  double theta_start = 0.4;
00698 
00699 stresstensor stress = stress.pqtheta2stress(p_start, q_start, theta_start);
00700 stress.report("stress\n");
00701 
00702 
00703 straintensor strain = D2("ijkl") * stress("kl");
00704 strain.report("strain = D2(\"ijkl\") * stress(\"kl\") \n");
00705 
00706 
00707 
00708 
00709 
00710 
00711 ::printf("\n\n\n\n\n");
00712 ::printf("\n\n----------------- STRESS TENSOR --------(Kaspar Willam tests)--------\n\n");
00713   
00714          static double stressvalues[] = {  1.0, 2.0, 3.0,
00715                                     2.0, 2.0, 5.0,
00716                                     3.0, 5.0, 9.0  };
00717 
00718   stresstensor sigma(stressvalues);
00719   sigma.report("\n\n stress tensor sigma (2nd-order with values assignment)");
00720 
00721 
00722          stresstensor s = sigma.deviator();
00723          s.report("\n\n stress deviator s \n\n"); 
00724 
00725          stresstensor test01 = s("ij") * s("ij");
00726          test01.reportshort("\n\n\n test01 \n\n\n ");
00727 
00728          stresstensor KWtest01 =  s("ij") * s("jk");
00729          stresstensor KWtest02 =  KWtest01("ik") * I2("ik");
00730          KWtest02.reportshort("\n\n\n KWtest02 \n\n\n "); 
00731 
00732 
00733 //  static double stressvector[] = {-3.0, -2.0, 5.0, 2.0, 3.0, 5.0};
00734   static double stressvector[] = {-3.0, -2.0, 5.0, 2.0*sqrt(2.0), 3.0*sqrt(2.0), 5.0*sqrt(2.0)};
00735 
00736 // vector constructor
00737   BJvector stressvector01( 6, stressvector);
00738   stressvector01.print("sigma","\n\n stressvector01\n");
00739 
00740          BJvector product = stressvector01.transpose() * stressvector01;
00741   product.print("product","\n\n product = stressvector01*stressvector01 \n");
00742 
00743 
00744 ::printf("\n\n\n");
00745 
00746 
00747 
00748 // --------------
00749 ::printf("\n\n\n --------------------------TENSOR SCALAR MULTIPLICATION ----\n\n");
00750   tensor EEEE1 = E2;
00751   tensor EEEE2 = EEEE1*2.0;
00752   EEEE1.print("E1","tensor EEEE1");
00753   EEEE2.print("E2","tensor EEEE2");
00754 
00755 
00756 //###printf("\n\n------------VECTOR AND SKYMATRIX -----------------\n\n");
00757 //###// 1) use of member function full_val is of crucial importance here
00758 //###// and it enable us to use skymatrix as if it is full matrix.
00759 //###// There is however small time overhead but that can be optimized . . .
00760 //###double vect4[] = {1.0, 2.0, 3.0, 4.0, 5.0};
00761 //###
00762 //###matrix res2;
00763 //###vector vector2(5, vect4);
00764 //###second.full_print();
00765 //###vector2.print();
00766 //###res2 = vector2.transpose() * second;
00767 //###res2.print();
00768 //###
00769 //###
00770 //###printf("\n\n------------ MATRIX AND SKYMATRIX -----------------\n\n");
00771 //###// 1) use of member function full_val is of crucial importance here
00772 //###// and it enable us to use skymatrix as if it is full matrix.
00773 //###// There is however small time overhead but that can be optimized . . .
00774 //###
00775 //###matrix big_result;
00776 //###big_result = first_matrix * second;
00777 //###big_result.print();
00778 
00779 
00780 
00781 
00782   exit(1);
00783 //  return 1;
00784 }

Generated on Mon Oct 23 15:05:24 2006 for OpenSees by doxygen 1.5.0