straint.cpp

Go to the documentation of this file.
00001 //################################################################################
00002 //# COPY-YES  (C):     :-))                                                      #
00003 //# PROJECT:           Object Oriented Finite Element Program                    #
00004 //# PURPOSE:           strain tensor with all necessery functions                #
00005 //# CLASS:             straintensor                                              #
00006 //#                                                                              #
00007 //# VERSION:                                                                     #
00008 //# LANGUAGE:          C++.ver >= 2.0 ( Borland C++ ver=3.00, SUN C++ ver=2.1 )  #
00009 //# TARGET OS:         DOS || UNIX || . . .                                      #
00010 //# DESIGNER(S):       Boris Jeremic                                             #
00011 //# PROGRAMMER(S):     Boris Jeremic                                             #
00012 //#                                                                              #
00013 //#                                                                              #
00014 //# DATE:              July 25 '93                                               #
00015 //# UPDATE HISTORY:    December 15 '93 replaced polinomial root solver for       #
00016 //#                    principal straines with explicit formula                  #
00017 //#                    August 22-29 '94 choped to separate files and worked on   #
00018 //#                                   const and & issues                         #
00019 //#                    August 30-31 '94 added use_def_dim to full the CC         #
00020 //#                                   resolved problem with temoraries for       #
00021 //#                                   operators + and - ( +=, -= )               #
00022 //#                                                                              #
00023 //#                                                                              #
00024 //#                                                                              #
00025 //#                                                                              #
00026 //#                                                                              #
00027 //#                                                                              #
00028 //################################################################################
00029 //
00030 #ifndef STRAINTENSOR_CC
00031 #define STRAINTENSOR_CC
00032 
00033 #include "straint.h"
00034 
00035 //##############################################################################
00036 straintensor::straintensor (int rank_of_tensor, double initval):
00037   tensor(rank_of_tensor, def_dim_2, initval)
00038     {   } // default constructor
00039 
00040 //##############################################################################
00041 straintensor::straintensor ( double *values ):
00042   tensor( 2, def_dim_2, values)
00043     {  }
00044 
00045 //##############################################################################
00046 straintensor::straintensor ( double initvalue ):
00047   tensor( 2, def_dim_2, initvalue) {  }
00048 
00049 //##############################################################################
00050 straintensor::straintensor( const straintensor & x ):
00051   tensor("NO")
00052     {
00053       x.pc_nDarray_rep->n++;  // tell the rval it has another reference
00054 //      x.reference_count(+1);              // we're adding another reference.
00055       pc_nDarray_rep = x.pc_nDarray_rep;  // point to the new tensor_rep.
00056 // add the indices
00057       indices1 = x.indices1;
00058       indices2 = x.indices2;
00059     }
00060 
00061 
00062 //##############################################################################
00063 straintensor::straintensor(const tensor & x):
00064   tensor( x ) {  } // copy-initializer
00065 
00066 //##############################################################################
00067 straintensor::straintensor(const nDarray & x):
00068   tensor( x ) {  }  // copy-initializer
00069 
00070 
00071 //#//##############################################################################
00072 //#straintensor::straintensor(straintensor & x)
00073 //#  {
00074 //#    x.reference_count(+1);              // we're adding another reference.
00075 //#    pc_nDarray_rep = x.pc_nDarray_rep;  // point to the new tensor_rep.
00076 //#// add the indices
00077 //#    indices1 = x.indices1;
00078 //#    indices2 = x.indices2;
00079 //#  }
00080 
00081 
00082  // IT IS NOT INHERITED so must be defined in all derived classes
00083  // See ARM page 277.
00084  //##############################################################################
00085 // straintensor::~straintensor()
00086 // {
00087 //   if (reference_count(-1) == 0)  // if reference count  goes to 0
00088 //     {
00089 // // DEallocate memory of the actual nDarray
00090 // //    delete [pc_nDarray_rep->pc_nDarray_rep->total_numb] pc_nDarray_rep->pd_nDdata;
00091 // // nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00092 // //                                                and note on the p.65($5.3.4)
00093 //     delete [] data();
00094 //     delete [] dim();
00095 //     delete pc_nDarray_rep;
00096 //   }
00097 // }
00098 //
00099 
00100 // IT IS NOT INHERITED so must be defined in all derived classes
00101 // See ARM page 306.
00102 //##############################################################################
00103 straintensor straintensor::operator=( const straintensor & rval)
00104 {
00105     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00106 //    rval.reference_count(+1);  // tell the rval it has another reference
00107 //   /*  It is important to increment the reference_counter in the new
00108 //       tensor before decrementing the reference_counter in the
00109 //       old tensor_rep to ensure proper operation when assigning a
00110 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00111 
00112  // clean up current value;
00113 //    if(--pc_nDarray_rep->n == 0)  // if nobody else is referencing us.
00114     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00115       {
00116 // DEallocate memory of the actual tensor
00117 //      delete [pc_tensor_rep->pc_tensor_rep->total_numb] pc_tensor_rep->pd_nDdata;
00118 // nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00119 //                                                and note on the p.65($5.3.4)
00120 //        delete  pc_nDarray_rep->pd_nDdata;
00121         delete [] data();
00122         delete [] dim();
00123 // ovo ne smem da brisem jer nije dinamicki alocirano
00124 //        delete pc_tensor_rep->indices;
00125         delete pc_nDarray_rep;
00126       }
00127 
00128  // connect to new value
00129     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00130 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00131 // null indices in the rval
00132 //    rval.indices1 = NULL;
00133 //    rval.indices2 = NULL;
00134 //    rval.null_indices();
00135 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00136     this->null_indices();
00137     return *this;
00138 }
00139 
00140 
00141 
00142 
00143 // IT IS NOT INHERITED so must be defined in all derived classes
00144 // See ARM page 306.
00145 //##############################################################################
00146 straintensor straintensor::operator=( const tensor & rval)
00147 {
00148     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00149 //    rval.reference_count(+1);  // tell the rval it has another reference
00150 //   /*  It is important to increment the reference_counter in the new
00151 //       tensor before decrementing the reference_counter in the
00152 //       old tensor_rep to ensure proper operation when assigning a
00153 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00154 
00155  // clean up current value;
00156     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00157       {
00158 // DEallocate memory of the actual tensor
00159 //      delete [pc_tensor_rep->pc_tensor_rep->total_numb] pc_tensor_rep->pd_nDdata;
00160 // nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00161 //                                                and note on the p.65($5.3.4)
00162 //        delete  pc_nDarray_rep->pd_nDdata;
00163         delete [] data();
00164         delete [] dim();
00165 // ovo ne smem da brisem jer nije dinamicki alocirano
00166 //        delete pc_tensor_rep->indices;
00167         delete pc_nDarray_rep;
00168       }
00169 
00170  // connect to new value
00171     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00172 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00173 // null indices in the rval
00174 //    rval.indices1 = NULL;
00175 //    rval.indices2 = NULL;
00176 //    rval.null_indices();
00177 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00178     this->null_indices();
00179     return *this;
00180 }
00181 
00182 // IT IS NOT INHERITED so must be defined in all derived classes
00183 // See ARM page 306.
00184 //##############################################################################
00185 straintensor straintensor::operator=( const nDarray & rval)
00186 {
00187     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00188 //    rval.reference_count(+1);  // tell the rval it has another reference
00189 //   /*  It is important to increment the reference_counter in the new
00190 //       tensor before decrementing the reference_counter in the
00191 //       old tensor_rep to ensure proper operation when assigning a
00192 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00193 
00194     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00195       {
00196         delete [] data();
00197         delete [] dim();
00198         delete pc_nDarray_rep;
00199       }
00200 
00201  // connect to new value
00202     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00203     return *this;
00204 }
00205 
00206 //##############################################################################
00207 // makes a complete new copy of straintensor!!
00208 straintensor straintensor::deep_copy(void)
00209   {
00210     return straintensor(this->data()); // call constructor and return it !
00211   }
00212 //..//##############################################################################
00213 //..// returns a pointer to this for a deep copy
00214 //..straintensor straintensor::p_deep_copy(void)
00215 //..  {
00216 //..    return &this->deep_copy(); // call constructor and return it !
00217 //..  }
00218 
00219 //ini  //##############################################################################
00220 //ini  // use "from" and initialize already allocated strain tensor from "from" values
00221 //ini  void straintensor::Initialize( const straintensor & from )
00222 //ini    {
00223 //ini  // copy onlu data because everything else is default
00224 //ini      for ( int i=0 ; i<pc_nDarray_rep->total_numb ; i++ )
00225 //ini        this->pc_nDarray_rep->pd_nDdata[i] = from.pc_nDarray_rep->pd_nDdata[i] ;
00226 //ini    }
00227 
00228 //___//##############################################################################
00229 //___//##############################################################################
00230 //___//##############################################################################
00231 //___straintensor & straintensor::operator()(short ir, short is, short it,
00232 //___                                        short tr, short ts, short tt  )
00233 //___// another overloading of operator() . . .  // overloaded for THREE arguments
00234 //___  {
00235 //___    short where = ir - 1;
00236 //___          where = where*ts + is - 1;
00237 //___          where = where*tt + it - 1;
00238 //___
00239 //___//::printf(" w=%ld ",where);
00240 //___    straintensor *p_value = this + where;
00241 //___    return (*p_value);
00242 //___  }
00243 
00244 
00245 //##############################################################################
00246 // invariants of the strain tensor              // Chen W.F. "plasticity for
00247 double straintensor::Iinvariant1()const       // Structural Engineers"
00248   {
00249     return (cval(1,1)+cval(2,2)+cval(3,3));
00250   }
00251 
00252 //##############################################################################
00253 double straintensor::Iinvariant2() const
00254   {
00255     return (cval(2,2)*cval(3,3)-cval(3,2)*cval(2,3)+
00256             cval(1,1)*cval(3,3)-cval(3,1)*cval(1,3)+
00257             cval(1,1)*cval(2,2)-cval(2,1)*cval(1,2));
00258   }
00259 
00260 //##############################################################################
00261 double straintensor::Iinvariant3() const
00262   {
00263 
00264     double I3 = cval(1,1)*cval(2,2)*cval(3,3) +
00265                 cval(1,2)*cval(2,3)*cval(3,1) +
00266                 cval(1,3)*cval(2,1)*cval(3,2) -
00267                 cval(1,3)*cval(2,2)*cval(3,1) -
00268                 cval(1,2)*cval(2,1)*cval(3,3) -
00269                 cval(1,1)*cval(2,3)*cval(3,2) ;
00270 
00271     return I3;
00272 
00273 //    return ( this->determinant());
00274   }
00275 
00276 
00277 
00278 //##############################################################################
00279 // invariants of the deviatoric strain tensor
00280 double straintensor::Jinvariant1() const
00281   {
00282     return (0.0);
00283   }
00284 
00285 //##############################################################################
00286 double straintensor::Jinvariant2() const
00287   {
00288     double EPS = sqrt(d_macheps());
00289     double temp1 = (Iinvariant1()*Iinvariant1()-3.0*Iinvariant2())/3.0;
00290     if ( temp1 < 0.0 || fabs(temp1) < EPS )
00291       {                    // this is because it might be close
00292         temp1 = 0.0;       // to zero ( -1e-19 ) numericaly
00293       }                    // but sqrt() does not accept it
00294     return ( temp1 );      // as (-) and theoreticaly J2d>0
00295   }
00296 
00297 //##############################################################################
00298 double straintensor::Jinvariant3() const
00299   {
00300     return ( (2.0*Iinvariant1()*Iinvariant1()*Iinvariant1()-
00301               9.0*Iinvariant1()*Iinvariant2() +
00302               27.0*Iinvariant3())/27.0 );
00303   }
00304 
00305 
00306 
00307 //##############################################################################
00308 double straintensor::equivalent( ) const          //Zhaohui added 09-02-2000
00309 {   
00310     // Evaluating e_eq = sqrt( 2.0 * epsilon_ij * epsilon_ij / 3.0)
00311     straintensor pstrain =  *this;
00312     tensor temp  = pstrain("ij") * pstrain("ij");
00313     double tempd = temp.trace();
00314     double e_eq  = pow( 2.0 * tempd / 3.0, 0.5 );
00315     //cout << "e_eq = " << e_eq << endlnn;
00316     return e_eq;
00317 
00318 }
00319 
00320 
00321 //##############################################################################
00322 straintensor straintensor::principal() const
00323   {
00324 
00325     straintensor ret;
00326 
00327     double p_     = this->p_hydrostatic();
00328     double q_     = this->q_deviatoric();
00329     double theta_ = this->theta();
00330 //old    while ( theta_ >= 2.0*PI )
00331 //old      theta_ = theta_ - 2.0*PI; // if bigger than full cycle
00332 //old    while ( theta_ >= 4.0*PI/3.0 )
00333 //old      theta_ = theta_ - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00334 //old    while ( theta_ >= 2.0*PI/3.0 )
00335 //old      theta_ = theta_ - 2.0*PI/3.0; // if bigger than two third of half cycle
00336 //old    while ( theta_ >= PI/3.0 )
00337 //old      theta_ = 2.0*PI/3.0 - theta_; // if bigger than one third of half cycle
00338 
00339 
00340 //    ret.report("ret");
00341 //    double sqrtJ2D = q/3.0;
00342 //    double 2osqrt3 = 2.0/sqrt(3.0);
00343     double temp = (2.0*q_)/3.0;
00344 
00345     double ct  = cos( theta_  );
00346     double ctm = cos( theta_ - 2.0*PI/3.0 );
00347     double ctp = cos( theta_ + 2.0*PI/3.0 );
00348 
00349     ret.val(1,1) = p_ + temp*ct;
00350     ret.val(2,2) = p_ + temp*ctm;
00351     ret.val(3,3) = p_ + temp*ctp;
00352 
00353 //    ret.report("ret");
00354     return ret;
00355 //..    static complex ac[4];               // Chen W.F. "plasticity for
00356 //..    static complex roots[4];            // Structural Engineers"
00357 //..    int polish = 1 ;                    // page 53
00358 //..    int m = 3;
00359 //..
00360 //..    ac[0] = complex( -(this->Iinvariant3()), 0.0 );
00361 //..    ac[1] = complex(  (this->Iinvariant2()), 0.0);
00362 //..    ac[2] = complex( -(this->Iinvariant1()), 0.0);
00363 //..    ac[3] = complex(  1.0, 0.0);
00364 //..
00365 //..// what was obtained for coefficients
00366 //..//DEBUGprint ::printf("ac[0].r = %lf  ac[0].i = %lf\n", real(ac[0]), imag(ac[0]));
00367 //..//DEBUGprint ::printf("ac[1].r = %lf  ac[1].i = %lf\n", real(ac[1]), imag(ac[1]));
00368 //..//DEBUGprint ::printf("ac[2].r = %lf  ac[2].i = %lf\n", real(ac[2]), imag(ac[2]));
00369 //..//DEBUGprint ::printf("ac[3].r = %lf  ac[3].i = %lf\n", real(ac[3]), imag(ac[3]));
00370 //..//DEBUGprint ::printf("m  = %d\n",m);
00371 //..
00372 //..    zroots( ac, m, roots, polish);
00373 //..
00374 //..//DEBUGprint ::printf("\nroots[1].r=%lf  roots[1].i=%lf\n",real(roots[1]),imag(roots[1]));
00375 //..//DEBUGprint ::printf("roots[2].r=%lf  roots[2].i=%lf\n",real(roots[2]),imag(roots[2]));
00376 //..//DEBUGprint ::printf("roots[3].r=%lf  roots[3].i=%lf\n",real(roots[3]),imag(roots[3]));
00377 //..
00378 //..
00379 //..    straintensor principal(0.0);
00380 //..
00381 //..    principal.val(1,1) = real(roots[3]); // since they are sorted by
00382 //..    principal.val(2,2) = real(roots[2]); // the zroot function in ascending
00383 //..    principal.val(3,3) = real(roots[1]); // order . . .
00384 //..                                         // sig1>sig2>sig3
00385 //..    return principal;
00386 //..
00387 //..
00388   }
00389 
00390 //##############################################################################
00391 straintensor straintensor::deviator() const
00392   {
00393     tensor I2("I", 2, def_dim_2);
00394     straintensor st_vol = I2 * (trace()*(1./3.));
00395     straintensor st_dev = (*this) - st_vol;
00396     return st_dev;
00397   }
00398 
00399 
00400 
00401 //##############################################################################
00402 double straintensor::sigma_octahedral() const  // Chen W.F. "plasticity for
00403   {                                            // Structural Engineers"
00404     return ( this->Iinvariant1()/3.0 );        // page 59-60
00405   }
00406 
00407 //##############################################################################
00408 double straintensor::tau_octahedral() const    // Chen W.F. "plasticity for
00409   {                                             // Structural Engineers"
00410     return(sqrt(2.0/3.0*(this->Jinvariant2())));// page 59-60
00411   }
00412 
00413 
00414 
00415 //##############################################################################
00416 double straintensor::ksi()  const                     // Chen W.F. "plasticity for
00417   {                                            // Structural Engineers"
00418     return( (this->Iinvariant1())/sqrt(3.0) ); // page 66
00419   }
00420 
00421 
00422 //##############################################################################
00423 double straintensor::ro() const                        // Chen W.F. "plasticity for
00424   {                                             // Structural Engineers"
00425     double temp1 = this->Jinvariant2();         // page 68
00426     double EPS = pow(d_macheps(),(1./2.));
00427     if ( temp1 < 0.0 || fabs(temp1) < EPS )
00428       {
00429         temp1 = 0.0;
00430       }
00431     return( sqrt(2.0*(temp1)));
00432   }
00433 
00434 //##############################################################################
00435 double straintensor::p_hydrostatic() const         // Desai "Constitutive Laws
00436   {                                         // for Engineering Materials"
00437     // Joey modified to make it consistent with stress tensor
00438     return( - (this->Iinvariant1())*ONEOVERTHREE );  // page 283
00439     
00440     //return( (this->Iinvariant1()) );    // page 283
00441   }
00442 
00443 
00444 //##############################################################################
00445 double straintensor::q_deviatoric() const        // Desai "Constitutive Laws
00446   {                                       // for Engineering Materials"
00447 //     double temp1 = this->Jinvariant2();   // page 283
00448 //     return( sqrt(4.0/3.0*temp1) );
00449 
00450     double tempsqrt = 2./3.*(deviator()("ij")*deviator()("ij")).trace();
00451     double EPS = d_macheps();
00452 // this is because it might be close
00453 // to zero ( -1e-19 ) numericaly
00454 // but sqrt() does not accept it
00455     if ( tempsqrt < 0.0 )
00456       {
00457 ::fprintf(stdout,"tempsqrt < 0.0 || fabs(tempsqrt) < EPS in ");
00458 ::fprintf(stdout," double straintensor::q_deviatoric() const\a\a\n");
00459 ::fprintf(stderr,"tempsqrt < 0.0 || fabs(tempsqrt) < EPS in ");
00460 ::fprintf(stderr," double straintensor::q_deviatoric() const \a\a\n");
00461         ::exit(1);
00462       }
00463     if ( fabs(tempsqrt) < EPS )
00464       {
00465         tempsqrt = 0.0;
00466       }
00467      double temp1 = sqrt(tempsqrt);
00468      return(temp1);
00469 
00470   }
00471 
00472 
00473 //##############################################################################
00474 double straintensor::theta()  const             // Chen W.F. "plasticity for
00475   {                                             // Structural Engineers"
00476                                                 // page 70
00477 //    double MULT = 1000000.0;
00478     double EPS = pow(d_macheps(),(1./2.));
00479     double temp1 = (3.0*sqrt(3.0)/2.0);
00480     double temp2 = (this->Jinvariant3());
00481     double temp3 = (this->Jinvariant2());
00482 //....    double temp2 = (this->Jinvariant3())*MULT*MULT*MULT;
00483 //....    double temp3 = (this->Jinvariant2())*MULT*MULT;
00484     if ( temp3 < 0.0 && fabs(temp3) < EPS )
00485       {
00486         temp3 = 0.0;
00487       }
00488     double temp4 = temp3 * temp3 * temp3;
00489     double temp5 = temp1 * temp2;
00490     double temp6 = sqrt(temp4);
00491     if ( (fabs(temp6)) <= fabs(temp5 * EPS) ) return ( 0.000001 );// slight perturbation because of 1/0 KERU06sep96
00492     double temp7 = temp5 / temp6;
00493     double tempabs1 = (fabs(temp7-1.0));
00494     double tempabs2 = (fabs(temp7+1.0));
00495     if ( tempabs1 < 0.001 ) return ( 0.000001 / 3.0 );// slight perturbation because of 1/0 KERU06sep96
00496 //    if ( tempabs2 < 0.001 ) return ( PI / 3.0 );
00497     if ( tempabs2 < 0.001 ) return ( 3.14159/3.0 );// slight perturbation because of 1/0 KERU06sep96
00498     if ( temp7>1.0 || temp7<-1.0 )
00499       {
00500         ::fprintf(stderr,"\a\n something is wrong in straintensor::theta() (temp7>1.0||temp7<-1.0)\n");
00501 
00502         ::fprintf(stderr,"temp1 = %.20e\n", temp1);
00503         ::fprintf(stderr,"temp2 = %.20e\n", temp2);
00504         ::fprintf(stderr,"temp3 = %.20e\n", temp3);
00505         ::fprintf(stderr,"temp4 = %.20e\n", temp4);
00506         ::fprintf(stderr,"temp5 = %.20e\n", temp5);
00507         ::fprintf(stderr,"temp6 = %.20e\n", temp6);
00508         ::fprintf(stderr,"temp7 = %.20e\n", temp7);
00509 
00510         ::fprintf(stdout,"\a\n something is wrong in straintensor::theta() (temp7>1.0||temp7<-1.0)\n");
00511         this->print("s","straintensor s");
00512         ::fprintf(stdout,"temp1 = %.20e\n", temp1);
00513         ::fprintf(stdout,"temp2 = %.20e\n", temp2);
00514         ::fprintf(stdout,"temp3 = %.20e\n", temp3);
00515         ::fprintf(stdout,"temp4 = %.20e\n", temp4);
00516         ::fprintf(stdout,"temp5 = %.20e\n", temp5);
00517         ::fprintf(stdout,"temp6 = %.20e\n", temp6);
00518         ::fprintf(stdout,"temp7 = %.20e\n", temp7);
00519 
00520         exit (1);
00521       }
00522     double temp8 = acos(temp7);
00523     double temp9 = temp8 / 3.0;
00524 
00525     return ( temp9 );
00526   }
00527 
00528 //##############################################################################
00529 double straintensor::thetaPI() const
00530   {
00531     double thetaPI = theta() / PI;
00532     return thetaPI;
00533   }
00534 
00535 
00536 
00537 //##############################################################################
00538 straintensor straintensor::pqtheta2strain( double p, double q, double theta)
00539   {
00540     straintensor ret;
00541 
00542 //    double sqrtJ2D = q/3.0;
00543 //    double 2osqrt3 = 2.0/sqrt(3.0);
00544     double temp = (2.0*q)/(3.0);
00545 
00546     while ( theta >= 2.0*PI )
00547       theta = theta - 2.0*PI; // if bigger than full cycle
00548     while ( theta >= 4.0*PI/3.0 )
00549       theta = theta - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00550     while ( theta >= 2.0*PI/3.0 )
00551       theta = theta - 2.0*PI/3.0; // if bigger than two third of half cycle
00552     while ( theta >= PI/3.0 )
00553       theta = 2.0*PI/3.0 - theta; // if bigger than one third of half cycle
00554 
00555     double ct  = cos( theta  );
00556     double ctm = cos( theta - 2.0*PI/3.0 );
00557     double ctp = cos( theta + 2.0*PI/3.0 );
00558 
00559     ret.val(1,1) = p + temp*ct;
00560     ret.val(2,2) = p + temp*ctm;
00561     ret.val(3,3) = p + temp*ctp;
00562 
00563     return ret;
00564 
00565   }
00566 
00567 
00568 //##############################################################################
00569 straintensor straintensor::evoleq2strain( double evol, double eq )
00570   {
00571     straintensor ret;
00572 
00573     ret.val(1,1) = 1./3.*evol + 1./2.*eq;
00574     ret.val(2,2) = 1./3.*evol + 1./2.*eq;
00575     ret.val(3,3) = 1./3.*evol - eq;
00576 
00577     return ret;
00578 
00579   }
00580 
00581 
00582 
00583 //##############################################################################
00584 void straintensor::report(char * msg) const
00585   {
00586     ::printf("\n****************  strain tensor report ****************\n");
00587     if ( msg ) ::printf("%s",msg);
00588 
00589     this->print("st","straintensor st");
00590 
00591     ::printf("I1 = %.8e ; I2 = %.8e ; I3 = %.8e \n",
00592               Iinvariant1(),Iinvariant2(),Iinvariant3());
00593 
00594     printf("st_trace = %.8e,  mean pressure p = %.8e\n",
00595              trace(),  trace()/3.0);
00596 
00597     tensor I2("I", 2, def_dim_2);
00598 
00599     straintensor st_vol = I2 * trace() * (1./3.);
00600     st_vol.print("st_v","tensor st_vol (volumetric part of the st tensor)");
00601 
00602     straintensor st_dev = this->deviator();  // - st_vol;
00603     st_dev.print("st_d","tensor st_dev (strain deviator)");
00604 
00605     ::printf("J1 = %.8e ; J2 = %.8e ; J3 = %.8e ;\n",
00606               Jinvariant1(),Jinvariant2(),Jinvariant3());
00607 //...  straintensor Jinv2 = st_dev("ij")*st_dev("ji")*0.5;
00608 
00609     straintensor st_principal = principal();
00610     st_principal.print("st_p","principal strain tensor");
00611 
00612 
00613     ::printf("sig_oct = %.8e  , tau_oct = %.8e\n",
00614               sigma_octahedral(), tau_octahedral());
00615 
00616 
00617     ::printf("ksi=%.6e, ro=%.6e, theta=%.6e=%.6e*PI \n",
00618               ksi(),    ro(),    theta(),  thetaPI());
00619 
00620     if ( msg ) ::printf("%s",msg);
00621     ::printf("\n############  end of strain tensor report ############\n");
00622   }
00623 
00624 
00625 //##############################################################################
00626 void straintensor::reportshort(char * msg) const
00627   {
00628 //    ::printf("\n         ****************** short strain tensor report ***\n");
00629 //    if ( msg ) ::printf("         %s",msg);
00630 
00631     this->print("st"," ");
00632 
00633 //    ::printf("ksi = %.8e ,ro = %.8e ,theta = %.8e\n",
00634 //              ksi(),       ro(),      theta());
00635 
00636 //    ::printf("p=%.12e , q=%.12e , theta=%.12e*PI\n",
00637 //              p_hydrostatic(), q_deviatoric(), thetaPI());
00638 
00639   }
00640 
00641 OPS_Stream& operator<< (OPS_Stream& os, const straintensor & rhs)
00642 {
00643   os << "straintensor: I1 = " << rhs.Iinvariant1() << ", I2 = " << rhs.Iinvariant2() << ", I3 = " << 
00644     rhs.Iinvariant3() << endln;
00645 
00646   os << "st_trace = " << rhs.trace() << ", mean pressure p = " << rhs.trace()/3.0 << endln;
00647 
00648   /*
00649     tensor I2("I", 2, def_dim_2);
00650 
00651     straintensor st_vol = I2 * trace() * (1./3.);
00652     st_vol.print("st_v","tensor st_vol (volumetric part of the st tensor)");
00653 
00654     straintensor st_dev = this->deviator();  // - st_vol;
00655     st_dev.print("st_d","tensor st_dev (strain deviator)");
00656 
00657     ::printf("J1 = %.8e ; J2 = %.8e ; J3 = %.8e ;\n",
00658               Jinvariant1(),Jinvariant2(),Jinvariant3());
00659 
00660     straintensor st_principal = principal();
00661     st_principal.print("st_p","principal strain tensor");
00662 
00663 
00664     ::printf("sig_oct = %.8e  , tau_oct = %.8e\n",
00665               sigma_octahedral(), tau_octahedral());
00666 
00667 
00668     ::printf("ksi=%.6e, ro=%.6e, theta=%.6e=%.6e*PI \n",
00669               ksi(),    ro(),    theta(),  thetaPI());
00670 
00671   */
00672   return os;
00673 }
00674 
00675 #endif

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