00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #ifndef MECHSYS_SUBBAR_H
00023 #define MECHSYS_SUBBAR_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 
00034 
00035 
00036 #include <iostream>
00037 
00038 
00039 #include <blitz/tinyvec-et.h>
00040 
00041 
00042 #include "models/coupled/coupledmodel.h"
00043 #include "tensors/tensors.h"
00044 #include "tensors/operators.h"
00045 #include "tensors/functions.h"
00046 #include "numerical/integschemesctes.h"
00047 #include "numerical/autostepme.h"
00048 #include "util/string.h"
00049 #include "util/array.h"
00050 #include "util/util.h"
00051 
00052 using Tensors::I;
00053 using Tensors::Tensor2;
00054 using Tensors::Tensor4;
00055 using Tensors::Stress_p_q;
00056 using Tensors::Strain_Ev_Ed;
00057 using Tensors::Stress_p_q_S_sin3th;
00058 using Tensors::Mult;
00059 
00061 class SubBar : public CoupledModel
00062 {
00063     static REAL Q_ZERO; 
00064 public:
00065 
00067     typedef blitz::TinyVector<REAL,4> IntVars; 
00068     typedef blitz::TinyVector<REAL,4> HardMod; 
00069     typedef blitz::TinyVector<REAL,4> T_dFdz;  
00070     typedef blitz::TinyVector<REAL,7> AugVec;  
00071 
00072     
00073     SubBar(Array<REAL> const & Prms, Array<REAL> const & IniData);
00074 
00075     
00076     String Name            () const { return "SubBar"; }
00077     void   TgStiffness     (Tensor4 & D, Tensor2 & d) const;
00078     REAL   Sr              () const; 
00079     REAL   phi             () const; 
00080     REAL   n_times_dSr_dPp () const; 
00081     void   TgPermeability  (Tensor2 & k) const;
00082     void   FlowVelocity    (Tensor1 const & Grad, Tensor1 & Vel) const;
00083     void   Actualize       (Tensor2 const & DSig, REAL const & DPp, Tensor2 & DEps, REAL & DnSr);
00084     void   StressUpdate    (Tensor2 const & DEps, REAL const & DPp, Tensor2 & DSig, REAL & DnSr);
00085     void   FlowUpdate      (REAL const & DPp) {}
00086     void   BackupState     ();
00087     void   RestoreState    ();
00088 
00089     
00090     REAL YieldFunc          (Tensor2 const & Sig, IntVars const & z, REAL const & Suc)                        const;
00091     REAL YieldFunc_Normal   (Tensor2 const & Sig, IntVars const & z, REAL const & Suc)                        const;
00092     void Calc_dFdSig_dFdSuc (Tensor2 const & Sig, IntVars const & z, REAL const & Suc, Tensor2 & V, REAL & S) const;
00093     REAL Calc_p0            (IntVars const & z, REAL const & Suc) const; 
00094     REAL Calc_C             (IntVars const & z, REAL const & Suc) const; 
00095 
00096     
00097     Tensor2 const & Sig() const { return  _sig;   }
00098     Tensor2 const & Eps() const { return  _eps;   }
00099     REAL            Pp () const { return  _ppr;   }
00100     REAL        GammaW () const { return  _gamaW; } 
00101     int  nInternalStateValues() const { return 5; }
00102     void InternalStateValues (Array<REAL>   & IntStateVals ) const;
00103     void InternalStateNames  (Array<String> & IntStateNames) const;
00104 
00105     
00106     REAL GetM(REAL Theta) const { REAL sin3th=sin(3.0*Theta); return _calc_M(sin3th); }
00107 
00108 private:
00109     
00110     REAL    _v;   
00111     Tensor2 _sig; 
00112     REAL    _suc; 
00113     Tensor2 _eps; 
00114     IntVars _z;   
00115     REAL    _ppr; 
00116     
00117     
00118     REAL    _bkp_v;   
00119     Tensor2 _bkp_sig; 
00120     REAL    _bkp_suc; 
00121     Tensor2 _bkp_eps; 
00122     IntVars _bkp_z;   
00123     REAL    _bkp_ppr; 
00124 
00125     
00126     REAL _lam0;
00127     REAL _kap;
00128     REAL _phics;
00129     REAL _G;
00130     REAL _r;
00131     REAL _bet;
00132     REAL _k;
00133     REAL _lams;
00134     REAL _kaps;
00135     REAL _patm;
00136     REAL _pref;
00137     REAL _BB;
00138 
00139     
00140     REAL _a;
00141     REAL _b;
00142     REAL _c;
00143     REAL _m;
00144     REAL _ks;
00145     REAL _gamaW;
00146 
00147     
00148     REAL _c0;
00149     REAL _cs;
00150 
00151     
00152     REAL _Mcs;
00153     REAL _wcs;
00154     REAL _alp;
00155 
00156     
00157     REAL _num_dLam; 
00158     REAL _bkp_num_dLam;
00159 
00160     
00161     REAL _MAX_ERR_F; 
00162     REAL _MIN_HP;    
00163 
00164     
00165     REAL _lam        (REAL const & Suc) const;
00166     REAL _psi        (REAL const & Suc) const;
00167 
00168     void _calc_Ce_ce(REAL const & v, Tensor2 const & Sig, REAL const & Suc, Tensor4 & Ce, Tensor2 & ce) const;
00169     void _calc_De_de(REAL const & v, Tensor2 const & Sig, REAL const & Suc, Tensor4 & De, Tensor2 & de) const;
00170 
00171     void _calc_f0_grads(Tensor2 const & Sig     ,
00172                         IntVars const & z       ,
00173                         REAL    const & Suc     ,
00174                         Tensor2       & df0_dSig,
00175                         REAL          & df0_dSuc,
00176                         REAL          & df0_dz0 ) const;
00177 
00178     void _calc_gradients_and_hardening(REAL    const & v  ,        
00179                                        Tensor2 const & Sig,        
00180                                        IntVars const & z  ,        
00181                                        REAL    const & Suc,        
00182                                        Tensor2       & r  ,        
00183                                        Tensor2       & V  ,        
00184                                        T_dFdz        & y  ,        
00185                                        REAL          & S  ,        
00186                                        HardMod       & HH ,        
00187                                        REAL          & hp ) const; 
00188 
00189     int _tg_deps_dz_given_dsig_and_dsuc(AugVec  const & SigSuc ,
00190                                         Tensor2 const & Eps    ,
00191                                         IntVars const & z      ,
00192                                         AugVec  const & dSigSuc,
00193                                         Tensor2       & dEps   ,
00194                                         IntVars       & dz     ) const;
00195 
00196     int _tg_dsig_dz_given_deps_and_dsuc(AugVec  const & EpsSuc ,
00197                                         Tensor2 const & Sig    ,
00198                                         IntVars const & z      ,
00199                                         AugVec  const & dEpsSuc,
00200                                         Tensor2       & dSig   ,
00201                                         IntVars       & dz     ) const;
00202 
00203     REAL _local_error(Tensor2 const & Ey, Tensor2 const & y_high,
00204                       IntVars const & Ez, IntVars const & z_high) const;
00205 
00207     void _force_consistency();
00208 
00209     
00210     REAL _calc_M(REAL const & sin3th) const;
00211 
00212 }; 
00213 
00214 REAL SubBar::Q_ZERO = 1.0e-7;
00215 
00216 
00218 
00219 
00220 inline SubBar::SubBar(Array<REAL> const & Prms, Array<REAL> const & IniData) 
00221     : _num_dLam(1.0)
00222 {
00223 
00224     
00225 
00226     
00227 
00228 
00229 
00230 
00231 
00232 
00233     
00234     const size_t n_prms = 20;
00235     if (Prms.size()!=n_prms)
00236         throw new Fatal(_("SubBar::SubBar: The number of parameters (%d) is incorrect. It must be equal to %d"), Prms.size(), n_prms);
00237 
00238     
00239     _lam0  = Prms[0];
00240     _kap   = Prms[1];
00241     _phics = Prms[2];
00242     _G     = Prms[3];
00243     _r     = Prms[4];
00244     _bet   = Prms[5];
00245     _k     = Prms[6];
00246     _lams  = Prms[7];
00247     _kaps  = Prms[8];
00248     _patm  = Prms[9];
00249     _pref  = Prms[10];
00250     _BB    = Prms[11];
00251 
00252     
00253     _a     = Prms[12];
00254     _b     = Prms[13];
00255     _c     = Prms[14];
00256     _m     = Prms[15];
00257     _ks    = Prms[16];
00258     _gamaW = Prms[17];
00259 
00260     
00261     _c0 = Prms[18];
00262     _cs = Prms[19];
00263 
00264     
00265     REAL sin_phi = sin(Util::ToRad(_phics));
00266     _Mcs = 6.0*sin_phi/(3.0-sin_phi);
00267     _wcs = pow((3.0-sin_phi)/(3.0+sin_phi),4.0);
00268     _alp = (_Mcs*(_Mcs-9.0)*(_Mcs-3.0)) / (9.0*(6.0-_Mcs)*(1.0-_kap/_lam0));
00269     
00270     
00271 
00272     
00273     if (IniData.size()!=7) 
00274         throw new Fatal(_("SubBar::SubBar: The number of initial data is not sufficiet (it must be equal to 5). { SigX SigY SigZ vini OCR OSI Pp }"));
00275 
00276     
00277     REAL sig_x = IniData[0]; 
00278     REAL sig_y = IniData[1]; 
00279     REAL sig_z = IniData[2]; 
00280             _v = IniData[3]; 
00281     REAL   OCR = IniData[4]; 
00282     REAL   OSI = IniData[5]; 
00283     REAL    Pp = IniData[6]; 
00284 
00285     
00286     REAL sq2=Util::Sq2();
00287     _sig = sig_x, sig_y, sig_z, 0.0*sq2, 0.0*sq2, 0.0*sq2; 
00288     _eps = 0.0,0.0,0.0,0.0*sq2,0.0*sq2,0.0*sq2;
00289 
00290     
00291     _ppr = Pp;       
00292     _suc = 0.0 - Pp; 
00293     if (_suc<0.0) _suc=0.0;
00294 
00295     
00296     
00297     _z    = 0;
00298 #ifdef SUBBAR_INIT1
00299     _z(3) = _suc+OSI;
00300     _z(1) = _suc;
00301     _force_consistency(); 
00302     _z(2) = OCR*_z(0);    
00303 #else
00304     _force_consistency(); 
00305     _z(2) = OCR*_z(0);    
00306     _z(3) = OSI+_z(1);    
00307 #endif
00308 
00309     
00310     if (_z(0)>_z(2)) throw new Fatal(_("SubBar::SubBar: Subloading surface (z0=%f) must be smaller than normal surface (z2=%f)"),_z(0),_z(2));
00311     if (_z(1)>_z(3)) throw new Fatal(_("SubBar::SubBar: Subloading surface (z1=%f) must be smaller than normal surface (z3=%f)"),_z(1),_z(3));
00312 
00313     
00314     _MAX_ERR_F = (1.0/100.0)*_pref*_pref; 
00315     _MIN_HP    = (1.0/100.0)*_pref*_pref; 
00316 
00317 #ifndef SUBBAR_INIT1
00318     
00319     REAL F = YieldFunc(_sig, _z, _suc);
00320     if (fabs(F)>_MAX_ERR_F) throw new Fatal(_("SubBar::SubBar: Stress point is outside yield surface (F_ini = %f)"),F);
00321     
00322 #endif
00323 
00324 } 
00325 
00326 inline void SubBar::TgStiffness(Tensor4 & D, Tensor2 & d) const 
00327 {
00328     if (_num_dLam<0) 
00329     {
00330         _calc_De_de(_v,_sig,_suc, D,d); 
00331     }
00332     else 
00333     {
00334         
00335         Tensor2 r;    
00336         Tensor2 V;    
00337         T_dFdz  y;    
00338         REAL    S;    
00339         HardMod HH;   
00340         REAL    hp;   
00341         _calc_gradients_and_hardening(_v, _sig, _z, _suc, r, V, y, S, HH, hp);
00342 
00343         
00344         Tensor4 De;
00345         Tensor2 de;
00346         _calc_De_de(_v,_sig,_suc, De,de);
00347 
00348         
00349         REAL Phi = Tensors::Reduce(V,De,r)+hp;  
00350         Tensors::GerX(-1.0/Phi,De,r,V,De,De,D); 
00351 
00352         
00353         Tensors::Dot(De,r, d);                   
00354         d = de - ((Tensors::Dot(V,de)+S)/Phi)*d; 
00355     }
00356 } 
00357 
00358 inline REAL SubBar::Sr() const 
00359 {
00360     if (_suc <= 0.0) 
00361         return 1.0;
00362     else
00363         return 1.0/pow(1.0+pow(_suc/_a,_b),_c); 
00364 } 
00365 
00366 inline REAL SubBar::phi() const 
00367 {
00368     return Sr();
00369 } 
00370 
00371 inline REAL SubBar::n_times_dSr_dPp() const 
00372 {
00373     if (_suc <= 0.0) 
00374         return 0.0;
00375     else
00376     {
00377         REAL dSr_dPp = -_b*_c*pow(_suc/_a,_b-1.0)/(_a*pow(1.0+pow(_suc/_a,_b),_c+1.0));
00378         REAL       n = (_v-1.0)/_v;
00379         return n*dSr_dPp;
00380     }
00381 } 
00382 
00383 inline void SubBar::TgPermeability(Tensor2 & k) const 
00384 {
00385     k = (_ks*pow(Sr(),_m))*I;
00386 } 
00387 
00388 inline void SubBar::FlowVelocity(Tensor1 const & Grad, Tensor1 & Vel) const 
00389 {
00390     Tensor2 K;
00391     TgPermeability(K); 
00392     Tensors::Dot(-K,Grad, Vel);
00393 } 
00394 
00395 inline void SubBar::Actualize(Tensor2 const & DSig, REAL const & DPp, Tensor2 & DEps, REAL & DnSr) 
00396 {
00397     
00398     Tensor2 eps_ini = _eps;
00399     REAL    n_ini   = (_v-1.0)/_v;
00400     REAL    Sr_ini  = Sr();
00401     REAL    nSr_ini = n_ini * Sr_ini;
00402 
00403     
00404     REAL DSuc = 0.0 - DPp;
00405     if ((_suc+DSuc)<0.0) DSuc=0.0-_suc;
00406 
00407     
00408     Tensor2 r;    
00409     Tensor2 V;    
00410     T_dFdz  y;    
00411     REAL    S;    
00412     HardMod HH;   
00413     REAL    hp;   
00414     _calc_gradients_and_hardening(_v, _sig, _z, _suc, r, V, y, S, HH, hp);
00415 
00416     
00417     REAL dLam = (Tensors::Dot(V,DSig) + S*DSuc)/hp; 
00418 
00419     
00420 
00421     
00422     if (dLam<0.0) 
00423     {
00424         
00425         
00426             
00427 
00428             
00429             int n_div=_isc.FE_ndiv();
00430             Tensor2 dsig = DSig/n_div;
00431             REAL    dsuc = DSuc/n_div;
00432             for (int i=0; i<n_div; ++i)
00433             {
00434                 
00435                 Tensor4 Ce; Tensor2 ce; _calc_Ce_ce(_v,_sig,_suc, Ce,ce);
00436                 Tensors::Dot(Ce,dsig, DEps); DEps += ce * dsuc; 
00437                 
00438                 
00439                 _sig += dsig;
00440                 _suc += dsuc;
00441                 _eps += DEps;
00442 
00443                 _z(1) += dsuc;
00444                 
00445                 _force_consistency();
00446             }
00447         
00448         
00449 
00450         
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464     }
00465     else 
00466     {
00467         if (CoupledModel::_isc.Type()==IntegSchemesCtes::FE)
00468         {
00469             
00470 
00471             
00472             int n_div=_isc.FE_ndiv();
00473             Tensor2 dsig;     dsig    = DSig/n_div;
00474             REAL    dsuc;     dsuc    = DSuc/n_div;
00475             AugVec  dsigsuc;  dsigsuc = dsig(0),dsig(1),dsig(2),dsig(3),dsig(4),dsig(5),dsuc;
00476             for (int i=0; i<n_div; ++i)
00477             {
00478                 IntVars dz;
00479                 AugVec sigsuc;  sigsuc = _sig(0),_sig(1),_sig(2),_sig(3),_sig(4),_sig(5),_suc;
00480                 _tg_deps_dz_given_dsig_and_dsuc(sigsuc, _eps, _z, dsigsuc, DEps, dz);
00481                 _sig += dsig;
00482                 _suc += dsuc;
00483                 _eps += DEps;
00484                 _z   += dz;
00485             }
00486         }
00487         else 
00488         {
00489             
00490             AugVec  sigsuc;   sigsuc = _sig(0),_sig(1),_sig(2),_sig(3),_sig(4),_sig(5),_suc;
00491             AugVec dsigsuc;  dsigsuc = DSig(0),DSig(1),DSig(2),DSig(3),DSig(4),DSig(5),DSuc;
00492 
00493             
00494             AutoStepME<AugVec,Tensor2,IntVars,SubBar> TI(CoupledModel::_isc);
00495 
00496             
00497             int nss = TI.Solve(this,                                        
00498                                &SubBar::_tg_deps_dz_given_dsig_and_dsuc, 
00499                                &SubBar::_local_error,                    
00500                                sigsuc, _eps, _z, dsigsuc);
00501             
00502             if (nss==-1)
00503                 throw new Fatal(_("SubBar::Actualize: (Loading) Number of max sub-steps (%d) was not sufficient for AutoStepME."), CoupledModel::_isc.ME_maxSS());
00504 
00505             
00506             _sig = sigsuc(0),sigsuc(1),sigsuc(2),sigsuc(3),sigsuc(4),sigsuc(5);
00507             _suc = sigsuc(6);
00508         }
00509     }
00510 
00511     
00512     DEps = _eps - eps_ini;
00513 
00514     
00515     _v += -(DEps(0)+DEps(1)+DEps(2))*_v; 
00516 
00517     
00518     _ppr += DPp;
00519 
00520     
00521     REAL n_fin   = (_v-1.0)/_v;
00522     REAL Sr_fin  = Sr();
00523     REAL nSr_fin = n_fin * Sr_fin;
00524     DnSr = nSr_fin - nSr_ini; 
00525 
00526 } 
00527 
00528 inline void SubBar::StressUpdate(Tensor2 const & DEps, REAL const & DPp, Tensor2 & DSig, REAL & DnSr) 
00529 {
00530     
00531     Tensor2 sig_ini = _sig;
00532     REAL    n_ini   = (_v-1.0)/_v;
00533     REAL    Sr_ini  = Sr();
00534     REAL    nSr_ini = n_ini * Sr_ini;
00535 
00536     
00537     REAL DSuc = 0.0 - DPp;
00538     if ((_suc+DSuc)<0.0) DSuc=0.0-_suc;
00539 
00540     
00541     Tensor2 r;    
00542     Tensor2 V;    
00543     T_dFdz  y;    
00544     REAL    S;    
00545     HardMod HH;   
00546     REAL    hp;   
00547     _calc_gradients_and_hardening(_v, _sig, _z, _suc, r, V, y, S, HH, hp);
00548 
00549     
00550     Tensor4 De;
00551     Tensor2 de;
00552     _calc_De_de(_v,_sig,_suc, De,de);
00553 
00554     
00555     _num_dLam = (Tensors::Reduce(V,De,DEps) + Tensors::Dot(V,de)*DSuc + S*DSuc);
00556 
00557     
00558     if (_num_dLam<0.0) 
00559     {
00560         
00561         
00562             
00563 
00564             
00565             int n_div=_isc.FE_ndiv();
00566             Tensor2 deps = DEps/n_div;
00567             REAL    dsuc = DSuc/n_div;
00568             for (int i=0; i<n_div; ++i)
00569             {
00570                 
00571                 _calc_De_de(_v,_sig,_suc, De,de);
00572                 Tensors::Dot(De,deps, DSig); DSig += de * dsuc; 
00573                 
00574                 
00575                 _sig += DSig;
00576                 _suc += dsuc;
00577                 _eps += deps;
00578 
00579                 _z(1) += dsuc;
00580                 
00581                 _force_consistency();
00582             }
00583         
00584     }
00585     else 
00586     {
00587         if (CoupledModel::_isc.Type()==IntegSchemesCtes::FE)
00588         {
00589             
00590             int n_div = _isc.FE_ndiv();
00591             Tensor2 deps = DEps/n_div;
00592             REAL    dsuc = DSuc/n_div;
00593             AugVec depssuc;  depssuc = deps(0),deps(1),deps(2),deps(3),deps(4),deps(5),dsuc;
00594             for (int i=0; i<n_div; ++i)
00595             {
00596                 IntVars dz;
00597                 AugVec epssuc;  epssuc = _eps(0),_eps(1),_eps(2),_eps(3),_eps(4),_eps(5),_suc;
00598                 _tg_dsig_dz_given_deps_and_dsuc(epssuc, _sig, _z, depssuc, DSig, dz);
00599                 _sig += DSig;
00600                 _suc += dsuc;
00601                 _eps += deps;
00602                 _z   += dz;
00603             }
00604         }
00605         else
00606         {
00607             
00608             AugVec  epssuc;   epssuc = _eps(0),_eps(1),_eps(2),_eps(3),_eps(4),_eps(5),_suc;
00609             AugVec depssuc;  depssuc = DEps(0),DEps(1),DEps(2),DEps(3),DEps(4),DEps(5),DSuc;
00610 
00611             
00612             AutoStepME<AugVec,Tensor2,IntVars,SubBar> TI(CoupledModel::_isc);
00613 
00614             
00615             int nss = TI.Solve(this,                                         
00616                                &SubBar::_tg_dsig_dz_given_deps_and_dsuc, 
00617                                &SubBar::_local_error,                    
00618                                epssuc, _sig, _z, depssuc);
00619             
00620             if (nss==-1)
00621                 throw new Fatal(_("SubBar::StressUpdate: (Loading) Number of max sub-steps (%d) was not sufficient for AutoStepME."), CoupledModel::_isc.ME_maxSS());
00622 
00623             
00624             _eps = epssuc(0),epssuc(1),epssuc(2),epssuc(3),epssuc(4),epssuc(5);
00625             _suc = epssuc(6);
00626         }
00627     }
00628 
00629     
00630     DSig = _sig - sig_ini;
00631 
00632     
00633     _v += -(DEps(0)+DEps(1)+DEps(2))*_v; 
00634 
00635     
00636     _ppr += DPp;
00637 
00638     
00639     REAL n_fin   = (_v-1.0)/_v;
00640     REAL Sr_fin  = Sr();
00641     REAL nSr_fin = n_fin * Sr_fin;
00642     DnSr = nSr_fin - nSr_ini; 
00643 
00644 } 
00645 
00646 inline void SubBar::BackupState() 
00647 {
00648     _bkp_v   = _v;
00649     _bkp_sig = _sig;
00650     _bkp_suc = _suc;
00651     _bkp_eps = _eps;
00652     _bkp_z   = _z;
00653     _bkp_ppr = _ppr;
00654     _bkp_num_dLam = _num_dLam;
00655 } 
00656 
00657 inline void SubBar::RestoreState() 
00658 {
00659       _v = _bkp_v;
00660     _sig = _bkp_sig;
00661     _suc = _bkp_suc;
00662     _eps = _bkp_eps;
00663       _z = _bkp_z;
00664     _ppr = _bkp_ppr;
00665     _num_dLam = _bkp_num_dLam;
00666 } 
00667 
00668 inline REAL SubBar::_lam(REAL const & Suc) const 
00669 {
00670     return _lam0*((1.0-_r)*exp(-_bet*Suc) + _r);
00671 } 
00672 
00673 inline REAL SubBar::_psi(REAL const & Suc) const 
00674 {
00675     return (_lam0-_kap)/(_lam(Suc)-_kap);
00676 } 
00677 
00678 inline REAL SubBar::Calc_p0(IntVars const & z, REAL const & Suc) const 
00679 {
00680     return _pref*pow(z(0)/_pref, _psi(Suc));
00681 } 
00682 
00683 inline REAL SubBar::Calc_C(IntVars const & z, REAL const & Suc) const 
00684 {
00685     return (_pref*_pref) * ( exp(_BB*(Suc-z(1))/_pref) - exp(-_BB*z(1)/_pref) );
00686 } 
00687 
00688 inline REAL SubBar::YieldFunc(Tensor2 const & Sig, IntVars const & z, REAL const & Suc) const 
00689 {
00690     REAL     p,q,sin3th;
00691     Tensor2  devS;
00692     Stress_p_q_S_sin3th(Sig, p,q,devS,sin3th);
00693     REAL M = _calc_M(sin3th);
00694     REAL g = - M*M * (p+_k*Suc) * (Calc_p0(z,Suc)-p);
00695     REAL F = q*q + g + Calc_C(z,Suc);
00696     
00697     return F;
00698 } 
00699 
00700 inline REAL SubBar::YieldFunc_Normal(Tensor2 const & Sig, IntVars const & z, REAL const & Suc) const 
00701 {
00702     IntVars z_tmp; z_tmp=z(2),z(3),0,0;
00703     REAL     p,q,sin3th;
00704     Tensor2  devS;
00705     Stress_p_q_S_sin3th(Sig, p,q,devS,sin3th);
00706     REAL M = _calc_M(sin3th);
00707     REAL g = - M*M * (p+_k*Suc) * (Calc_p0(z_tmp,Suc)-p);
00708     REAL F = q*q + g + Calc_C(z_tmp,Suc);
00709     
00710     return F;
00711 } 
00712 
00713 inline void SubBar::_calc_Ce_ce(REAL const & v, Tensor2 const & Sig, REAL const & Suc, Tensor4 & Ce, Tensor2 & ce) const 
00714 {
00715     
00716     REAL p = (Sig(0)+Sig(1)+Sig(2))/3.0;
00717 
00718     
00719     REAL K  =  p         *v/_kap;
00720     REAL Ks = (Suc+_patm)*v/_kaps;
00721 
00722     
00723     Tensors::AddScaled(1.0/(2.0*_G), Tensors::Psd, 1.0/(9.0*K), Tensors::IdyI,  Ce);
00724 
00725     
00726     ce = (1.0/(3.0*Ks)) * I;
00727 
00728 } 
00729 
00730 inline void SubBar::_calc_De_de(REAL const & v, Tensor2 const & Sig, REAL const & Suc, Tensor4 & De, Tensor2 & de) const 
00731 {
00732     
00733     REAL p = (Sig(0)+Sig(1)+Sig(2))/3.0;
00734 
00735     
00736     REAL K  =  p         *v/_kap;
00737     REAL Ks = (Suc+_patm)*v/_kaps;
00738 
00739     
00740     Tensors::AddScaled(2.0*_G,Tensors::Psd, K,Tensors::IdyI, De);
00741 
00742     
00743     de = (-K/Ks)*I;
00744 
00745 } 
00746 
00747 inline void SubBar::Calc_dFdSig_dFdSuc(Tensor2 const & Sig, IntVars const & z, REAL const & Suc, Tensor2 & V, REAL & S) const 
00748 {
00749     
00750     REAL     p,q,sin3th;
00751     Tensor2  devS;
00752     Stress_p_q_S_sin3th(Sig, p,q,devS,sin3th);
00753 
00754     
00755     REAL lam = _lam(Suc);
00756     REAL psi = _psi(Suc);
00757     REAL  p0 = Calc_p0(z,Suc);
00758     REAL  ps = _k*Suc;
00759 
00760     
00761     REAL        M = _calc_M(sin3th);
00762     REAL       MM = M*M;
00763     REAL      tmp = MM*(2.0*p-p0+ps)/3.0;
00764     REAL dp0_dSuc = p0*log(z(0)/_pref)*psi*_bet*_lam0*(1.0-_r)*exp(-_bet*Suc)/(lam-_kap);
00765     REAL  dC_dSuc = _BB*_pref*exp(_BB*(Suc-z(1))/_pref);
00766     REAL  dg_dSuc = MM*((p-p0)*_k - (p+ps)*dp0_dSuc);
00767                 V = tmp*I + 3.0*devS;  
00768                 S = dg_dSuc + dC_dSuc; 
00769     if (q>Q_ZERO)
00770     {
00771         REAL  ss3th = pow(sin3th,2.0);
00772         REAL cos3th = (ss3th>1.0 ? 0.0 : sqrt(1.0-ss3th));
00773         if (cos3th>Q_ZERO) 
00774         {
00775             REAL                dM_dth = (0.75*M*(1.0-_wcs)*cos3th) / (1.0+_wcs+(_wcs-1.0)*sin3th);
00776             Tensor2 SS;         Mult(devS,devS,SS);
00777             Tensor2 dev_SS;     dev_SS = SS - (I * (SS(0)+SS(1)+SS(2))/3.0);
00778             Tensor2 dth_dsig; dth_dsig = (1.5/(q*q*cos3th)) * (dev_SS*(3.0/q) - devS*sin3th);
00779                                     V += dth_dsig*(2.0*M*(p-p0)*(p+ps)*dM_dth);
00780         }
00781     }
00782 
00783 } 
00784 
00785 inline void SubBar::_calc_f0_grads(Tensor2 const & Sig     , 
00786                                    IntVars const & z       ,
00787                                    REAL    const & Suc     ,
00788                                    Tensor2       & df0_dSig,
00789                                    REAL          & df0_dSuc, 
00790                                    REAL          & df0_dz0 ) const
00791 {
00792     
00793     REAL     p,q,sin3th;
00794     Tensor2  devS;
00795     Stress_p_q_S_sin3th(Sig, p,q,devS,sin3th);
00796 
00797     
00798     REAL lam = _lam(Suc);
00799     REAL psi = _psi(Suc);
00800     REAL  p0 = Calc_p0(z,Suc);
00801     REAL  ps = _k*Suc;
00802 
00803     
00804     REAL        M = _calc_M(sin3th);
00805     REAL       MM = M*M;
00806     REAL dp0_dSuc = p0*log(z(0)/_pref)*psi*_bet*_lam0*(1.0-_r)*exp(-_bet*Suc)/(lam-_kap);
00807          df0_dSuc = MM*((p-p0)*_k - (p+ps)*dp0_dSuc);
00808          df0_dSig = (MM*(2.0*p-p0+ps)/3.0)*I + 3.0*devS;
00809           df0_dz0 = -MM*psi*p0*(p+ps)/z(0);
00810     
00811 } 
00812 
00813 inline void SubBar::_calc_gradients_and_hardening(REAL    const & v, 
00814                                                   Tensor2 const & Sig,
00815                                                   IntVars const & z,
00816                                                   REAL    const & Suc,
00817                                                   Tensor2       & r,
00818                                                   Tensor2       & V,
00819                                                   T_dFdz        & y, 
00820                                                   REAL          & S,
00821                                                   HardMod       & HH,
00822                                                   REAL          & hp) const
00823 {
00824     
00825     REAL     p,q,sin3th;
00826     Tensor2  devS;
00827     Stress_p_q_S_sin3th(Sig, p,q,devS,sin3th);
00828 
00829     
00830     REAL lam = _lam(Suc);
00831     REAL psi = _psi(Suc);
00832     REAL  p0 = Calc_p0(z,Suc);
00833     REAL  ps = _k*Suc;
00834 
00835     
00836     
00837     
00838     REAL        M = _calc_M(sin3th);
00839     REAL       MM = M*M;
00840     REAL      tmp = MM*(2.0*p-p0+ps)/3.0;
00841     REAL dp0_dSuc = p0*log(z(0)/_pref)*psi*_bet*_lam0*(1.0-_r)*exp(-_bet*Suc)/(lam-_kap);
00842     REAL  dC_dSuc = _BB*_pref*exp(_BB*(Suc-z(1))/_pref);
00843     REAL  dg_dSuc = MM*((p-p0)*_k - (p+ps)*dp0_dSuc);
00844                 r = tmp*I + (3.0*_alp)*devS;  
00845                 V = tmp*I +  3.0      *devS;  
00846                 S = dg_dSuc + dC_dSuc;        
00847     if (q>Q_ZERO)
00848     {
00849         REAL  ss3th = pow(sin3th,2.0);
00850         REAL cos3th = (ss3th>1.0 ? 0.0 : sqrt(1.0-ss3th));
00851         if (cos3th>Q_ZERO) 
00852         {
00853             REAL                dM_dth = (0.75*M*(1.0-_wcs)*cos3th) / (1.0+_wcs+(_wcs-1.0)*sin3th);
00854             Tensor2 SS;         Mult(devS,devS,SS);
00855             Tensor2 dev_SS;     dev_SS = SS - (I * (SS(0)+SS(1)+SS(2))/3.0);
00856             Tensor2 dth_dsig; dth_dsig = (1.5/(q*q*cos3th)) * (dev_SS*(3.0/q) - devS*sin3th);
00857                                     V += dth_dsig*(2.0*M*(p-p0)*(p+ps)*dM_dth);
00858                                     r += dth_dsig*(2.0*M*(p-p0)*(p+ps)*dM_dth);
00859         }
00860     }
00861     y(0) = -MM*psi*p0*(p+ps)/z(0);
00862     y(1) = -_BB*Calc_C(z,Suc)/_pref;
00863     y(2) = 0.0;
00864     y(3) = 0.0;
00865 
00866     
00867     REAL  tr_r = r(0)+r(1)+r(2);
00868     REAL  chi0 = (_lam0 - _kap )/v;
00869     REAL  chis = (_lams - _kaps)/v;
00870     REAL     L = _c0*pow(chi0*log( z(2)       / z(0)       ),2.0)/p;
00871     REAL    Ls = _cs*pow(chis*log((z(3)+_patm)/(z(1)+_patm)),2.0)/(Suc+_patm);
00872          HH(0) =  z(0)       *(tr_r+L )/chi0;
00873          HH(1) = (z(1)+_patm)*(tr_r+Ls)/chis;
00874          HH(2) =  z(2)       * tr_r    /chi0;
00875          HH(3) = (z(3)+_patm)* tr_r    /chis;
00876 
00877     
00878     hp = -(y(0)*HH(0)+y(1)*HH(1));
00879 
00880     
00881     
00882 } 
00883 
00884 inline int SubBar::_tg_deps_dz_given_dsig_and_dsuc(AugVec  const & SigSuc, 
00885                                                    Tensor2 const & Eps,
00886                                                    IntVars const & z,
00887                                                    AugVec  const & dSigSuc,
00888                                                    Tensor2       & dEps,
00889                                                    IntVars       & dz) const
00890 {
00891     
00892     REAL ev,ed;
00893     Tensors::Strain_Ev_Ed(Eps, ev,ed);
00894     if (ed>CoupledModel::_isc.EdMax()) 
00895         throw new Warning(_("SubBar::_tg_deps_dz_given_dsig_and_dsuc: Max devaitoric strain Ed=%f greater than EdMax=%f"),ed,_isc.EdMax());
00896 
00897     
00898     Tensor2  sig;   sig =  SigSuc(0), SigSuc(1), SigSuc(2), SigSuc(3), SigSuc(4), SigSuc(5);
00899     Tensor2 dsig;  dsig = dSigSuc(0),dSigSuc(1),dSigSuc(2),dSigSuc(3),dSigSuc(4),dSigSuc(5);
00900     REAL     suc;   suc =  SigSuc(6);
00901     REAL    dsuc;  dsuc = dSigSuc(6);
00902     
00903     
00904     REAL    v=_v; 
00905     Tensor2 r;    
00906     Tensor2 V;    
00907     T_dFdz  y;    
00908     REAL    S;    
00909     HardMod HH;   
00910     REAL    hp;   
00911     _calc_gradients_and_hardening(v, sig, z, suc, r, V, y, S, HH, hp);
00912 
00913     
00914     if (fabs(hp/(sig(0)+sig(1)+sig(2)))<=_MIN_HP)
00915         throw new Warning(_("SubBar::_tg_deps_dz_given_dsig_and_dsuc: hp=%f (zero). Maybe it is the start of softening behaviour"),hp);
00916 
00917     
00918     Tensor4 Cep; 
00919     Tensor2 ce;
00920     _calc_Ce_ce(v,sig,suc, Cep,ce); 
00921 
00922     
00923     Tensors::Ger(1.0/hp,r,V, Cep); 
00924 
00925     
00926     Tensor2 cep;
00927     cep = (S/hp)*r + ce;
00928 
00929     
00930     Tensors::Dot(Cep,dsig, dEps);
00931     dEps += cep*dsuc;            
00932 
00933     
00934     REAL dLam = (Tensors::Dot(V,dsig) + S*dsuc)/hp; 
00935            dz = dLam*HH;
00936 
00937     return 0;
00938 
00939 } 
00940 
00941 inline int SubBar::_tg_dsig_dz_given_deps_and_dsuc(AugVec  const & EpsSuc, 
00942                                                    Tensor2 const & Sig,
00943                                                    IntVars const & z,
00944                                                    AugVec  const & dEpsSuc,
00945                                                    Tensor2       & dSig,
00946                                                    IntVars       & dz) const
00947 {
00948     
00949     Tensor2  eps;   eps =  EpsSuc(0), EpsSuc(1), EpsSuc(2), EpsSuc(3), EpsSuc(4), EpsSuc(5);
00950     Tensor2 deps;  deps = dEpsSuc(0),dEpsSuc(1),dEpsSuc(2),dEpsSuc(3),dEpsSuc(4),dEpsSuc(5);
00951     REAL     suc;   suc =  EpsSuc(6);
00952     REAL    dsuc;  dsuc = dEpsSuc(6);
00953     
00954     
00955     REAL    v=_v; 
00956     Tensor2 r;    
00957     Tensor2 V;    
00958     T_dFdz  y;    
00959     REAL    S;    
00960     HardMod HH;   
00961     REAL    hp;   
00962     _calc_gradients_and_hardening(v, Sig, z, suc, r, V, y, S, HH, hp);
00963 
00964     
00965     Tensor4 De;
00966     Tensor2 de;
00967     _calc_De_de(v,Sig,suc, De,de);
00968 
00969     
00970     Tensor4 Dep;
00971     REAL Phi = Tensors::Reduce(V,De,r)+hp;    
00972     Tensors::GerX(-1.0/Phi,De,r,V,De,De,Dep); 
00973 
00974     
00975     Tensor2 dep;
00976     Tensors::Dot(De,r, dep);                     
00977     dep = de - ((Tensors::Dot(V,de)+S)/Phi)*dep; 
00978 
00979     
00980     Tensors::Dot(Dep,deps, dSig); 
00981     dSig += dep*dsuc;             
00982 
00983     
00984     REAL dLam = (Tensors::Reduce(V,De,deps) + Tensors::Dot(V,de)*dsuc + S*dsuc)/Phi; 
00985            dz = dLam*HH;
00986 
00987     return 0;
00988 
00989 } 
00990 
00991 inline REAL SubBar::_local_error(Tensor2 const & Ey, Tensor2 const & y_high, 
00992                                      IntVars const & Ez, IntVars const & z_high) const
00993 {
00994     REAL Err_y = Tensors::Norm(Ey)/Tensors::Norm(y_high);
00995     REAL Err_z = sqrt(blitz::dot(Ez,Ez))/sqrt(blitz::dot(z_high,z_high));
00996     return (Err_y>Err_z ? Err_y : Err_z);
00997 } 
00998 
00999 inline void SubBar::_force_consistency() 
01000 {
01001     
01002     REAL     p,q,sin3th;
01003     Tensor2  devS;
01004     Stress_p_q_S_sin3th(_sig, p,q,devS,sin3th);
01005 
01006     
01007     REAL   M = _calc_M(sin3th);
01008     REAL  MM = M*M;
01009     REAL psi = _psi(_suc);
01010     REAL  p0 = p + (q*q)/(MM*(p+_k*_suc));
01011 
01012     
01013     _z(0) = _pref*pow(p0/_pref,1.0/psi);
01014 
01015 #ifndef SUBBAR_INIT1
01016     
01017           int          k = 0;
01018     const int      maxIt = 20;
01019     const REAL resid_TOL = 1.0e-7;
01020                    _z(1) = _suc; 
01021           REAL         g = -MM*(p+_k*_suc)*(p0-p);
01022           REAL    C_star = -q*q - g;
01023     while (k<=maxIt)
01024     {
01025         REAL    Ck = Calc_C(_z, _suc);
01026         REAL resid = C_star - Ck;
01027         if (fabs(resid)<=resid_TOL)
01028         {
01029             
01030             return;
01031         }
01032         REAL dresid_dz1 = _BB*Ck/_pref;
01033         _z(1) = _z(1) - resid/dresid_dz1;
01034         k++;
01035     }
01036     throw new Fatal (_("SubBar::_force_consistency Newton-Raphson failed"));
01037 #endif
01038 
01039 } 
01040 
01041 inline void SubBar::InternalStateValues(Array<REAL> & IntStateVals) const 
01042 {
01043     IntStateVals.resize(5); 
01044     IntStateVals[0] = _z(0);
01045     IntStateVals[1] = _z(1);
01046     IntStateVals[2] = _z(2);
01047     IntStateVals[3] = _z(3);
01048     IntStateVals[4] = _v;
01049 } 
01050 
01051 inline void SubBar::InternalStateNames(Array<String> & IntStateNames) const 
01052 {
01053     IntStateNames.resize(5); 
01054     IntStateNames[0] = "z0";
01055     IntStateNames[1] = "z1";
01056     IntStateNames[2] = "z2";
01057     IntStateNames[3] = "z3";
01058     IntStateNames[4] = "v";
01059 } 
01060 
01061 inline REAL SubBar::_calc_M(REAL const & sin3th) const 
01062 {
01063     return _Mcs*pow( 2.0*_wcs/(1.0+_wcs+(_wcs-1.0)*sin3th) ,0.25);
01064 } 
01065 
01066 
01068 
01069 
01070 
01071 CoupledModel * SubBarMaker(Array<REAL> const & Prms, Array<REAL> const & IniData) 
01072 {
01073     return new SubBar(Prms, IniData);
01074 } 
01075 
01076 
01077 int SubBarRegister() 
01078 {
01079     CoupledModelFactory["SubBar"] = SubBarMaker;
01080     return 0;
01081 } 
01082 
01083 
01084 int __SubBar_dummy_int = SubBarRegister();
01085 
01086 #endif // MECHSYS_SUBBAR_H
01087 
01088