stresst.cpp

Go to the documentation of this file.
00001 //##########################################################################
00002 //#                                                                        #
00003 //#                                                                        #
00004 //#             /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/~~\            #
00005 //#            |                                          |____|           #
00006 //#            |                                          |                #
00007 //#            |                                          |                #
00008 //#            |                                          |                #
00009 //#            |           P L A S T I C I T Y            |                #
00010 //#            |                                          |                #
00011 //#            |                                          |                #
00012 //#            |              C L A S S E S               |                #
00013 //#            |                                          |                #
00014 //#            |                                          |                #
00015 //#            |          C + +     S O U R C E           |                #
00016 //#            |                                          |                #
00017 //#            |                                          |                #
00018 //#            |                                          |                #
00019 //#            |                                          |                #
00020 //#         /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/   |                #
00021 //#         \_________________________________________\__/                 #
00022 //#                                                                        #
00023 //#                                                                        #
00024 //##########################################################################
00025 //##########################################################################
00026 //##########################################################################
00027 //##########################################################################
00028 //                         PAZI 'VAMO:
00029 //
00030 //
00031 //  1. organizuj klase tako da u baznoj Yield_Function ( i novoj
00032 //     Potential_Function ) budu oni izvodi a kasnije po klasama
00033 //     ( VM, DP, MRSL, . . .  ) samo oni delovi koji se ticu
00034 //     izvoda funkcije po invarijantama !!  Tako ces napraviti
00035 //     lepu hijerarhiju za plasticnost !!
00036 //
00037 //  2. Napravi neku vrstu header fajla sa onim uvek potrebnim tenzorima
00038 //     ( I2_ij, I4_ijkl . . .  ) pa neka to budu GLOBALNE konstante
00039 //     jer ih svaki cas pravis i unistavas . . .
00040 //
00041 //
00042 //
00043 //
00044 //#############################################################################
00045 //#############################################################################
00046 //#############################################################################
00047 
00049 //################################################################################
00050 //# COPY-YES  (C):     :-))                                                      #
00051 //# PROJECT:           Object Oriented Finite Element Program                    #
00052 //# PURPOSE:           stress tensor with all necessery functions                #
00053 //# CLASS:             stresstensor                                              #
00054 //#                                                                              #
00055 //# VERSION:                                                                     #
00056 //# LANGUAGE:          C++.ver >= 2.0 ( Borland C++ ver=3.00, SUN C++ ver=2.1 )  #
00057 //# TARGET OS:         DOS || UNIX || . . .                                      #
00058 //# DESIGNER(S):       Boris Jeremic                                             #
00059 //# PROGRAMMER(S):     Boris Jeremic                                             #
00060 //#                                                                              #
00061 //#                                                                              #
00062 //# DATE:              July 22 '93                                               #
00063 //# UPDATE HISTORY:    December 15 '93 replaced polinomial root solver for       #
00064 //#                    principal stresses with explicit formula                  #
00065 //#                    August 22-29 '94 choped to separate files and worked on   #
00066 //#                                   const and & issues                         #
00067 //#                    August 30-31 '94 added use_def_dim to full the CC         #
00068 //#                                   resolved problem with temoraries for       #
00069 //#                                   operators + and - ( +=, -= )               #
00070 //#                    13 septembar '96 added reportAnim  :)                     #
00071 //#                                                                              #
00072 //#                                                                              #
00073 //#                                                                              #
00074 //#                                                                              #
00075 //#                                                                              #
00076 //################################################################################
00077 //*/
00078 
00079 
00080 #ifndef STRESSTENSOR_CPP
00081 #define STRESSTENSOR_CPP
00082 
00083 #include "stresst.h"
00084 
00085 #include <iomanip>
00086 using std::ios;
00087 
00088 // just send appropriate arguments to the base constructor
00089 //##############################################################################
00090 stresstensor::stresstensor (int rank_of_tensor, double initval):
00091   BJtensor(rank_of_tensor, def_dim_2, initval) {  } // default constructor
00092 
00093 
00094 //##############################################################################
00095 stresstensor::stresstensor ( double *values ):
00096   BJtensor( 2, def_dim_2, values) {  }
00097 
00098 //##############################################################################
00099 stresstensor::stresstensor ( double initvalue ):
00100   BJtensor( 2, def_dim_2, initvalue)  {  }
00101 
00102 //##############################################################################
00103 stresstensor::stresstensor( const stresstensor & x ):
00104   BJtensor("NO")
00105     {
00106       x.pc_nDarray_rep->n++;  // tell the rval it has another reference
00107 //      x.reference_count(+1);              // we're adding another reference.
00108       pc_nDarray_rep = x.pc_nDarray_rep;  // point to the new tensor_rep.
00109 // add the indices
00110       indices1 = x.indices1;
00111       indices2 = x.indices2;
00112     }
00113 
00114 
00115 //##############################################################################
00116 stresstensor::stresstensor( const tensor & x):
00117   BJtensor( x )
00118     {  } // copy-initializer
00119 
00120 //##############################################################################
00121 stresstensor::stresstensor( const nDarray & x):
00122   BJtensor ( x )
00123     {  } // copy-initializer
00124 
00125 
00126 
00127  // IT IS NOT INHERITED so must be defined in all derived classes
00128  // See ARM page 277.
00129  //##############################################################################
00130 // stresstensor::~stresstensor()
00131 // {
00132 //   if (reference_count(-1) <= 0)  // Zhaohui changed  == 0 to <= 0 // if reference count  goes to 0
00133 //     {
00134 // // DEallocate memory of the actual nDarray
00135 // //    delete [pc_nDarray_rep->pc_nDarray_rep->total_numb] pc_nDarray_rep->pd_nDdata;
00136 // // nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00137 // //                                                and note on the p.65($5.3.4)
00138 //     delete [] data();
00139 //     delete [] dim();
00140 //     delete pc_nDarray_rep;
00141 //   }
00142 // }
00143 //
00144 
00145 //##############################################################################
00146 // IT IS NOT INHERITED so must be defined in all derived classes
00147 // See ARM page 306.
00148 //##############################################################################
00149 stresstensor stresstensor::operator=( const stresstensor & rval)
00150 {
00151     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00152 //    rval.reference_count(+1);  // tell the rval it has another reference
00153 //   /*  It is important to increment the reference_counter in the new
00154 //       tensor before decrementing the reference_counter in the
00155 //       old tensor_rep to ensure proper operation when assigning a
00156 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00157  // clean up current value;
00158     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00159       {
00160 // DEallocate memory of the actual tensor
00161         delete [] data();
00162         delete [] dim();
00163         delete pc_nDarray_rep;
00164       }
00165  // connect to new value
00166     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00167 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00168 // null indices in the rval
00169 //    rval.indices1 = NULL;
00170 //    rval.indices2 = NULL;
00171 //    rval.null_indices();
00172 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00173     this->null_indices();
00174     return *this;
00175 }
00176 
00177 // IT IS NOT INHERITED so must be defined in all derived classes
00178 // See ARM page 306.
00179 //##############################################################################
00180 stresstensor stresstensor::operator=( const tensor & rval)
00181 {
00182     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00183 //    rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00184 //    rval.reference_count(+1);  // tell the rval it has another reference
00185 //   /*  It is important to increment the reference_counter in the new
00186 //       tensor before decrementing the reference_counter in the
00187 //       old tensor_rep to ensure proper operation when assigning a
00188 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00189 
00190  // clean up current value;
00191 //    if(--pc_nDarray_rep->n == 0)  // if nobody else is referencing us.
00192     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00193       {
00194 // DEallocate memory of the actual tensor
00195 //      delete [pc_tensor_rep->pc_tensor_rep->total_numb] pc_tensor_rep->pd_nDdata;
00196 // nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00197 //                                                and note on the p.65($5.3.4)
00198 //        delete  pc_nDarray_rep->pd_nDdata;
00199         delete [] data();
00200         delete [] dim();
00201 // ovo ne smem da brisem jer nije dinamicki alocirano
00202 //        delete pc_tensor_rep->indices;
00203         delete pc_nDarray_rep;
00204       }
00205 
00206  // connect to new value
00207     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00208 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00209 // null indices in the rval
00210 //    rval.indices1 = NULL;
00211 //    rval.indices2 = NULL;
00212 //    rval.null_indices();
00213 // Temporary out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00214     this->null_indices();
00215     return *this;
00216 }
00217 
00218 
00219 // IT IS NOT INHERITED so must be defined in all derived classes
00220 // See ARM page 306.
00221 //##############################################################################
00222 stresstensor stresstensor::operator=( const nDarray & rval)
00223 {
00224     rval.pc_nDarray_rep->n++;  // tell the rval it has another reference
00225 //    rval.reference_count(+1);  // tell the rval it has another reference
00226 //   /*  It is important to increment the reference_counter in the new
00227 //       tensor before decrementing the reference_counter in the
00228 //       old tensor_rep to ensure proper operation when assigning a
00229 //       tensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00230 
00231     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00232       {
00233         delete [] data();
00234         delete [] dim();
00235         delete pc_nDarray_rep;
00236       }
00237 
00238  // connect to new value
00239     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval tensor_rep
00240     return *this;
00241 }
00242 
00243 
00244 //##############################################################################
00245 // makes a complete new copy of stresstensor!!
00246 stresstensor stresstensor::deep_copy(void)
00247   {
00248     return stresstensor(this->data()); // call constructor and return it !
00249   }
00250 //..//##############################################################################
00251 //../ returns a pointer to the stresstensor!!
00252 //..stresstensor * stresstensor::p_deep_copy(void)
00253 //..  {
00254 //..    stresstensor temp = this->deep_copy();
00255 //..    return &temp; // call constructor and return it !
00256 //..  }
00257 
00258 //ini  //##############################################################################
00259 //ini  // use "from" and initialize already allocated stress tensor from "from" values
00260 //ini  void stresstensor::Initialize( const stresstensor & from )
00261 //ini    {
00262 //ini  // copy only data because everything else is default
00263 //ini      for ( int i=0 ; i<pc_nDarray_rep->total_numb ; i++ )
00264 //ini        this->pc_nDarray_rep->pd_nDdata[i] = from.pc_nDarray_rep->pd_nDdata[i] ;
00265 //ini    }
00266 
00267 //___//##############################################################################
00268 //___//##############################################################################
00269 //___//##############################################################################
00270 //___stresstensor & stresstensor::operator()(short ir, short is, short it,
00271 //___                                        short tr, short ts, short tt  )
00272 //___// another overloading of operator() . . .  // overloaded for THREE arguments
00273 //___  {
00274 //___    short where = ir - 1;
00275 //___          where = where*ts + is - 1;
00276 //___          where = where*tt + it - 1;
00277 //___
00278 //___//::printf(" w=%ld ",where);
00279 //___    stresstensor *p_value = this + where;
00280 //___    return (*p_value);
00281 //___  }
00282 
00283 //##############################################################################
00284 // invariants of the stress tensor              // Chen W.F. "plasticity for
00285 double stresstensor::Iinvariant1() const       // Structural Engineers"
00286   {
00287     return (cval(1,1)+cval(2,2)+cval(3,3));
00288   }
00289 
00290 //##############################################################################
00291 double stresstensor::Iinvariant2() const
00292   {
00293     return (cval(2,2)*cval(3,3)-cval(3,2)*cval(2,3)+
00294             cval(1,1)*cval(3,3)-cval(3,1)*cval(1,3)+
00295             cval(1,1)*cval(2,2)-cval(2,1)*cval(1,2));
00296   }
00297 
00298 //##############################################################################
00299 double stresstensor::Iinvariant3()  const
00300   {
00301 
00302     double I3 = cval(1,1)*cval(2,2)*cval(3,3) +
00303                 cval(1,2)*cval(2,3)*cval(3,1) +
00304                 cval(1,3)*cval(2,1)*cval(3,2) -
00305                 cval(1,3)*cval(2,2)*cval(3,1) -
00306                 cval(1,2)*cval(2,1)*cval(3,3) -
00307                 cval(1,1)*cval(2,3)*cval(3,2) ;
00308 
00309     return I3;
00310 //    return ( this->determinant());
00311   }
00312 
00313 
00314 //##############################################################################
00315 // invariants of the deviatoric stress tensor
00316 double stresstensor::Jinvariant1()  const
00317   {
00318     return (0.0);
00319   }
00320 
00321 //##############################################################################
00322 double stresstensor::Jinvariant2()  const
00323   {
00324     double temp1 = (Iinvariant1()*Iinvariant1()-3.0*Iinvariant2())*ONEOVERTHREE;
00325 //    double EPS = sqrt(d_macheps());
00326 //    if ( temp1 < 0.0 || fabs(temp1) < EPS )
00327     if ( temp1 < 0.0 )
00328       {                    // this is because it might be close
00329         temp1 = 0.0;       // to zero ( -1e-19 ) numericaly
00330       }                    // but sqrt() does not accept it
00331     return ( temp1 );      // as (-) and theoreticaly J2d>0
00332   }
00333 
00334 //##############################################################################
00335 double stresstensor::Jinvariant3()  const
00336   {
00337     double I1 = Iinvariant1();
00338     double I2 = Iinvariant2();
00339     double I3 = Iinvariant3();
00340 
00341     return ( (2.0*I1*I1*I1 - 9.0*I1*I2 + 27.0*I3)/27.0 );
00342   }
00343 
00344 //##############################################################################
00345 stresstensor stresstensor::principal()  const
00346   {
00347     stresstensor ret;
00348 
00349     double p_     = this->p_hydrostatic();
00350     double q_     = this->q_deviatoric();
00351     double theta_ = this->theta();
00352 //old    while ( theta_ >= 2.0*PI )
00353 //old      theta_ = theta_ - 2.0*PI; // if bigger than full cycle
00354 //old    while ( theta_ >= 4.0*PI/3.0 )
00355 //old      theta_ = theta_ - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00356 //old    while ( theta_ >= 2.0*PI/3.0 )
00357 //old      theta_ = theta_ - 2.0*PI/3.0; // if bigger than two third of half cycle
00358 //old    while ( theta_ >= PI/3.0 )
00359 //old      theta_ = 2.0*PI/3.0 - theta_; // if bigger than one third of half cycle
00360 
00361 //    ret.report("ret");
00362 //    double sqrtJ2D = q/3.0;
00363 //    double 2osqrt3 = 2.0/sqrt(3.0);
00364     double temp = q_*TWOOVERTHREE;
00365 
00366     double ct  = cos( theta_  );
00367     double ctm = cos( theta_ - TWOOVERTHREE*PI );
00368     double ctp = cos( theta_ + TWOOVERTHREE*PI );
00369 
00370     ret.val(1,1) = - p_ + temp*ct;  // - becasue p is p = -1/3 sigma_ij delta_ii
00371     ret.val(2,2) = - p_ + temp*ctm;
00372     ret.val(3,3) = - p_ + temp*ctp;
00373 
00374 //    ret.report("ret");
00375     return ret;
00376 
00377 //..    static complex ac[4];               // Chen W.F. "plasticity for
00378 //..    static complex roots[4];            // Structural Engineers"
00379 //..    int polish = 1 ;                    // page 53
00380 //..    int m = 3;
00381 //..
00382 //..    ac[0] = complex( -(this->Iinvariant3()), 0.0 );
00383 //..    ac[1] = complex(  (this->Iinvariant2()), 0.0);
00384 //..    ac[2] = complex( -(this->Iinvariant1()), 0.0);
00385 //..    ac[3] = complex(  1.0, 0.0);
00386 //..
00387 //..// what was obtained for coefficients
00388 //..//DEBUGprint ::printf("ac[0].r = %lf  ac[0].i = %lf\n", real(ac[0]), imag(ac[0]));
00389 //..//DEBUGprint ::printf("ac[1].r = %lf  ac[1].i = %lf\n", real(ac[1]), imag(ac[1]));
00390 //..//DEBUGprint ::printf("ac[2].r = %lf  ac[2].i = %lf\n", real(ac[2]), imag(ac[2]));
00391 //..//DEBUGprint ::printf("ac[3].r = %lf  ac[3].i = %lf\n", real(ac[3]), imag(ac[3]));
00392 //..//DEBUGprint ::printf("m  = %d\n",m);
00393 //..
00394 //..    zroots( ac, m, roots, polish);
00395 //..
00396 //..//DEBUGprint ::printf("\nroots[1].r=%lf  roots[1].i=%lf\n",real(roots[1]),imag(roots[1]));
00397 //..//DEBUGprint ::printf("roots[2].r=%lf  roots[2].i=%lf\n",real(roots[2]),imag(roots[2]));
00398 //..//DEBUGprint ::printf("roots[3].r=%lf  roots[3].i=%lf\n",real(roots[3]),imag(roots[3]));
00399 //..
00400 //..
00401 //..    stresstensor principal(0.0);
00402 //..
00403 //..    principal.val(1,1) = real(roots[3]); // since they are sorted by
00404 //..    principal.val(2,2) = real(roots[2]); // the zroot function in ascending
00405 //..    principal.val(3,3) = real(roots[1]); // order . . .
00406 //..                                         // sig1>sig2>sig3
00407 //..    return principal;
00408 //..
00409 //..
00410   }
00411 
00412 //##############################################################################
00413 stresstensor stresstensor::deviator() const
00414   {
00415     BJtensor I2("I", 2, def_dim_2); // Kronecker delta  \delta_{ij}
00416     stresstensor st_vol = I2 * (this->trace()*(0.333333333));
00417     stresstensor st_dev = (*this) - st_vol;
00418 
00419     return st_dev;
00420   }
00421 
00422 
00423 
00424 //##############################################################################
00425 double stresstensor::sigma_octahedral() const // Chen W.F. "plasticity for
00426   {                                            // Structural Engineers"
00427     return ( this->Iinvariant1()*ONEOVERTHREE );        // page 59-60
00428   }
00429 
00430 //##############################################################################
00431 double stresstensor::tau_octahedral() const    // Chen W.F. "plasticity for
00432   {                                             // Structural Engineers"
00433     return(sqrt(TWOOVERTHREE*(this->Jinvariant2())));// page 59-60
00434   }
00435 
00436 
00437 //##############################################################################
00438 double stresstensor::ksi() const                     // Chen W.F. "plasticity for
00439   {                                            // Structural Engineers"
00440     return( (this->Iinvariant1())/sqrt(3.0) ); // page 66
00441   }
00442 
00443 //##############################################################################
00444 double stresstensor::xi() const                // Chen W.F. "plasticity for
00445   {                                            // Structural Engineers"
00446     return( (this->Iinvariant1())/sqrt(3.0) ); // page 66
00447   }
00448 
00449 //##############################################################################
00450 double stresstensor::ro()  const                      // Chen W.F. "plasticity for
00451   {                                             // Structural Engineers"
00452     double temp1 = this->Jinvariant2();         // page 68
00453     double EPS = pow(d_macheps(),(1./2.));
00454     if ( temp1 < 0.0 && fabs(temp1) < EPS )
00455       {
00456         temp1 = 0.0;
00457       }
00458     return( sqrt(2.0*(temp1)));
00459   }
00460 //##############################################################################
00461 double stresstensor::rho()  const                      // Chen W.F. "plasticity for
00462   {                                             // Structural Engineers"
00463     double temp1 = this->Jinvariant2();         // page 68
00464     double EPS = pow(d_macheps(),(1./2.));
00465     if ( temp1 < 0.0 && fabs(temp1) < EPS )
00466       {
00467         temp1 = 0.0;
00468       }
00469     return( sqrt(2.0*(temp1)));
00470   }
00471 
00472 //##############################################################################
00473 double stresstensor::p_hydrostatic() const        // Desai "Constitutive Laws
00474   {                                         // for Engineering Materials"
00475     return( - (this->Iinvariant1())*ONEOVERTHREE );  // page 283
00476   }  //sign (-) because tension is positive
00477 
00478 
00479 //##############################################################################
00480 double stresstensor::q_deviatoric() const       // Desai "Constitutive Laws
00481   {                                       // for Engineering Materials"
00482     double temp1 = this->Jinvariant2();   // page 283
00483 //    double EPS = pow(d_macheps(),(1./2.));
00484 //    if ( temp1 < 0.0 || fabs(temp1) < EPS )
00485     if ( temp1 < 0.0 )
00486       {
00487         temp1 = 0.0;
00488       }
00489 
00490     return( sqrt(3.0*temp1) );
00491   }
00492 
00493 //##############################################################################
00494 double stresstensor::theta( ) const              // Chen W.F. "plasticity for
00495   {                                             // Structural Engineers"
00496                                                 // page 70
00497     double EPS = pow(d_macheps(),(1./4.));
00498     double temp1 = (3.0*sqrt(3.0)/2.0);
00499     double J3D = (this->Jinvariant3());
00500     double J2D = (this->Jinvariant2());
00501     if ( J2D < 0.0 || fabs(J2D) < EPS )
00502       {
00503         J2D = 0.0;
00504       }
00505     double temp4 = J2D * J2D * J2D;
00506     double temp5 = temp1 * J3D;
00507     double temp6 = sqrt(temp4);
00508     if ( (fabs(temp6)) <= fabs(temp5 * EPS) ) return ( 0.000001 );// slight perturbation because of 1/0 KERU06sep96
00509     if ( (fabs(temp6)) < EPS  ) return ( 0.000001 );// slight perturbation because of 1/0 KERU06sep96
00510     double temp7 = temp5 / temp6;
00511     double tempabs1 = (fabs(temp7-1.0));
00512     double tempabs2 = (fabs(temp7+1.0));
00513     if ( tempabs1 < 0.1 ) return ( 0.000001/3.0 );// slight perturbation because of 1/0 KERU06sep96
00514 //    if ( tempabs2 < 0.001 ) return ( PI/3.0 );
00515     if ( tempabs2 < 0.1 ) return ( 3.14159/3.0 );// slight perturbation because of 1/0 KERU06sep96
00516     if ( temp7>1.0 || temp7<-1.0 )
00517       {
00518         ::fprintf(stderr,"\n something is wrong in stresstensor::theta() (temp7>1.0||temp7<-1.0)\n");
00519         ::fprintf(stderr,"returning Pi/3.\n");
00520 
00521         ::fprintf(stderr,"temp1 = %.20e\n", temp1);
00522         ::fprintf(stderr,"J3D = %.20e\n", J3D);
00523         ::fprintf(stderr,"J2D = %.20e\n", J2D);
00524         ::fprintf(stderr,"temp4 = %.20e\n", temp4);
00525         ::fprintf(stderr,"tempabs1 = %.20e\n", tempabs1);
00526         ::fprintf(stderr,"tempabs2 = %.20e\n", tempabs2);
00527         ::fprintf(stderr,"temp5 = %.20e\n", temp5);
00528         ::fprintf(stderr,"temp6 = %.20e\n", temp6);
00529         ::fprintf(stderr,"temp7 = %.20e\n", temp7);
00530 
00531         ::fprintf(stdout,"\n something is wrong in stresstensor::theta() (temp7>1.0||temp7<-1.0)\n");
00532         ::fprintf(stdout,"returning Pi/3.\n");
00533         this->print("s","stresstensor s");
00534         ::fprintf(stdout,"temp1 = %.20e\n", temp1);
00535         ::fprintf(stdout,"J3D = %.20e\n", J3D);
00536         ::fprintf(stdout,"J2D = %.20e\n", J2D);
00537         ::fprintf(stdout,"temp4 = %.20e\n", temp4);
00538         ::fprintf(stdout,"tempabs1 = %.20e\n", tempabs1);
00539         ::fprintf(stdout,"tempabs2 = %.20e\n", tempabs2);
00540         ::fprintf(stdout,"temp5 = %.20e\n", temp5);
00541         ::fprintf(stdout,"temp6 = %.20e\n", temp6);
00542         ::fprintf(stdout,"temp7 = %.20e\n", temp7);
00543 
00544         return (  3.14159/ 3.0 );// slight perturbation because of 1/0 KERU06sep96
00545 //        exit(1);
00546       }
00547     double temp8 = acos(temp7);
00548     double temp9 = temp8 * ONEOVERTHREE;
00549 
00550     return ( temp9 );
00551   }
00552 
00553 //##############################################################################
00554 double stresstensor::thetaPI()  const
00555   {
00556     double thetaPI = theta() / PI;
00557     return thetaPI;
00558   }
00559 
00560 
00564 //    double stresstensor::func( stresstensor & start_stress,
00565 //                               stresstensor & end_stress,
00566 //                               Material_Model & YC,
00567 //                               double alfa )
00568 //      {
00569 //        stresstensor delta_stress = end_stress - start_stress;
00570 //        stresstensor intersection_stress = start_stress + delta_stress*alfa;
00571 //        double f = YC.f(intersection_stress);
00572 //        return f;
00573 //      }
00574 
00575 
00576 
00577 
00578 //#############################################################################
00579 tensor stresstensor::dpoverds( void ) const
00580   {
00581     tensor ret(2, def_dim_2, 0.0);
00582     tensor I2("I", 2, def_dim_2);
00583     ret = I2*(-1.0/3.0);
00584     ret.null_indices();
00585     return ret;
00586   }
00587 
00588 //#############################################################################
00589 tensor stresstensor::dqoverds( void ) const
00590   {
00591     
00592 //    stresstensor stress = EPS->getStress();
00593     
00594     tensor ret(2, def_dim_2, 0.0);
00595     double q = this->q_deviatoric();
00596     stresstensor s( 0.0);
00597 //...    double J2D = stress.Jinvariant2();
00598 //...    double temp1 = sqrt(J2D);
00599 //...    double temp2 = sqrt(3.0)/(2.0*temp1);
00600     double temp2 = (3.0/2.0)*(1/q);
00601     s = this->deviator();
00602     ret = s*temp2;
00603     ret.null_indices();
00604     return ret;
00605   }
00606 
00607 //#############################################################################
00608 tensor stresstensor::dthetaoverds( void ) const
00609   {
00610 //    stresstensor stress = EPS->getStress();
00611 
00612     tensor ret(2, def_dim_2, 0.0);
00613     stresstensor s( 0.0);
00614     stresstensor t( 0.0);
00615     tensor I2("I", 2, def_dim_2);
00616 
00617 //    double EPS = pow(d_macheps(),(1./3.));
00618     double J2D   = this->Jinvariant2();
00619     double q     = this->q_deviatoric();
00620     double theta = this->theta();
00621 
00622 //out    while ( theta >= 2.0*PI )
00623 //out      theta = theta - 2.0*PI; // if bigger than full cycle
00624 //out    while ( theta >= 4.0*PI/3.0 )
00625 //out      theta = theta - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00626 //out    while ( theta >= 2.0*PI/3.0 )
00627 //out      theta = theta - 2.0*PI/3.0; // if bigger than two third of half cycle
00628 //out    while ( theta >= PI/3.0 )
00629 //out      theta = 2.0*PI/3.0 - theta; // if bigger than one third of half cycle
00630 //out
00631 //out    if ( theta < 0.0001 )
00632 //out      {
00633 //out        ::printf("theta = %.10e in CAMPotentialSurface::dthetaoverds(stress)\n",
00634 //out                           theta);
00635 //out//>><<>><<>><<        return ret;
00636 //out      }
00637 
00638     double c3t = cos(3.0*theta);
00639     double s3t = sin(3.0*theta);
00640 
00641     double tempS = (3.0/2.0)*(c3t/(q*q*s3t));
00642     double tempT = (9.0/2.0)*(1.0/(q*q*q*s3t));
00643 
00644     s = this->deviator();
00645     t = s("qk")*s("kp") - I2*(J2D*(2.0/3.0));
00646 
00647     s.null_indices();
00648     t.null_indices();
00649 
00650     ret = s*tempS - t*tempT;
00651     ret.null_indices();
00652     return ret;
00653   }
00654 
00655 //#############################################################################
00661 //#############################################################################
00662 tensor stresstensor::d2poverds2( void ) const
00663   {
00664     tensor ret(4, def_dim_4, 0.0);
00665     return ret;
00667   }
00668 
00669 
00670 //#############################################################################
00671 tensor stresstensor::d2qoverds2( void ) const
00672   {
00673 //    stresstensor stress = EPS->getStress();
00674 
00675 
00676     //first the return tensor in order not to fragment the memory
00677     tensor ret( 4, def_dim_4, 0.0); //  second derivative of q over
00678                                     //  d sigma_pq  d sigma_mn
00679     //setting up some constants
00680 
00681     tensor I2("I", 2, def_dim_2);      // To check out this three fourth-order
00682     tensor I_pqmn("I", 4, def_dim_4);  // isotropic tensor please see
00683     I_pqmn = I2("pq")*I2("mn");        // W.Michael Lai, David Rubin,
00684     I_pqmn.null_indices();
00685     tensor I_pmqn("I", 4, def_dim_4);  // Erhard Krempl
00686     I_pmqn = I_pqmn.transpose0110();   // " Introduction to Continuum Mechanics"
00687                                        // QA808.2  ;   ISBN 0-08-022699-X
00688 
00689     double q_dev   = this->q_deviatoric();
00690 
00691     stresstensor s = this->deviator();
00692     s.null_indices();
00693 
00694     tensor iso1( 4, def_dim_4, 0.0); //this will be d_pm*d_nq-d_pq*d_nm*(1/3)
00695     iso1 = I_pmqn  - I_pqmn*(1.0/3.0);
00696 
00697     double tempiso1  = (3.0/2.0)*(1/q_dev);
00698     double tempss    = (9.0/4.0)*(1.0/( q_dev * q_dev * q_dev ));
00699 
00700     ret = iso1*tempiso1 - (s("pq")*s("mn"))*tempss;
00701     ret.null_indices();
00702     return ret;
00703   }
00704 
00705 
00706 //#############################################################################
00707 tensor stresstensor::d2thetaoverds2( void ) const
00708   {
00709     tensor ret( 4, def_dim_4, 0.0);
00710 
00711     tensor I2("I", 2, def_dim_2);
00712     tensor I_pqmn("I", 4, def_dim_4);  // To check out this three fourth-order
00713     I_pqmn = I2("pq")*I2("mn");        // isotropic tensor please see
00714     I_pqmn.null_indices();
00715     tensor I_pmqn("I", 4, def_dim_4);  // W.Michael Lai, David Rubin,
00716     I_pmqn = I_pqmn.transpose0110();   // Erhard Krempl
00717 //no    tensor I_pnqm("I", 4, def_dim_4);  // " Introduction to Continuum Mechanics"
00718 //no    I_pnqm = I_pqmn.transpose0111();   // QA808.2  ;   ISBN 0-08-022699-X
00719 
00720     double J2D = this->Jinvariant2();
00721 
00722 //    double EPS = pow(d_macheps(),(1./3.));
00723 
00724     tensor s( 2, def_dim_2, 0.0);
00725     tensor t( 2, def_dim_2, 0.0);
00726     s = this->deviator();
00727     t = s("qk")*s("kp") - I2*(J2D*(2.0/3.0));
00728 //s.print("s"," \n\n tensor s \n\n");
00729 //t.print("t"," \n\n tensor t \n\n");
00730     s.null_indices();
00731     t.null_indices();
00732 
00733     tensor p( 4, def_dim_4, 0.0); //this will be d_mp*d_nq - d_pq*d_nm*(1/3)
00734     tensor w( 4, def_dim_4, 0.0);
00735 
00736     double theta = this->theta();
00737 //out    while ( theta >= 2.0*PI )
00738 //out      theta = theta - 2.0*PI; // if bigger than full cycle
00739 //out    while ( theta >= 4.0*PI/3.0 )
00740 //out      theta = theta - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00741 //out    while ( theta >= 2.0*PI/3.0 )
00742 //out      theta = theta - 2.0*PI/3.0; // if bigger than two third of half cycle
00743 //out    while ( theta >= PI/3.0 )
00744 //out      theta = 2.0*PI/3.0 - theta; // if bigger than one third of half cycle
00745 //out
00746 //out    if ( theta < 0.0001 )
00747 //out      {
00748 //out        ::printf("\n\ntheta = %.10e in CAMPotentialSurface::d2thetaoverds2(stress)\n",
00749 //out                           theta);
00750 //out//>><<>><<>><<        return ret;
00751 //out      }
00752 //out
00753 
00754     double q_dev = this->q_deviatoric();
00755 
00756   //setting up some constants
00757 //......    double sqrt3 = sqrt(3.0);
00758     double c3t    = cos(3*theta);
00759     double s3t    = sin(3*theta);
00760     double s3t3   = s3t*s3t*s3t;
00761     double q3     = q_dev * q_dev * q_dev;
00762     double q4     = q_dev * q_dev * q_dev * q_dev;
00763     double q5     = q_dev * q_dev * q_dev * q_dev * q_dev;
00764     double q6     = q_dev * q_dev * q_dev * q_dev * q_dev * q_dev;
00765 
00766 
00767     double tempss = - (9.0/2.0)*(c3t)/(q4*s3t) - (27.0/4.0)*(c3t/(s3t3*q4));
00768 
00769     double tempst = (81.0/4.0)*(1.0)/(s3t3*q5);
00770 
00771     double tempts = (81.0/4.0)*(1.0/(s3t*q5)) + (81.0/4.0)*(c3t*c3t)/(s3t3*q5);
00772 
00773     double temptt = - (243.0/4.0)*(c3t/(s3t3*q6));
00774 
00775     double tempp  = +(3.0/2.0)*(c3t/(s3t*q_dev*q_dev));
00776 
00777     double tempw  = -(9.0/2.0)*(1.0/(s3t*q3));
00778 
00779 
00780 //))))))))
00781 //))))))))    double tempss = 0.0;
00782 //))))))))
00783 //))))))))    double tempst = 0.0;
00784 //))))))))
00785 //))))))))    double tempts = 0.0;
00786 //))))))))
00787 //))))))))    double temptt = 0.0;
00788 //))))))))
00789 //))))))))    double tempp  = 0.0;
00790 //))))))))
00791 //))))))))    double tempw  = 0.0;
00792 //))))))))
00793 
00794 
00795 // fourth order tensors in the final equation for second derivative
00796 // of theta over ( d \sigma_{pq} d \sigma_{mn} )
00797 // BE CAREFULL order is   PQ MN
00798 
00799     tensor s_pq_d_mn( 4, def_dim_4, 0.0);
00800     tensor s_pn_d_mq( 4, def_dim_4, 0.0);
00801 //...    tensor s_pm_d_nq( 4, def_dim_4, 0.0);
00802 
00803     tensor d_pq_s_mn( 4, def_dim_4, 0.0);
00804     tensor d_pn_s_mq( 4, def_dim_4, 0.0);
00805 //...    tensor d_pm_s_nq( 4, def_dim_4, 0.0);
00806 
00807     p = I_pmqn  - I_pqmn*(1.0/3.0);
00808 
00809 // privremena stampa
00810 //..........................................................................
00811 //.......p.print("p"," tensor p = I_pmqn  - I_pqmn*(1.0/3.0)");
00812 
00813 
00814     s_pq_d_mn = s("pq")*I2("mn");
00815     s_pq_d_mn.null_indices();
00816     s_pn_d_mq = s_pq_d_mn.transpose0101();
00817 //...    s_pm_d_nq = s_pn_d_mq.transpose0110();
00818 
00819     d_pq_s_mn = I2("pq")*s("mn");
00820     d_pq_s_mn.null_indices();
00821     d_pn_s_mq = d_pq_s_mn.transpose0101();
00822 //...    d_pm_s_nq = d_pn_s_mq.transpose0110();
00823 
00826 //s_pq_d_mn.print("sd"," tensor s_pq_d_mn = s(\"pq\")*I2(\"mn\") ");
00827 //s_pn_d_mq.print("sd"," tensor s_pn_d_mq = s_pq_d_mn.transpose0101()");
00829 //d_pq_s_mn.print("ds"," tensor d_pq_s_mn = I2(\"pq\")*s(\"mn\") ");
00830 //d_pn_s_mq.print("ds"," tensor d_pn_s_mq = d_pq_s_mn.transpose0101()");
00833 
00834     w =  s_pn_d_mq + d_pn_s_mq - s_pq_d_mn*(2.0/3.0) - d_pq_s_mn*(2.0/3.0);
00835 
00836 //.....// symmetric w
00837 //.....    w = ( s_pn_d_mq + s_pm_d_nq ) * 0.5 +
00838 //.....        ( d_pn_s_mq + d_pm_s_nq ) * 0.5
00839 //.....        - s_pq_d_mn*(2.0/3.0) - d_pq_s_mn*(2.0/3.0);
00840 //.....
00841 
00844 //w.print("w","w=s_pn_d_mq+d_pn_s_mq-s_pq_d_mn*(2.0/3.0)-d_pq_s_mn*(2.0/3.0)");
00846 
00849 //tensor ss = s("pq")*s("mn");
00850 //tensor st = s("pq")*t("mn");
00851 //tensor ts = t("pq")*s("mn");
00852 //tensor tt = t("pq")*t("mn");
00853 //ss.print("ss","\n tensor ss ");
00854 //st.print("st","\n tensor st ");
00855 //ts.print("ts","\n tensor ts ");
00856 //tt.print("tt","\n tensor tt ");
00858 
00859 // finally
00860     ret = (   s("pq")*s("mn") * tempss
00861             + s("pq")*t("mn") * tempst
00862             + t("pq")*s("mn") * tempts
00863             + t("pq")*t("mn") * temptt
00864             + p               * tempp
00865             + w               * tempw );
00866                 
00867     ret.null_indices();
00868     return ret;
00869   }
00870 
00871 
00872 //--//##############################################################################
00873 //--// trying to find intersection point
00874 //--// according to M. Crisfield's book
00875 //--// " Non-linear Finite Element Analysis of Solids and Structures "
00876 //--// chapter 6.6.1 page 168.
00877 //--stresstensor stresstensor::yield_surface_cross(stresstensor & end_stress,
00878 //--                                               Material_Model & YC)
00879 //--{
00880 //--// bounds
00881 //--  double x1 = 0.0;
00882 //--  double x2 = 1.0;
00883 //--// accuracy
00884 //--  double const TOL = 1.0e-9;
00885 //--  double a = zbrentstress( *this, end_stress, YC, x1, x2, TOL );
00886 //--//  ::printf("\n****\n a = %lf \n****\n",a);
00887 //--  stresstensor delta_stress = end_stress - *this;
00888 //--  stresstensor intersection_stress = *this + delta_stress * a;
00889 //--//***  intersection_this->reportshort("FINAL Intersection stress\n");
00890 //--
00891 //--  return intersection_stress;
00892 //--
00893 //--}
00894 
00895 //##############################################################################
00896 stresstensor stresstensor::pqtheta2stress( double p, double q, double theta)
00897   {
00898     stresstensor ret;
00899 //    ret.report("ret");
00900 //    double sqrtJ2D = q/3.0;
00901 //    double 2osqrt3 = 2.0/sqrt(3.0);
00902     double temp = q*TWOOVERTHREE;
00903 
00904 //    while ( theta >= 2.0*PI )
00905 //      theta = theta - 2.0*PI; // if bigger than full cycle
00906 //    while ( theta >= 4.0*PI/3.0 )
00907 //      theta = theta - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00908 //    while ( theta >= 2.0*PI/3.0 )
00909 //      theta = theta - 2.0*PI/3.0; // if bigger than two third of half cycle
00910 //    while ( theta >= PI/3.0 )
00911 //      theta = 2.0*PI/3.0 - theta; // if bigger than one third of half cycle
00912 
00913     double ct  = cos( theta  );
00914     double ctm = cos( theta - TWOOVERTHREE*PI );
00915     double ctp = cos( theta + TWOOVERTHREE*PI );
00916 
00917     ret.val(1,1) = temp*ct  - p;
00918     ret.val(2,2) = temp*ctm - p;
00919     ret.val(3,3) = temp*ctp - p;
00920 
00921 //    ret.report("ret");
00922     return ret;
00923 
00924   }
00925 
00926 //##############################################################################
00927 void stresstensor::report(char * msg) const
00928   {
00929     ::printf("****************  stress tensor report ****************\n");
00930     if ( msg ) ::printf("%s",msg);
00931 
00932     this->print("st","stresstensor st");
00933 
00934     ::fprintf(stdout,"I1 = %.8e ; I2 = %.8e ; I3 = %.8e ;\n",
00935               Iinvariant1(),Iinvariant2(),Iinvariant3());
00936 
00937     fprintf(stdout,"st_trace = %.8e,  mean pressure p = %.8e\n ",
00938              trace(),  trace()/3.0);
00939 
00940     BJtensor I2("I", 2, def_dim_2);
00941 
00942     stresstensor st_vol = I2 * trace() * (1./3.);
00943     st_vol.print("st_v","tensor st_vol (volumetric part of the st tensor)");
00944 
00945     stresstensor st_dev = this->deviator();   // - st_vol;
00946     st_dev.print("st_d","tensor st_dev (stress deviator)");
00947 
00948     ::fprintf(stdout,"J1 = %.8e ; J2 = %.8e ; J3 = %.8e ;\n",
00949               Jinvariant1(),Jinvariant2(),Jinvariant3());
00950 //...  stresstensor Jinv2 = st_dev("ij")*st_dev("ji")*0.5;
00951 
00952     stresstensor st_principal = principal();
00953     st_principal.print("st_p","principal stress tensor");
00954 
00955 
00956     ::fprintf(stdout,"sig_oct = %.8e  , tau_oct = %.8e\n",
00957               sigma_octahedral(), tau_octahedral());
00958 
00959 
00960     ::printf("ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
00961               ksi(),       ro(),      theta());
00962 
00963     ::printf("p=%.12e , q=%.12e , theta=%.12e*PI\n",
00964               p_hydrostatic(), q_deviatoric(), thetaPI());
00965 
00966     if ( msg ) ::printf("%s",msg);
00967     ::printf("############  end of stress tensor report ############\n");
00968   }
00969 
00970 
00971 //##############################################################################
00972 void stresstensor::reportshort(char * msg) const
00973   {
00974 //..    ::printf("\n** short stress tensor report ****************\n");
00975 //    if ( msg ) ::printf("** %s",msg);
00976 
00977     this->print("st"," ");
00978 //    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
00979 //              ksi(),       ro(),      theta());
00980 //    ::printf(" p=%.8e  q=%.8e  theta=%.8e\n",
00981 //              p_hydrostatic(), q_deviatoric(), theta() );
00982   }
00983 
00984 //##############################################################################
00985 void stresstensor::reportshortpqtheta(char * msg) const
00986   {
00987 //..    ::printf("\n** short stress tensor report ****************\n");
00988     if ( msg ) ::printf("%s",msg);
00989 
00990 //..    this->print("st","stresstensor st");
00991 //..    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
00992 //..              ksi(),       ro(),      theta());
00993 
00994     double p = p_hydrostatic();
00995     double q = q_deviatoric();
00996     double t = theta();
00997     ::printf(" p= %+.6e q= %+.6e theta= %+.6e \n", p, q, t);
00998   }
00999 //##############################################################################
01000 void stresstensor::reportSHORTpqtheta(char * msg) const
01001   {
01002 //..    ::printf("\n** short stress tensor report ****************\n");
01003     if ( msg ) ::printf("%s",msg);
01004 
01005 //..    this->print("st","stresstensor st");
01006 //..    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
01007 //..              ksi(),       ro(),      theta());
01008 
01009     double p = p_hydrostatic();
01010     double q = q_deviatoric();
01011     double t = theta();
01012     ::printf(" p= %+.6e q= %+.6e theta= %+.6e ", p, q, t);
01013   }
01014 //##############################################################################
01015 void stresstensor::reportSHORTs1s2s3(char * msg) const
01016   {
01017 //..    ::printf("\n** short stress tensor report ****************\n");
01018     if ( msg ) ::printf("%s",msg);
01019 
01020 //..    this->print("st","stresstensor st");
01021 //..    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
01022 //..              ksi(),       ro(),      theta());
01023 
01024     this->print("st","");
01025   }
01026 //##############################################################################
01027 void stresstensor::reportKLOTpqtheta(char * msg) const
01028   {
01029 //..    ::printf("\n** short stress tensor report ****************\n");
01030     if ( msg ) ::printf("%s",msg);
01031 
01032 //..    this->print("st","stresstensor st");
01033 //..    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
01034 //..              ksi(),       ro(),      theta());
01035 
01036     double p = p_hydrostatic();
01037     double q = q_deviatoric();
01038     double t = theta();
01039     ::printf(" %+.6e %+.6e %+.6e  ", p, q, t);
01040   }
01041 //##############################################################################
01042 void stresstensor::reportshortI1J2J3(char * msg) const
01043   {
01044 //..    ::printf("\n** short stress tensor report ****************\n");
01045     if ( msg ) ::printf("%s",msg);
01046 
01047 //..    this->print("st","stresstensor st");
01048 //..    ::printf("** ksi = %.8e ,  ro = %.8e , theta = %.8e\n",
01049 //..              ksi(),       ro(),      theta());
01050 
01051     double I1 = Iinvariant1();
01052     double J2 = Jinvariant2();
01053     double J3 = Jinvariant3();
01054     ::printf(" I1= %.6e J2= %.6e J3= %.6e \n", I1, J2, J3);
01055   }
01056 //##############################################################################
01057 void stresstensor::reportAnim(void) const
01058   {
01059     ::printf("Anim p= %f ; q= %f ; theta= %f  \n",
01060               p_hydrostatic(), q_deviatoric(), theta());
01061   }
01062 //##############################################################################
01063 void stresstensor::reportTensor(char * msg) const
01064   {
01065 //..    ::printf("\n** short stress tensor report ****************\n");
01066     if ( msg ) ::printf("%s",msg);
01067 
01068     ::fprintf(stdout," %+.6e %+.6e %+.6e %+.6e %+.6e %+.6e \n",
01069                       this->cval(1,1),
01070                       this->cval(1,2),
01071                       this->cval(1,3),
01072                       this->cval(2,2),
01073                       this->cval(2,3),
01074                       this->cval(3,3));
01075   }
01076 
01077 
01078 //##############################################################################
01079 OPS_Stream& operator<< (OPS_Stream& os, const stresstensor & rhs)
01080 //ostream& operator<< (ostream& os, const stresstensor & rhs)
01081       {
01082         //if ( msg ) ::printf("%s",msg);
01083     
01084         //      os.setf( ios::showpos | ios::scientific);
01085 
01086         os.precision(4);
01087         os.width(10);
01088 
01089         //os << endlnn;
01090         //os << rhs.cval(1,1) << "  ";
01091         //os.width(10);
01092         //os << rhs.cval(1,2) << "  ";
01093         //os.width(10);
01094         //os << rhs.cval(1,3) << endlnn;
01095         //os << rhs.cval(2,1) << "  ";
01096         //os.width(10);
01097         //os << rhs.cval(2,2) << "  ";
01098         //os.width(10);
01099         //os << rhs.cval(2,3) << endlnn;
01100         //
01101         //os << rhs.cval(3,1) << "  ";
01102         //os.width(10);
01103         //os << rhs.cval(3,2) << "  ";
01104         //os.width(10);
01105         //os << rhs.cval(3,3) << endlnn;
01106         
01107         os.width(10);
01108         //os << "p = " << rhs.p_hydrostatic();
01109         os << " "<< rhs.p_hydrostatic();
01110         os.width(10);
01111         //os << " q = " << rhs.q_deviatoric();
01112         os << " " << rhs.q_deviatoric();
01113         os.width(10);
01114         //os << " theta = " << rhs.theta();
01115 
01116         return os;
01117      }
01118 
01119 
01120 
01121 
01122 #endif
01123 

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