MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/models/unconv03.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_UNCONV03_H
00021 #define MECHSYS_UNCONV03_H
00022 
00023 // MechSys
00024 #include <mechsys/models/model.h>
00025 
00026 using std::cout;
00027 using std::endl;
00028 
00029 class Unconv03 : public Model
00030 {
00031 public:
00032     // Constructor
00033     Unconv03 (int NDim, SDPair const & Prms);
00034 
00035     // Derived methods
00036     void InitIvs    (SDPair const & Ini, State * Sta)                             const;
00037     void TgIncs     (State const * Sta, Vec_t & DEps, Vec_t & DSig, Vec_t & DIvs) const;
00038     void Stiffness  (State const * Sta, Mat_t & D)                                const;
00039     bool LoadCond   (State const * Sta, Vec_t const & DEps, double & alpInt)      const;
00040     void UpdatePath (State const * Sta, Vec_t const & DEps, Vec_t const & DSig)   const;
00041 
00042     // Data
00043     double         l0,l1,l3,betb,betbb; 
00044     mutable double v0,xR10,xR30;        
00045     mutable double K,G,nu;              
00046     double         M;                   
00047     Vec_t          I;                   
00048     mutable Mat_t  De;                  
00049     mutable double alpha;               
00050 
00051     // Scratchpad
00052     mutable Vec_t  V,Vb,VDe,DeW,devSig,depsEl; 
00053     mutable double p,q,t,A0,A2,R,c,yb;         
00054     mutable double lamb,lambb,kapbb,hp;        
00055 
00056 private:
00057     // internal methods
00058     void _calc_invariants_and_gradients (EquilibState const * Sta) const 
00059     {
00060         // invariants
00061         OctInvs (Sta->Sig, p,q,t);
00062         Dev     (Sta->Sig, devSig);
00063 
00064         // gradients
00065         R  = q/(M*p);
00066         //if (R>0.0)
00067         //{
00068             //A0 = exp(Sta->Ivs(0))*(1.0-sin(alpha));
00069             //A2 = (2.0/M)*sin(alpha);
00070         //}
00071         //else
00072         //{
00073             A0 = exp(Sta->Ivs(0));
00074             A2 = 0.0;
00075         //}
00076         V = ((R*R-1.0)/Util::SQ3)*I + (2.0/(M*M*p))*devSig;
00077         //yb = -1.0;
00078         yb = -M*M*p;
00079         //if (R>1.0) throw new Fatal("Unconv03::_calc_invariants_and_gradients: R(%g) must be smaller than 1",R);
00080     }
00081     void _calc_hardening (EquilibState const * Sta) const 
00082     {
00083         // internal variables
00084         double z0 = Sta->Ivs(0);
00085         double z1 = Sta->Ivs(1);
00086         double v  = Sta->Ivs(3);
00087 
00088         // isotropic coefficients
00089         double xR1    = xR10 + (log(v0/v))/l1;
00090         double distb  = z1 - xR1;
00091         double distbb = z1 - z0;
00092         double trW    = Tra(V);
00093         if (distb <0.0) distb  = 0.0;
00094         if (distbb<0.0) distbb = 0.0;
00095         lamb  = l3+(l1  -l3)*exp(-betb *distb);
00096         lambb = l0+(lamb-l0)*exp(-betbb*distbb);
00097         double H0 = -trW/lambb;
00098         Vb = V + (A0/(3.0*lambb*K))*I; // Vb = V + y0*HH0
00099 
00100         // deviatoric coefficients
00101         c = 2.0*G*(1.0-R);
00102         //c = 2.0*G*(1.0-exp(-1.0*(1.0-R)))/100.;
00103         if (q>1.0e-10) Vb += (A2*c/(2.0*G*q))*devSig;
00104         double H2 = c*2.0*R/M;
00105 
00106         // hardening coefficient
00107         hp = -A0*H0 - A2*H2;
00108         //cout << "c = " << c << ", A0 = " << A0 << ", H0 = " << H0 << ", A2 = " << A2 << ", H2 = " << H2 << ", hp = " << hp << endl;
00109     }
00110     double _calc_yield_function (EquilibState const * Sta) const
00111     {
00112         OctInvs (Sta->Sig, p,q,t);
00113         R = q/(M*p);
00114         return p*(1.0+R*R) - Sta->Ivs(2);
00115     }
00116 };
00117 
00118 
00120 
00121 
00122 inline Unconv03::Unconv03 (int NDim, SDPair const & Prms)
00123     : Model (NDim,Prms,5,"Unconv03"), alpha(0.0)
00124 {
00125     // parameters
00126     l0    = Prms("l0");
00127     l1    = Prms("l1");
00128     l3    = Prms("l3");
00129     betb  = Prms("betb");
00130     betbb = Prms("betbb");
00131     M     = Phi2M(Prms("phi"));
00132     nu    = Prms("nu"); // Poisson's coefficient
00133     //K     = Prms("K");  // bulk modulus
00134     //G     = Prms("G");  // shear modulus
00135     if (l3<l1) throw new Fatal("Unconv03::Unconv03: l3(%g) must be greater than or equal to l1(%g)",l3,l1);
00136 
00137     // constants
00138     I.change_dim (NCps);
00139     if (NDim==2) I = 1.0, 1.0, 1.0, 0.0;
00140     else         I = 1.0, 1.0, 1.0, 0.0, 0.0, 0.0;
00141 
00142     // internal values
00143     IvNames.Push ("z0"); // 0
00144     IvNames.Push ("z1"); // 1
00145     IvNames.Push ("pb"); // 2
00146     IvNames.Push ("v");  // 3: specific volume = 1+e
00147     IvNames.Push ("z2"); // 4
00148 
00149     // scratchpad
00150     V     .change_dim (NCps);
00151     Vb    .change_dim (NCps);
00152     VDe   .change_dim (NCps);
00153     DeW   .change_dim (NCps);
00154     devSig.change_dim (NCps);
00155     depsEl.change_dim (NCps);
00156 }
00157 
00158 inline void Unconv03::InitIvs (SDPair const & Ini, State * Sta) const
00159 {
00160     // initialize state
00161     EquilibState * sta = static_cast<EquilibState*>(Sta);
00162     sta->Init (Ini, NIvs);
00163 
00164     // NCL position and specific void
00165     xR10 = Ini("xR10");
00166     xR30 = Ini("xR30");
00167     v0   = Ini("v0");
00168 
00169     // invariants
00170     OctInvs (sta->Sig, p,q,t);
00171     R = q/(M*p);
00172 
00173     // calculate K and G
00174     K = v0*p/(l0*Util::SQ3);
00175     G = 3.0*K*(1.0-2.0*nu)/(2.0*(1.0+nu));
00176     //cout << "K = " << K << ", G = " << G << endl;
00177 
00178     // elastic stiffness
00179     if (GTy==pse_t) throw new Fatal("Unconv03::Unconv03: This model does not work for plane-stress (pse)");
00180     Mat_t Psd, IdyI;
00181     Calc_Psd  (NCps,Psd);
00182     Calc_IdyI (NCps,IdyI);
00183     De = (2.0*G)*Psd + K*IdyI;
00184 
00185     // internal variables
00186     double pb = p*(1.0+R*R);
00187     sta->Ivs(0) = log(pb);
00188     sta->Ivs(1) = xR30;
00189     sta->Ivs(2) = pb;
00190     sta->Ivs(3) = v0;
00191     sta->Ivs(4) = M*pb/2.0;
00192 
00193     // check initial yield function
00194     double f = _calc_yield_function(sta);
00195     if (f>1.0e-15) throw new Fatal("Unconv03:InitIvs: stress point (sig=(%g,%g,%g,%g], p=%g, q=%g) is outside yield surface (f=%g) with pb=%g",sta->Sig(0),sta->Sig(1),sta->Sig(2),sta->Sig(3)/Util::SQ2,p,q,f,pb);
00196 }
00197 
00198 inline void Unconv03::TgIncs (State const * Sta, Vec_t & DEps, Vec_t & DSig, Vec_t & DIvs) const
00199 {
00200     // state
00201     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00202 
00203     //cout << "DEps = " << PrintVector(DEps);
00204     //cout << "f    = " << _calc_yield_function(sta) << endl;
00205 
00206     // invariants and gradients
00207     _calc_invariants_and_gradients (sta); // calculate: devSig,p,q,t,V,yb,y0,y2
00208 
00209     // volume strain increment and internal variables
00210     double dev = Calc_ev(DEps);
00211     double v   = sta->Ivs(3);
00212     double pb  = sta->Ivs(2);
00213 
00214     // increments
00215     if (sta->Ldg)
00216     {
00217         // hardening
00218         _calc_hardening (sta);  // calculate: lamb,lambb,kapbb,Vb,hp
00219 
00220         // plastic multiplier
00221         Mult (Vb, De, VDe);
00222         double phi = dot(VDe,V) - hp;
00223         double gam = dot(VDe,DEps)/phi;
00224         //if (gam<0.0) throw new Fatal("Unconv03::TgIncs: Error: gam(%g)<0 for loading!",gam);
00225         // TODO: remove Loading method, since we can use this method from now on to check Ldg
00226 
00227         // stress increment
00228         depsEl = DEps - gam*V;
00229         DSig   = De*depsEl;
00230 
00231         //cout << "dev = " << dev << ", ded = " << Calc_ed(DEps) << endl;
00232         //cout << "DSig = " << PrintVector(DSig);
00233         //double gam_ = -dot(Vb,DSig)/hp;
00234         //cout << "gam = " << gam << ", gam_ = " << gam_ << endl;
00235 
00236         // increment of z2
00237         double ded = Calc_edoct(DEps);
00238         DIvs(4) = c*ded;
00239 
00240         // increment of internal values
00241         DIvs(0) = (-1.0/lambb)*dev;
00242         DIvs(1) = (-1.0/lamb )*dev;
00243         DIvs(2) = A0*DIvs(0) + A2*DIvs(4);
00244         DIvs(3) = v*dev;
00245 
00246         //cout << "alpha = " << alpha*180.0/Util::PI << "   ";
00247         //cout << DIvs(2) << "  ";
00248         //cout << (1.0-sin(alpha))*exp(z0)*DIvs(0) << "   " << 2.0*sin(alpha)*DIvs(2)/M << ",  dpb = " << DIvs(3) << endl;
00249 
00250         //Vec_t HH0((-1.0/(3.0*lambb*K))*I);
00251         //Vec_t HH2((-kapbb/(3.0*K))*I);
00252         //double dz0 = dot(HH0,DSig)+H0*gam;
00253         //double dz2 = dot(HH2,DSig)+H2*gam;
00254         //cout << "dz0 = " << dz0 << " == " << DIvs(0) << ",  dz2 = " << dz2 << " == " << DIvs(2) << endl;
00255     }
00256     else
00257     {
00258         // TODO: check this for unloading
00259         
00260         // stress increment
00261         DSig = De*DEps;
00262 
00263         // increment of internal values
00264         Vec_t VDe;
00265         Mult (V, De, VDe);
00266         DIvs(1) = 0.0;
00267         DIvs(2) = -dot(V,DSig)/yb;
00268         DIvs(3) = v*dev;
00269         DIvs(4) = 0.0;
00270         DIvs(0) = DIvs(2)/pb;
00271     }
00272 
00273     //cout << endl;
00274 }
00275 
00276 inline void Unconv03::Stiffness (State const * Sta, Mat_t & D) const
00277 {
00278     // state
00279     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00280 
00281     // stiffness
00282     if (sta->Ldg)
00283     {
00284         // invariants and gradients
00285         _calc_invariants_and_gradients (sta); // calculate: devSig,p,q,t,V,yb,y0,y2
00286 
00287         // hardening
00288         _calc_hardening (sta); // calculate: lamb,lambb,kapbb,Vb,hp
00289 
00290         // auxiliar vectors
00291         Mult (Vb, De, VDe);
00292         double phi = dot(VDe,V) - hp;
00293         DeW = De*V;
00294 
00295         // elastoplastic stiffness
00296         D.change_dim (NCps, NCps);
00297         for (size_t i=0; i<NCps; ++i)
00298         for (size_t j=0; j<NCps; ++j)
00299             D(i,j) = De(i,j) - DeW(i)*VDe(j)/phi;
00300 
00301         //Mat_t Cep(NCps,NCps);
00302         //cout << "det(Dep) = " << Det(D) << endl;
00303         //cout << "Dep = \n" << PrintMatrix(D);
00304         //Inv (D, Cep);
00305         //cout << "Cep = \n" << PrintMatrix(Cep);
00306     }
00307     else D = De;
00308 }
00309 
00310 inline bool Unconv03::LoadCond (State const * Sta, Vec_t const & DEps, double & alpInt) const
00311 {
00312     // no intersection (never in this model)
00313     alpInt = -1.0;
00314 
00315     // state
00316     EquilibState const * sta = static_cast<EquilibState const *>(Sta);
00317 
00318     // invariants and gradients
00319     _calc_invariants_and_gradients (sta); // calculate: devSig,p,q,t,V,yb,y0,y2
00320 
00321     // check loading condition
00322     Mult (V, De, VDe);
00323     double num = dot(VDe,DEps);
00324     //cout << "VDe  = " << PrintVector(VDe);
00325     //cout << "DEps = " << PrintVector(DEps);
00326     //cout << "num  = " << num << endl;
00327     if (fabs(num)<1.0e-12) return true; // neutral loading
00328     //if (num<0.0) throw new Fatal("Unconv03::LoadCond: num(%g)<0 not ready yet",num);
00329     return (num>0.0);
00330 }
00331 
00332 inline void Unconv03::UpdatePath (State const * Sta, Vec_t const & DEps, Vec_t const & DSig) const
00333 {
00334     double dq  = Calc_qoct (DSig);
00335     double dp  = Calc_poct (DSig);
00336     //double dqc = Calc_qcam (DSig);
00337     //double dpc = Calc_pcam (DSig);
00338     alpha = atan2(dq,dp);
00339     //cout << "alpha = " << 180.0*alpha/Util::PI << ", sin(alpha) = " << sin(alpha) << endl;
00340     /*
00341     cout << "dqc = " << dqc << ",  dpc = " << dpc << ", dqc/dpc = " << dqc/dpc << ",  alphac = atan(dqc/dpc) = " << 180.0*atan2(dqc,dpc)/Util::PI << endl;
00342     cout << "dq  = " << dq  << ",  dp  = " << dp  << ", dq /dp  = " << dq /dp  << ",  alpha  = atan(dq /dp)  = " << 180.0*alpha/Util::PI          << endl;
00343     cout << endl;
00344     */
00345 }
00346 
00347 
00349 
00350 
00351 Model * Unconv03Maker(int NDim, SDPair const & Prms, Model const * O) { return new Unconv03(NDim,Prms); }
00352 
00353 int Unconv03Register()
00354 {
00355     ModelFactory["Unconv03"] = Unconv03Maker;
00356     MODEL.Set ("Unconv03", (double)MODEL.Keys.Size());
00357     return 0;
00358 }
00359 
00360 int __Unconv03_dummy_int = Unconv03Register();
00361 
00362 #endif // MECHSYS_UNCONV03_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines