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_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