![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
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_FEM_NLROD_H 00021 #define MECHSYS_FEM_NLROD_H 00022 00023 // MechSys 00024 #include <mechsys/fem/element.h> 00025 #include <mechsys/models/model.h> 00026 00027 namespace FEM 00028 { 00029 00030 class NLRodState : public State 00031 { 00032 public: 00033 NLRodState (int NDim) : State(NDim) {} 00034 void Init (SDPair const & Ini, size_t NIvs=0) { sa = (Ini.HasKey("sa") ? Ini("sa") : 0.0); ea = (Ini.HasKey("ea") ? Ini("ea") : 0.0); } 00035 void Backup () { sa_bkp = sa; ea_bkp = ea; } 00036 void Restore () { sa = sa_bkp; ea = ea_bkp; } 00037 size_t PckSize () const { return 2; } 00038 void Pack (Array<double> & V) const { V.Resize(2); V = sa, ea; } 00039 void Unpack (Array<double> const & V) { sa=V[0]; ea=V[1]; } 00040 void Output (SDPair & KeysVals) const { KeysVals.Set("sa ea", sa, ea); } 00041 double sa, sa_bkp; 00042 double ea, ea_bkp; 00043 }; 00044 00045 class NLRod : public Element 00046 { 00047 public: 00048 // Constructor 00049 NLRod (int NDim, 00050 Mesh::Cell const & Cell, 00051 Model const * Mdl, 00052 Model const * XMdl, 00053 SDPair const & Prp, 00054 SDPair const & Ini, 00055 Array<Node*> const & Nodes); 00056 00057 // Methods 00058 void GetLoc (Array<size_t> & Loc) const; 00059 void CalcK (Mat_t & K) const; 00060 void CalcT (Mat_t & T, double & l) const; 00061 void UpdateState (Vec_t const & dU, Vec_t * F_int=NULL) const; 00062 void GetState (SDPair & KeysVals, int none=-1) const; 00063 00064 // Constants 00065 double E0; 00066 double alp; 00067 double A; 00068 }; 00069 00070 00072 00073 00074 inline NLRod::NLRod (int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) 00075 : Element(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes) 00076 { 00077 // check GTy 00078 if (GTy!=fra_t) throw new Fatal("NLRod::NLRod: Geometry type (GTy) must be equal to 'fra' (Frame). GTy=%s is invalid",GTypeToStr(GTy).CStr()); 00079 00080 // parameters/properties 00081 E0 = Prp("E0"); 00082 alp = Prp("alp"); 00083 A = Prp("A"); 00084 00085 // allocate and initialize state (constant along element) 00086 Sta.Push (new NLRodState(NDim)); 00087 Sta[0]->Init (Ini); 00088 } 00089 00090 inline void NLRod::GetLoc (Array<size_t> & Loc) const 00091 { 00092 Loc.Resize (2*NDim); 00093 for (size_t i=0; i<2; ++i) 00094 { 00095 Loc[i*NDim+0] = Con[i]->Eq("ux"); 00096 Loc[i*NDim+1] = Con[i]->Eq("uy"); if (NDim==3) 00097 Loc[i*NDim+2] = Con[i]->Eq("uz"); 00098 } 00099 } 00100 00101 inline void NLRod::CalcK (Mat_t & K) const 00102 { 00103 // rod length and T matrix 00104 double l; 00105 Mat_t T; 00106 CalcT (T, l); 00107 00108 // local K 00109 double dgde = (1.0-2.0*alp*static_cast<NLRodState*>(Sta[0])->ea); 00110 double m = dgde*E0*A/l; 00111 Mat_t Kl(2,2); 00112 Kl = m, -m, 00113 -m, m; 00114 00115 // K matrix 00116 int nrows = 2*NDim; // number of rows in local K matrix 00117 K.change_dim (nrows,nrows); 00118 K = trans(T)*Kl*T; 00119 } 00120 00121 inline void NLRod::CalcT (Mat_t & T, double & l) const 00122 { 00123 // coordinates 00124 double x0 = Con[0]->Vert.C[0]; 00125 double y0 = Con[0]->Vert.C[1]; 00126 double x1 = Con[1]->Vert.C[0]; 00127 double y1 = Con[1]->Vert.C[1]; 00128 00129 if (NDim==2) 00130 { 00131 // derived variables 00132 l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)); // rod length 00133 double c = (x1-x0)/l; // cosine 00134 double s = (y1-y0)/l; // sine 00135 00136 // transformation matrix 00137 T.change_dim (2,4); 00138 T = c, s, 0.0, 0.0, 00139 0.0, 0.0, c, s; 00140 } 00141 else 00142 { 00143 // derived variables 00144 double z0 = Con[0]->Vert.C[2]; 00145 double z1 = Con[1]->Vert.C[2]; 00146 l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)+pow(z1-z0,2.0)); // rod length 00147 double c = (x1-x0)/l; 00148 double s = (y1-y0)/l; 00149 double t = (z1-z0)/l; 00150 00151 // transformation matrix 00152 T.change_dim (2,6); 00153 T = c, s, t, 0.0, 0.0, 0.0, 00154 0.0, 0.0, 0.0, c, s, t; 00155 } 00156 } 00157 00158 inline void NLRod::UpdateState (Vec_t const & dU, Vec_t * F_int) const 00159 { 00160 // get location array 00161 Array<size_t> loc; 00162 GetLoc (loc); 00163 00164 // element nodal displacements 00165 int nrows = Con.Size()*NDim; // number of rows in local K matrix 00166 Vec_t dUe(nrows); 00167 for (size_t i=0; i<loc.Size(); ++i) dUe(i) = dU(loc[i]); 00168 00169 // rod length and T matrix 00170 double l; 00171 Mat_t T; 00172 CalcT (T, l); 00173 00174 // axial strain increment 00175 Vec_t dUa(T * dUe); // dUa = T * dUe 00176 double dea = (dUa(1)-dUa(0))/l; 00177 00178 // update strain and stress 00179 NLRodState * sta = static_cast<NLRodState*>(Sta[0]); 00180 double dsa = sta->sa; 00181 sta->ea += dea; 00182 sta->sa = E0*(sta->ea - alp*pow(sta->ea,2.0)); 00183 dsa = sta->sa - dsa; 00184 00185 // element nodal forces 00186 Vec_t dFl(2); // local 00187 dFl = -A*(dsa), A*(dsa); 00188 Vec_t dFe(nrows); 00189 dFe = trans(T)*dFl; 00190 00191 // add results to Fint (internal forces) 00192 if (F_int!=NULL) for (size_t i=0; i<loc.Size(); ++i) (*F_int)(loc[i]) += dFe(i); 00193 } 00194 00195 inline void NLRod::GetState (SDPair & KeysVals, int none) const 00196 { 00197 Sta[0]->Output (KeysVals); 00198 KeysVals.Set ("fa", A*static_cast<NLRodState*>(Sta[0])->sa); 00199 } 00200 00201 00203 00204 00205 // Allocate a new element 00206 Element * NLRodMaker(int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) { return new NLRod(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes); } 00207 00208 // Register element 00209 int NLRodRegister() 00210 { 00211 ElementFactory["NLRod"] = NLRodMaker; 00212 ElementVarKeys["NLRod2D"] = std::make_pair ("ux uy", "fx fy"); 00213 ElementVarKeys["NLRod3D"] = std::make_pair ("ux uy uz", "fx fy fz"); 00214 PROB.Set ("NLRod", (double)PROB.Keys.Size()); 00215 return 0; 00216 } 00217 00218 // Call register 00219 int __NLRod_dummy_int = NLRodRegister(); 00220 00221 }; // namespace FEM 00222 00223 #endif // MECHSYS_FEM_NLROD