MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/models/bbmx.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_BBMX_H
00021 #define MECHSYS_BBMX_H
00022 
00023 // MechSys
00024 #include <mechsys/models/model.h>
00025 
00026 class BBMx : public Model
00027 {
00028 public:
00029     // Constructor
00030     BBMx (int NDim, SDPair const & Prms);
00031 
00032     // Derived methods
00033     void   InitIvs      (SDPair const & Ini, State * Sta)                                                    const;
00034     void   TgIncs       (State const * Sta, double pw, Vec_t & DEps, double Dpw, Vec_t & DSig, Vec_t & DIvs) const;
00035     void   Stiffness    (State const * Sta, double pw, Mat_t & D, Vec_t & d)                                 const;
00036     bool   LoadCond     (State const * Sta, double pw, Vec_t const & DEps, double Dpw)                       const;
00037     size_t CorrectDrift (State * Sta, double & pw)                                                           const;
00038 
00039     // Internal methods
00040     void Gradients  (Vec_t const & Sig, Vec_t const & Ivs, double pc) const;
00041     void Hardening  (Vec_t const & Sig, Vec_t const & Ivs, double pc) const;
00042     void Calc_De_de (Vec_t const & Sig, Vec_t const & Ivs, double pc) const;
00043 
00044     // Parameters and constants
00045     double lam0,kap,phi,nu,r,bet,kc,lams,kaps,B,c0,c1;
00046     double Mcs,wcs,pref;
00047 
00048     // Initial values
00049     mutable double v0;
00050 
00051     // Data
00052     double qTol; 
00053 
00054     // Scratchpad
00055     mutable double p, q, t, th;  
00056     mutable Vec_t  dthdsig;      
00057     mutable Vec_t  s;            
00058     mutable Vec_t  V;            
00059     mutable double S;            
00060     mutable Vec_t  W;            
00061     mutable Vec_t  Y;            
00062     mutable Vec_t  H;            
00063     mutable Mat_t  De;           
00064     mutable Vec_t  de;           
00065     mutable Mat_t  Dep;          
00066     mutable Vec_t  VDe;          
00067     mutable Vec_t  DeW;          
00068     mutable Vec_t  DEpsEl;       
00069     mutable Vec_t  DEpsPl;       
00070     mutable Vec_t  DSigTr;       
00071 
00072     // Auxiliary methods
00073     double Calc_lam (double pc)            const { return (pc>0.0 ? lam0*((1.0-r)*exp(-bet*pc)+r) : lam0);                  }
00074     double Calc_psi (double pc)            const { return (pc>0.0 ? (lam0-kap)/(Calc_lam(pc)-kap) : 1.0);                   }
00075     double Calc_ps  (double pc)            const { return (pc>0.0 ? kc*pc : pc);                                            }
00076     double Calc_p0  (double z0, double pc) const { return (pc>0.0 ? pref*pow(z0/pref, Calc_psi(pc)) : z0-pc);               }
00077     double Calc_C   (double z1, double pc) const { return (pc>0.0 ? pref*pref*(exp(B*(pc-z1)/pref)-exp(-B*z1/pref)) : 0.0); } 
00078     double Calc_M   (double sin3th)        const { return Mcs*pow(2.0*wcs/(1.0+wcs-(1.0-wcs)*sin3th),1.0/4.0);              }
00079 };
00080 
00081 
00083 
00084 
00085 inline BBMx::BBMx (int NDim, SDPair const & Prms)
00086     : Model (NDim, Prms, /*niv*/4, "BBMx"), pref(1.0), qTol(1.0e-7)
00087 {
00088     // set hm model
00089     HMCoup = true;
00090 
00091     // parameters
00092     lam0  = Prms("lam0");
00093     kap   = Prms("kap");
00094     phi   = Prms("phi");
00095     nu    = Prms("nu");
00096     r     = Prms("r");
00097     bet   = Prms("bet");
00098     kc    = Prms("kc");
00099     lams  = Prms("lams");
00100     kaps  = Prms("kaps");
00101     B     = Prms("B");
00102     c0    = Prms("c0");
00103     c1    = Prms("c1");
00104 
00105     // constants
00106     double sin_phi = sin(phi*Util::PI/180.0);
00107     Mcs = Phi2M(phi,"oct");
00108     wcs = pow((3.0-sin_phi)/(3.0+sin_phi),4.0);
00109 
00110     // internal values
00111     IvNames = "z0", "z1", "z2", "z3";
00112 
00113     // check
00114     if (GTy==pse_t) throw new Fatal("BBMx::BBMx: This model does not work for plane-stress (pse)");
00115 
00116     // allocate memory
00117     s      .change_dim (NCps);
00118     dthdsig.change_dim (NCps);
00119     V      .change_dim (NCps);
00120     W      .change_dim (NCps);
00121     Y      .change_dim (NIvs);
00122     H      .change_dim (NIvs);
00123     De     .change_dim (NCps,NCps);
00124     de     .change_dim (NCps);
00125     Dep    .change_dim (NCps,NCps);
00126     VDe    .change_dim (NCps);
00127     DeW    .change_dim (NCps);
00128     DEpsEl .change_dim (NCps);
00129     DEpsPl .change_dim (NCps);
00130     DSigTr .change_dim (NCps);
00131 }
00132 
00133 inline void BBMx::InitIvs (SDPair const & Ini, State * Sta) const
00134 {
00135     // initialize state
00136     EquilibState * sta = static_cast<EquilibState*>(Sta);
00137     sta->Init (Ini, NIvs);
00138     v0 = Ini("v0");
00139 
00140     // invariants
00141     OctInvs (sta->Sig, p,q,t,th,s, qTol);
00142     double M = Calc_M (t);
00143 
00144     // internal variables
00145     double pc0 = -Ini("pw");
00146     double p0  = p+(q*q)/(p*M*M);
00147     double OCR = (Ini.HasKey("OCR") ? Ini("OCR") : 1.0);
00148     double OSI = (Ini.HasKey("OSI") ? Ini("OSI") : 1.0);
00149     sta->Ivs(0) = p0;
00150     sta->Ivs(1) = pc0;
00151     sta->Ivs(2) = OCR*p0;
00152     sta->Ivs(3) = sta->Ivs(1) + OSI;
00153 }
00154 
00155 inline void BBMx::TgIncs (State const * Sta, double pw, Vec_t & DEps, double Dpw, Vec_t & DSig, Vec_t & DIvs) const
00156 {
00157     // state
00158     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00159 
00160     // zero internal values
00161     DIvs.change_dim (NIvs);
00162     set_to_zero     (DIvs);
00163 
00164     // De and de: elastic stiffness
00165     double pc  = -pw;
00166     double Dpc = -Dpw;
00167     Calc_De_de (sta->Sig, sta->Ivs, pc);
00168 
00169     // increments
00170     if (sta->Ldg)
00171     {
00172         // gradients, flow rule, hardening, and hp
00173         Gradients (sta->Sig, sta->Ivs, pc);
00174         Hardening (sta->Sig, sta->Ivs, pc);
00175         double hp = Y(0)*H(0) + Y(1)*H(1);
00176 
00177         // plastic multiplier
00178         Mult (V, De, VDe);
00179         double phi = dot(VDe,W) - hp;
00180         double Lam = (dot(VDe,DEps) + dot(V,de)*Dpc + S*Dpc)/phi;
00181 
00182         // increments
00183         DEpsPl = Lam*W;
00184         DEpsEl = DEps - DEpsPl;
00185         DSig   = De*DEpsEl;
00186 
00187         // increment of internal values
00188         DIvs = Lam*H;
00189     }
00190     else
00191     {
00192         // stress increment
00193         DSig = De*DEps;
00194 
00195         // new stress update
00196         DIvs(0) = -dot(V, DSig) / Y(0);
00197         DIvs(1) = Dpc;
00198     }
00199 }
00200 
00201 inline void BBMx::Stiffness (State const * Sta, double pw, Mat_t & D, Vec_t & d) const
00202 {
00203     // state
00204     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00205 
00206     // De and de: elastic stiffness
00207     double pc = -pw;
00208     Calc_De_de (sta->Sig, sta->Ivs, pc);
00209 
00210     // stiffness
00211     if (sta->Ldg)
00212     {
00213         // gradients, flow rule, hardening, and hp
00214         Gradients (sta->Sig, sta->Ivs, pc);
00215         Hardening (sta->Sig, sta->Ivs, pc);
00216         double hp = Y(0)*H(0) + Y(1)*H(1);
00217 
00218         // auxiliary vectors
00219         Mult (V, De, VDe);
00220         double phi = dot(VDe,W) - hp;
00221         DeW = De*W;
00222 
00223         // elastoplastic stiffness
00224         D.change_dim (NCps, NCps);
00225         for (size_t i=0; i<NCps; ++i)
00226         for (size_t j=0; j<NCps; ++j)
00227             D(i,j) = De(i,j) - DeW(i)*VDe(j)/phi;
00228 
00229         // dep
00230         d = de - ((dot(V,de)+S)/phi)*DeW;
00231     }
00232     else
00233     {
00234         D = De;
00235         d = de;
00236     }
00237 }
00238 
00239 inline bool BBMx::LoadCond (State const * Sta, double pw, Vec_t const & DEps, double Dpw) const
00240 {
00241     // state
00242     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00243 
00244     // numerator of Lagrange multiplier
00245     double pc  = -pw;
00246     double dpc = -Dpw;
00247     Calc_De_de (sta->Sig, sta->Ivs, pc);
00248     Gradients  (sta->Sig, sta->Ivs, pc);
00249     DSigTr = De * DEps;
00250     double numL = dot(V, DSigTr) + dot(V,de)*dpc + S*dpc;
00251     if (numL>0.0) return true;
00252     else          return false;
00253 }
00254 
00255 inline size_t BBMx::CorrectDrift (State * Sta, double & pw) const
00256 {
00257     // state
00258     //EquilibState * sta = static_cast<EquilibState *>(Sta);
00259 
00260     // iterations
00261     //double fnew = YieldFunc (sta->Sig, sta->Ivs, pw);
00262     size_t it   = 0;
00263     /*
00264     while (fnew>DCFTol && it<DCMaxIt)
00265     {
00266         // gradients, flow rule, hardening, and hp
00267         Gradients (sta->Sig, sta->Ivs, -pw);
00268         Hardening (sta->Sig, sta->Ivs, -pw);
00269         double hp = Y(0)*H(0) + Y(1)*H(1);
00270 
00271         // elastic stiffness
00272         if (it==0) Calc_De_de (sta->Sig, sta->Ivs, -pw);
00273 
00274         // auxiliary vectors
00275         Mult (V, De, VDe);
00276         double dgam = fnew/(dot(VDe,W)-hp);
00277         DeW = De*W;
00278 
00279         // update stress and ivs (only)
00280         sta->Sig -= dgam*DeW;
00281         sta->Ivs += dgam*H;
00282         fnew = YieldFunc (sta->Sig, sta->Ivs);
00283         //if (NewSU) fnew = fabs(fnew); // TODO: should do this, but it does not converge
00284 
00285         // check convergence
00286         if (fabs(fnew)<DCFTol) break;
00287         it++;
00288     }
00289 
00290     // check number of iterations
00291     if (it>=DCMaxIt) throw new Fatal("BBMx::CorrectDrift: Yield surface drift correction did not converge after %d iterations (fnew=%g, DCFTol=%g)",it,fnew,DCFTol);
00292     */
00293     return it;
00294 }
00295 
00296 inline void BBMx::Gradients (Vec_t const & Sig, Vec_t const & Ivs, double pc) const
00297 {
00298     // variables
00299     OctInvs (Sig, p,q,t,th,s, qTol, &dthdsig);
00300     double lam = Calc_lam (pc);
00301     double psi = Calc_psi (pc);
00302     double ps  = Calc_ps  (pc);
00303     double p0  = Calc_p0  (Ivs(0), pc);
00304 
00305     // auxiliary variables
00306     double M    = Calc_M (t);
00307     double MM   = M*M;
00308     double dfdp = MM*(2.0*p+ps-p0);
00309     double m    = -dfdp/Util::SQ3;
00310 
00311     // gradients: pc
00312     double dCdpc  =  0.0;
00313     double dp0dpc = -1.0;
00314     double dpsdpc =  1.0;
00315     if (pc>0.0)
00316     {
00317         double dlamdpc = -bet*lam0*(1.0-r)*exp(-bet*pc);
00318         double dpsidpc = (-psi/(lam-kap))*dlamdpc;
00319         dCdpc  = pref*B*exp(B*(pc-Ivs(1))/pref);
00320         dp0dpc = p0*log(Ivs(0)/pref)*dpsidpc;
00321         dpsdpc = kc;
00322     }
00323     S = dCdpc - MM*dpsdpc*(p0-p) - MM*dp0dpc*(ps+p);
00324 
00325     // gradients: sig
00326     if (q>qTol)
00327     {
00328         double dMdt  = 0.25*M*(1.0-wcs)/(1.0+wcs-(1.0-wcs)*t);
00329         double dtdth = 3.0*cos(3.0*th);
00330         double dMdth = dMdt*dtdth;
00331         double dfdth = -2.0*M*dMdth*(p0-p)*(ps+p);
00332         V = 2.0*s + m*I + dfdth*dthdsig;
00333     }
00334     else V = m*I;
00335     W = V;
00336 
00337     // internal variables
00338     double dCdz1  = 0.0;
00339     double dp0dz0 = 1.0;
00340     if (pc>0.0)
00341     {
00342         dCdz1  = -B*Calc_C(Ivs(1),pc)/pref;
00343         dp0dz0 = pref*psi*pow(Ivs(0)/pref,psi)/Ivs(0);
00344     }
00345     Y(0) = -MM*dp0dz0*(ps+p);
00346     Y(1) = dCdz1;
00347     Y(2) = 0.0;
00348     Y(3) = 0.0;
00349 }
00350 
00351 inline void BBMx::Hardening (Vec_t const & Sig, Vec_t const & Ivs, double pc) const
00352 {
00353     double trW   = W(0)+W(1)+W(2);
00354     double chi0  = -(lam0 - kap )/v0;
00355     double chis  = -(lams - kaps)/v0;
00356     double L0    = c0*pow(log(    Ivs(2)/     Ivs(0)) ,2.0);
00357     double L1    = c1*pow(log(1.0+Ivs(3)/(1.0+Ivs(1))),2.0);
00358     H(2) = Ivs(2)*trW/chi0;
00359     H(3) = Ivs(3)*trW/chis;
00360     H(0) = Ivs(0)*(trW+L0)/chi0;
00361     H(1) = Ivs(1)*(trW+L1)/chis;
00362 }
00363 
00364 inline void BBMx::Calc_De_de (Vec_t const & Sig, Vec_t const & Ivs, double pc) const
00365 {
00366     // bulk modulus
00367     double pcam = fabs(Sig(0)+Sig(1)+Sig(2))/3.0;
00368     double K    = pcam*v0/kap;
00369     double Kc   = pc  *v0/kaps;
00370 
00371     // elastic stiffness
00372     double G = Calc_G_ (K, nu);
00373     De = (2.0*G)*Psd + K*IdyI;
00374     if (pc>0.0) de = (-K/Kc)*I;
00375     else set_to_zero(de);
00376 }
00377 
00378 
00380 
00381 
00382 Model * BBMxMaker(int NDim, SDPair const & Prms, Model const * O) { return new BBMx(NDim,Prms); }
00383 
00384 int BBMxRegister()
00385 {
00386     ModelFactory   ["BBMx"] = BBMxMaker;
00387     MODEL.Set      ("BBMx", (double)MODEL.Keys.Size());
00388     MODEL_PRM_NAMES["BBMx"].Resize(12);
00389     MODEL_PRM_NAMES["BBMx"] = "lam0", "kap", "phi", "nu", "r", "bet", "kc", "lams", "kaps", "B", "c0", "c1";
00390     MODEL_IVS_NAMES["BBMx"].Resize(3);
00391     MODEL_IVS_NAMES["BBMx"] = "v0", "OCR", "OSI";
00392     return 0;
00393 }
00394 
00395 int __BBMx_dummy_int = BBMxRegister();
00396 
00397 #endif // MECHSYS_BBMX_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines