00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MECHSYS_SUBCAMX_H
00023 #define MECHSYS_SUBCAMX_H
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #else
00028 #ifndef REAL
00029 #define REAL double
00030 #endif
00031 #endif
00032
00033 #include "models/genericep.h"
00034 #include "tensors/operators.h"
00035 #include "tensors/functions.h"
00036 #include "util/string.h"
00037 #include "util/util.h"
00038
00039 using Tensors::Tensor2;
00040 using Tensors::Tensor4;
00041 using Tensors::Stress_p_q;
00042 using Tensors::Stress_p_q_S_sin3th;
00043 using Tensors::AddScaled;
00044 using Tensors::Dyad;
00045 using Tensors::Mult;
00046 using Tensors::Psd;
00047 using Tensors::IdyI;
00048 using Tensors::I;
00049 using Util::ToRad;
00050 using Util::Sq2;
00051
00052 class SubCamX : public GenericEP<3>
00053 {
00054 static REAL Q_ZERO;
00055 public:
00056 SubCamX(Array<REAL> const & Prms, Array<REAL> const & IniData);
00057 String Name() const { return "SubCamX"; }
00058 private:
00059
00060 REAL _lam;
00061 REAL _kap;
00062 REAL _phics;
00063 REAL _c;
00064 REAL _G0;
00065 REAL _psiv0;
00066 REAL _A;
00067 REAL _B;
00068 REAL _alp;
00069 REAL _bet;
00070 REAL _C;
00071
00072
00073 REAL _Mcs;
00074 REAL _wcs;
00075
00076
00077 void _calc_grads_hards(REAL const & v ,
00078 Tensor2 const & Sig,
00079 IntVars const & z ,
00080 Tensor2 & r ,
00081 Tensor2 & V ,
00082 T_dfdz & y ,
00083 HardMod & HH ,
00084 REAL & cp ) const;
00085
00086 void _calc_De(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & De) const;
00087 void _calc_Ce(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & Ce) const;
00088 void _unloading_update_int_vars();
00089 void _calc_dz(Tensors::Tensor2 const & dSig, Tensors::Tensor2 const & dEps, REAL const & dLam, HardMod const & HH, IntVars & dz) const
00090 {
00091 dz(0) = HH(0) * dLam;
00092 dz(1) = HH(1) * dLam;
00093 dz(2) = HH(2) * fabs(dLam);
00094 }
00095
00096
00097 REAL _calc_M(REAL const & sin3th) const;
00098
00099 };
00100
00101 REAL SubCamX::Q_ZERO = 1.0e-7;
00102
00103
00105
00106
00107 inline SubCamX::SubCamX(Array<REAL> const & Prms, Array<REAL> const & IniData)
00108 {
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 const size_t n_prms = 11;
00122 if (Prms.size()!=n_prms)
00123 throw new Fatal(_("SubCamX::Constructor: The number of parameters (%d) is incorrect. It must be equal to %d"), Prms.size(), n_prms);
00124
00125 _lam = Prms[0];
00126 _kap = Prms[1];
00127 _phics = Prms[2];
00128 _G0 = Prms[3];
00129 _c = Prms[4];
00130 _psiv0 = Prms[5];
00131 _A = Prms[6];
00132 _B = Prms[7];
00133 _C = Prms[8];
00134 _alp = Prms[9];
00135 _bet = Prms[10];
00136
00137
00138 REAL sin_phi = sin(Util::ToRad(_phics));
00139 _Mcs = 6.0*sin_phi/(3.0-sin_phi);
00140 _wcs = pow((3.0-sin_phi)/(3.0+sin_phi),4.0);
00141
00142
00143
00144
00145 if (IniData.size()!=5)
00146 throw new Fatal(_("SubCamX::Constructor: The number of initial data is not sufficiet (it must be equal to 5). { SigX SigY SigZ vini OCR }"));
00147
00148
00149 REAL sig_x = IniData[0];
00150 REAL sig_y = IniData[1];
00151 REAL sig_z = IniData[2];
00152 _v = IniData[3];
00153 REAL OCR = IniData[4];
00154
00155
00156 _sig = sig_x, sig_y, sig_z, 0.0*Sq2(), 0.0*Sq2(), 0.0*Sq2();
00157 _eps = 0.0,0.0,0.0,0.0*Sq2(),0.0*Sq2(),0.0*Sq2();
00158
00159
00160 _unloading_update_int_vars();
00161 _z(1) = _z(0)*OCR;
00162 _z(2) = 0.0;
00163
00164 }
00165
00166 inline void SubCamX::_unloading_update_int_vars()
00167 {
00168
00169 REAL p,q,sin3th;
00170 Tensor2 S;
00171 Stress_p_q_S_sin3th(_sig, p,q,S,sin3th);
00172 REAL M = _calc_M(sin3th);
00173
00174
00175 _z(0) = p + pow(q/M,2.0)/p;
00176 }
00177
00178 inline void SubCamX::_calc_grads_hards(REAL const & v ,
00179 Tensor2 const & Sig,
00180 IntVars const & z ,
00181 Tensor2 & r ,
00182 Tensor2 & V ,
00183 T_dfdz & y ,
00184 HardMod & HH ,
00185 REAL & cp ) const
00186 {
00187
00188 REAL p,q,sin3th;
00189 Tensor2 S;
00190 Stress_p_q_S_sin3th(Sig, p,q,S,sin3th);
00191
00192
00193
00194
00195 if (Util::IsNanOrInf(q))
00196 throw new Fatal("SubCamX::_calc_grads_hards: q is NAN or INF");
00197
00198
00199 REAL M = _calc_M(sin3th);
00200 REAL MM = M*M;
00201 V = (MM*(2.0*p-z(0))/3.0)*I + 3.0 *S;
00202 r = (MM*(2.0*p-z(0))/3.0)*I + (3.0*_C)*S;
00203 if (q>Q_ZERO)
00204 {
00205 REAL ss3th = pow(sin3th,2.0);
00206 REAL cos3th = (ss3th>1.0 ? 0.0 : sqrt(1.0-ss3th));
00207 if (cos3th>Q_ZERO)
00208 {
00209 REAL dM_dth = (0.75*M*(1.0-_wcs)*cos3th)/(1.0+_wcs-(1.0-_wcs)*sin3th);
00210 Tensor2 SS; Mult(S,S,SS);
00211 Tensor2 dev_SS; dev_SS = SS - (I * (SS(0)+SS(1)+SS(2))/3.0);
00212 Tensor2 dth_dsig; dth_dsig = (1.5/(q*q*cos3th)) * (dev_SS*(3.0/q) - S*sin3th);
00213 V += dth_dsig*(2.0*M*p*(p-z(0))*dM_dth);
00214 r += dth_dsig*(2.0*M*p*(p-z(0))*dM_dth);
00215 }
00216 }
00217 y(0) = -MM*p;
00218 y(1) = 0.0;
00219 y(2) = 0.0;
00220
00221
00222 REAL chi = (_lam - _kap)/v;
00223 REAL L = (_c*pow(chi*log(z(1)/z(0)),2.0)/p) * exp(_A*z(2)/p);
00224 REAL tr_r = r(0)+r(1)+r(2);
00225 HH(0) = z(0)*(tr_r+L)/chi;
00226 HH(1) = z(1)*tr_r/chi;
00227
00228 Tensor2 dev_r; dev_r = r - (tr_r/3.0)*I;
00229
00230 HH(2) = exp(z(2))*Norm(dev_r);
00231
00232
00233 cp = -y(0)*HH(0);
00234
00235
00236 REAL alp = _alp*log(z(1)/z(0));
00237 REAL bet = _bet*log(z(1)/z(0));
00238 r = (1.0-alp/(1.0+q/p))*dev_r + ((1.0-bet/p)*tr_r/3.0)*I;
00239
00240 }
00241
00242 inline void SubCamX::_calc_De(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & De) const
00243 {
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 throw new Fatal(_("SubCamX::_calc_De ERROR"));
00254 }
00255
00256 inline void SubCamX::_calc_Ce(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & Ce) const
00257 {
00258
00259 REAL p,q,sin3th;
00260 Tensor2 S;
00261 Stress_p_q_S_sin3th(Sig, p,q,S,sin3th);
00262 Tensor4 IdyS; Dyad(I, S, IdyS);
00263
00264
00265 REAL K = p*v/_kap;
00266
00267 if (IsUnloading)
00268 {
00269 AddScaled(0.5/(_G0*(1.0+q/p)), Psd, 1.0/(9.0*K), IdyI, Ce);
00270 if (q>Q_ZERO)
00271 {
00272 REAL psiv = _psiv0*log(z(1)/z(0))*z(2)*exp(-_B*z(2));
00273 AddScaled(1.0, Ce, -psiv/(2.0*q), IdyS, Ce);
00274 }
00275 }
00276 else
00277 AddScaled(0.5/_G0, Psd, 1.0/(9.0*K), IdyI, Ce);
00278
00279 }
00280
00281 inline REAL SubCamX::_calc_M(REAL const & sin3th) const
00282 {
00283 return _Mcs*pow( 2.0*_wcs/(1.0+_wcs-(1.0-_wcs)*sin3th) ,0.25);
00284 }
00285
00287
00288
00289
00290 EquilibModel * SubCamXMaker(Array<REAL> const & Prms, Array<REAL> const & IniData)
00291 {
00292 return new SubCamX(Prms, IniData);
00293 }
00294
00295
00296 int SubCamXRegister()
00297 {
00298 EquilibModelFactory["SubCamX"] = SubCamXMaker;
00299 return 0;
00300 }
00301
00302
00303 int __SubCamX_dummy_int = SubCamXRegister();
00304
00305 #endif // MECHSYS_SUBCAMX_H
00306
00307