MD_PS.cpp

Go to the documentation of this file.
00001 
00002 //================================================================================
00003 //# COPYRIGHT (C):     :-))                                                      #
00004 //# PROJECT:           Object Oriented Finite Element Program                    #
00005 //# PURPOSE:           Manzari-Dafalias  potential surface                       #
00006 //#                    (Ref. Geotechnique v.47 No.2 255-272, 1997)               #
00007 //# CLASS:             MDPotentialSurface                                        #
00008 //#                                                                              #
00009 //# VERSION:                                                                     #
00010 //# LANGUAGE:          C++.ver >= 2.0 ( Borland C++ ver=3.00, SUN C++ ver=2.1 )  #
00011 //# TARGET OS:         DOS || UNIX || . . .                                      #
00012 //# PROGRAMMER(S):     Boris Jeremic, ZHaohui Yang                               #
00013 //#                                                                              #
00014 //#                                                                              #
00015 //# DATE:              
00016 //# UPDATE HISTORY:    
00017 //#                                                                              #
00018 //#                                                                              #
00019 //#                                                                              #
00020 //#                                                                              #
00021 //#                                                                              #
00022 //================================================================================
00023 
00024 
00025 #ifndef MD_PS_CPP
00026 #define MD_PS_CPP
00027 
00028 #include "MD_PS.h"
00029 #include <basics.h>
00030 #include <math.h>
00031 
00032 #define sqrt23rd 0.8165
00033 
00034 //================================================================================
00035 // Normal constructor
00036 //================================================================================
00037 
00038 MDPotentialSurface::MDPotentialSurface( ) { } 
00039 
00040 
00041 //================================================================================
00042 //create a clone of itself
00043 //================================================================================
00044 
00045 PotentialSurface * MDPotentialSurface::newObj() {  
00046 
00047      PotentialSurface  *new_PS = new MDPotentialSurface();
00048      return new_PS;
00049 
00050 }
00051 
00052 //================================================================================
00053 //  tensor dQ/dsigma_ij: the normal to the potential surface
00054 //================================================================================
00055 
00056 tensor MDPotentialSurface::dQods(const EPState *EPS) const { 
00057 
00058   tensor dQoverds( 2, def_dim_2, 0.0);
00059   tensor I2("I", 2, def_dim_2);
00060 
00061   tensor S = EPS->getStress().deviator();
00062   //double p = EPS->getStress().p_hydrostatic();
00063   
00064   tensor alpha = EPS->getTensorVar( 1 ); //the first tensor hardening var is alpha_ij
00065 
00066   //double m = EPS->getScalarVar( 1 );   //the first scalar hardening var is m
00067   double D = EPS->getScalarVar( 2 );     // D is stored in scalar var array's second cell
00068 
00069   stresstensor n = EPS->getTensorVar( 2 );
00070   //stresstensor n;
00071 
00073   //stresstensor r = S *(1.0/p);
00074   //stresstensor r_bar = r - alpha;
00075   //stresstensor norm2 = r_bar("ij") * r_bar("ij");
00076   //double norm = sqrt( norm2.trace() );
00077   //if ( norm >= d_macheps() ){ 
00078   //  n = r_bar *(1.0 / norm );
00079   //}
00080   //else {
00081   //  opserr->fatal("MDYieldSurface::dQods |n_ij| = 0, divide by zero! Program exits.");
00082   //  exit(-1);
00083   //}
00084   //
00087   
00088   dQoverds =  n + I2 * D *(1.0/3.0);
00089 
00090   return dQoverds;
00091 }
00092 
00093 
00094 //================================================================================
00095 // tensor d2Q/dsigma_ij2: the second derivatives to the potential surface
00096 //================================================================================
00097 
00098 tensor MDPotentialSurface::d2Qods2(const EPState *EPS) const 
00099 {
00100 
00101   
00102   tensor d2Qoverds2;
00103   tensor I2("I", 2, def_dim_2);
00104 
00105   stresstensor stress = EPS->getStress();
00106   
00107   //double J2D = stress.Jinvariant2();
00108   //double q     = stress.q_deviatoric();
00109   double theta = stress.theta();
00110 
00111   tensor S = stress.deviator();
00112   double p = stress.p_hydrostatic();
00113   
00114   tensor alpha = EPS->getTensorVar( 1 ); //the first tensor hardening var is alpha_ij
00115            
00116   /*
00117   tensor r = S *(1.0/p);
00118   stresstensor r_bar = r - alpha;
00119   stresstensor norm2 = r_bar("ij") * r_bar("ij");
00120   double norm = sqrt( norm2.trace() );
00121 
00122   stresstensor n;
00123   if ( norm >= d_macheps() ){ 
00124     n = r_bar *(1.0 / norm );
00125   }
00126   else {
00127     opserr << "MDPotentialSurface::dQods  |n_ij| = 0, divide by zero! Program exits.\n";
00128     exit(-1);
00129   }
00130   */
00131   
00132   //tensor d2Qoverds2( 2, def_dim_2, 0.0); // dummy second derivatives. To be redefined.
00133   tensor dnds =  dnods( EPS);
00134   double A = 2.64;
00135   double Mc = 1.14;
00136   double kcd = 4.2;
00137   //double m = EPS->getScalarVar( 1 );
00138   if (p < 0.0)
00139   {
00140      opserr << "MDPotentialSurface::d2Qods2  p < 0, Program exits.\n";
00141      exit(-1);
00142   }
00143 
00144   //double ec = 0.80 - 0.025 * log( p / 160 ); //p_ref = 160; (ec)ref = 0.8
00145   //double ec = (EPS->getec()) - (EPS->getLam()) * log( p / (EPS->getpo()) );
00146   //opserr << " ************" << log(2.718) << "\n";
00147 
00148   //double e = EPS->gete();
00149   double xi = EPS->getpsi();
00150 
00151   double c = 1.0;
00152   double cd = 0.0167; //0.7;
00153 
00154   double dgodthetac  = dgoverdt(theta, c);
00155   double dgodthetacd = dgoverdt(theta, cd);
00156   tensor dthetaods = dthetaoverds(EPS);
00157   //stresstensor d = EPS->getTensorVar( 3 );   // getting  d_ij from EPState
00158   
00159   //tensor dtods = dthetaods("pq"); 
00160 
00161   tensor dDds1 = dthetaods*A*(dgodthetac*Mc+dgodthetacd*kcd*xi)*sqrt(2.0/3.0);
00162   tensor dDds2 = apqdnods(EPS)*A;
00163   tensor dDds = dDds1 - dDds2;
00164   dDds.null_indices(); 
00165    
00166   d2Qoverds2 = dnds + dDds("mn")*I2("pq")*(1.0/3.0);
00167   d2Qoverds2.null_indices();
00168   
00169 
00170   tensor d2Qoverds2x( 4, def_dim_2, 0.0); // dummy second derivatives. To be redefined.
00171   return d2Qoverds2x;
00172   //return dnds;
00173 }
00174 
00175 //================================================================================
00176 // tensor dn_pq/dsigma_mn
00177 //================================================================================
00178 tensor MDPotentialSurface::dnods(const EPState *EPS) const
00179 {
00180   /*
00181   tensor xdnods;
00182   tensor I2("I", 2, def_dim_2);
00183 
00184   stresstensor S = EPS->getStress().deviator();
00185   //S.reportshort("S");
00186 
00187   double p = EPS->getStress().p_hydrostatic();
00188   //printf("Here we go!  p %f\n", p);
00189   double m = EPS->getScalarVar( 1 );
00190 
00191   double fac = 1.0/(sqrt(2.0/3.0)*m);
00192 
00193   tensor Ipmnq = I2("pm") * I2("nq");
00194   tensor Imnpq = I2("mn") * I2("pq");
00195   tensor Spqmn = S("pq") * I2("mn");
00196   tensor temp  = Ipmnq - Imnpq*(1.0/3.0);
00197   
00198   xdnods = (temp*p - Spqmn*(1.0/3.0))*(fac/p/p);
00199   return  xdnods;
00200   */
00201   
00202   
00203   tensor dnods;
00204   tensor I2("I", 2, def_dim_2);
00205 
00206   stresstensor S = EPS->getStress().deviator();
00207   //S.reportshort("S");
00208   stresstensor alpha = EPS->getTensorVar( 1 );
00209 
00210   double p = EPS->getStress().p_hydrostatic();
00211   //p = p -  Pc;
00212 
00213   //double m = EPS->getScalarVar( 1 );
00214   //double fac = 1.0/(sqrt(2.0/3.0)*m);
00215 
00216   tensor Ipmnq = I2("pm") * I2("nq");
00217   tensor Imnpq = I2("mn") * I2("pq");
00218   tensor Apqmn = alpha("pq") * I2("mn");
00219   tensor X  = Ipmnq - Imnpq*(1.0/3.0)  - Apqmn*(1.0/3.0);
00220 
00221   //Ipmnq.print("in MD_PS01", "");
00222   
00223   tensor s_bar = S("ij") - alpha("ij")*p;
00224 
00225   tensor ad = alpha - I2; //Vlado found a bug
00226   tensor sa = S("ij") * ad("ij");
00227   double sad =sa.trace();
00228   tensor aa = alpha("ij") * ad("ij");
00229   double aad =aa.trace();
00230   tensor Y = s_bar +I2 * (1.0/3.0) * (sad-p*aad);
00231   Y.null_indices();
00232 
00233   s_bar.null_indices();
00234   tensor t_norm2 = s_bar("ij") * s_bar("ij");
00235   double norm2 = t_norm2.trace();
00236   double norm =  sqrt( norm2 );
00237 
00238   double norm21 = 1.0/( norm2 );
00239   s_bar.null_indices();
00240   tensor tmp = s_bar("pq")*Y("mn");
00241   dnods = ( X - tmp*norm21)*(1.0/norm);
00242   
00243   return  dnods;
00244   
00245 
00246 }
00247 
00248 //================================================================================
00249 // tensor alpha_pq*dnods
00250 //================================================================================
00251 tensor MDPotentialSurface::apqdnods(const EPState *EPS) const
00252 {
00253   /* old fomulation, not correct
00254   tensor ddnods( 2, def_dim_2, 0.0);
00255   tensor I2("I", 2, def_dim_2);
00256 
00257   stresstensor S = EPS->getStress().deviator();
00258   //S.reportshort("S");
00259 
00260   double p = EPS->getStress().p_hydrostatic();
00261   //printf("Here we go!  p %f\n", p);
00262   double m = EPS->getScalarVar( 1 );
00263 
00264   double fac = 1.0/(sqrt(2.0/3.0)*m);
00265 
00266   stresstensor d = EPS->getTensorVar( 3 );   // getting  d_ij from EPState
00267   tensor dkk = d("ij") * I2("ij");
00268   double dkkd =dkk.trace();
00269   tensor dkkImn = dkkd * I2;
00270 
00271   tensor Spqdpq = S("pq") * d("pq");
00272   double Sqpdpqd =Spqdpq.trace();
00273   tensor dSI = Sqpdpqd*I2;
00274      
00275   tensor temp  = d  - (1.0/3.0)*dkkImn;
00276   
00277   ddnods = fac/p*(temp - 1.0/(p*3.0)*dSI);
00278   return  ddnods;
00279   */
00280 
00281   /*
00282   tensor ddnods( 2, def_dim_2, 0.0);
00283   tensor I2("I", 2, def_dim_2);
00284 
00285   stresstensor S = EPS->getStress().deviator();
00286   //S.reportshort("S");
00287 
00288   double p = EPS->getStress().p_hydrostatic();
00289   //p = p -  Pc;
00290 
00291   //printf("Here we go!  p %f\n", p);
00292               
00293   stresstensor alpha = EPS->getTensorVar( 1 );
00294   //stresstensor d = EPS->getTensorVar( 3 );   // getting  d_ij from EPState
00295 
00296   tensor akk = alpha("ij") * I2("ij");
00297   double akkd =akk.trace();
00298 
00299   tensor aa = alpha("ij") * alpha("ij");
00300   double aad =aa.trace();
00301 
00302   tensor aX = alpha - I2*(akkd +aad)*0.3333333;
00303                  
00304   //Ymn
00305   tensor sa = S("ij") * alpha("ij");
00306   double sad =sa.trace();
00307   tensor Y = S - I2*( p + 0.333333333*(sad-p*aad) );
00308   Y.null_indices();
00309   
00310   tensor s_bar = S - alpha*p;
00311   s_bar.null_indices();
00312 
00313   tensor as_bar = alpha("pq") * s_bar("pq");
00314   double as_bard = as_bar.trace();
00315   s_bar.null_indices();
00316   
00317   //Norm
00318   tensor norm2 = s_bar("ij") * s_bar("ij");
00319   double norm = norm2.trace();
00320   
00321                      
00322   ddnods = (aX - Y*2.0*as_bard)*(1.0/norm);
00323   return  ddnods;
00324   */
00325 
00326   tensor xdnods = dnods(EPS);
00327   stresstensor alpha = EPS->getTensorVar( 1 );
00328 
00329   tensor adnods = alpha("pq") * xdnods("pqmn");
00330 
00331   return adnods;
00332 
00333 }
00334 
00335 
00336 //================================================================================
00337 // tensor dg(theta, c)/dsigma_mn
00338 //================================================================================
00339 double MDPotentialSurface::dgoverdt(double theta, double c) const
00340 {
00341    //stresstensor stress = EPS->getStress();
00342   
00343    //double J2D = stress.Jinvariant2();
00344    //double q     = stress.q_deviatoric();
00345    //double theta = stress.theta();
00346   
00347    double temp = (-6*(1 - c)*c*sin(3*theta))/pow(1 + c - (1 - c)*cos(3*theta),2);  
00348    return temp;
00349 }
00350 
00351 //================================================================================
00352 // tensor dtheta/dsigma_pq
00353 //================================================================================
00354 tensor MDPotentialSurface::dthetaoverds(const EPState *EPS) const
00355 {
00356    tensor ret(2, def_dim_2, 0.0);
00357    stresstensor s( 0.0);
00358    stresstensor t( 0.0);
00359    tensor I2("I", 2, def_dim_2);
00360 
00361    //double EPS = pow(d_macheps(),(1./3.));
00362    stresstensor stress = EPS->getStress();
00363   
00364    double J2D = stress.Jinvariant2();
00365    double q     = stress.q_deviatoric();
00366    double theta = stress.theta();
00367 
00368    //out    while ( theta >= 2.0*PI )
00369    //out      theta = theta - 2.0*PI; // if bigger than full cycle
00370    //out    while ( theta >= 4.0*PI/3.0 )
00371    //out      theta = theta - 4.0*PI/3.0; // if bigger than four thirds of half cycle
00372    //out    while ( theta >= 2.0*PI/3.0 )
00373    //out      theta = theta - 2.0*PI/3.0; // if bigger than two third of half cycle
00374    //out    while ( theta >= PI/3.0 )
00375    //out      theta = 2.0*PI/3.0 - theta; // if bigger than one third of half cycle
00376    //out
00377    //out    if ( theta < 0.0001 )
00378    //out      {
00379    //out        ::printf("theta = %.10e in Material_Model::dthetaoverds(stress)\n",
00380    //out                           theta);
00381    //out//>><<>><<>><<        return ret;
00382    //out      }
00383    
00384    double c3t = cos(3.0*theta);
00385    double s3t = sin(3.0*theta);
00386 
00387    double tempS = (3.0/2.0)*(c3t/(q*q*s3t));
00388    double tempT = (9.0/2.0)*(1.0/(q*q*q*s3t));
00389 
00390    s = stress.deviator();
00391    t = s("qk")*s("kp") - I2*(J2D*(2.0/3.0));
00392 
00393    s.null_indices();
00394    t.null_indices();
00395 
00396    ret = s*tempS - t*tempT;
00397    ret.null_indices();
00398    return ret;
00399 }
00400 
00401 
00402 
00403 
00404 #endif
00405 

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