MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/models/strainupdate.h
Go to the documentation of this file.
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_STRAINUPDATE_H
00021 #define MECHSYS_STRAINUPDATE_H
00022 
00023 // Std Lib
00024 #include <iostream>
00025 
00026 // MechSys
00027 #include <mechsys/models/model.h>
00028 #include <mechsys/models/equilibstate.h>
00029 
00030 class StrainUpdate
00031 {
00032 public:
00033     // enum
00034     enum Scheme_t { ME_t, SingleFE_t }; 
00035 
00036     // Constructor
00037     StrainUpdate (Model const * Mdl);
00038 
00039     // Methods
00040     void Update (Vec_t const & DSig, State * Sta, Vec_t & DEps) const;
00041 
00042     // Data
00043     Model const * Mdl;
00044 
00045     // Constants for integration
00046     Scheme_t Scheme; 
00047     double   STOL;
00048     double   dTini;
00049     double   mMin;
00050     double   mMax;
00051     size_t   MaxSS;
00052     bool     CDrift; 
00053 };
00054 
00055 
00057 
00058 
00059 inline StrainUpdate::StrainUpdate (Model const * TheMdl)
00060     : Mdl    (TheMdl),
00061       Scheme (ME_t),
00062       STOL   (1.0e-5),
00063       dTini  (1.0),
00064       mMin   (0.1),
00065       mMax   (10.0),
00066       MaxSS  (2000),
00067       CDrift (true)
00068 {
00069 }
00070 
00071 inline void StrainUpdate::Update (Vec_t const & DSig, State * Sta, Vec_t & DEps) const
00072 {
00073     // current state
00074     EquilibState * sta = static_cast<EquilibState*>(Sta);
00075     DEps = sta->Eps; // temporary copy to calculate increment later
00076 
00077     // constants
00078     size_t ncp = size(sta->Sig); // num of stress components
00079     size_t niv = size(sta->Ivs); // num of internal variables
00080 
00081     // auxiliar variables
00082     Vec_t dsig(ncp);
00083     Vec_t deps(ncp);
00084     Vec_t divs(niv);
00085 
00086     if (Scheme==SingleFE_t) // without intersection detection (should be used for linear elasticity only)
00087     {
00088         dsig = DSig;
00089         Mdl->InvTgIncs (sta, dsig, deps, divs);
00090         sta->Eps += deps;
00091         sta->Sig += dsig;
00092         sta->Ivs += divs;
00093     }
00094     else if (Scheme==ME_t)
00095     {
00096         // auxiliar variables
00097         EquilibState sta_1 (Mdl->NDim);              // intermediate state
00098         EquilibState sta_ME(Mdl->NDim);              // Modified-Euler state
00099         Vec_t deps_1(ncp), dsig_1(ncp), divs_1(niv); // intermediate increments
00100         Vec_t deps_2(ncp), divs_2(niv);              // ME increments
00101         Vec_t eps_dif(ncp);                          // ME - FE strain difference
00102 
00103         // update with full DSig
00104         dsig = DSig;
00105 
00106         // for each pseudo time T
00107         double T  = 0.0;
00108         double dT = dTini;
00109         size_t k  = 0;
00110         for (k=0; k<MaxSS; ++k)
00111         {
00112             // exit point
00113             if (T>=1.0) break;
00114 
00115             // FE and ME increments
00116             dsig_1 = dT*dsig;
00117             Mdl->InvTgIncs (sta, dsig_1, deps_1, divs_1);
00118             sta_1.Eps = sta->Eps + deps_1;
00119             sta_1.Sig = sta->Sig + dsig_1;
00120             sta_1.Ivs = sta->Ivs + divs_1;
00121             Mdl->InvTgIncs (&sta_1, dsig_1, deps_2, divs_2);
00122             sta_ME.Eps = sta->Eps + 0.5*(deps_1+deps_2);
00123             sta_ME.Ivs = sta->Ivs + 0.5*(divs_1+divs_2);
00124 
00125             // local error estimate
00126             eps_dif = sta_ME.Eps - sta_1.Eps;
00127             double eps_err = Norm(eps_dif)/(1.0+Norm(sta_ME.Eps));
00128             double ivs_err = 0.0;
00129             for (size_t i=0; i<niv; ++i) ivs_err += fabs(sta_ME.Ivs(i)-sta_1.Ivs(i))/(1.0+fabs(sta_ME.Ivs(i)));
00130             double error = eps_err + ivs_err;
00131 
00132             // step multiplier
00133             double m = (error>0.0 ? 0.9*sqrt(STOL/error) : mMax);
00134 
00135             // update
00136             if (error<STOL)
00137             {
00138                 // update state
00139                 T += dT;
00140                 sta->Eps = sta_ME.Eps;
00141                 sta->Sig = sta_1 .Sig;
00142                 sta->Ivs = sta_ME.Ivs;
00143 
00144                 // drift correction
00145                 if (CDrift) Mdl->CorrectDrift (sta);
00146 
00147                 // update stress path in model
00148                 Mdl->UpdatePath (sta, Vec_t(0.5*(deps_1+deps_2)), dsig_1);
00149 
00150                 // limit change on stepsize
00151                 if (m>mMax) m = mMax;
00152             }
00153             else if (m<mMin) m = mMin;
00154 
00155             // change next step size
00156             dT = m * dT;
00157 
00158             // check for last increment
00159             if (dT>1.0-T) dT = 1.0-T;
00160         }
00161         if (k>=MaxSS) throw new Fatal("StrainUpdate::Update: Modified-Euler (local) did not converge after %d substeps",k);
00162     }
00163     else throw new Fatal("StrainUpdate::Update: Scheme is not available yet");
00164 
00165     // return total stress increment
00166     DEps = sta->Eps - DEps;
00167 }
00168 
00169 #endif // MECHSYS_STRAINUPDATE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines