MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/fem/beam.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_BEAM_H
00021 #define MECHSYS_FEM_BEAM_H
00022 
00023 // Std Lib
00024 #include <ostream>
00025 
00026 // MechSys
00027 #include <mechsys/fem/element.h>
00028 #include <mechsys/util/util.h>
00029 
00030 namespace FEM
00031 {
00032 
00033 class Beam : public Element
00034 {
00035 public:
00036     // Constructor
00037     Beam (int                  NDim,   
00038           Mesh::Cell   const & Cell,   
00039           Model        const * Mdl,    
00040           Model        const * XMdl,   
00041           SDPair       const & Prp,    
00042           SDPair       const & Ini,    
00043           Array<Node*> const & Nodes); 
00044 
00045     // Methods
00046     void SetBCs       (size_t IdxEdgeOrFace, SDPair const & BCs, BCFuncs * BCF); 
00047     void ClrBCs       ();                                                        
00048     void GetLoc       (Array<size_t> & Loc)                               const; 
00049     void CalcK        (Mat_t & K)                                         const; 
00050     void CalcM        (Mat_t & M)                                         const; 
00051     void CalcT        (Mat_t & T, double & l, Vec3_t * normal=NULL)       const; 
00052     void UpdateState  (Vec_t const & dU, Vec_t * F_int=NULL)              const;
00053     void StateKeys    (Array<String> & Keys)                              const; 
00054     void StateAtNodes (Array<SDPair> & Results)                           const; 
00055     void CalcRes      (double r, double & N, double & V, double & M)      const; 
00056     void Draw         (std::ostream & os, MPyPrms const & Prms)           const; 
00057 
00058     // Constants
00059     double E;     
00060     double A;     
00061     double Izz;   
00062     double rho;   
00063     double qnl;   
00064     double qnr;   
00065     bool   HasQn; 
00066 };
00067 
00068 
00070 
00071 
00072 inline Beam::Beam (int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes)
00073     : Element(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes), qnl(0.0), qnr(0.0), HasQn(false)
00074 {
00075     // check GTy
00076     if (GTy!=fra_t) throw new Fatal("Beam::Beam: Geometry type (GTy) must be equal to 'fra' (Frame). GTy=%s is invalid",GTypeToStr(GTy).CStr());
00077 
00078     // parameters/properties
00079     E   = Prp("E");
00080     A   = Prp("A");
00081     Izz = Prp("Izz");
00082     rho = (Prp.HasKey("rho") ? Prp("rho") : 1.0);
00083 }
00084 
00085 inline void Beam::SetBCs (size_t IdxEdgeOrFace, SDPair const & BCs, BCFuncs * BCF)
00086 {
00087     if (NDim==3) throw new Fatal("Beam::SetBCs: Method not available for 3D yet");
00088 
00089     // length and T matrix
00090     double l;
00091     Mat_t  T;
00092     Vec3_t normal;
00093     CalcT (T, l, &normal);
00094 
00095     // boundary conditions
00096     bool has_qx  = BCs.HasKey("qx");  // x component of distributed loading
00097     bool has_qy  = BCs.HasKey("qy");  // y component of distributed loading
00098     bool has_qn  = BCs.HasKey("qn");  // normal distributed loading
00099     bool has_qnl = BCs.HasKey("qnl"); // normal distributed loading (left)
00100     bool has_qnr = BCs.HasKey("qnr"); // normal distributed loading (right)
00101     bool has_qt  = BCs.HasKey("qt");  // tangential distributed loading (2D only)
00102 
00103     // loads
00104     HasQn = false;
00105     qnl   = 0.0;
00106     qnr   = 0.0;
00107     double qt = 0.0;
00108     if (BCs.HasKey("gravity"))
00109     {
00110         double g   = BCs("gravity");
00111         double gam = rho*g;
00112         double qy  = -gam*A;
00113         double qn  =  normal(1)*qy;
00114         qt    = -normal(0)*qy;
00115         qnl   = qn;
00116         qnr   = qn;
00117         HasQn = true;
00118     }
00119     else if (has_qx || has_qy)
00120     {
00121         throw new Fatal("Beam::SetBCs: Setting up of boundary conditions with 'qx' and 'qy' is not available");
00122         // TODO: this need check (seems OK, though)
00123         /*
00124         double qx = (has_qx ? BCs("qx") : 0.0);
00125         double qy = (has_qy ? BCs("qy") : 0.0);
00126         double qn = normal(0)*qx + normal(1)*qy;
00127         qt    = normal(1)*qx - normal(0)*qy;
00128         qnl   = qn;
00129         qnr   = qn;
00130         HasQn = true;
00131         */
00132     }
00133     else if (has_qn || has_qnl || has_qnr || has_qt)
00134     {
00135         if (has_qnl || has_qnr)
00136         {
00137             qnl = (has_qnl ? BCs("qnl") : 0.0);
00138             qnr = (has_qnr ? BCs("qnr") : 0.0);
00139             if (qnl*qnr<0.0) throw new Fatal("Beam::SetBCs: qnl=%g and qnr=%g must have the same sign",qnl,qnr);
00140         }
00141         else
00142         {
00143             double qn = (has_qn ? BCs("qn") : 0.0);
00144             qnl = qn;
00145             qnr = qn;
00146         }
00147         qt    = (has_qt ? BCs("qt") : 0.0);
00148         HasQn = true;
00149 
00150         // is node 0 leftmost ?
00151         bool n0_is_left = true;
00152         if (fabs(Con[1]->Vert.C[0]-Con[0]->Vert.C[0])<1.0e-7) { // vertical segment
00153              if (Con[1]->Vert.C[1]<Con[0]->Vert.C[1]) n0_is_left = false; }
00154         else if (Con[1]->Vert.C[0]<Con[0]->Vert.C[0]) n0_is_left = false;
00155         if (!n0_is_left)
00156         {
00157             Util::Swap(qnl,qnr);
00158             qnl *= -1.;
00159             qnr *= -1.; 
00160             qt  *= -1.;
00161         }
00162     }
00163 
00164     // set equivalent forces at nodes
00165     if (HasQn)
00166     {
00167         // local and global forces
00168         Vec_t Fe(6);
00169         Fe = qt*l/2.0, l*(7.0*qnl+3.0*qnr)/20.0,  l*l*(3.0*qnl+2.0*qnr)/60.0,
00170              qt*l/2.0, l*(3.0*qnl+7.0*qnr)/20.0, -l*l*(2.0*qnl+3.0*qnr)/60.0;
00171         Vec_t F(trans(T)*Fe);
00172 
00173         // add to nodes
00174         for (size_t j=0; j<2; ++j)
00175         {
00176             Con[j]->AddToPF("fx", F(0+j*3), BCF);
00177             Con[j]->AddToPF("fy", F(1+j*3), BCF);
00178             Con[j]->AddToPF("mz", F(2+j*3), BCF);
00179         }
00180     }
00181 }
00182 
00183 inline void Beam::ClrBCs ()
00184 {
00185     qnl   = 0.0;
00186     qnr   = 0.0;
00187     HasQn = false;
00188 }
00189 
00190 inline void Beam::GetLoc (Array<size_t> & Loc) const
00191 {
00192     Loc.Resize (6);
00193     for (size_t i=0; i<2; ++i)
00194     {
00195         Loc[i*3+0] = Con[i]->Eq("ux");
00196         Loc[i*3+1] = Con[i]->Eq("uy");
00197         Loc[i*3+2] = Con[i]->Eq("wz");
00198     }
00199 }
00200 
00201 inline void Beam::CalcK (Mat_t & K) const
00202 {
00203     // length and T matrix
00204     double l;
00205     Mat_t  T;
00206     CalcT (T, l);
00207 
00208     // local K
00209     double ll = l*l;
00210     double m  = E*A/l;
00211     double n  = E*Izz/(ll*l);
00212     Mat_t Kl(6,6);
00213     Kl =  m,        0.,       0.,   -m,        0.,       0.,
00214          0.,   12.  *n,  6.*l *n,   0.,  -12.  *n,  6.*l *n,
00215          0.,    6.*l*n,  4.*ll*n,   0.,   -6.*l*n,  2.*ll*n,
00216          -m,        0.,       0.,    m,        0.,       0.,
00217          0.,  -12.  *n, -6.*l *n,   0.,   12.  *n, -6.*l *n,
00218          0.,    6.*l*n,  2.*ll*n,   0.,   -6.*l*n,  4.*ll*n;
00219 
00220     // K matrix
00221     K.change_dim (6,6);
00222     K = trans(T)*Kl*T;
00223 }
00224 
00225 inline void Beam::CalcM (Mat_t & M) const
00226 {
00227     // length and T matrix
00228     double l;
00229     Mat_t  T;
00230     CalcT (T, l);
00231 
00232     // local M
00233     double ll = l*l;
00234     double m  = rho*A*l/420.;
00235     Mat_t Ml(6,6);
00236     Ml = 140.*m ,    0.     ,   0.      ,   70.*m ,    0.     ,    0.      ,
00237            0.   ,  156.*m   ,  22.*l*m  ,    0.   ,   54.*m   ,  -13.*l*m  ,
00238            0.   ,   22.*l*m ,   4.*ll*m ,    0.   ,   13.*l*m ,   -3.*ll*m ,
00239           70.*m ,    0.     ,   0.      ,  140.*m ,    0.     ,    0.      ,
00240            0.   ,   54.*m   ,  13.*l*m  ,    0.   ,  156.*m   ,  -22.*l*m  ,
00241            0.   ,  -13.*l*m ,  -3.*ll*m ,    0.   ,  -22.*l*m ,    4.*ll*m ;
00242 
00243     // M matrix
00244     M.change_dim (6,6);
00245     M = trans(T)*Ml*T;
00246 }
00247 
00248 inline void Beam::CalcT (Mat_t & T, double & l, Vec3_t * normal) const
00249 {
00250     // coordinates
00251     double x0 = Con[0]->Vert.C[0];
00252     double y0 = Con[0]->Vert.C[1];
00253     double x1 = Con[1]->Vert.C[0];
00254     double y1 = Con[1]->Vert.C[1];
00255 
00256     if (NDim==2)
00257     {
00258         // derived variables
00259         l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)); // length
00260         double c = (x1-x0)/l;                    // cosine
00261         double s = (y1-y0)/l;                    // sine
00262 
00263         // transformation matrix
00264         T.change_dim (6,6);
00265         T =   c,  s,  0.,  0.,  0.,  0.,
00266              -s,  c,  0.,  0.,  0.,  0.,
00267              0., 0.,  1.,  0.,  0.,  0.,
00268              0., 0.,  0.,   c,   s,  0.,
00269              0., 0.,  0.,  -s,   c,  0.,
00270              0., 0.,  0.,  0.,  0.,  1.;
00271 
00272         // normal
00273         if (normal!=NULL) (*normal) = -s, c, 0.0;
00274     }
00275     else throw new Fatal("Beam::CalcT: 3D Beam is not available yet");
00276 }
00277 
00278 inline void Beam::UpdateState (Vec_t const & dU, Vec_t * F_int) const
00279 {
00280     if (F_int!=NULL)
00281     {
00282         // get location array
00283         Array<size_t> loc;
00284         GetLoc (loc);
00285 
00286         // element nodal displacements
00287         Vec_t dUe(6);
00288         for (size_t i=0; i<loc.Size(); ++i) dUe(i) = dU(loc[i]);
00289 
00290         // K matrix
00291         Mat_t K;
00292         CalcK (K);
00293 
00294         // element nodal forces
00295         Vec_t dFe(6);
00296         dFe = K * dUe;
00297 
00298         /*
00299         // length and T matrix
00300         double l;
00301         Mat_t  T;
00302         CalcT (T, l);
00303 
00304         // increment of displacements in local coordinates
00305         Vec_t dUl(T * dUe);
00306 
00307         // axial and shear forces
00308         double ll  = l*l;
00309         double lll = ll*l;
00310         double dN  = E*A*(dUl(3)-dUl(0))/l;
00311         double dV  = E*Izz*((12.*dUl(1))/lll + (6.*dUl(2))/ll - (12.*dUl(4))/lll + (6.*dUl(5))/ll);
00312         double dM0 = E*Izz*(dUl(1)*(           -6./ll) + dUl(2)*(         -4./l) + dUl(4)*(6./ll            ) + dUl(5)*(         -2./l));
00313         double dM1 = E*Izz*(dUl(1)*((12.*l)/lll-6./ll) + dUl(2)*((6.*l)/ll-4./l) + dUl(4)*(6./ll-(12.*l)/lll) + dUl(5)*((6.*l)/ll-2./l));
00314 
00315         // element nodal forces in global coordinates
00316         Vec_t dFl(6);
00317         dFl = -dN, dV, -dM0,  dN, -dV, dM1;
00318         Vec_t dFe(trans(T) * dFl);
00319         */
00320 
00321         // add results to Fint (internal forces)
00322         for (size_t i=0; i<loc.Size(); ++i) (*F_int)(loc[i]) += dFe(i);
00323     }
00324 }
00325 
00326 inline void Beam::StateKeys (Array<String> & Keys) const
00327 {
00328     Keys.Resize (3);
00329     Keys = "N", "V", "M";
00330 }
00331 
00332 inline void Beam::StateAtNodes (Array<SDPair> & Results) const
00333 {
00334     Results.Resize (2);
00335     double N, V, M;
00336     CalcRes (0.0, N, V, M);
00337     Results[0].Set ("N V M",N,V,M);
00338     CalcRes (1.0, N, V, M);
00339     Results[1].Set ("N V M",N,V,M);
00340 }
00341 
00342 inline void Beam::CalcRes (double r, double & N, double & V, double & M) const
00343 {
00344     // rod length and T matrix
00345     double l;
00346     Mat_t  T;
00347     Vec3_t normal;
00348     CalcT (T, l, &normal);
00349 
00350     if (NDim==2)
00351     {
00352         // displacements in global coordinates
00353         Vec_t U(6);
00354         for (size_t j=0; j<2; ++j)
00355         {
00356             U(0+j*3) = Con[j]->U("ux");
00357             U(1+j*3) = Con[j]->U("uy");
00358             U(2+j*3) = Con[j]->U("wz");
00359         }
00360 
00361         // displacements in local coordinates
00362         Vec_t Ul(T * U);
00363 
00364         // local (natural) coordinate
00365         double s   = r*l;
00366         double ll  = l*l;
00367         double lll = ll*l;
00368 
00369         // axial force
00370         N = E*A*(Ul(3)-Ul(0))/l;
00371 
00372         // shear force
00373         V = E*Izz*((12.*Ul(1))/lll + (6.*Ul(2))/ll - (12.*Ul(4))/lll + (6.*Ul(5))/ll);
00374 
00375         // bending moment
00376         M = E*Izz*(Ul(1)*((12.*s)/lll-6./ll) + Ul(2)*((6.*s)/ll-4./l) + Ul(4)*(6./ll-(12.*s)/lll) + Ul(5)*((6.*s)/ll-2./l));
00377 
00378         if (HasQn)
00379         {
00380             double ss  = s*s;
00381             double sss = ss*s;
00382             V += -(3.*qnr*ll +7.*qnl*ll-20.*qnl*s*l -10.*qnr*ss  +10.*qnl*ss)/(20.*l);
00383             M +=  (2.*qnr*lll+3.*qnl*lll-9.*qnr*s*ll-21.*qnl*s*ll+30.*qnl*ss*l+10.*qnr*sss-10.*qnl*sss)/(60.*l);
00384         }
00385 
00386         // correct the sign of M
00387         if (qnl>0.0) M = -M;
00388     }
00389 }
00390 
00391 inline void Beam::Draw (std::ostream & os, MPyPrms const & Prms) const
00392 {
00393     // coordinates
00394     double x0 = Con[0]->Vert.C[0];
00395     double y0 = Con[0]->Vert.C[1];
00396     double x1 = Con[1]->Vert.C[0];
00397     double y1 = Con[1]->Vert.C[1];
00398 
00399     if (NDim==2)
00400     {
00401         // draw shape
00402         os << "XY = array([["<<x0<<","<<y0<<"],["<<x1<<","<<y1<<"]])\n";
00403         os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor=dred, lw=8))\n";
00404 
00405         // derived variables
00406         double l = sqrt(pow(x1-x0,2.0)+pow(y1-y0,2.0)); // length
00407         double c = (x1-x0)/l;                           // cosine
00408         double s = (y1-y0)/l;                           // sine
00409 
00410         // normal
00411         double xn = -s;
00412         double yn =  c;
00413 
00414         // results
00415         double N, V, M,  Mmax,  Mmin,  Vmax,  Vmin;
00416         double r, x, y, rMmax, rMmin, rVmax, rVmin;
00417         double sf, xf, yf, val;
00418         rMmax = 0.0;
00419         rMmin = 0.0;
00420         rVmax = 0.0;
00421         rVmin = 0.0;
00422         CalcRes (rMmax, N, Vmax, Mmax);
00423         CalcRes (rMmin, N, Vmin, Mmin);
00424         os << "dat_beam = []\n";
00425         if (Prms.DrawN) os << "dat_beam_ax = []\n";
00426         for (size_t i=0; i<Prms.NDiv+1; ++i)
00427         {
00428             r = static_cast<double>(i)/static_cast<double>(Prms.NDiv);
00429             CalcRes (r, N, V, M);
00430             if (Prms.DrawN)
00431             {
00432                 val = N;
00433                 sf  = fabs(Prms.SF*N)/2.0;
00434                 x   = x0 + r*(x1-x0);
00435                 y   = y0 + r*(y1-y0);
00436                 xf  = x - sf*xn;
00437                 yf  = y - sf*yn;
00438                 x   = x + sf*xn;
00439                 y   = y + sf*yn;
00440             }
00441             else
00442             {
00443                 if (Prms.DrawV)
00444                 {
00445                     val = V;
00446                     sf  = Prms.SF*V;
00447                     if (V>Vmax) { rVmax = r;  Vmax = V; }
00448                     if (V<Vmin) { rVmin = r;  Vmin = V; }
00449                 }
00450                 else
00451                 {
00452                     val = M;
00453                     if (qnl>0.0) sf = -Prms.SF*M;
00454                     else         sf =  Prms.SF*M;
00455                     if (M>Mmax) { rMmax = r;  Mmax = M; }
00456                     if (M<Mmin) { rMmin = r;  Mmin = M; }
00457                 }
00458                 x  = x0 + r*(x1-x0);
00459                 y  = y0 + r*(y1-y0);
00460                 xf = x - sf*xn;
00461                 yf = y - sf*yn;
00462             }
00463             os << "XY = array([["<<x<<","<<y<<"],["<<xf<<","<<yf<<"]])\n";
00464             os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor="<<(val<0.0?"dpink":"dblue")<<", lw=1))\n";
00465             if (i>0) os << "dat_beam.append((PH.LINETO, (" << xf << "," << yf << ")))\n";
00466             else     os << "dat_beam.append((PH.MOVETO, (" << xf << "," << yf << ")))\n";
00467             if (Prms.DrawN)
00468             {
00469                 if (i>0) os << "dat_beam_ax.append((PH.LINETO, (" << x << "," << y << ")))\n";
00470                 else     os << "dat_beam_ax.append((PH.MOVETO, (" << x << "," << y << ")))\n";
00471             }
00472         }
00473         os << "cmd_beam,vert_beam = zip(*dat_beam)\n";
00474         os << "ph_beam       = PH (vert_beam, cmd_beam)\n";
00475         os << "pc_beam       = PC (ph_beam, facecolor='none', edgecolor=dblue, linewidth=1)\n";
00476         os << "ax.add_patch  (pc_beam)\n\n";
00477         if (Prms.DrawN)
00478         {
00479             os << "cmd_beam_ax,vert_beam_ax = zip(*dat_beam_ax)\n";
00480             os << "ph_beam_ax       = PH (vert_beam_ax, cmd_beam_ax)\n";
00481             os << "pc_beam_ax       = PC (ph_beam_ax, facecolor='none', edgecolor=dblue, linewidth=1)\n";
00482             os << "ax.add_patch    (pc_beam_ax)\n\n";
00483         }
00484 
00485         // Text
00486         if (Prms.WithTxt)
00487         {
00488             if (Prms.DrawN)
00489             {
00490                 // max or min N
00491                 bool is_max_or_min = (this==Prms.EleNmax || this==Prms.EleNmin);
00492                 bool skip = (Prms.OnlyTxtLim && !is_max_or_min);
00493                 CalcRes (0.5, N, V, M);
00494                 if (fabs(N)>1.0e-13 && !skip)
00495                 {
00496                     sf = fabs(Prms.SF*N)/2.0;
00497                     x  = x0 + 0.5*(x1-x0);
00498                     y  = y0 + 0.5*(y1-y0);
00499                     String buf;
00500                     buf.Printf ("%g",N);
00501                     os << "ax.text ("<<x<<","<<y<<", " << buf << ", backgroundcolor=pink, va='top', ha='center', fontsize="<<Prms.TxtSz<<")\n";
00502                 }
00503             }
00504             else if (Prms.DrawV)
00505             {
00506                 // max V
00507                 bool skip = (Prms.OnlyTxtLim && Prms.EleVmax!=this);
00508                 if (fabs(Vmax)>1.0e-13 && !skip)
00509                 {
00510                     x  = x0 + rVmax*(x1-x0);
00511                     y  = y0 + rVmax*(y1-y0);
00512                     sf = Prms.SF*Vmax;
00513                     xf = x - sf*xn;
00514                     yf = y - sf*yn;
00515                     String buf;
00516                     buf.Printf ("%g",Vmax);
00517                     os << "XY = array([["<<x<<","<<y<<"],["<<xf<<","<<yf<<"]])\n";
00518                     os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor="<<(Vmax<0.0?"dpink":"dblue")<<", lw=4))\n";
00519                     os << "ax.text ("<<(x+xf)/2.<<","<<(y+yf)/2.<<", " << buf << ", backgroundcolor=pink, va='top', ha='center', fontsize="<<Prms.TxtSz<<")\n";
00520                 }
00521 
00522                 // min V
00523                 skip = (Prms.OnlyTxtLim && Prms.EleVmin!=this);
00524                 if (fabs(Vmin)>1.0e-13 && !skip)
00525                 {
00526                     x  = x0 + rVmin*(x1-x0);
00527                     y  = y0 + rVmin*(y1-y0);
00528                     sf = Prms.SF*Vmin;
00529                     xf = x - sf*xn;
00530                     yf = y - sf*yn;
00531                     String buf;
00532                     buf.Printf ("%g",Vmin);
00533                     os << "XY = array([["<<x<<","<<y<<"],["<<xf<<","<<yf<<"]])\n";
00534                     os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor="<<(Vmin<0.0?"dpink":"dblue")<<", lw=4))\n";
00535                     os << "ax.text ("<<(x+xf)/2.<<","<<(y+yf)/2.<<", " << buf << ", backgroundcolor=pink, va='top', ha='center', fontsize="<<Prms.TxtSz<<")\n";
00536                 }
00537             }
00538             else // DrawM
00539             {
00540                 // max M
00541                 bool skip = (Prms.OnlyTxtLim && Prms.EleMmax!=this);
00542                 if (fabs(Mmax)>1.0e-13 && !skip)
00543                 {
00544                     x  = x0 + rMmax*(x1-x0);
00545                     y  = y0 + rMmax*(y1-y0);
00546                     if (qnl>0.0) sf = -Prms.SF*Mmax;
00547                     else         sf =  Prms.SF*Mmax;
00548                     xf = x - sf*xn;
00549                     yf = y - sf*yn;
00550                     String buf;
00551                     buf.Printf ("%g",Mmax);
00552                     os << "XY = array([["<<x<<","<<y<<"],["<<xf<<","<<yf<<"]])\n";
00553                     os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor="<<(Mmax<0.0?"dpink":"dblue")<<", lw=4))\n";
00554                     os << "ax.text ("<<(x+xf)/2.<<","<<(y+yf)/2.<<", " << buf << ", backgroundcolor=pink, va='top', ha='center', fontsize="<<Prms.TxtSz<<")\n";
00555                 }
00556                 
00557                 // min M
00558                 skip = (Prms.OnlyTxtLim && Prms.EleMmin!=this);
00559                 if (fabs(Mmin)>1.0e-13 && !skip)
00560                 {
00561                     x  = x0 + rMmin*(x1-x0);
00562                     y  = y0 + rMmin*(y1-y0);
00563                     if (qnl>0.0) sf = -Prms.SF*Mmin;
00564                     else         sf =  Prms.SF*Mmin;
00565                     xf = x - sf*xn;
00566                     yf = y - sf*yn;
00567                     String buf;
00568                     buf.Printf ("%g",Mmin);
00569                     os << "XY = array([["<<x<<","<<y<<"],["<<xf<<","<<yf<<"]])\n";
00570                     os << "ax.add_patch (MPL.patches.Polygon(XY, closed=False, edgecolor="<<(Mmin<0.0?"dpink":"dblue")<<", lw=4))\n";
00571                     os << "ax.text ("<<(x+xf)/2.<<","<<(y+yf)/2.<<", " << buf << ", backgroundcolor=pink, va='top', ha='center', fontsize="<<Prms.TxtSz<<")\n";
00572                 }
00573             }
00574         }
00575     }
00576     else throw new Fatal("Beam::GetState: 3D Beam is not available yet");
00577 }
00578 
00579 
00581 
00582 
00583 // Allocate a new element
00584 Element * BeamMaker(int NDim, Mesh::Cell const & Cell, Model const * Mdl, Model const * XMdl, SDPair const & Prp, SDPair const & Ini, Array<Node*> const & Nodes) { return new Beam(NDim,Cell,Mdl,XMdl,Prp,Ini,Nodes); }
00585 
00586 // Register element
00587 int BeamRegister()
00588 {
00589     ElementFactory  ["Beam"]   = BeamMaker;
00590     ElementVarKeys  ["Beam2D"] = std::make_pair ("ux uy wz", "fx fy mz");
00591     ElementExtraKeys["Beam2D"] = Array<String>  ("qx", "qy", "qn"); 
00592     PROB.Set ("Beam", (double)PROB.Keys.Size());
00593     return 0;
00594 }
00595 
00596 // Call register
00597 int __Beam_dummy_int = BeamRegister();
00598 
00599 }; // namespace FEM
00600 
00601 #endif // MECHSYS_FEM_BEAM
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines