![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_PROBLEMEP_H 00021 #define MECHSYS_PROBLEMEP_H 00022 00023 // MechSys 00024 #include <mechsys/models/model.h> 00025 #include <mechsys/models/equilibstate.h> 00026 #include <mechsys/numerical/root.h> 00027 00028 class ProblemEP : public Model 00029 { 00030 public: 00031 // enums 00032 enum FCrit_t { VM_t, DP_t, MC_t, MN_t }; 00033 00034 // Constructor & Destructor 00035 ProblemEP (int NDim, SDPair const & Prms, bool DerivedModel=false); 00036 virtual ~ProblemEP () {} 00037 00038 // Derived methods 00039 virtual void TgIncs (State const * Sta, Vec_t & DEps, Vec_t & DSig, Vec_t & DIvs) const; 00040 virtual void Stiffness (State const * Sta, Mat_t & D) const; 00041 virtual size_t CorrectDrift (State * Sta) const; 00042 virtual bool LoadCond (State const * Sta, Vec_t const & DEps, double & alpInt) const; 00043 00044 // Internal methods to be overloaded by derived classes 00045 virtual void InitIvs (SDPair const & Ini, State * Sta) const; 00046 virtual void Gradients (Vec_t const & Sig, Vec_t const & Ivs) const; 00047 virtual void FlowRule (Vec_t const & Sig, Vec_t const & Ivs) const; 00048 virtual void Hardening (Vec_t const & Sig, Vec_t const & Ivs) const; 00049 virtual double YieldFunc (Vec_t const & Sig, Vec_t const & Ivs) const; 00050 virtual double CalcE (Vec_t const & Sig, Vec_t const & Ivs) const { return E; } 00051 virtual void ELStiff (Vec_t const & Sig, Vec_t const & Ivs) const; 00052 00053 // Constants 00054 bool Derived; 00055 double E; 00056 double nu; 00057 FCrit_t FC; 00058 double kVM; 00059 double kDP; 00060 double kMN; 00061 double Hb; 00062 bool NonAssoc; 00063 double sphi; 00064 double spsi; 00065 double FTol; 00066 double DCFTol; 00067 size_t DCMaxIt; 00068 double pTol; 00069 double qTol; 00070 bool NewSU; 00071 double BetSU; 00072 double AlpSU; 00073 Vec_t I; 00074 00075 // State data (mutable/scratch-pad) 00076 mutable Vec_t Sig0, Ivs0, SigA, DSigTr; 00077 mutable Vec_t DEpsEl; 00078 mutable Vec_t DEpsPl; 00079 mutable Vec_t V; 00080 mutable Vec_t W, devW; 00081 mutable Vec_t Y; 00082 mutable Vec_t H; 00083 mutable Mat_t De; 00084 mutable Mat_t Dep; 00085 mutable Vec_t VDe; 00086 mutable Vec_t DeW; 00087 mutable Vec_t s; 00088 mutable Vec_t dthdsig; 00089 mutable Vec_t dgdsig; 00090 mutable Vec_t dI1dsig,dI2dsig,dI3dsig; 00091 mutable double p, q, t, th, g, I1, I2, I3; 00092 00093 // Methods for yield surface crossing 00094 double Fa (double Alp, void*) { SigA=Sig0+Alp*DSigTr; return YieldFunc(SigA,Ivs0); } 00095 double dFada (double Alp, void*) { SigA=Sig0+Alp*DSigTr; Gradients(SigA,Ivs0); return dot(V,DSigTr); } 00096 00097 // Auxiliary methods 00098 void Calc_pq (Vec_t const & Sig) const { p=Calc_poct(Sig); q=Calc_qoct(Sig); } 00099 void Calc_pqg (Vec_t const & Sig) const { OctInvs(Sig,p,q,t); th=asin(t)/3.0; g=Util::SQ2*sphi/(Util::SQ3*cos(th)-sphi*sin(th)); } 00100 void Calc_dgdsig (Vec_t const & Sig, bool Potential=false) const 00101 { 00102 double sinp = (Potential ? spsi : sphi); 00103 OctInvs (Sig, p,q,t,th,s, qTol, &dthdsig); 00104 g = Util::SQ2*sinp/(Util::SQ3*cos(th)-sinp*sin(th)); 00105 double dgdth = g*(Util::SQ3*sin(th)+sinp*cos(th))/(Util::SQ3*cos(th)-sinp*sin(th)); 00106 dgdsig = dgdth * dthdsig; 00107 } 00108 }; 00109 00110 00112 00113 00114 inline ProblemEP::ProblemEP (int NDim, SDPair const & Prms, bool Deriv) 00115 : Model (NDim,Prms,/*niv*/3,"ProblemEP"), Derived(Deriv), 00116 E(0.0), nu(0.0), FC(VM_t), kVM(0.0), Hb(0.0), NonAssoc(false), FTol(1.0e-7), DCFTol(1.0e-8), DCMaxIt(10), 00117 pTol(1.0e-6), qTol(1.0e-7), NewSU(false) 00118 { 00119 // resize scratchpad arrays 00120 Sig0 .change_dim (NCps); 00121 Ivs0 .change_dim (NIvs); 00122 SigA .change_dim (NCps); 00123 DSigTr .change_dim (NCps); 00124 DEpsEl .change_dim (NCps); 00125 V .change_dim (NCps); 00126 W .change_dim (NCps); 00127 devW .change_dim (NCps); 00128 De .change_dim (NCps,NCps); 00129 Dep .change_dim (NCps,NCps); 00130 VDe .change_dim (NCps); 00131 DeW .change_dim (NCps); 00132 s .change_dim (NCps); 00133 dthdsig.change_dim (NCps); 00134 dgdsig .change_dim (NCps); 00135 dI1dsig.change_dim (NCps); 00136 dI2dsig.change_dim (NCps); 00137 dI3dsig.change_dim (NCps); 00138 I .change_dim (NCps); 00139 set_to_zero(I); 00140 I(0) = 1.0; 00141 I(1) = 1.0; 00142 I(2) = 1.0; 00143 00144 if (!Derived) // for instance, CamClay 00145 { 00146 // parameters 00147 if (!Prms.HasKey("E")) throw new Fatal("ProblemEP::ProblemEP: Young modulus (E) must be provided"); 00148 if (!Prms.HasKey("nu")) throw new Fatal("ProblemEP::ProblemEP: Poisson coefficient (nu) must be provided"); 00149 E = Prms("E"); 00150 nu = Prms("nu"); 00151 if (Prms.HasKey("DP")) FC = DP_t; 00152 if (Prms.HasKey("MC")) FC = MC_t; 00153 if (Prms.HasKey("MN")) FC = MN_t; 00154 if (FC==VM_t) 00155 { 00156 if (Prms.HasKey("sY")) kVM = sqrt(2.0/3.0)*Prms("sY"); 00157 else if (Prms.HasKey("c")) kVM = (GTy==psa_t ? sqrt(2.0)*Prms("c") : 2.0*sqrt(2.0/3.0)*Prms("c")); 00158 else throw new Fatal("ProblemEP::ProblemEP: With VM (von Mises), either sY (uniaxial yield stress) or c (undrained cohesion) must be provided"); 00159 } 00160 else 00161 { 00162 if (!Prms.HasKey("phi")) throw new Fatal("ProblemEP::ProblemEP: friction angle phi (degrees) must be provided"); 00163 double c = (Prms.HasKey("c") ? Prms("c") : 0.0); 00164 double phi_deg = Prms("phi"); 00165 double phi_rad = phi_deg*Util::PI/180.0; 00166 double psi_rad = 0.0; 00167 if (phi_deg<1.0e-3) throw new Fatal("ProblemEP::ProblemEP: Friction angle (phi [deg]) must be greater than zero (1.0e-3). phi=%g is invalid",phi_deg); 00168 if (c<0.0) throw new Fatal("ProblemEP::ProblemEP: 'cohesion' must be greater than zero. c=%g is invalid",c); 00169 if (Prms.HasKey("psi")) 00170 { 00171 NonAssoc = true; 00172 psi_rad = Prms("psi")*Util::PI/180.0; 00173 } 00174 sphi = sin(phi_rad); 00175 spsi = sin(psi_rad); 00176 if (FC==DP_t) kDP = 2.0*sqrt(2.0)*sphi/(3.0-sphi); 00177 if (FC==MN_t) kMN = 9.0+8.0*pow(tan(phi_rad),2.0); 00178 } 00179 00180 // hardening 00181 if (Prms.HasKey("Hp")) Hb = (2.0/3.0)*Prms("Hp"); // Hp=H_prime 00182 00183 // internal values 00184 NIvs = 3; 00185 Y.change_dim (NIvs); 00186 H.change_dim (NIvs); 00187 IvNames.Push ("z0"); 00188 IvNames.Push ("evp"); 00189 IvNames.Push ("edp"); 00190 00191 // name 00192 switch (FC) 00193 { 00194 case VM_t: { Name = "ProblemEP(VM)"; break; } 00195 case DP_t: { Name = "ProblemEP(DP)"; break; } 00196 case MC_t: { Name = "ProblemEP(MC)"; break; } 00197 case MN_t: { Name = "ProblemEP(MN)"; break; } 00198 } 00199 00200 // set model in stress update 00201 SUp.SetModel (this); 00202 } 00203 00204 // new stress update parmeters 00205 NewSU = (Prms.HasKey("newsu") ? (int)Prms("newsu") : false); 00206 if (NewSU) 00207 { 00208 BetSU = Prms("betsu"); 00209 AlpSU = Prms("alpsu"); 00210 } 00211 } 00212 00213 inline void ProblemEP::TgIncs (State const * Sta, Vec_t & DEps, Vec_t & DSig, Vec_t & DIvs) const 00214 { 00215 // state 00216 EquilibState const * sta = static_cast<EquilibState const *>(Sta); 00217 00218 // zero internal values (if any) 00219 DIvs.change_dim (NIvs); 00220 set_to_zero (DIvs); 00221 00222 // De: elastic stiffness 00223 ELStiff (sta->Sig, sta->Ivs); 00224 00225 // increments 00226 if (sta->Ldg) 00227 { 00228 // limit tensile strength 00229 /* 00230 if (FC!=VM_t) 00231 { 00232 p = Calc_poct (sta->Sig); 00233 if (p<pTol) 00234 { 00235 printf("ProblemEP::TgIncs: __tensile_loading__\n"); 00236 if (!Derived) // plastic strains 00237 { 00238 DIvs(1) = Calc_ev (DEps); // devp 00239 DIvs(2) = Calc_ed (DEps); // dedp 00240 } 00241 set_to_zero (DSig); 00242 return; 00243 } 00244 } 00245 */ 00246 00247 // gradients, flow rule, hardening, and hp 00248 Gradients (sta->Sig, sta->Ivs); 00249 FlowRule (sta->Sig, sta->Ivs); 00250 Hardening (sta->Sig, sta->Ivs); 00251 double hp = (NIvs>0 ? Y(0)*H(0) : 0.0); 00252 00253 // plastic multiplier 00254 Mult (V, De, VDe); 00255 double phi = dot(VDe,W) - hp; 00256 double Lam = dot(VDe,DEps)/phi; 00257 00258 // increments 00259 DEpsPl = Lam*W; 00260 DEpsEl = DEps - DEpsPl; 00261 DSig = De*DEpsEl; 00262 00263 // increment of internal values 00264 DIvs = Lam*H; 00265 00266 // plastic strains 00267 if (!Derived) 00268 { 00269 DIvs(1) = Calc_ev (DEpsPl); // devp 00270 DIvs(2) = Calc_ed (DEpsPl); // dedp 00271 } 00272 } 00273 else 00274 { 00275 // stress increment 00276 DSig = De*DEps; 00277 00278 // new stress update 00279 if (NewSU) DIvs(0) = -dot(V, DSig) / Y(0); 00280 } 00281 00282 // correct strain increment for plane stress 00283 if (GTy==pse_t) DEps(2) = -nu*(DSig(0)+DSig(1))/CalcE(sta->Sig, sta->Ivs); 00284 } 00285 00286 inline void ProblemEP::Stiffness (State const * Sta, Mat_t & D) const 00287 { 00288 // state 00289 EquilibState const * sta = static_cast<EquilibState const *>(Sta); 00290 00291 // De: elastic stiffness 00292 ELStiff (sta->Sig, sta->Ivs); 00293 00294 // stiffness 00295 if (sta->Ldg) 00296 { 00297 // limit tensile strength 00298 /* 00299 if (FC!=VM_t) 00300 { 00301 p = Calc_poct (sta->Sig); 00302 if (p<pTol) 00303 { 00304 D.change_dim (NCps,NCps); 00305 set_to_zero (D); 00306 return; 00307 } 00308 } 00309 */ 00310 00311 // gradients, flow rule, hardening, and hp 00312 Gradients (sta->Sig, sta->Ivs); 00313 FlowRule (sta->Sig, sta->Ivs); 00314 Hardening (sta->Sig, sta->Ivs); 00315 double hp = (NIvs>0 ? Y(0)*H(0) : 0.0); 00316 00317 // auxiliary vectors 00318 Mult (V, De, VDe); 00319 double phi = dot(VDe,W) - hp; 00320 DeW = De*W; 00321 00322 // elastoplastic stiffness 00323 D.change_dim (NCps, NCps); 00324 for (size_t i=0; i<NCps; ++i) 00325 for (size_t j=0; j<NCps; ++j) 00326 D(i,j) = De(i,j) - DeW(i)*VDe(j)/phi; 00327 } 00328 else D = De; 00329 00330 // plane stress 00331 if (GTy==pse_t) 00332 { 00333 for (size_t i=0; i<NCps; ++i) 00334 { 00335 D(2,i) = 0.0; 00336 D(i,2) = 0.0; 00337 } 00338 } 00339 } 00340 00341 inline size_t ProblemEP::CorrectDrift (State * Sta) const 00342 { 00343 // state 00344 EquilibState * sta = static_cast<EquilibState *>(Sta); 00345 00346 // limit tensile strength 00347 /* 00348 if (FC!=VM_t) 00349 { 00350 p = Calc_poct (sta->Sig); 00351 if (p<pTol) { p = pTol; return 666; } 00352 } 00353 */ 00354 00355 // iterations 00356 double fnew = YieldFunc (sta->Sig, sta->Ivs); 00357 size_t it = 0; 00358 while (fnew>DCFTol && it<DCMaxIt) 00359 { 00360 // gradients, flow rule, hardening, and hp 00361 Gradients (sta->Sig, sta->Ivs); 00362 FlowRule (sta->Sig, sta->Ivs); 00363 Hardening (sta->Sig, sta->Ivs); 00364 double hp = (NIvs>0 ? Y(0)*H(0) : 0.0); 00365 00366 // elastic stiffness 00367 if (it==0) ELStiff (sta->Sig, sta->Ivs); 00368 00369 // auxiliary vectors 00370 Mult (V, De, VDe); 00371 double dgam = fnew/(dot(VDe,W)-hp); 00372 DeW = De*W; 00373 00374 // update stress and ivs (only) 00375 sta->Sig -= dgam*DeW; 00376 sta->Ivs += dgam*H; 00377 fnew = YieldFunc (sta->Sig, sta->Ivs); 00378 00379 // check convergence 00380 if (fabs(fnew)<DCFTol) break; 00381 it++; 00382 } 00383 00384 // check number of iterations 00385 if (it>=DCMaxIt) throw new Fatal("ProblemEP::CorrectDrift: Yield surface drift correction did not converge after %d iterations (fnew=%g, DCFTol=%g)",it,fnew,DCFTol); 00386 return it; 00387 } 00388 00389 inline bool ProblemEP::LoadCond (State const * Sta, Vec_t const & DEps, double & alpInt) const 00390 { 00391 // default return values 00392 alpInt = -1.0; // no intersection 00393 bool ldg = false; // => unloading (or crossing) 00394 00395 // current state 00396 EquilibState const * sta = static_cast<EquilibState const *>(Sta); 00397 00398 // trial state 00399 ELStiff (sta->Sig, sta->Ivs); 00400 DSigTr = De * DEps; 00401 SigA = sta->Sig + DSigTr; 00402 00403 // yield function values 00404 double f = YieldFunc (sta->Sig, sta->Ivs); 00405 double f_tr = YieldFunc (SigA, sta->Ivs); 00406 00407 // numerator of Lagrange multiplier 00408 Gradients (sta->Sig, sta->Ivs); 00409 double numL = dot(V, DSigTr); 00410 printf("f=%g, ftr=%g, numL=%g\n",f,f_tr,numL); 00411 00412 // new stress update 00413 if (NewSU) 00414 { 00415 q = Calc_qoct (sta->Sig); 00416 if (q>qTol) 00417 { 00418 if (numL>0.0) ldg = true; 00419 } 00420 else 00421 { 00422 double qf = Calc_qoct (SigA); 00423 double Dq = qf - q; 00424 if (Dq>0.0) ldg = true; 00425 } 00426 printf(">>>>>>> (new su) >>>>>>>>>>> f=%g, ftr=%g, ldg=%d\n",f,f_tr,ldg); 00427 return ldg; 00428 } 00429 00430 // going outside 00431 if (f_tr>0.0) 00432 { 00433 bool crossing = false; 00434 if (f<-FTol && f_tr>FTol) // (f<0.0) does not work, (f<-FTol) does not work 00435 { 00436 Sig0 = sta->Sig; 00437 Ivs0 = sta->Ivs; 00438 crossing = true; 00439 } 00440 else if (numL<-qTol) // (numL<0.0) does not work, since it may be equal to -0.0 => neutral loading 00441 { 00442 // moving stress state slighlty to the inside of the yield surface in order to have f=-FTol 00443 double df = -FTol - f; 00444 double dalp = df / numL; // numL = dfdalpha 00445 Sig0 = sta->Sig + dalp*DSigTr; 00446 Ivs0 = sta->Ivs; 00447 crossing = true; 00448 double fnew = YieldFunc (Sig0, Ivs0); 00449 if (fnew>0.0) throw new Fatal("ProblemEP::LoadCond: __internal_error__: correction for numL<0 failed (dalp=%g, fnew=%g)",dalp,fnew); 00450 //throw new Fatal("ProblemEP::LoadCond: Strain increment is too large (f=%g, f_tr=%g, numL=%g). Crossing and going all the way through the yield surface to the other side.",f,f_tr,numL); 00451 } 00452 if (crossing) 00453 { 00454 Numerical::Root<ProblemEP> root(const_cast<ProblemEP*>(this), &ProblemEP::Fa, &ProblemEP::dFada); 00455 //root.Scheme = "Newton"; 00456 //root.Verbose = true; 00457 alpInt = root.Solve (0.0, 1.0); 00458 if (alpInt<0) throw new Fatal("ProblemEP::LoadCond: alpInt=%g must be positive",alpInt); 00459 } 00460 else ldg = true; 00461 } 00462 00463 // return true if there is loading. returns false (unloading) with intersection 00464 return ldg; 00465 } 00466 00467 inline void ProblemEP::InitIvs (SDPair const & Ini, State * Sta) const 00468 { 00469 // initialize state 00470 EquilibState * sta = static_cast<EquilibState*>(Sta); 00471 sta->Init (Ini, NIvs); 00472 00473 // internal variables 00474 sta->Ivs(0) = 1.0; // z0 00475 sta->Ivs(1) = 0.0; // evp 00476 sta->Ivs(2) = 0.0; // edp 00477 00478 // new stress update 00479 if (NewSU) 00480 { 00481 switch (FC) 00482 { 00483 case VM_t: 00484 { 00485 q = Calc_qoct (sta->Sig); 00486 sta->Ivs(0) = q/kVM; 00487 break; 00488 } 00489 case DP_t: 00490 { 00491 Calc_pq (sta->Sig); 00492 sta->Ivs(0) = q/(p*kDP); 00493 break; 00494 } 00495 case MC_t: 00496 { 00497 Calc_pqg (sta->Sig); 00498 sta->Ivs(0) = q/(p*g); 00499 break; 00500 } 00501 case MN_t: 00502 { 00503 CharInvs (sta->Sig, I1,I2,I3); 00504 sta->Ivs(0) = I1*I2/(I3*kMN); 00505 break; 00506 } 00507 } 00508 } 00509 00510 // check initial yield function 00511 double f = YieldFunc (sta->Sig, sta->Ivs); 00512 if (f>FTol) throw new Fatal("ProblemEP:InitIvs: stress point (sig=(%g,%g,%g,%g]) is outside yield surface (f=%g) with z0=%g",sta->Sig(0),sta->Sig(1),sta->Sig(2),sta->Sig(3)/Util::SQ2,f,sta->Ivs(0)); 00513 if (NewSU && f<-FTol) throw new Fatal("ProblemEP:InitIvs: stress point (sig=(%g,%g,%g,%g]) is outside yield surface (f=%g) with z0=%g",sta->Sig(0),sta->Sig(1),sta->Sig(2),sta->Sig(3)/Util::SQ2,f,sta->Ivs(0)); 00514 } 00515 00516 inline void ProblemEP::Gradients (Vec_t const & Sig, Vec_t const & Ivs) const 00517 { 00518 // derivative of internal values 00519 Y(0) = 0.0; // dfdz0 00520 Y(1) = 0.0; // dfdz1 00521 Y(2) = 0.0; // dfdz2 00522 00523 // new stress update 00524 if (NewSU) Y(0) = -1.0; 00525 00526 // limit tensile strength 00527 /* 00528 if (FC!=VM_t) 00529 { 00530 p = Calc_poct (Sig); 00531 if (p<pTol) { V = I; return; } 00532 } 00533 */ 00534 00535 switch (FC) 00536 { 00537 case VM_t: 00538 { 00539 OctInvs (Sig, p,q,s, qTol); 00540 V = s/(q*kVM); 00541 break; 00542 } 00543 case DP_t: 00544 { 00545 OctInvs (Sig, p,q,s, qTol); 00546 V = (1.0/(p*q*kDP))*s + (q/(p*p*kDP*Util::SQ3))*I; 00547 break; 00548 } 00549 case MC_t: 00550 { 00551 Calc_dgdsig (Sig); 00552 V = (q/(g*p*p*Util::SQ3))*I + (1.0/(p*q*g))*s - (q/(p*g*g))*dgdsig; 00553 break; 00554 } 00555 case MN_t: 00556 { 00557 CharInvs (Sig, I1,I2,I3, dI1dsig,dI2dsig,dI3dsig); 00558 V = (I2/(I3*kMN))*dI1dsig + (I1/(I3*kMN))*dI2dsig - (I1*I2/(I3*I3*kMN))*dI3dsig; 00559 break; 00560 } 00561 } 00562 } 00563 00564 inline void ProblemEP::FlowRule (Vec_t const & Sig, Vec_t const & Ivs) const 00565 { 00566 switch (FC) 00567 { 00568 case VM_t: { W = V; break; } 00569 case DP_t: { W = V; break; } 00570 case MC_t: 00571 { 00572 if (NonAssoc) 00573 { 00574 Calc_dgdsig (Sig, true); 00575 //W = (q/(g*p*p*Util::SQ3))*I + (1.0/(p*q*g))*s - (q/(p*g*g))*dgdsig; 00576 W = (g/Util::SQ3)*I + (1.0/q)*s - p*dgdsig; 00577 } 00578 else W = V; 00579 break; 00580 } 00581 case MN_t: { W = V; break; } 00582 } 00583 } 00584 00585 inline void ProblemEP::Hardening (Vec_t const & Sig, Vec_t const & Ivs) const 00586 { 00587 // internal values 00588 H(0) = 0.0; 00589 H(1) = 0.0; 00590 H(2) = 0.0; 00591 00592 // new stress update 00593 if (NewSU) 00594 { 00595 double F; 00596 switch (FC) 00597 { 00598 case VM_t: 00599 { 00600 q = Calc_qoct (Sig); 00601 F = q/kVM - 1.0; 00602 break; 00603 } 00604 case DP_t: 00605 { 00606 Calc_pq (Sig); 00607 F = q/(p*kDP) - 1.0; 00608 break; 00609 } 00610 case MC_t: 00611 { 00612 Calc_pqg (Sig); 00613 F = q/(p*g) - 1.0; 00614 break; 00615 } 00616 case MN_t: 00617 { 00618 CharInvs (Sig, I1,I2,I3); 00619 F = I1*I2/(I3*kMN) - 1.0; 00620 break; 00621 } 00622 } 00623 double H1 = 0.0; 00624 if (F>0.0) F = 0.0; 00625 H(0) = AlpSU + (H1-AlpSU)*exp(BetSU*F); 00626 } 00627 } 00628 00629 inline double ProblemEP::YieldFunc (Vec_t const & Sig, Vec_t const & Ivs) const 00630 { 00631 // limit tensile strength 00632 /* 00633 if (FC!=VM_t) 00634 { 00635 p = Calc_poct (Sig); 00636 if (p<pTol) { return FTol; } 00637 } 00638 */ 00639 00640 double f; 00641 switch (FC) 00642 { 00643 case VM_t: 00644 { 00645 q = Calc_qoct (Sig); 00646 f = q/kVM - Ivs(0); 00647 break; 00648 } 00649 case DP_t: 00650 { 00651 Calc_pq (Sig); 00652 f = q/(p*kDP) - Ivs(0); 00653 break; 00654 } 00655 case MC_t: 00656 { 00657 Calc_pqg (Sig); 00658 f = q/(p*g) - Ivs(0); 00659 break; 00660 } 00661 case MN_t: 00662 { 00663 CharInvs (Sig, I1,I2,I3); 00664 f = I1*I2/(I3*kMN) - Ivs(0); 00665 break; 00666 } 00667 } 00668 return f; 00669 } 00670 00671 inline void ProblemEP::ELStiff (Vec_t const & Sig, Vec_t const & Ivs) const 00672 { 00673 if (NDim==2) 00674 { 00675 if (GTy==pse_t) 00676 { 00677 double c = CalcE(Sig,Ivs)/(1.0-nu*nu); 00678 De = c, c*nu, 0.0, 0.0, 00679 c*nu, c, 0.0, 0.0, 00680 0.0, 0.0, 0.0, 0.0, 00681 0.0, 0.0, 0.0, c*(1.0-nu); 00682 } 00683 else if (GTy==psa_t || GTy==axs_t) 00684 { 00685 double c = CalcE(Sig,Ivs)/((1.0+nu)*(1.0-2.0*nu)); 00686 De = c*(1.0-nu), c*nu , c*nu , 0.0, 00687 c*nu , c*(1.0-nu), c*nu , 0.0, 00688 c*nu , c*nu , c*(1.0-nu), 0.0, 00689 0.0 , 0.0 , 0.0 , c*(1.0-2.0*nu); 00690 } 00691 else throw new Fatal("ProblemEP::Stiffness: 2D: This model is not available for GeometryType = %s",GTypeToStr(GTy).CStr()); 00692 } 00693 else 00694 { 00695 if (GTy==d3d_t) 00696 { 00697 double c = CalcE(Sig,Ivs)/((1.0+nu)*(1.0-2.0*nu)); 00698 De = c*(1.0-nu), c*nu , c*nu , 0.0, 0.0, 0.0, 00699 c*nu , c*(1.0-nu), c*nu , 0.0, 0.0, 0.0, 00700 c*nu , c*nu , c*(1.0-nu), 0.0, 0.0, 0.0, 00701 0.0 , 0.0 , 0.0 , c*(1.0-2.0*nu), 0.0, 0.0, 00702 0.0 , 0.0 , 0.0 , 0.0, c*(1.0-2.0*nu), 0.0, 00703 0.0 , 0.0 , 0.0 , 0.0, 0.0, c*(1.0-2.0*nu); 00704 } 00705 else throw new Fatal("ProblemEP::Stiffness: 3D: This model is not available for GeometryType = %s",GTypeToStr(GTy).CStr()); 00706 } 00707 } 00708 00709 00711 00712 00713 Model * ProblemEPMaker(int NDim, SDPair const & Prms, Model const * O) { return new ProblemEP(NDim,Prms); } 00714 00715 int ProblemEPRegister() 00716 { 00717 ModelFactory ["ProblemEP"] = ProblemEPMaker; 00718 MODEL.Set ("ProblemEP", (double)MODEL.Keys.Size()); 00719 MODEL_PRM_NAMES["ProblemEP"].Resize (14); 00720 MODEL_PRM_NAMES["ProblemEP"] = "E", "nu", "sY", "c", "phi", "Hp", "psi", "VM", "DP", "MC", "MN", "newsu", "betsu", "alpsu"; 00721 MODEL_IVS_NAMES["ProblemEP"].Resize (0); 00722 return 0; 00723 } 00724 00725 int __ProblemEP_dummy_int = ProblemEPRegister(); 00726 00727 00728 #endif // MECHSYS_PROBLEMEP_H