MultiaxialCyclicPlasticity.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** ****************************************************************** */
00015                                                                         
00016  
00017 /*----+----+----+----+----+----+----+----+----+----+----+----+----+----+----*
00018  |                                                                          | 
00019  |              MultiaxialCyclicPlasticity  NDMaterial                      |
00020  +                                                                          +
00021  |--------------------------------------------------------------------------|
00022  |                                                                          |
00023  +             Authors: Gang Wang  AND  Professor Nicholas Sitar            +
00024  |                                                                          |
00025  |                         Department of Civil and Environmental Engineering            |
00026  +                         Univeristy of California, Berkeley, CA 94720, USA            +
00027  |                                                                          |
00028  |             Email: wang@ce.berkeley.edu (G.W.)                           |
00029  +                                                                          + 
00030  |  Disclaimers:                                                            |
00031  |  (1) This is implemenation of MultiaxialCyclicPlasticity for clays       |
00032  +      Model References:                                                   +
00033  |      Borja R.I, Amies, A.P. Multiaxial Cyclic Plasticity Model for       |
00034  |            Clays, ASCE J. Geotech. Eng. Vol 120, No 6, 1051-1070         |
00035  +      Montans F.J, Borja R.I. Implicit J2-bounding Surface Plasticity     +    
00036  |            using Prager's translation rule. Int. J. Numer. Meth. Engng.  |
00037  |            55:1129-1166, 2002                                            |
00038  +      Code References:                                                    +
00039  |      Ignacio Romero and Adrian Rodriguez Marek, Brick element model with |
00040  |            a Multiaxial Cyclic Plasticity Model, in GEOFEAP, UC Berkeley |
00041  +  (2) Questions regarding this code should be directed to Gang Wang       +
00042  |  (3) Documentation could be found at                                     |
00043  |        www.ce.berkeley.edu/~wang/papers/MultiaxialCyclicPlasticity.pdf   |
00044  +                                                                          +
00045  |  Development History:                                                    |
00046  |  First Draft   -- April 2004                                             |
00047  +  Rewrite       -- Nov   2004                                             + 
00048  |  Final Release --                                                        |
00049  |                                                                          | 
00050  +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----*/
00051 
00052 
00053 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00054   
00055                               User Command
00056 
00057    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00058     nDMaterial MultiaxialCyclicPlasticity $tag, $rho, $K, $G,
00059                                               $Su , $Ho , $h, $m, $beta, $KCoeff
00060    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00061    where: 
00062       tag   : tag for this material
00063           rho   : density
00064           K     : buck modulus
00065           G     : maximum (small strain) shear modulus
00066           Su    : undrained shear strength, size of bounding surface R=sqrt(8/3)*Su
00067           Ho    : linear kinematic hardening modulus of bounding surface
00068           h     : hardening parameter
00069           m     : hardening parameter
00070           beta  : integration parameter, usually beta=0.5
00071           KCoeff: coefficient of earth pressure, K0
00072 
00073   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00074 
00075 
00076 #include <math.h>
00077 #include <MultiaxialCyclicPlasticity.h>
00078 #include <MultiaxialCyclicPlasticity3D.h> 
00079 #include <MultiaxialCyclicPlasticityAxiSymm.h>
00080 #include <MultiaxialCyclicPlasticityPlaneStrain.h>
00081 #include <Information.h>
00082 
00083 #include <Channel.h>
00084 #include <FEM_ObjectBroker.h>
00085 
00086 //this is mike's problem
00087 Tensor MultiaxialCyclicPlasticity :: rank2(2, def_dim_2, 0.0 ) ;
00088 Tensor MultiaxialCyclicPlasticity :: rank4(2, def_dim_2, 0.0 ) ;
00089 
00090 //parameters
00091 const double MultiaxialCyclicPlasticity :: one3   = 1.0 / 3.0 ;
00092 const double MultiaxialCyclicPlasticity :: two3   = 2.0 / 3.0 ;
00093 const double MultiaxialCyclicPlasticity :: four3  = 4.0 / 3.0 ;
00094 const double MultiaxialCyclicPlasticity :: root23 = sqrt( 2.0 / 3.0 ) ;
00095 const double MultiaxialCyclicPlasticity :: infinity  = 1.0e12;
00096 
00097 double MultiaxialCyclicPlasticity::initialTangent[3][3][3][3] ;   //material tangent
00098 double MultiaxialCyclicPlasticity::IIdev[3][3][3][3] ; //rank 4 deviatoric 
00099 double MultiaxialCyclicPlasticity::IbunI[3][3][3][3] ; //rank 4 I bun I 
00100 
00101 int MultiaxialCyclicPlasticity::MaterialStageID = 2;   // classwide load stage tag, 
00102                                                        // elasto-plastic by default
00103 int MultiaxialCyclicPlasticity::IncrFormulationFlag=1;
00104 
00105 
00106 //zero internal variables
00107 void MultiaxialCyclicPlasticity :: initialize ( ) 
00108 {
00109   stress.Zero();
00110   strain.Zero();
00111   stress_n.Zero();
00112   strain_n.Zero();
00113   backs.Zero();                  // back stress fopr BS
00114   backs_n.Zero(); 
00115   so.Zero();                     // reversal deviatoric back stress
00116   so_n.Zero();
00117   
00118 
00119   // some flags
00120 
00121   flagjustunload=0;
00122   flagfirstload=0;
00123   icounter=0;
00124   iternum=0;
00125   plasticflag=0;
00126   plasticflag_n=0;
00127  
00128   // initialize s0 and kappa
00129   kappa = infinity;
00130   Psi   = 2 * shear;
00131   load  = 0.0; 
00132   //opserr<<"MCP::debug128: kappa = "<< kappa <<endln;
00133   X[1] = 2 * shear;
00134   X[2] = kappa;
00135   alp=0;
00136 }
00137 
00138 
00139 //null constructor
00140 MultiaxialCyclicPlasticity ::  MultiaxialCyclicPlasticity( ) : 
00141 NDMaterial( ), stress(3,3), strain(3,3),
00142 stress_n(3,3), strain_n(3,3), backs(3,3), backs_n(3,3), so(3,3), so_n(3,3)
00143 { 
00144   bulk        = 0.0 ;
00145   shear       = 0.0 ;
00146   bulk_K0     = 0.0 ;
00147   shear_K0    = 0.0 ;
00148   eta         = 0.0 ;
00149 
00150   density     = 0.0 ; 
00151 
00152   this->initialize( ) ;     // or (*this).zero( ) 
00153 
00154   int i, j, k, l ;
00155 
00156   //zero rank4 IIdev and IbunI 
00157   for ( i = 0; i < 3; i++ ) {
00158     for ( j = 0; j < 3; j++ )  {
00159       for ( k = 0; k < 3; k++ ) {
00160                 for ( l = 0; l < 3; l++)  { 
00161 
00162                   IbunI[i][j][k][l] = 0.0 ;
00163 
00164                   IIdev[i][j][k][l] = 0.0 ;
00165 
00166                 } // end for l
00167       } // end for k
00168     } // end for j
00169   } // end for i
00170 
00171 
00172   //form rank4 IbunI 
00173 
00174   IbunI [0][0] [0][0] = 1.0 ;
00175   IbunI [0][0] [1][1] = 1.0 ;
00176   IbunI [0][0] [2][2] = 1.0 ;
00177   IbunI [1][1] [0][0] = 1.0 ;
00178   IbunI [1][1] [1][1] = 1.0 ;
00179   IbunI [1][1] [2][2] = 1.0 ;
00180   IbunI [2][2] [0][0] = 1.0 ;
00181   IbunI [2][2] [1][1] = 1.0 ;
00182   IbunI [2][2] [2][2] = 1.0 ;
00183 
00184   //form rank4 IIdev
00185 
00186   IIdev [0][0] [0][0] =  two3 ; // 0.666667 
00187   IIdev [0][0] [1][1] = -one3 ; //-0.333333 
00188   IIdev [0][0] [2][2] = -one3 ; //-0.333333 
00189   IIdev [0][1] [0][1] = 0.5 ;
00190   IIdev [0][1] [1][0] = 0.5 ;
00191   IIdev [0][2] [0][2] = 0.5 ;
00192   IIdev [0][2] [2][0] = 0.5 ;
00193   IIdev [1][0] [0][1] = 0.5 ;
00194   IIdev [1][0] [1][0] = 0.5 ;
00195   IIdev [1][1] [0][0] = -one3 ; //-0.333333 
00196   IIdev [1][1] [1][1] =  two3 ; // 0.666667 
00197   IIdev [1][1] [2][2] = -one3 ; //-0.333333 
00198   IIdev [1][2] [1][2] = 0.5 ;
00199   IIdev [1][2] [2][1] = 0.5 ;
00200   IIdev [2][0] [0][2] = 0.5 ;
00201   IIdev [2][0] [2][0] = 0.5 ;
00202   IIdev [2][1] [1][2] = 0.5 ;
00203   IIdev [2][1] [2][1] = 0.5 ;
00204   IIdev [2][2] [0][0] = -one3 ; //-0.333333 
00205   IIdev [2][2] [1][1] = -one3 ; //-0.333333 
00206   IIdev [2][2] [2][2] =  two3 ; // 0.666667 
00207 }
00208 
00209 
00210 //full constructor
00211 MultiaxialCyclicPlasticity::MultiaxialCyclicPlasticity(int    tag,
00212                                                        int    classTag,
00213                                                        double rho,
00214                                                        double K,
00215                                                        double G,
00216                                                        double Su,
00217                                                        double Ho_kin,
00218                                                        double Parameter_h,
00219                                                        double Parameter_m,
00220                                                        double Parameter_beta,
00221                                                        double Kcoeff,
00222                                                        double viscosity)
00223   : NDMaterial(tag, ND_TAG_MultiaxialCyclicPlasticity),
00224     stress(3,3), strain(3,3), stress_n(3,3), strain_n(3,3), 
00225     backs(3,3), backs_n(3,3), so(3,3), so_n(3,3)
00226 {
00227   density     = rho; 
00228   bulk        = K ;
00229   shear       = G ;
00230   R           = sqrt(8.0/3.0)*Su;
00231   //opserr<<"MCP::235 R= "<<R <<endln; 
00232   Ho          = Ho_kin;        // kinematic hardening modulus
00233   h                       = Parameter_h; 
00234   m           = Parameter_m ;
00235   beta        = Parameter_beta ;
00236   eta         = viscosity ;
00237  
00239   K0 = Kcoeff;
00240   // Poisson's ratio v=K0/(1+K0)
00241   double v = K0 /(1+K0); 
00242   double E = 9 * bulk * shear / (3*bulk+shear);
00243   // compute shear and bulk modulus for K0 consolidation, cf. Fung, p.141
00244   shear_K0 =  E /(2*(1+v));
00245   bulk_K0  =  E/(3*(1-2*v));
00247   
00248   if (tag==200) { // to be a fluid
00249           v = 0.499;
00250       shear_K0 =  1;
00251       bulk_K0  *=  1000;
00252   }
00253 
00254   this->initialize( ) ;
00255 
00256   int i, j, k, l ;
00257 
00258   //zero rank4 IIdev and IbunI 
00259   for ( i = 0; i < 3; i++ ) {
00260     for ( j = 0; j < 3; j++ ) {
00261       for ( k = 0; k < 3; k++ ) {
00262                 for ( l = 0; l < 3; l++)  { 
00263 
00264                   IbunI[i][j][k][l] = 0.0 ;
00265 
00266                   IIdev[i][j][k][l] = 0.0 ;
00267 
00268                 } // end for l
00269       } // end for k
00270     } // end for j
00271   } // end for i
00272 
00273 
00274   //form rank4 IbunI 
00275 
00276   IbunI [0][0] [0][0] = 1.0 ;
00277   IbunI [0][0] [1][1] = 1.0 ;
00278   IbunI [0][0] [2][2] = 1.0 ;
00279   IbunI [1][1] [0][0] = 1.0 ;
00280   IbunI [1][1] [1][1] = 1.0 ;
00281   IbunI [1][1] [2][2] = 1.0 ;
00282   IbunI [2][2] [0][0] = 1.0 ;
00283   IbunI [2][2] [1][1] = 1.0 ;
00284   IbunI [2][2] [2][2] = 1.0 ;
00285 
00286   //form rank4 IIdev
00287 
00288   IIdev [0][0] [0][0] =  two3 ; // 0.666667 
00289   IIdev [0][0] [1][1] = -one3 ; //-0.333333 
00290   IIdev [0][0] [2][2] = -one3 ; //-0.333333 
00291   IIdev [0][1] [0][1] = 0.5 ;
00292   IIdev [0][1] [1][0] = 0.5 ;
00293   IIdev [0][2] [0][2] = 0.5 ;
00294   IIdev [0][2] [2][0] = 0.5 ;
00295   IIdev [1][0] [0][1] = 0.5 ;
00296   IIdev [1][0] [1][0] = 0.5 ;
00297   IIdev [1][1] [0][0] = -one3 ; //-0.333333 
00298   IIdev [1][1] [1][1] =  two3 ; // 0.666667 
00299   IIdev [1][1] [2][2] = -one3 ; //-0.333333 
00300   IIdev [1][2] [1][2] = 0.5 ;
00301   IIdev [1][2] [2][1] = 0.5 ;
00302   IIdev [2][0] [0][2] = 0.5 ;
00303   IIdev [2][0] [2][0] = 0.5 ;
00304   IIdev [2][1] [1][2] = 0.5 ;
00305   IIdev [2][1] [2][1] = 0.5 ;
00306   IIdev [2][2] [0][0] = -one3 ; //-0.333333 
00307   IIdev [2][2] [1][1] = -one3 ; //-0.333333 
00308   IIdev [2][2] [2][2] =  two3 ; // 0.666667 
00309 }
00310 
00311 
00312 //elastic constructor
00313 MultiaxialCyclicPlasticity :: 
00314 MultiaxialCyclicPlasticity(  int tag, int classTag, 
00315                                                    double rho, double K, double G ) 
00316 :NDMaterial(tag, classTag),
00317 stress(3,3), strain(3,3), stress_n(3,3), strain_n(3,3), 
00318 backs(3,3), backs_n(3,3), so(3,3), so_n(3,3)
00319 { 
00320   density     = rho; 
00321   bulk        = K ;
00322   shear       = G ; 
00323   bulk_K0     = K ;
00324   shear_K0    = G ; 
00325   eta         = 0.0 ;
00326 
00327   this->initialize( ) ;
00328 
00329   int i, j, k, l ;
00330 
00331   //zero rank4 IIdev and IbunI 
00332   for ( i = 0; i < 3; i++ ) {
00333     for ( j = 0; j < 3; j++ )  {
00334       for ( k = 0; k < 3; k++ ) {
00335                 for ( l = 0; l < 3; l++)  { 
00336 
00337                   IbunI[i][j][k][l] = 0.0 ;
00338 
00339                   IIdev[i][j][k][l] = 0.0 ;
00340 
00341                 } // end for l
00342       } // end for k
00343     } // end for j
00344   } // end for i
00345 
00346 
00347   //form rank4 IbunI 
00348 
00349   IbunI [0][0] [0][0] = 1.0 ;
00350   IbunI [0][0] [1][1] = 1.0 ;
00351   IbunI [0][0] [2][2] = 1.0 ;
00352   IbunI [1][1] [0][0] = 1.0 ;
00353   IbunI [1][1] [1][1] = 1.0 ;
00354   IbunI [1][1] [2][2] = 1.0 ;
00355   IbunI [2][2] [0][0] = 1.0 ;
00356   IbunI [2][2] [1][1] = 1.0 ;
00357   IbunI [2][2] [2][2] = 1.0 ;
00358 
00359   //form rank4 IIdev
00360 
00361   IIdev [0][0] [0][0] =  two3 ; // 0.666667 
00362   IIdev [0][0] [1][1] = -one3 ; //-0.333333 
00363   IIdev [0][0] [2][2] = -one3 ; //-0.333333 
00364   IIdev [0][1] [0][1] = 0.5 ;
00365   IIdev [0][1] [1][0] = 0.5 ;
00366   IIdev [0][2] [0][2] = 0.5 ;
00367   IIdev [0][2] [2][0] = 0.5 ;
00368   IIdev [1][0] [0][1] = 0.5 ;
00369   IIdev [1][0] [1][0] = 0.5 ;
00370   IIdev [1][1] [0][0] = -one3 ; //-0.333333 
00371   IIdev [1][1] [1][1] =  two3 ; // 0.666667 
00372   IIdev [1][1] [2][2] = -one3 ; //-0.333333 
00373   IIdev [1][2] [1][2] = 0.5 ;
00374   IIdev [1][2] [2][1] = 0.5 ;
00375   IIdev [2][0] [0][2] = 0.5 ;
00376   IIdev [2][0] [2][0] = 0.5 ;
00377   IIdev [2][1] [1][2] = 0.5 ;
00378   IIdev [2][1] [2][1] = 0.5 ;
00379   IIdev [2][2] [0][0] = -one3 ; //-0.333333 
00380   IIdev [2][2] [1][1] = -one3 ; //-0.333333 
00381   IIdev [2][2] [2][2] =  two3 ; // 0.666667 
00382 }
00383 
00384 
00385 //destructor
00386 MultiaxialCyclicPlasticity :: ~MultiaxialCyclicPlasticity( ) 
00387 {  } 
00388 
00389 
00390 NDMaterial*
00391 MultiaxialCyclicPlasticity :: getCopy (const char *type)
00392 {
00393     if (strcmp(type,"PlaneStress2D") == 0 || strcmp(type,"PlaneStress") == 0)
00394     {
00395     opserr << "MultiaxialCyclicPlasticity type plane stress material is NOT available now....";
00396         return 0;
00397     }
00398     else if (strcmp(type,"PlaneStrain2D") == 0 || strcmp(type,"PlaneStrain") == 0)
00399     {
00400         MultiaxialCyclicPlasticityPlaneStrain  *clone ;
00401         clone = new MultiaxialCyclicPlasticityPlaneStrain(this->getTag(), density, bulk, shear, sqrt(3.0/8.0)*R,
00402                           Ho, h, m, beta, K0, eta) ; 
00403         return clone ;  
00404         }
00405     else if (strcmp(type,"AxiSymmetric2D") == 0 || strcmp(type,"AxiSymmetric") == 0)
00406     {
00407         MultiaxialCyclicPlasticityAxiSymm  *clone ;
00408         clone = new MultiaxialCyclicPlasticityAxiSymm(this->getTag(), density, bulk, shear, sqrt(3.0/8.0)*R,
00409                           Ho, h, m, beta, K0, eta) ; 
00410         return clone ;  
00411         }
00412     else if ((strcmp(type,"ThreeDimensional") == 0) || (strcmp(type,"3D") == 0))
00413     {
00414         MultiaxialCyclicPlasticity3D  *clone ;
00415         clone = new MultiaxialCyclicPlasticity3D(this->getTag(), density, bulk, shear, sqrt(3.0/8.0)*R,
00416                                                  Ho, h, m, beta, K0, eta) ; 
00417         return clone ;  
00418     }
00419     else if ( (strcmp(type,"PlateFiber") == 0) )
00420     {
00421     opserr << "MultiaxialCyclicPlasticity type plate fiber material is NOT available now....";
00422         return 0;
00423     }
00424     // Handle other cases
00425     else
00426     {
00427       opserr << "MultiaxialCyclicPlasticity::getModel failed to get model: " << type << endln;
00428       return 0;
00429     }
00430 }
00431 
00432 //print out material data
00433 void MultiaxialCyclicPlasticity :: Print( OPS_Stream &s, int flag )
00434 {
00435   s << endln ;
00436   s << "MultiaxialCyclicPlasticity : " ; 
00437   s << this->getType( )  << endln ;
00438   s << "K    =   " << bulk        << endln ;
00439   s << "Gmax =   " << shear       << endln ;
00440   s << "Rho  =   " << density     << endln ;
00441   s << "R    =   " << R           << endln ;
00442   s << "Ho   =   " << Ho          << endln ;
00443   s << "h    =   " << h           << endln ;
00444   s << "m    =   " << m           << endln ;
00445   s << "beta =   " << beta        << endln ;
00446   s << "eta  =   " << eta         << endln ;
00447   s << endln ;
00448 }
00449 
00450 
00451 void MultiaxialCyclicPlasticity :: elastic_integrator( )
00452 {
00453   static Matrix dev_strain(3,3) ; //deviatoric strain  
00454 
00455   static Matrix dev_stress(3,3) ; //deviatoric stress
00456 
00457   // add
00458   double pressure;                // 1/3 trace(stress) 
00459 
00460   double trace = 0.0 ; //trace of strain
00461 
00462   int i,j,k,l;
00463   int ii, jj ; 
00464 
00465 
00466   if (IncrFormulationFlag==0){
00467 
00468   trace = strain(0,0) + strain(1,1) + strain(2,2) ;
00469   
00470   //compute the deviatoric strains
00471   dev_strain = strain ;
00472 
00473   for ( i = 0; i < 3; i++ )
00474    dev_strain(i,i) -= ( one3*trace ) ;
00475 
00476   //compute the trial deviatoric stresses
00477   dev_stress = dev_strain;
00478   dev_stress *= 2.0 * shear_K0; 
00479   
00480   // compute the trial pressure    
00481   pressure   = trace ;
00482   pressure  *= bulk_K0 ;                                                 
00483   }
00484 
00485   static Matrix IncrStrain(3,3);
00486 
00487   static Matrix DevStress_n(3,3);
00488 
00489   static double pressure_n;
00490 
00491   if (IncrFormulationFlag==1){
00492    
00493           
00494   // opserr<<"DP::elasticintegrator:stress_n"<<stress_n;
00495   // opserr<<"DP::elasticintegrator:strain_n"<<strain_n;
00496 
00497   IncrStrain = strain;
00498   IncrStrain -= strain_n ;
00499 
00500   trace = IncrStrain(0,0) + IncrStrain(1,1) + IncrStrain(2,2) ;
00501 
00502   dev_strain = IncrStrain ;
00503   for ( i = 0; i < 3; i++ )  dev_strain(i,i) -= ( one3*trace ) ;
00504  
00505   pressure_n  = one3 * (stress_n(0,0)+stress_n(1,1)+stress_n(2,2));
00506   
00507   DevStress_n = stress_n ;
00508   
00509   for ( i = 0; i < 3; i++ )  DevStress_n(i,i) -= pressure_n ;
00510 
00511   // Delta_S = 2*shear*Delta_e
00512   // Delta_p = bulk * Delta_theta
00513   
00514   // incremental formulation, NOTE: now dev_strain and trace are INCREMENTAL strains
00515 
00516   dev_stress = dev_strain;
00517   dev_stress *= 2.0 * shear_K0;
00518   dev_stress += DevStress_n;
00519   
00520   pressure = trace;
00521   pressure *= bulk_K0;
00522   pressure += pressure_n;
00523 
00524   }  
00525   
00526   // add on bulk part of stress, compute TOTAL stress at t=n+1
00527 
00528   stress = dev_stress ;
00529   for ( i = 0; i < 3; i++ )
00530      stress(i,i) += pressure ;
00531 
00532 
00533   //compute the tangent 
00534   
00535   for ( ii = 0; ii < 6; ii++ ) {
00536     for ( jj = 0; jj < 6; jj++ )  {
00537 
00538           index_map( ii, i, j ) ;
00539           index_map( jj, k, l ) ;
00540 
00541           //elastic terms
00542           tangent[i][j][k][l]  = bulk_K0 * IbunI[i][j][k][l] ;
00543 
00544           tangent[i][j][k][l] += (2.0*shear_K0) * IIdev[i][j][k][l] ;
00545 
00546           //minor symmetries 
00547           tangent [j][i][k][l] = tangent[i][j][k][l] ;
00548           tangent [i][j][l][k] = tangent[i][j][k][l] ;
00549           tangent [j][i][l][k] = tangent[i][j][k][l] ;
00550 
00551     } // end for jj
00552   } // end for ii
00553 
00554   flagfirstload=0; // prepare for MCP integrator
00555   
00556   return ;
00557 } 
00558 
00559 
00560 
00561 
00562 // set up for initial elastic
00563 void MultiaxialCyclicPlasticity :: doInitialTangent( )
00564 {
00565   int ii,jj,i,j,k,l;
00566 
00567   //compute the deviatoric strains
00568   for ( ii = 0; ii < 6; ii++ ) {
00569     for ( jj = 0; jj < 6; jj++ )  {
00570 
00571           index_map( ii, i, j ) ;
00572           index_map( jj, k, l ) ;
00573 
00574           //elastic terms
00575           initialTangent[i][j][k][l]  = bulk * IbunI[i][j][k][l] ;
00576           initialTangent[i][j][k][l] += (2.0*shear) * IIdev[i][j][k][l] ;
00577 
00578           //minor symmetries 
00579           initialTangent [j][i][k][l] = initialTangent[i][j][k][l] ;
00580           initialTangent [i][j][l][k] = initialTangent[i][j][k][l] ;
00581           initialTangent [j][i][l][k] = initialTangent[i][j][k][l] ;
00582 
00583     } // end for jj
00584   } // end for ii
00585 
00586   return ;
00587 } 
00588 
00589 
00590 
00591 //matrix_index ---> tensor indices i,j
00592 void MultiaxialCyclicPlasticity :: index_map( int matrix_index, int &i, int &j )
00593 {
00594   switch ( matrix_index+1 ) { //add 1 for standard tensor indices
00595 
00596     case 1 :
00597       i = 1 ; 
00598       j = 1 ;
00599       break ;
00600  
00601     case 2 :
00602       i = 2 ;
00603       j = 2 ; 
00604       break ;
00605 
00606     case 3 :
00607       i = 3 ;
00608       j = 3 ;
00609       break ;
00610 
00611     case 4 :
00612       i = 1 ;
00613       j = 2 ;
00614       break ;
00615 
00616     case 5 :
00617       i = 2 ;
00618       j = 3 ;
00619       break ;
00620 
00621     case 6 :
00622       i = 3 ;
00623       j = 1 ;
00624       break ;
00625 
00626 
00627     default :
00628       i = 1 ;
00629       j = 1 ;
00630       break ;
00631 
00632   } //end switch
00633 
00634 i-- ; //subtract 1 for C-indexing
00635 j-- ;
00636 
00637 return ; 
00638 }
00639 
00640 
00641 NDMaterial*
00642 MultiaxialCyclicPlasticity::getCopy (void)
00643 {
00644   opserr << "MultiaxialCyclicPlasticity::getCopy -- subclass responsibility\n"; 
00645   exit(-1);
00646   return 0;
00647 }
00648 
00649 const char*
00650 MultiaxialCyclicPlasticity::getType (void) const
00651 {
00652     opserr << "MultiaxialCyclicPlasticity::getType -- subclass responsibility\n";
00653     exit(-1);
00654     return 0;
00655 }
00656 
00657 int
00658 MultiaxialCyclicPlasticity::getOrder (void) const
00659 {
00660     opserr << "MultiaxialCyclicPlasticity::getOrder -- subclass responsibility\n";
00661     exit(-1);
00662     return 0;
00663 }
00664 
00665 
00666 int 
00667 MultiaxialCyclicPlasticity::commitState( ) 
00668 {
00669  
00670   stress_n   = stress;     // april 2, 2004
00671   strain_n   = strain;     // april 2, 2004
00672 
00673   backs_n    = backs;
00674   so_n       = so; 
00675  
00676   Psi   = X[1];
00677   kappa = X[2];
00678 
00679   plasticflag_n=plasticflag;
00680   if (plasticflag==2 ){
00681           plasticflag_n=1;
00682   }
00683 
00684   iternum=0;   // reset global newton iteration counter
00685   return 0;
00686 
00687 }
00688 
00689 
00690 int 
00691 MultiaxialCyclicPlasticity::revertToLastCommit( ) 
00692 {
00693   return 0;
00694 }
00695 
00696 
00697 int 
00698 MultiaxialCyclicPlasticity::revertToStart( ) {
00699 
00700   this->initialize( ) ;
00701 
00702   return 0;
00703 }
00704 
00705 int
00706 MultiaxialCyclicPlasticity::sendSelf(int commitTag, Channel &theChannel)
00707 {
00708   // we place all the data needed to define material and it's state
00709   // int a vector object
00710   static Vector data(10); 
00711   int cnt = 0;
00712   data(cnt++) = this->getTag();
00713   data(cnt++) = density;   //add
00714   data(cnt++) = bulk;
00715   data(cnt++) = shear;
00716   data(cnt++) = R;   //add
00717   data(cnt++) = Ho;   //add
00718   data(cnt++) = h;
00719   data(cnt++) = m;
00720   data(cnt++) = beta;
00721   data(cnt++) = eta;
00722  
00723   // send the vector object to the channel
00724   if (theChannel.sendVector(this->getDbTag(), commitTag, data) < 0) {
00725     opserr << "MultiaxialCyclicPlasticity::sendSelf - failed to send vector to channel\n";
00726     return -1;
00727   }
00728 
00729   return 0;
00730 }
00731 
00732 int
00733 MultiaxialCyclicPlasticity::recvSelf (int commitTag, Channel &theChannel, 
00734                          FEM_ObjectBroker &theBroker)
00735 {
00736 
00737   // recv the vector object from the channel which defines material param and state
00738   static Vector data(10);
00739   if (theChannel.recvVector(this->getDbTag(), commitTag, data) < 0) {
00740     opserr << "MultiaxialCyclicPlasticity::recvSelf - failed to recv vector from channel\n";
00741     return -1;
00742   }
00743 
00744   // set the material parameters and state variables
00745   int cnt = 0;
00746   this->setTag(data(cnt++));
00747   density = data(cnt++);
00748   bulk    = data(cnt++);
00749   shear   = data(cnt++);
00750   R       = data(cnt++);
00751   Ho      = data(cnt++);
00752   h       = data(cnt++);
00753   m       = data(cnt++);
00754   beta    = data(cnt++);
00755   eta     = data(cnt++);
00756   
00757  
00758   return 0;
00759 }
00760 
00761 
00762 
00763 
00764 
00765 double 
00766 MultiaxialCyclicPlasticity::getRho()
00767 {  
00768    return density; 
00769 }
00770 
00771 
00772 
00773 int MultiaxialCyclicPlasticity::updateParameter(int responseID, Information &info)
00774 {
00775 
00776   // not finished
00777   this-> MaterialStageID = responseID;
00778    return 0;
00779 }
00780 
00781 
00782 // GEOFEAP subroutine model34(d,eps,sig,cc,cee,hn,h1,nhv,isw,n)
00783 void MultiaxialCyclicPlasticity::plastic_integrator()
00784 { 
00785 
00786   int unloadflag;
00787 
00788   // toleraces
00789 
00790   static double ZERO      = 1.0e-16; 
00791 
00792   static double zerotol   = 1.0e-10;    // tol for zeroloading...||de||<zerotol
00793   static double tolforload= 1.0e-10;     // tol to determine loading/unloading
00794   static double tolforX   = 1.0e-6;;       // tol for compute norm g1g2 in iteration X[1], X[2]
00795   
00796   double twomu; 
00797   int ii,jj;              // for loop iterators
00798   int i,j,k,l;
00799 
00800   static Matrix de(3,3) ;   //incremental deviatoric strain  
00801   static Matrix  s(3,3) ;   //deviatoric stress
00802  // add
00803   static double p;          // pressure, 1/3 trace(stress) 
00804   static double e;          // incr. vol.strain, trace(incremental strains)
00805 
00806   static Matrix IncrStrain(3,3); // Frank let all Matrix be static
00807   static Matrix s_n(3,3);        // dev. stress at t_n 
00808   static double p_n;             // pressure at t_n
00809   //static Matrix soinit(3,3);   // save s0_n here
00810   double normchi=0;
00811   static Matrix strial(3,3);
00812   static Matrix chitri(3,3);
00813   static Matrix alpha_n(3,3); // backstress of loading surface at t_n
00814   static double  Psi_split; // Psi for strain split step
00815   static Matrix temp6(3,3);
00816   static double dottemp6;
00817   double norm = 0;
00818         
00819   double Hn =0;
00820   double Hn1=0;
00821   double ftrial;
00822   double temp;
00823   double normde;
00824   double fn;
00825   int zeroloadflag;
00826   int showdebugInfo;
00827 
00828   showdebugInfo=0;
00829 
00830   Vector debugInfo(10);
00831 
00832   debugInfo.Zero();
00833   for ( i = 0; i < 10; i++ )  debugInfo(i) = -1.0 ;
00834 
00835   unloadflag=0;
00836   zeroloadflag=0;
00837   load = 0;
00838   icounter=0;
00839   flagjustunload = 0;
00840   X[1]=0; X[2]=0;
00841 
00842   iternum++;
00843 
00844   // (0) calculate input incr. strain: (de, e)
00845   //     retrieve stress and stress of t_n step (s_n, p_n)
00846 
00847 
00848   IncrStrain = strain;
00849   IncrStrain -= strain_n ;       // incremental
00850   e  = IncrStrain(0,0) + IncrStrain(1,1) + IncrStrain(2,2) ;
00851   de = IncrStrain ;
00852   for ( i = 0; i < 3; i++ )  de(i,i) -= ( one3*e ) ;
00853  
00854   // compute p and s 
00855   p_n = one3 * (stress_n(0,0)+stress_n(1,1)+stress_n(2,2));
00856   s_n = stress_n ;
00857 
00858   for ( i = 0; i < 3; i++ )  s_n(i,i) -= p_n ;
00859  
00860   flagfirstload++;
00861 
00862   // initialize so_n if it is a very first call of this routine
00863   if (flagfirstload==1){
00864           //opserr<<"MCP::firstload"<<endln;
00865           so_n=s_n;
00866           so=so_n;
00867           backs_n=s_n;
00868           kappa=infinity;
00869           Psi=2*shear;
00870           plasticflag=0;
00871           X[1]=2*shear;
00872           X[2]=infinity;
00873           debugInfo(1)=1;
00874           goto LABEL10;
00875   }
00876 
00877   so=so_n;
00878 
00879 
00880   // normde=||de||
00881   normde=0;
00882   for ( i = 0; i < 3; i++ ){
00883           for ( j = 0; j < 3; j++ ) {
00884                   normde += de(i,j)*de(i,j) ;
00885           }
00886   } //end for i 
00887 
00888   if (normde >= 0.0) {
00889           normde=sqrt(normde); 
00890   } else {
00891           opserr<<"MCP:1061:problem!!"<<endln;
00892   }
00893 
00894   if (normde<=zerotol)
00895   {
00896           X[1] = 2*shear;
00897       X[2] = infinity;
00898           plasticflag=0;
00899           load = 1000; 
00900           zeroloadflag=1;
00901           debugInfo(1)=2;
00902           //opserr<<"MCP::small strain incr" <<endln;
00903           goto LABEL10;
00904   }
00905   MCPparameter(9) = normde ;
00906 
00907 
00908 
00909   //(1) Solve Kappa_n from s_n 
00910   //    assign plasticflag_n
00911 
00912    double kappasave;
00913    int plasticflagsave;
00914 
00915    kappasave=kappa;  // this kappa is obtained from previous solution of X[2]
00916    plasticflagsave=plasticflag_n;
00917 
00918    fn=0;
00919 
00920    chitri=s_n-backs_n;
00921    normchi=0;
00922    for ( i = 0; i < 3; i++ ){
00923            for ( j = 0; j < 3; j++ ) {
00924                    normchi += chitri(i,j)*chitri(i,j) ;
00925            }
00926         } //end for i 
00927 
00928     if (normchi >= 0) {
00929           normchi =sqrt(normchi); 
00930         } else {
00931           normchi = 0;
00932       opserr<<"Problem!!"<<endln;
00933         }
00934 
00935         fn = normchi - R;
00936 
00937         if ((fn >=0)&&(plasticflag_n!=1))
00938         {
00939                 opserr<<"MCP::995:strange, fn="<<fn<<" plasticflag_n="<<plasticflag_n<<endln;
00940                 showdebugInfo=1;
00941         }
00942 
00943         if (fn >=0 ){
00944         kappa=0;
00945                 plasticflag_n=1;
00946                 //opserr<<"MCP::tn on yield surface"<<endln;
00947         }
00948         else {
00949 
00950                 plasticflag_n=0;
00951                 // compute kappa from s_n, backs_n, so
00952                 double n1 =0;
00953                 double n2 =0;
00954                 double t1dott2=0;
00955 
00956                 n1=0.0;
00957 
00958                 for ( i = 0; i < 3; i++ ){
00959                         for ( j = 0; j < 3; j++ ) {
00960                                 temp=s_n(i,j)-backs_n(i,j);
00961                             n1 += temp*temp;
00962                         }
00963                 } //end for i 
00964                 
00965                 if (n1 >= 0.0) {
00966                         n1=sqrt(n1); 
00967                 }
00968 
00969                 n2=0.0;
00970                 for ( i = 0; i < 3; i++ ){
00971                         for ( j = 0; j < 3; j++ ) {
00972                 temp=s_n(i,j)-so_n(i,j);
00973                                 n2 += temp*temp  ;
00974                         }
00975                 } //end for i 
00976 
00977                 if (n2 >= 0.0) {
00978                         n2=sqrt(n2); 
00979                 }
00980 
00981                 if (n2==0){ // just unload
00982                         kappa=infinity;
00983                 } else{
00984                         t1dott2=0;
00985                         for ( i = 0; i < 3; i++ ){
00986                                 for ( j = 0; j < 3; j++ ) {
00987                                         t1dott2 += (s_n(i,j)-backs_n(i,j))*(s_n(i,j)-so_n(i,j)) ;
00988                                 }
00989                         } //end for i 
00990                     t1dott2=t1dott2/(n1*n2);
00991 
00992 
00993                     // find kappa directly for t_n    cf Montans Eq. (15)
00994                         //kappa =-n1/n2*t1dott2+sqrt(R*R/n2/n2-n1*n1/n2/n2*(1-t1dott2*t1dott2));
00995                                 
00996  
00997                         // just another formula, cf Borja   Eq. (29), better than Montans!!
00998                         // because Montans requires n1,n2!=0, borja only requires n2!=0
00999                         // which is just unload case for n2=0
01000 
01001                         temp=t1dott2*n1*n2,
01002                         kappa =sqrt(temp*temp+n2*n2*(R*R-normchi*normchi))-t1dott2*n1*n2;
01003                         kappa *=1.0/(n2*n2);
01004 
01005                         if ((fabs(kappa-kappasave)>1e-6)&&((fabs(kappasave)<infinity))){
01006                            // opserr<<"MCP:992 big error in last computed X[2]" <<endln;
01007                         //      opserr<<"MCP:992 kappa-kappaS   ="<<kappa-kappasave   <<endln;  
01008                         //      opserr<<"MCP:992 kappa="<<kappa<<" kappaS="<<kappasave   <<endln;
01009                         }
01010                         
01011                 }
01012                    
01013         }
01014 
01015 
01016    
01017 
01018 
01021         
01022         kappa=kappasave;
01023     //plasticflag_n=plasticflagsave;
01024 
01025 
01026         //(2) compute alpha_n
01027 
01028         for ( i = 0; i < 3; i++ ){
01029                 for ( j = 0; j < 3; j++ ) {
01030                         alpha_n(i,j)= so_n(i,j)+ (backs_n(i,j)-so_n(i,j)) /(1+kappa);
01031                 }
01032         } //end for i 
01033 
01034 
01035 
01036 
01037 
01038         // (3) compute for Psi for t_n
01039 
01040         Hn=h*pow(kappa,m)+Ho; 
01041 
01042         Psi=2.0*shear*(1.0-shear/(shear+Hn/3.0));
01043 
01044         // in general Psi is not equal X[1]. since the latter is secant of
01045         // step n-> n+1, and Psi is secant of step n only
01046 
01047         
01048     Psi_split=2.0*shear*(1.0-shear/(shear+((1-beta)*Hn+beta*Ho)/3.0)); // Gang
01049     //Psi_split=2.0*shear/(1.0+3.0*shear*((1-beta)/Hn+beta/Ho)); // Borja
01050 
01051 
01052 
01053         // (4) check for loading/unloading
01054 
01055   load=0; temp6.Zero(); temp=0;
01056   for ( i = 0; i < 3; i++ ){
01057           for ( j = 0; j < 3; j++ ) {
01058             temp6(i,j) = s_n(i,j)-alpha_n(i,j);
01059         load += temp6(i,j)*de(i,j) ;
01060             temp += temp6(i,j)*temp6(i,j);
01061           }
01062   } //end for i 
01063 
01064   load *= 1.0/(sqrt(temp));
01065 
01066 
01067    if (load < tolforload*normde)  // unloading
01068         {   
01069           if (plasticflag_n==1){
01070                   debugInfo(2)=1;
01071                   //opserr<<"MCP1091::unload checked!! from plastic, load="<<load<<" normde="<<normde<<endln;
01072                   //opserr<<"MCP1091::plasticflag_n="<<plasticflag_n<<endln;
01073                   //opserr<<"MCP1091::fn="<<fn<<" R="<<R<<" load="<<load<<endln;
01074           } else {
01075                   debugInfo(2)=2;
01076                   //opserr<<"MCP1095::unload checked!! within B.S.,  load="<<load<<" normde="<<normde<<endln;
01077                   //opserr<<"MCP1095::plasticflag_n="<<plasticflag_n<<endln;
01078                   //opserr<<"MCP1095::fn="<<fn<<" R="<<R<<" load="<<load<<endln;
01079           }
01080                 
01081                 kappa = infinity ;
01082                 Psi   = 2*shear;
01083                 so = s_n; 
01084                 flagjustunload = 1;   // not used
01085                 unloadflag = 1;  
01086                 X[1] = 2*shear;
01087                 X[2] = infinity;
01088                 //unloadcounter +=1;
01089                 plasticflag=0;     // force it go to plasticflag=0 tangent
01090                 goto LABEL10;
01091                 //goto LABEL6;
01092         }
01093 
01094 
01095   // (5) set plasticflag
01096 
01097 
01098  // begin: check for plastic loading if LAST loading is plastic
01099   if (plasticflag_n==1){    
01100           strial = s_n + 2.0 * shear * de; 
01101           chitri = strial ;
01102           chitri-= backs_n;
01103 
01104           // check yield
01105           normchi = 0 ;
01106           for ( i = 0; i < 3; i++ ){
01107                   for ( j = 0; j < 3; j++ ) {
01108                         normchi += chitri(i,j)*chitri(i,j) ;
01109                   }
01110                 } //end for i 
01111       
01112       // compute normchi
01113           if (normchi >= 0){
01114                   normchi = sqrt(normchi);
01115           } else {
01116                   opserr<<"MCP 1060::Problem, normchi<0"<<endln;
01117           }
01118 
01119           ftrial=normchi-R;
01120           if (ftrial > 0){
01121                   plasticflag=1;
01122                   debugInfo(3)=1;
01123           } else {
01124                   debugInfo(3)=2;
01125                   opserr<<"MCP1419::unload from plastic" <<endln;
01126                   // update plasticflag
01127                   plasticflag = 0;
01128                   kappa = infinity ;
01129                   Psi   = 2*shear;
01130                   so    = s_n;   
01131                   X[1] = 2*shear;
01132                   X[2] = infinity;
01133                   flagjustunload = 1;   // not used
01134                   unloadflag = 1;
01135                   goto LABEL10;
01136                   //goto LABEL6;
01137           }
01138   } else {  // last loading is NOT plastic, assign plasticflag=0 or 2
01139       debugInfo(3)=3;
01140           chitri  = Psi*de;
01141           chitri += s_n;
01142           chitri -= backs_n;
01143  
01144           normchi=0;
01145           for ( i = 0; i < 3; i++ ){
01146                   for ( j = 0; j < 3; j++ ) {
01147                    normchi += chitri(i,j)*chitri(i,j) ;
01148                   }
01149                 } //end for i 
01150       
01151       // compute normchi
01152           if (normchi >= 0){
01153                   normchi =sqrt(normchi);
01154           } else {
01155                   opserr<<"MCP 1089::Problem, normchi<0 normchi="<< normchi<<endln;
01156           }   
01157 
01158           plasticflag=0;
01159 
01160           ftrial=normchi-R;
01161           if (ftrial >= 0) {   
01162                         //Psi_split is calculated in the very beginning
01163                         chitri  = Psi_split*de;
01164                         chitri += s_n;
01165                         chitri -= backs_n;
01166                         
01167                         normchi=0;
01168                         for ( i = 0; i < 3; i++ ){
01169                                 for ( j = 0; j < 3; j++ ) {  
01170                                         normchi += chitri(i,j)*chitri(i,j) ;
01171                                 }
01172                         } //end for i 
01173 
01174                         // compute normchi
01175                         if (normchi >= 0){
01176                                 normchi =sqrt(normchi);
01177                         } else {
01178                                 opserr<<"MCP 1111::Problem, normchi<0"<<endln;
01179                         }   
01180 
01181                         ftrial=normchi-R;
01182                         if (ftrial>=0){            
01183                                 debugInfo(3)=4;
01184                                 plasticflag=2;
01185                         } else {
01186                                 debugInfo(3)=5;  // it is really an awkward situation when it comes here....
01187                                 plasticflag=0;   // diverge if it set to 1
01188                         }
01189           } //end if ftrial>0
01190   }
01191    
01192   // end: check for plastic loading
01193 
01194 
01195 
01196 
01197   // (6) if loading within B.S., solve  Psi_n+1, kappa_n+1 (i.e. X[1] and X[2])
01198  
01199 LABEL6:
01200   if (plasticflag==0){
01201         // intitialize
01202 
01203     // converge better
01204         X[1] = Psi  ;         // stiff at time n
01205         X[2] = kappa;         // kappa at time n
01206 
01207 
01208         //X[1] = 2*shear  ;        // stiff at time n
01209         //X[2] = infinity;         // kappa at time n
01210     
01211         double g1, g2;
01212         double aa, bb, cc, dd;  
01213 
01214         Hn  = h* pow(kappa, m) + Ho;
01215         Hn1 = h* pow(X[2],m) + Ho;
01216         // define g1, g2
01217         //g1= 2.0*shear-X[1]-3.0*shear*X[1]*((1-beta)/Hn + beta/Hn1);  // borja
01218         g1=X[1]-2.0*shear*(1.0-shear/(shear+((1-beta)*Hn+beta*Hn1)/3.0));    // Gang
01219 
01220         temp6.Zero();
01221 
01222         //temp6 = s-backs + X[1]*de + X[2]*(s+X[1]*de-so);  
01223     for ( i = 0; i < 3; i++ ){
01224                 for ( j = 0; j < 3; j++ ) {
01225                         temp6(i,j) = s_n(i,j)-backs_n(i,j) + X[1]*de(i,j) + X[2]*(s_n(i,j)+X[1]*de(i,j)-so(i,j));  
01226                 }
01227          } //end for i 
01228 
01229 
01230         dottemp6=0;
01231     for ( i = 0; i < 3; i++ ){
01232                 for ( j = 0; j < 3; j++ ) {
01233               dottemp6 += temp6(i,j)*temp6(i,j);
01234                 }
01235          } //end for i 
01236 
01237          if (dottemp6 >=0){
01238                  g2=R-sqrt(dottemp6);
01239          } else {
01240                  opserr<<"MCP1244::problem, dottemp6<0 "<<dottemp6<<endln;
01241                  g2=R;
01242          }
01243 
01244          norm = g1*g1+g2*g2;
01245          if (norm >= 0){
01246                  norm = sqrt(norm);
01247          } else { 
01248                  opserr<<"MCP::problem, norm<0 "<<norm<<endln;
01249                  norm = 0.0; 
01250          }
01251 
01252         
01253          icounter = 0;
01254    // begin iterations to solve Psi_n+1, Kappa_n+1 !!!!  
01255          while ((norm>tolforX)&&(icounter<60)&&(X[2]>0))
01256          //while ((icounter<30))
01257          { 
01258           //   compute Jacobian 
01259           //   aa = dg1/dPsi    bb=dg1/dKappa
01260           //   cc = dg2/dPsi    dd=dg2/dKappa
01261           //  
01262           //       | aa  bb |
01263           //   J = |        |
01264           //       | cc  dd |
01265 
01266 
01267 
01268                 //Hn  = h* pow(kappa, m) + Ho;
01269                 Hn1 = h* pow(X[2],m) + Ho;
01270 
01271 
01272                 //aa = -1.0 - 3.0*shear*((1.0-beta)/Hn + beta/Hn1); // borja
01273                 //bb = 3.0 * shear * X[1] * beta * m * h * pow(X[2],m-1.0) / pow(Hn1,2); // borja
01274 
01275                 // reformulate 
01276                 aa = 1.0;                                                 // Gang
01277                 temp=shear + ((1.0-beta)*Hn+beta*Hn1)/3.0;
01278 
01279                 bb= -2.0/3.0*beta*shear*shear/(temp*temp)*h*m*pow(X[2],m-1.0);  // Gang
01280         // we will have problem if X[2]=0, then bb=NaN. Problem: pow(X[2],m-1)
01281 
01282 
01283                 if (sqrt(dottemp6) > ZERO) {
01284                         cc = 0 ;
01285                         for ( i = 0; i < 3; i++ ){
01286                                 for ( j = 0; j < 3; j++ ) {
01287                                    cc += temp6(i,j)*de(i,j);
01288                                 }
01289                         } 
01290                         cc *= -(1+X[2])/sqrt(dottemp6);
01291 
01292                         dd = 0 ;
01293                         for ( i = 0; i < 3; i++ ){
01294                                 for ( j = 0; j < 3; j++ ) {
01295                          dd += temp6(i,j)*(s_n(i,j)+X[1]*de(i,j)-so(i,j));
01296                                 }
01297                          }  
01298                     dd *= -1.0/sqrt(dottemp6);
01299                 } else {
01300                         opserr<<"MCP:: singularity in Jacobian, dottemp6="<<dottemp6<<endln;
01301                     //opserr<<"MCP:: icounter="<<icounter<<endln;
01302                         opserr<<"MCP:: X[1]="<<X[1]<<" X[2]="<<X[2]<<endln;
01303                         opserr<<"MCP:: plasticflag_n="<<plasticflag_n<<" kappa="<<kappa<<" Psi="<<Psi <<endln;
01304                         cc = 0;
01305                         dd = 0;
01306                 }
01307 
01308                 if (fabs(aa*dd-cc*bb)>=ZERO){
01309                         X[1] += -1.0 /(aa*dd - cc*bb)*( dd*g1 - bb*g2);
01310                         X[2] += -1.0 /(aa*dd - cc*bb)*(-cc*g1 + aa*g2);
01311                 } else {
01312                         opserr<<"MCP:: Fatal error: infinite Jacobian"  <<endln;
01313                     // remarks: arrive here maybe simply X[2] < 0, s.t. pow() gives NaN -1.#IND
01314                         // so we must exit the loop once X[2]<0 is found
01315             opserr<<"MCP::pow()="<<pow(X[2],m)<<endln;
01316                         opserr<<"MCP::X[2]="<<X[2]<<endln;  // Gang
01317 
01318                         //exit(1);
01319                 }
01320  
01321                 if (X[2]<=0) {
01322                    icounter = 100; // go out of the loop
01323                    //  exit the loop
01324                 }
01325 
01326         // re-evaluate
01327                 //Hn  = h* pow(kappa, m) + Ho;
01328                 Hn1 = h* pow(X[2],m) + Ho;
01329 
01330 
01331                 // update g1, g2
01332         // g1= 2.0*shear-X[1]-3.0*shear*X[1]*((1.0-beta)/Hn + beta/Hn1);   // borja
01333 
01334                 g1=X[1]-2.0*shear*(1.0-shear/(shear+((1.0-beta)*Hn+beta*Hn1)/3.0));    // Gang
01335 
01336 
01337                 temp6.Zero();
01338  
01339                 for ( i = 0; i < 3; i++ ){
01340                         for ( j = 0; j < 3; j++ ) {
01341                                 temp6(i,j) = s_n(i,j)-backs_n(i,j) + X[1]*de(i,j) + X[2]*(s_n(i,j)+X[1]*de(i,j)-so(i,j));  
01342                         }
01343                 }
01344 
01345 
01346                 dottemp6 = 0;
01347                 for ( i = 0; i < 3; i++ ){
01348                         for ( j = 0; j < 3; j++ ) {
01349                                 dottemp6 += temp6(i,j)*temp6(i,j);
01350                         }
01351                  } //end for i 
01352 
01353                 if (dottemp6 >=0){
01354                          g2=R-sqrt(dottemp6);
01355                 } else {
01356                          // remark: come here wrong because X[2]=0
01357              opserr<<"MCP1353::aa="<<aa<<" bb="<<bb<<" cc="<<cc<<" dd="<<dd<<endln;
01358                          opserr<<"MCP1353::X[2]="<<X[2]<<endln;
01359                          opserr<<"MCP1353::pow(X[2],m-1)"<<pow(X[2],m-1)<<endln;
01360                          icounter=1353;
01361                 }
01362                 norm = g1*g1+g2*g2;
01363                 if (norm > 0){
01364                         norm = sqrt(norm);
01365                 } else { 
01366                         norm = 0.0; 
01367                 }
01368  
01369                 icounter +=1;
01370     
01371          } // end of while loop
01372  
01373          // begin: check kappa converged to a positive value
01374     debugInfo(4)=1;
01375 
01376     if ((norm > tolforX)&&(X[2]!=0)){
01377          opserr<<endln<<endln<<"MCP::X[1] X[2] is not converged!! norm = "<<norm <<" icounter="<<icounter<<endln;
01378      opserr<<"MCP::plasticflag_n= "<<plasticflag_n <<" plasticflag="<< plasticflag<<endln;
01379          opserr<<"MCP::X[2] ="<< X[2]<<endln<<endln;
01380          opserr<<"MCP::debugInfo= "<<debugInfo<<endln;
01381          showdebugInfo=1;
01382         }
01383 
01384         if (X[2]<=0.0)
01385          {   debugInfo(4)=2;
01386                  
01387                  //opserr<< endln;
01388                  //opserr<<"MCP1299::WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endln;
01389                  //opserr<<"MCP1299::norm = "<<norm <<" icounter="<<icounter<<endln;
01390                  //opserr<<"MCP1299::kappa= "<<kappa<<" Psi ="<<Psi<<endln;
01391                  //opserr<<"MCP1299::Negative value for X[2] (kappa_n+1) "<< X[2]<<" set it to 0 "<<endln<<endln;
01392                          
01393  
01394              X[2]=0.0;
01395                  
01396                  if (unloadflag == 1){
01397                          debugInfo(4)=3;
01398                          plasticflag=0;
01399                          X[1] = 2*shear;
01400                  } else {
01401                         chitri = Psi_split*de;
01402                         chitri += s_n;
01403                         chitri -= backs_n;
01404                         normchi=0;
01405                         for ( i = 0; i < 3; i++ ){
01406                                 for ( j = 0; j < 3; j++ ) {
01407                                         normchi += chitri(i,j)*chitri(i,j) ;
01408                                 }
01409                         } //end for i 
01410 
01411                         // compute normchi
01412                         if (normchi >= 0){
01413                                 normchi =sqrt(normchi);
01414                         } else {
01415                                 opserr<<"MCP 1111::Problem, normchi<0"<<endln;
01416                         }   
01417 
01418                         ftrial=normchi-R;
01419                         if (ftrial>=0){
01420                                 debugInfo(4)=4;
01421                                 plasticflag=2;
01422                                 X[1]=Psi_split; //Psi_split=2.0*shear*(1-shear/(shear+((1-beta)*Hn+beta*Ho)/3.0)); // Gang
01423                         } else {
01424                                 debugInfo(4)=X[2];
01425                                 plasticflag=0;  // diverge if it set to 1
01426                                 // question: should plasticflag=0?? or 1?? for this case?
01427                                 X[1]=2.0*shear*(1.0-shear/(shear+((1.0-beta)*Hn+beta*Ho)/3.0));
01428                                 //X[1]=Psi;  // cannot converge if use this
01429                         }
01430                  }
01431                          
01432         } //end if X[2]<0
01433          
01434  
01435  } //end if (plasticflag==0)
01436 
01437 
01438 
01439  // (7) if strain split, calculate ratio alp and secant modulus Psi_split
01440 
01441  if (plasticflag==2){
01442                    // we are here when the loading is partially inside BS, partially on BS
01443                    // alp is defined as epstotal=eps(inside)*alp+eps(outside)*(1-alp)
01444                    // value of Psi between kappa (t=n) inside BS and kappa=0 on BS      
01445                 debugInfo(4)=6;
01446         
01447                         double chichi;
01448                         double chide ;
01449                         chichi=0; chide=0;
01450                         for ( i = 0; i < 3; i++ ){
01451                                 for ( j = 0; j < 3; j++ ) {
01452                                         chichi += (s_n(i,j)-backs_n(i,j))*(s_n(i,j)-backs_n(i,j));
01453                                         chide  += (s_n(i,j)-backs_n(i,j))*de(i,j);
01454                                 } // end for j
01455                         } //end for i 
01456 
01457                         // compute strain splitter
01458                         alp = (-chide+sqrt(chide*chide+normde*normde*(R*R-chichi)));
01459                         alp = alp /(Psi_split *normde*normde); 
01460 
01461  
01462                     double insidesqrt;
01463                         insidesqrt=chide*chide+normde*normde*(R*R-chichi);
01464 
01465                         if ((alp > 1.0)||(insidesqrt<0)||(alp < 0.0) ){
01466                                 debugInfo(4)=7;
01467                                 opserr<<"MCP:1394::WRONG!!! alpha="<<alp<<" chichi-R*R="<<chichi-R*R<<endln;
01468                                 opserr<<"MCP::debugInfo= "<<debugInfo<<endln;
01469                                 // remark: will have problem if chichi>R*R
01470                                 alp=0;
01471                                 plasticflag=1;
01472                                 showdebugInfo=1;
01473                         }
01474 
01475  }
01476 
01477         
01478  //(8) Compute consistent tangent, consistency paramter, and update stresses
01479 
01481 
01482 LABEL10:
01483 
01484    debugInfo(0)=plasticflag_n;
01485    debugInfo(6)=normde;
01486    debugInfo(7)=plasticflag;
01487    debugInfo(8)=X[1];
01488    debugInfo(9)=X[2];
01489 
01490  if (plasticflag==0)  // bounding surface mapping rule
01491  {  
01492 
01493               debugInfo(5)=1;
01494               // update cauchy stresses using incremental strain
01495                   twomu=X[1];
01496 
01497                   s  = s_n ;
01498                   s += twomu * de;
01499                   p = p_n + bulk  * e ;
01500           // add on bulk part of stress, compute TOTAL stress at t=n+1
01501                   stress = s; 
01502                   for ( i = 0; i < 3; i++ )  stress(i,i)= s(i,i) + p ;
01503                   
01504                   backs=backs_n;
01505                   // check stress_n+1 is on the yield surface
01506                   
01507                   temp6=s-backs;
01508                   temp=0;
01509                   for ( i = 0; i < 3; i++ ){
01510                           for ( j = 0; j < 3; j++ ) {
01511                                   temp += temp6(i,j)*temp6(i,j);
01512                           } // end for j
01513                   } //end for i 
01514 
01515                  
01516                   if (sqrt(temp)-R>=0){
01517                           if (unloadflag!=1){
01518                                   plasticflag=1;
01519                           }
01520 
01521                         // Remark:
01522                         // a big problem for this update is, upon unload from plastic, the 
01523                         // predicted de is still very high, may cause this >=0. And if you
01524                         // just simply let plasticflag = 1, it is not unload at all. Continue
01525                         // to yield at plastic
01526                     // opserr<<"MCP1535::plasticflag=0: |S|-R = " << sqrt(temp)-R<<endln;
01527                   }
01528 
01529 
01530                   // a consistent tangent
01531 
01532           // compute tangent again
01533               for ( ii = 0; ii < 6; ii++ ) {
01534                           for ( jj = 0; jj < 6; jj++ )  {
01535                                   index_map( ii, i, j ) ;
01536                                   index_map( jj, k, l ) ;
01537                                   tangent[i][j][k][l]  = bulk * IbunI[i][j][k][l] ;
01538                                   tangent[i][j][k][l] += twomu * IIdev[i][j][k][l] ;
01539                                   //minor symmetries 
01540                                   tangent [j][i][k][l] = tangent[i][j][k][l] ;
01541                                   tangent [i][j][l][k] = tangent[i][j][k][l] ;
01542                                   tangent [j][i][l][k] = tangent[i][j][k][l] ;
01543                           }
01544                   }
01545    } 
01546 
01547    if (plasticflag > 0) // plasticflag = 1,2   plastic loading   pp.15
01548    { 
01549             
01550             if ((X[1]==2.0*shear)&&(unloadflag!=1)&&(zeroloadflag!=1)){
01551                           opserr<<"MCP::warning...WHY X[1]=2G at plasticflag>0 and not unload?"<<endln;
01552                           opserr<<"MCP::debugInfo= "<<debugInfo<<endln;
01553                           showdebugInfo=1;
01554                 }
01555 
01556 
01557                 twomu   = 2.0 * shear;
01558                 if (plasticflag==1)
01559                 {       debugInfo(5)=2;
01560                         alp = 0.0;
01561                         strial  = s_n ;
01562                         strial += twomu*de;
01563                         chitri  = strial;
01564                         chitri -= backs_n;
01565                         Psi_split = 0; // just give a number
01566                 }//end plasticfl=1
01567  
01568                 if (plasticflag==2)
01569                 {
01570                         debugInfo(5)=3;
01571                         strial  = s_n ;
01572                         strial += alp * Psi_split * de;
01573                     strial += (1-alp)*twomu*de;
01574                         chitri  = strial;
01575                         chitri -= backs_n;
01576                 } // end if plasticflag=2
01577 
01578                 normchi = 0.0;
01579                 // double check yield
01580                 for ( i = 0; i < 3; i++ ){
01581                         for ( j = 0; j < 3; j++ ) {
01582                                 normchi += chitri(i,j)*chitri(i,j);
01583                         } // end for j
01584                 } //end for i 
01585                 if (normchi >= 0) {
01586                         normchi = sqrt (normchi);
01587                 } 
01588                 else {
01589                         opserr<<"MCP1873:: normchi = " << normchi <<endln;
01590                     opserr<<"MCP:: plastic loading with zero stresses, problem" <<endln; 
01591                 }
01592 
01593                 ftrial =  normchi - R; 
01594 
01595                 if (ftrial < ZERO)
01596                 {   // Remark: come here, means, unload, but goes to wrong place
01597                         opserr<<"MCP1472:: ftrial = " <<ftrial<<endln;
01598                         opserr<<"MCP1472:: strange! set ftrial=0, plasticflag="<<plasticflag <<endln;
01599                         opserr<<"MCP1372:: plasticflag_n="<<plasticflag_n<<" fn="<<fn<<" normde="<<normde<<" Psi_split="<<Psi_split<<endln;
01600                         opserr<<"MCP1372:: load="<<load<<endln;
01601                         showdebugInfo=1;
01602                 }
01603 
01604                 // compute consistency parameter
01605                 double gamma;
01606                 gamma =  ftrial /(twomu + 2.0*Ho/3.0);
01607                 // leave stress slightly outside yield surface
01608         gamma *= (1.0 - 1e-08) ; // add July 2, 2004 !!!!!! very important add !!!!!
01609                                 
01610                 // update plastic variable for backstresses
01611                 
01612                 backs  = backs_n;
01613                 backs +=  two3 * Ho * gamma * chitri/ normchi ;
01614 
01615         s  = s_n + alp * Psi_split * de;
01616                 s += twomu * ((1-alp) * de - gamma * chitri/normchi );  
01617 
01618 
01619                 // check stress_n+1 is on the yield surface
01620                 temp6=s-backs;
01621                 temp=0;
01622                 for ( i = 0; i < 3; i++ ){
01623                         for ( j = 0; j < 3; j++ ) {
01624                                 temp += temp6(i,j)*temp6(i,j);
01625                                 } // end for j
01626                 } //end for i 
01627 
01628                  
01629                 if ((sqrt(temp)-R>(1.0e-3)*R)||(sqrt(temp)-R<0)){
01630            opserr<<"MCP1690::plastic: alp   = " << alp <<endln;
01631                    opserr<<"MCP1690::plastic: |S|-R = " << sqrt(temp)-R<<endln;
01632                    opserr<<"MCP::debugInfo= "<<debugInfo<<endln;
01633                    showdebugInfo=1;
01634                    // Remark: dangerous if <0... 
01635                 }
01636 
01637                 //s  = s_n;
01638                 //s += twomu * ( de - gamma * chitri/normchi) ;  
01639                 p = p_n + bulk  * e;
01640                 
01641                 stress = s ;
01642                 for ( i = 0; i < 3; i++ )
01643                         stress(i,i) += p ;   // add on pressure part
01644 
01645  
01646                 // remark: this update is very important, since when commit
01647                 // we assign Psi=X[1], kappa=X[2]
01648                 if (Ho==0){
01649                         X[1] = 0; 
01650                 } else 
01651                 {       
01652                         X[1] = 2.0 * shear /(1.0 + 3.0*shear/Ho);
01653                 }
01654         X[2] = 0 ;   // kappa = 0
01655 
01656 
01657         //compute the tangent
01658                 double theta1 = 1.0 - 2.0 *shear *gamma/normchi;
01659                 double theta2 = 1.0/(1.0+Ho/3.0/shear) - (1.0-theta1);
01660 
01661                 double NbunN;
01662 
01663                 for ( ii = 0; ii < 6; ii++ ) {
01664                         for ( jj = 0; jj < 6; jj++ )  {
01665 
01666                                 index_map( ii, i, j ) ;
01667                                 index_map( jj, k, l ) ;
01668 
01669                                 NbunN  = chitri(i,j)*chitri(k,l)/(normchi*normchi) ; 
01670 
01671                                 // elasto-plastic term  (1-alp) * C_ep
01672                         // ****** Elasto-plastic consistent modulus, from Simo & Hughes Box 3.2
01673                                 // ---------------------------------------------------------------------
01674                 //        C_ep = K IbunI + 2 shear ( theta1* IIdev - theta2 * NbunN)
01675                                 // _____________________________________________________________________
01676 
01678                                 tangent[i][j][k][l]  = (1-alp)* bulk * IbunI[i][j][k][l] ;
01679                                 tangent[i][j][k][l] += (1-alp)* 2.0*shear*theta1 * IIdev[i][j][k][l] ;
01680                                 tangent[i][j][k][l] -= (1-alp)* 2.0*shear*theta2 * NbunN ;
01681                                 
01682                                 // bounding surface terms alp * C_bound
01683                                 //****** Consistent modulus from Bounding Surface Plasticity
01684                                 //----------------------------------------------------------------------- 
01685                                 //       C_bound = K IbunI + Psi_split IIdev
01686                                 //_______________________________________________________________________
01687 
01688                                 tangent[i][j][k][l] += alp * bulk * IbunI[i][j][k][l] ;
01689                 tangent[i][j][k][l] += alp * Psi_split * IIdev[i][j][k][l] ;
01690               
01691                                 // tangent = alp * C_bound + (1-alp) * C_ep;
01692 
01693                                 //minor symmetries 
01694                                 tangent[j][i][k][l] = tangent[i][j][k][l] ;
01695                                 tangent[i][j][l][k] = tangent[i][j][k][l] ;
01696                                 tangent[j][i][l][k] = tangent[i][j][k][l] ;
01697 
01698                         } // end for jj
01699                 } // end for ii
01700    } // end if(plasticflag)
01701 
01702 
01703 
01704    if (showdebugInfo==1){
01705           opserr<<"END OF INTEGRATOR::debugInfo= "<<debugInfo<<endln;   
01706    }
01707           //if ((iternum>20)&&(this->getEleTag()==151)){
01708            //opserr<<"MCP::debugInfo= "<<debugInfo<<endln;
01709        //opserr<<"MCP::plasticflag= "<<plasticflag<<endln;
01710           //}
01711 }  // end of this subroutine
01712 
01713 
01714 Vector MultiaxialCyclicPlasticity::MCPparameter(10) ;
01715 
01716 
01717 
01718 
01719 Vector& 
01720 MultiaxialCyclicPlasticity::getMCPparameter()
01721 {
01722  //opserr<<"getMCPparameter"<<endln;
01723  MCPparameter(0) = plasticflag;
01724  MCPparameter(1) = X[1];
01725  MCPparameter(2) = X[2]; // kappa
01726  MCPparameter(3) = alp ;
01727  MCPparameter(4) = stress(0,1) ;
01728  MCPparameter(5) = backs(0,1)  ;
01729 
01730 
01731  double norm = 0 ;
01732  double p = one3 * (stress(0,0)+stress(1,1)+stress(2,2));
01733  Matrix s = stress ;
01734  int i; 
01735  for (i = 0; i < 3; i++ )  s(i,i) -= p ;
01736  
01737  for (i = 0; i < 3; i++ ){
01738    for (int j = 0; j < 3; j++ ) {
01739      norm   += (s(i,j)-backs(i,j)) * (s(i,j)-backs(i,j)) ;
01740    } // end for j
01741  } //end for i 
01742 
01743  MCPparameter(6) = sqrt(norm) ;
01744  MCPparameter(7) = load ;
01745 
01746  norm=0;
01747  for (i = 0; i < 3; i++ ){
01748         for (int j = 0; j < 3; j++ ) {
01749            norm   += (strain(i,j)) * (strain(i,j)) ;
01750         } // end for j
01751   } //end for i 
01752 
01753  MCPparameter(8) = norm ;
01754  // MCPparameter(9) = normde ;   get directly from subroutine plastic_integrator
01755  return MCPparameter;
01756 
01757 }

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