MD_PS.cppGo 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 |