![]() |
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_ROD_H 00021 #define MECHSYS_FEM_ROD_H 00022 00023 // MechSys 00024 #include <mechsys/fem/element.h> 00025 00026 namespace FEM 00027 { 00028 00029 class Rod : public Element 00030 { 00031 public: 00032 // Constructor 00033 Rod (int NDim, 00034 Mesh::Cell const & Cell, 00035 Model const * Mdl, 00036 Model const * XMdl, 00037 SDPair const & Prp, 00038 SDPair const & Ini, 00039 Array<Node*> const & Nodes); 00040 00041 // Methods 00042 void GetLoc (Array<size_t> & Loc) const; 00043 void CalcK (Mat_t & K) const; 00044 void CalcT (Mat_t & T, double & l) const; 00045 void UpdateState (Vec_t const & dU, Vec_t * F_int=NULL) const; 00046 void StateKeys (Array<String> & Keys) const; 00047 void StateAtNodes (Array<SDPair> & Results) const; 00048 void Draw (std::ostream & os, MPyPrms const & Prms) const; 00049 00050 // Constants 00051 double E; 00052 double A; 00053 }; 00054 00055 00057 00058 00059 inline Rod::Rod (int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) 00060 : Element(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes) 00061 { 00062 // check GTy 00063 if (GTy!=fra_t) throw new Fatal("Rod::Rod: Geometry type (GTy) must be equal to 'fra' (Frame). GTy=%s is invalid",GTypeToStr(GTy).CStr()); 00064 00065 // parameters/properties 00066 E = Prp("E"); 00067 A = Prp("A"); 00068 } 00069 00070 inline void Rod::GetLoc (Array<size_t> & Loc) const 00071 { 00072 Loc.Resize (2*NDim); 00073 for (size_t i=0; i<2; ++i) 00074 { 00075 Loc[i*NDim+0] = Con[i]->Eq("ux"); 00076 Loc[i*NDim+1] = Con[i]->Eq("uy"); if (NDim==3) 00077 Loc[i*NDim+2] = Con[i]->Eq("uz"); 00078 } 00079 } 00080 00081 inline void Rod::CalcK (Mat_t & K) const 00082 { 00083 // rod length and T matrix 00084 double l; 00085 Mat_t T; 00086 CalcT (T, l); 00087 00088 // local K 00089 double m = E*A/l; 00090 Mat_t Kl(2,2); 00091 Kl = m, -m, 00092 -m, m; 00093 00094 // K matrix 00095 int nrows = 2*NDim; // number of rows in local K matrix 00096 K.change_dim (nrows,nrows); 00097 K = trans(T)*Kl*T; 00098 } 00099 00100 inline void Rod::CalcT (Mat_t & T, double & l) const 00101 { 00102 // coordinates 00103 double x0 = Con[0]->Vert.C[0]; 00104 double y0 = Con[0]->Vert.C[1]; 00105 double x1 = Con[1]->Vert.C[0]; 00106 double y1 = Con[1]->Vert.C[1]; 00107 00108 if (NDim==2) 00109 { 00110 // derived variables 00111 l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)); // rod length 00112 double c = (x1-x0)/l; // cosine 00113 double s = (y1-y0)/l; // sine 00114 00115 // transformation matrix 00116 T.change_dim (2,4); 00117 T = c, s, 0.0, 0.0, 00118 0.0, 0.0, c, s; 00119 } 00120 else 00121 { 00122 // derived variables 00123 double z0 = Con[0]->Vert.C[2]; 00124 double z1 = Con[1]->Vert.C[2]; 00125 l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)+pow(z1-z0,2.0)); // rod length 00126 double c = (x1-x0)/l; 00127 double s = (y1-y0)/l; 00128 double t = (z1-z0)/l; 00129 00130 // transformation matrix 00131 T.change_dim (2,6); 00132 T = c, s, t, 0.0, 0.0, 0.0, 00133 0.0, 0.0, 0.0, c, s, t; 00134 } 00135 } 00136 00137 inline void Rod::UpdateState (Vec_t const & dU, Vec_t * F_int) const 00138 { 00139 if (F_int!=NULL) 00140 { 00141 // get location array 00142 Array<size_t> loc; 00143 GetLoc (loc); 00144 00145 // element nodal displacements 00146 int nrows = Con.Size()*NDim; // number of rows in local K matrix 00147 Vec_t dUe(nrows); 00148 for (size_t i=0; i<loc.Size(); ++i) dUe(i) = dU(loc[i]); 00149 00150 // K matrix 00151 Mat_t K; 00152 CalcK (K); 00153 00154 // element nodal forces 00155 Vec_t dFe(nrows); 00156 dFe = K * dUe; 00157 00158 // add results to Fint (internal forces) 00159 for (size_t i=0; i<loc.Size(); ++i) (*F_int)(loc[i]) += dFe(i); 00160 } 00161 } 00162 00163 inline void Rod::StateKeys (Array<String> & Keys) const 00164 { 00165 Keys.Resize (1); 00166 Keys[0] = "N"; 00167 } 00168 00169 inline void Rod::StateAtNodes (Array<SDPair> & Results) const 00170 { 00171 // rod length and T matrix 00172 double l; 00173 Mat_t T; 00174 CalcT (T, l); 00175 00176 // displacements in global coordinates 00177 Vec_t U(2*NDim); 00178 for (size_t j=0; j<2; ++j) 00179 { 00180 U(0+j*NDim) = Con[j]->U("ux"); 00181 U(1+j*NDim) = Con[j]->U("uy"); if (NDim==3) 00182 U(2+j*NDim) = Con[j]->U("uz"); 00183 } 00184 00185 // displacements in local coordinates 00186 Vec_t Ul(T * U); 00187 00188 // axial force 00189 double N = E*A*(Ul(1)-Ul(0))/l; 00190 Results.Resize (2); 00191 Results[0].Set ("N", N); 00192 Results[1].Set ("N", N); 00193 } 00194 00195 inline void Rod::Draw (std::ostream & os, MPyPrms const & Prms) const 00196 { 00197 // coordinates 00198 double x0 = Con[0]->Vert.C[0]; 00199 double y0 = Con[0]->Vert.C[1]; 00200 double x1 = Con[1]->Vert.C[0]; 00201 double y1 = Con[1]->Vert.C[1]; 00202 00203 if (NDim==2) 00204 { 00205 // draw shape 00206 os << "XY = array([["<<x0<<","<<y0<<"],["<<x1<<","<<y1<<"]])\n"; 00207 os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor=orange, lw=4))\n"; 00208 } 00209 else throw new Fatal("Rod::Draw: Method not available for 3D yet"); 00210 } 00211 00212 00214 00215 00216 // Allocate a new element 00217 Element * RodMaker(int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) { return new Rod(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes); } 00218 00219 // Register element 00220 int RodRegister() 00221 { 00222 ElementFactory ["Rod"] = RodMaker; 00223 ElementVarKeys ["Rod2D"] = std::make_pair ("ux uy", "fx fy"); 00224 ElementVarKeys ["Rod3D"] = std::make_pair ("ux uy uz", "fx fy fz"); 00225 ElementExtraKeys["Rod2D"] = Array<String> (); 00226 ElementExtraKeys["Rod3D"] = Array<String> (); 00227 PROB.Set ("Rod", (double)PROB.Keys.Size()); 00228 return 0; 00229 } 00230 00231 // Call register 00232 int __Rod_dummy_int = RodRegister(); 00233 00234 }; // namespace FEM 00235 00236 #endif // MECHSYS_FEM_ROD