MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/fem/rod.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines