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