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