00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MECHSYS_SUBCAM_H
00023 #define MECHSYS_SUBCAM_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::Stress_p_q_S_sin3th;
00041 using Tensors::AddScaled;
00042 using Tensors::I;
00043 using Tensors::Mult;
00044 using Tensors::Psd;
00045 using Tensors::IdyI;
00046
00047 class SubCam : public GenericEP<2+2>
00048 {
00049 public:
00050
00051
00052 SubCam(Array<REAL> const & Prms, Array<REAL> const & IniData);
00053
00054
00055 String Name() const { return "SubCam"; }
00056
00057
00058 static REAL Q_ZERO;
00059 static size_t NPRMS;
00060 static size_t NIDAT;
00061
00062
00063 int nAdditionalInternalStateValues () const { return 1; }
00064 void AdditionalInternalStateValues (Array<REAL> & IntStateVals) const;
00065 void AdditionalInternalStateNames (Array<String> & IntStateNames) const;
00066
00067 private:
00068
00069 REAL _lam;
00070 REAL _kap;
00071 REAL _phics;
00072 REAL _G;
00073 REAL _c;
00074 REAL _Mcs;
00075 REAL _wcs;
00076 REAL _alp;
00077
00078
00079 void _calc_grads_hards(REAL const & v ,
00080 Tensor2 const & Sig,
00081 IntVars const & z ,
00082 Tensor2 & r ,
00083 Tensor2 & V ,
00084 T_dfdz & y ,
00085 HardMod & HH ,
00086 REAL & cp ) const;
00087
00088 void _calc_De(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & De) const;
00089 void _calc_Ce(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & Ce) const;
00090 void _unloading_update_int_vars();
00091 void _calc_dz(Tensors::Tensor2 const & dSig, Tensors::Tensor2 const & dEps, REAL const & dLam, HardMod const & HH, IntVars & dz) const
00092 { dz = dLam * HH; }
00093
00094
00095 REAL _calc_M(REAL const & sin3th) const;
00096
00097 };
00098
00099 REAL SubCam::Q_ZERO = 1.0e-7;
00100 size_t SubCam::NPRMS = 5;
00101 size_t SubCam::NIDAT = 5;
00102
00103
00105
00106
00107 inline SubCam::SubCam(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 = 5;
00122 if (Prms.size()!=n_prms)
00123 throw new Fatal(_("SubCam::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 _G = Prms[3];
00129 _c = Prms[4];
00130
00131
00132 REAL sin_phi = sin(Util::ToRad(_phics));
00133 _Mcs = 6.0*sin_phi/(3.0-sin_phi);
00134 _wcs = pow((3.0-sin_phi)/(3.0+sin_phi),4.0);
00135 _alp = 1.0;
00136
00137
00138
00139
00140 if (IniData.size()!=5)
00141 throw new Fatal(_("SubCam::Constructor: The number of initial data is not sufficiet (it must be equal to 5). { SigX SigY SigZ vini OCR }"));
00142
00143
00144 REAL sig_x = IniData[0];
00145 REAL sig_y = IniData[1];
00146 REAL sig_z = IniData[2];
00147 _v = IniData[3];
00148 REAL OCR = IniData[4];
00149
00150
00151 REAL sq2=sqrt(2.0);
00152 _sig = sig_x, sig_y, sig_z, 0.0*sq2, 0.0*sq2, 0.0*sq2;
00153 _eps = 0.0,0.0,0.0,0.0*sq2,0.0*sq2,0.0*sq2;
00154
00155
00156 _unloading_update_int_vars();
00157 _z(1) = _z(0)*OCR;
00158
00159
00160 _z(2) = 0.0;
00161 _z(3) = 0.0;
00162
00163 }
00164
00165 inline void SubCam::_unloading_update_int_vars()
00166 {
00167
00168 REAL p,q,sin3th;
00169 Tensor2 S;
00170 Stress_p_q_S_sin3th(_sig, p,q,S,sin3th);
00171 REAL M = _calc_M(sin3th);
00172
00173
00174 _z(0) = p + pow(q/M,2.0)/p;
00175 }
00176
00177 inline void SubCam::_calc_grads_hards(REAL const & v ,
00178 Tensor2 const & Sig,
00179 IntVars const & z ,
00180 Tensor2 & r ,
00181 Tensor2 & V ,
00182 T_dfdz & y ,
00183 HardMod & HH ,
00184 REAL & cp ) const
00185 {
00186
00187 REAL p,q,sin3th;
00188 Tensor2 S;
00189 Stress_p_q_S_sin3th(Sig, p,q,S,sin3th);
00190
00191
00192 REAL M = _calc_M(sin3th);
00193 REAL MM = M*M;
00194 V = (MM*(2.0*p-z(0))/3.0)*I + 3.0 *S;
00195 r = (MM*(2.0*p-z(0))/3.0)*I + (3.0*_alp)*S;
00196 if (q>Q_ZERO)
00197 {
00198 REAL ss3th = pow(sin3th,2.0);
00199 REAL cos3th;
00200 if (ss3th>1.0) cos3th = 0.0;
00201 else cos3th = sqrt(1.0-ss3th);
00202 if (cos3th>Q_ZERO)
00203 {
00204 REAL dM_dth = (0.75*M*(1.0-_wcs)*cos3th) / (1.0+_wcs+(_wcs-1.0)*sin3th);
00205 Tensor2 SS; Mult(S,S,SS);
00206 Tensor2 dev_SS; dev_SS = SS - (I * (SS(0)+SS(1)+SS(2))/3.0);
00207 Tensor2 dth_dsig; dth_dsig = (1.5/(q*q*cos3th)) * (dev_SS*(3.0/q) - S*sin3th);
00208 V += dth_dsig*(2.0*M*p*(p-z(0))*dM_dth);
00209 r += dth_dsig*(2.0*M*p*(p-z(0))*dM_dth);
00210 }
00211 }
00212 y(0) = -MM*p;
00213 y(1) = 0.0;
00214 y(2) = 0.0;
00215 y(3) = 0.0;
00216
00217
00218 REAL chi = (_lam - _kap)/v;
00219 REAL L = _c*pow(chi*log(z(0)/z(1)),2.0)/p;
00220 REAL tr_r = r(0)+r(1)+r(2);
00221 HH(0) = z(0)*(tr_r+L)/chi;
00222 HH(1) = z(1)*tr_r/chi;
00223 HH(2) = tr_r;
00224 HH(3) = L;
00225
00226
00227 cp = -y(0)*HH(0);
00228 }
00229
00230 inline void SubCam::_calc_De(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & De) const
00231 {
00232
00233 REAL p = (Sig(0)+Sig(1)+Sig(2))/3.0;
00234
00235
00236 REAL K = p*v/_kap;
00237
00238
00239 Tensors::AddScaled(2.0*_G,Tensors::Psd, K,Tensors::IdyI, De);
00240
00241 }
00242
00243 inline void SubCam::_calc_Ce(REAL const & v, Tensors::Tensor2 const & Sig, IntVars const & z, bool IsUnloading, Tensors::Tensor4 & Ce) const
00244 {
00245
00246 REAL p = (Sig(0)+Sig(1)+Sig(2))/3.0;
00247
00248
00249 REAL K = p*v/_kap;
00250
00251
00252 AddScaled(1.0/(2.0*_G), Psd, 1.0/(9.0*K), IdyI, Ce);
00253
00254 }
00255
00256 inline REAL SubCam::_calc_M(REAL const & sin3th) const
00257 {
00258 return _Mcs*pow( 2.0*_wcs/(1.0+_wcs+(_wcs-1.0)*sin3th) ,0.25);
00259 }
00260
00261 inline void SubCam::AdditionalInternalStateValues(Array<REAL> & IntStateVals) const
00262 {
00263 IntStateVals.resize(nAdditionalInternalStateValues());
00264 REAL p = (_sig(0)+_sig(1)+_sig(2))/3.0;
00265 REAL chi = (_lam - _kap)/_v;
00266 IntStateVals[0] = _c*pow(chi*log(_z(0)/_z(1)),2.0)/p;
00267 }
00268
00269 inline void SubCam::AdditionalInternalStateNames(Array<String> & IntStateNames) const
00270 {
00271 IntStateNames.resize(nAdditionalInternalStateValues());
00272 IntStateNames[0] = "L";
00273 }
00274
00275
00277
00278
00279
00280 EquilibModel * SubCamMaker(Array<REAL> const & Prms, Array<REAL> const & IniData)
00281 {
00282 return new SubCam(Prms, IniData);
00283 }
00284
00285
00286 int SubCamRegister()
00287 {
00288 EquilibModelFactory["SubCam"] = SubCamMaker;
00289 return 0;
00290 }
00291
00292
00293 int __SubCam_dummy_int = SubCamRegister();
00294
00295 #endif // MECHSYS_SUBCAM_H
00296
00297