elastic.h

00001 /*************************************************************************************
00002  * MechSys - A C++ library to simulate (Continuum) Mechanical Systems                *
00003  * Copyright (C) 2005 Dorival de Moraes Pedroso <dorival.pedroso at gmail.com>       *
00004  * Copyright (C) 2005 Raul Dario Durand Farfan  <raul.durand at gmail.com>           *
00005  *                                                                                   *
00006  * This file is part of MechSys.                                                     *
00007  *                                                                                   *
00008  * MechSys is free software; you can redistribute it and/or modify it under the      *
00009  * terms of the GNU General Public License as published by the Free Software         *
00010  * Foundation; either version 2 of the License, or (at your option) any later        *
00011  * version.                                                                          *
00012  *                                                                                   *
00013  * MechSys is distributed in the hope that it will be useful, but WITHOUT ANY        *
00014  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   *
00015  * PARTICULAR PURPOSE. See the GNU General Public License for more details.          *
00016  *                                                                                   *
00017  * You should have received a copy of the GNU General Public License along with      *
00018  * MechSys; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, *
00019  * Fifth Floor, Boston, MA 02110-1301, USA                                           *
00020  *************************************************************************************/
00021 
00022 #ifndef MECHSYS_ELASTIC_H
00023 #define MECHSYS_ELASTIC_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/equilibmodel.h"
00034 #include "tensors/tensors.h"
00035 #include "tensors/operators.h"
00036 #include "tensors/functions.h"
00037 #include "numerical/autostepme.h"
00038 #include "util/string.h"
00039 
00040 using Tensors::Tensor2;
00041 
00042 class Elastic : public EquilibModel
00043 {
00044 public:
00045     // Constructor
00046     Elastic(Array<REAL> const & Prms, Array<REAL> const & IniData);
00047     String Name() const { return "Elastic"; }
00048     void TgStiffness(Tensors::Tensor4 & D) const;
00049     void BackupState();
00050     void StressUpdate(Tensors::Tensor2 const & DEps, Tensors::Tensor2 & DSig);
00051     void Actualize   (Tensors::Tensor2 const & DSig, Tensors::Tensor2 & DEps) {}
00052     void RestoreState();
00053     int  nInternalStateValues() const { return 0; };
00054     void InternalStateValues(Array<REAL> & IntStateVals)  const {}
00055     void InternalStateNames(Array<String> & IntStateNames)  const {}
00056 private:
00057     // Data
00058     REAL _E;       // Young
00059     REAL _nu;      // Poisson
00060     REAL _kappa;   // Edometric recompression inclination
00061     bool _non_lin; // Lin/non-Lin model
00062     REAL _v_ini;   // Initial specific volume
00063     // Methods
00064     int _D_times_dEps(Tensor2 const & Eps,           // In: (actual) strain tensor
00065                       Tensor2 const & Sig,           // In: (actual) stress tensor
00066                       REAL    const & dummy1,        // In: dummy
00067                       Tensor2 const & dEps,          // In: Strain increment
00068                       Tensor2       & dSig,          // Out: Stress increment
00069                       REAL          & dummy2) const; // Out: dummy
00070     // returns: -1 if failed, 0 to continue, 1 to stop
00071     
00072     REAL _local_error(Tensor2 const & Ey    ,         // In: Stress or Strain error between low and high order evaluation (FE and ME)
00073                       Tensor2 const & y_high,         // In: Stress or Strain high order evaluation - "correct" (ME)
00074                       REAL    const & dummy1 ,        // In: dummy
00075                       REAL    const & dummy2) const;  // In: dummy
00076 
00077 }; // class Elastic
00078 
00079 
00081 
00082 
00083 inline Elastic::Elastic(Array<REAL> const & Prms, Array<REAL> const & IniData) // {{{
00084         : _E  (Prms[0]),
00085           _nu (Prms[1])
00086 {
00087     // Check number of parameters (Lin/non-Lin model)
00088     if (Prms.size()==3) { _non_lin=true; _kappa=Prms[2]; }
00089     else _non_lin=false;
00090 
00091     // Check number of initial data
00092     if (IniData.size()!=4) // Layered analysis
00093         throw new Fatal(_("Elastic::Constructor: Initial data not sufficiet (4) for a layered analysis. { Sv' Sh' vini OCR }\n"));
00094 
00095     // Read initial data
00096     REAL sig_vert = IniData[0]; // Vertical stress component
00097     REAL sig_horz = IniData[1]; // Horizontal stress component
00098            _v_ini = IniData[2]; // Initial specific volume
00099            //_OCR = IniData[3]; // Over consolidation rate (not used here)
00100 
00101     // Fill stress and strain tensors
00102     _sig = sig_horz, sig_horz, sig_vert, 0.0, 0.0, 0.0; // Mandel representation
00103     _eps = 0.0,0.0,0.0,0.0,0.0,0.0;
00104 } // }}}
00105 
00106 inline void Elastic::TgStiffness(Tensors::Tensor4 & De) const // {{{
00107 {
00108     // Calculate Young modulus
00109     REAL E;
00110     if (_non_lin) E=(_sig(0)+_sig(1)+_sig(2)) * (1.0-2.0*_nu) * _v_ini / _kappa;
00111     else          E=_E;
00112 
00113     // Calculate elastic tangent tensor
00114     Tensors::AddScaled(     E/(1.0+_nu)                   ,  Tensors::IIsym ,
00115                         _nu*E/( (1.0+_nu)*(1.0-2.0*_nu) ) , Tensors::IdyI  , De ); // Z = a*X + b*Y
00116 } // }}}
00117 
00118 inline void Elastic::BackupState() // {{{
00119 {
00120     _sig_bkp = _sig;
00121     _eps_bkp = _eps;
00122 } // }}}
00123 
00124 inline void Elastic::StressUpdate(Tensors::Tensor2 const & DEps, Tensors::Tensor2 & DSig) // {{{
00125 {
00126     // Check if this model is linear or non-linear
00127     if (_non_lin)
00128     {
00129         // Allocate a Time Integration object
00130         AutoStepME<Tensor2, Tensor2, REAL, Elastic > TI(EquilibModel::_isc);
00131 
00132         // Save a temporary copy of _sig
00133         DSig = _sig;
00134 
00135         // Update stress (_sig) and strain (_eps) state
00136         REAL dummy=0;
00137         int num_sub_steps = TI.Solve(this,                    // Address of this instance of Elastic class
00138                                      &Elastic::_D_times_dEps, // Pointer to a function that calculates dSig = D:dEps
00139                                      &Elastic::_local_error , // Pointer to a function that calculates local error on dSig
00140                                      _eps, _sig, dummy, DEps);
00141 
00142         //cout << TI.Results() << endl;
00143 
00144         // Check num_sub_steps
00145         if (num_sub_steps==-1)
00146             throw new Fatal(_("Elastic::StressUpdate: Number of max sub-steps (%d) not sufficient for AutoStepME"), EquilibModel::_isc.ME_maxSS());
00147 
00148         // Calculate the total increment of stress
00149         DSig = _sig - DSig;
00150     }
00151     else
00152     {
00153         // Just a forward-Euler step
00154         Tensors::Tensor4 De;
00155         TgStiffness(De);
00156         Tensors::Dot(De,DEps, DSig);
00157     }
00158 } // }}}
00159 
00160 inline int Elastic::_D_times_dEps(Tensor2 const & Eps,           // In: (actual) strain tensor {{{
00161                                   Tensor2 const & Sig,           // In: (actual) stress tensor
00162                                   REAL    const & dummy1,        // In: dummy
00163                                   Tensor2 const & dEps,          // In: Strain increment
00164                                   Tensor2       & dSig,          // Out: Stress increment
00165                                   REAL          & dummy2) const  // Out: dummy
00166 {
00167     Tensors::Tensor4 De;
00168     TgStiffness(De);
00169     Tensors::Dot(De,dEps, dSig);
00170     return 0; // returns: -1 if failed, 0 to continue, 1 to stop
00171 } // }}}
00172 
00173 inline REAL Elastic::_local_error(Tensor2 const & Ey    ,         // In: Stress or Strain error between low and high order evaluation (FE and ME) {{{
00174                                   Tensor2 const & y_high,         // In: Stress or Strain high order evaluation - "correct" (ME)
00175                                   REAL    const & dummy1 ,        // In: dummy
00176                                   REAL    const & dummy2) const   // In: dummy
00177 {
00178     return Tensors::Norm(Ey)/Tensors::Norm(y_high);
00179 } // }}}
00180 
00181 inline void Elastic::RestoreState() // {{{
00182 {
00183     _sig = _sig_bkp;
00184     _eps = _eps_bkp;
00185 } // }}}
00186 
00187 
00189 
00190 
00191 // Allocate a new Elastic model
00192 EquilibModel * ElasticMaker(Array<REAL> const & Prms, Array<REAL> const & IniData) // {{{
00193 {
00194     return new Elastic(Prms, IniData);
00195 } // }}}
00196 
00197 // Register an Elastic model into ModelFactory array map
00198 int ElasticRegister() // {{{
00199 {
00200     EquilibModelFactory["Elastic"] = ElasticMaker;
00201     return 0;
00202 } // }}}
00203 
00204 // Execute the autoregistration
00205 int __Elastic_dummy_int = ElasticRegister();
00206 
00207 #endif // MECHSYS_ELASTIC_H
00208 
00209 // vim:fdm=marker

Generated on Wed Jan 24 15:56:27 2007 for MechSys by  doxygen 1.4.7