![]() |
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_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