MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/models/problemep.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines