1 // ============================================================================= 2 // PROJECT CHRONO - http://projectchrono.org 3 // 4 // Copyright (c) 2014 projectchrono.org 5 // All rights reserved. 6 // 7 // Use of this source code is governed by a BSD-style license that can be found 8 // in the LICENSE file at the top level of the distribution and at 9 // http://projectchrono.org/license-chrono.txt. 10 // 11 // ============================================================================= 12 // Authors: Alessandro Tasora 13 // ============================================================================= 14 15 #ifndef CHBEAMSECTIONEULER_H 16 #define CHBEAMSECTIONEULER_H 17 18 #include "chrono/fea/ChBeamSection.h" 19 20 namespace chrono { 21 namespace fea { 22 23 /// @addtogroup fea_utils 24 /// @{ 25 26 /// Base class for all constitutive models of sections of Euler beams. 27 /// To be used with ChElementBeamEuler. 28 /// For practical purposes, either you use the concrete inherited classes like ChBeamSectionEulerSimple, 29 /// ChBeamSectionEulerAdvanced etc., or you inherit your class from this. 30 31 class ChApi ChBeamSectionEuler : public ChBeamSection { 32 public: ChBeamSectionEuler()33 ChBeamSectionEuler() 34 : rdamping_beta(0.01), // default Rayleigh beta damping. 35 rdamping_alpha(0), // default Rayleigh alpha damping. 36 JzzJyy_factor(1. / 500.) // default tiny rotational inertia of section on Y and Z to avoid singular mass 37 {} ~ChBeamSectionEuler()38 virtual ~ChBeamSectionEuler() {} 39 40 // STIFFNESS INTERFACE 41 42 /// Gets the axial rigidity, usually A*E, but might be ad hoc 43 virtual double GetAxialRigidity() const = 0; 44 45 /// Gets the torsion rigidity, for torsion about X axis at elastic center, usually J*G, but might be ad hoc 46 virtual double GetXtorsionRigidity() const = 0; 47 48 /// Gets the bending rigidity, for bending about Y axis at elastic center, usually Iyy*E, but might be ad hoc 49 virtual double GetYbendingRigidity() const = 0; 50 51 /// Gets the bending rigidity, for bending about Z axis at elastic center, usually Izz*E, but might be ad hoc 52 virtual double GetZbendingRigidity() const = 0; 53 54 /// Set the rotation of the Y Z section axes for which the YbendingRigidity and ZbendingRigidity are defined. 55 virtual double GetSectionRotation() const = 0; 56 57 /// Gets the Y position of the elastic center respect to centerline. 58 virtual double GetCentroidY() const = 0; 59 /// Gets the Z position of the elastic center respect to centerline. 60 virtual double GetCentroidZ() const = 0; 61 62 /// Gets the Y position of the shear center respect to centerline. 63 virtual double GetShearCenterY() const = 0; 64 /// Gets the Z position of the shear center respect to centerline. 65 virtual double GetShearCenterZ() const = 0; 66 67 // MASS INTERFACE 68 69 /// Get mass per unit length, ex.SI units [kg/m] 70 virtual double GetMassPerUnitLength() const = 0; 71 72 /// Get the Jxx component of the inertia per unit length (polar inertia) in the Y Z unrotated reference 73 /// frame of the section at centerline. Note: it automatically follows Jxx=Jyy+Jzz for the polar theorem. Also, 74 /// Jxx=density*Ixx if constant density. 75 virtual double GetInertiaJxxPerUnitLength() const = 0; 76 77 /// Compute the 6x6 sectional inertia matrix, as in {x_momentum,w_momentum}=[Mm]{xvel,wvel} 78 /// The matrix is computed in the material reference (i.e. it is the sectional mass matrix) 79 virtual void ComputeInertiaMatrix(ChMatrixNM<double, 6, 6>& M ///< 6x6 sectional mass matrix values here 80 ) = 0; 81 82 /// Compute the 6x6 sectional inertia damping matrix [Ri] (gyroscopic matrix damping), as in linearization 83 /// dFi=[Mi]*d{xacc,wacc}+[Ri]*d{xvel,wvel}+[Ki]*d{pos,rot} 84 /// The matrix is computed in the material reference, i.e. both linear and rotational coords assumed in the basis of the centerline reference. 85 /// Default implementation: falls back to numerical differentiation of ComputeInertialForce to compute Ri, 86 /// please override this if analytical formula of Ri is known! 87 virtual void ComputeInertiaDampingMatrix(ChMatrixNM<double, 6, 6>& Ri, ///< 6x6 sectional inertial-damping (gyroscopic damping) matrix values here 88 const ChVector<>& mW ///< current angular velocity of section, in material frame 89 ); 90 91 /// Compute the 6x6 sectional inertia stiffness matrix [Ki^], as in linearization 92 /// dFi=[Mi]*d{xacc,wacc}+[Ri]*d{xvel,wvel}+[Ki]*d{pos,rot} 93 /// The matrix is computed in the material reference. 94 /// NOTE the matrix already contains the 'geometric' stiffness, so it transforms to absolute transl/local rot just like [Mi] and [Ri]: 95 /// [Ki]_al =[R,0;0,I]*[Ki^]*[R',0;0,I'] , with [Ki^]=([Ki]+[0,f~';0,0]) for f=current force part of inertial forces. 96 /// Default implementation: falls back to numerical differentiation of ComputeInertialForce to compute Ki^, 97 /// please override this if analytical formula of Ki^ is known! 98 virtual void ComputeInertiaStiffnessMatrix(ChMatrixNM<double, 6, 6>& Ki, ///< 6x6 sectional inertial-stiffness matrix [Ki^] values here 99 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 100 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 101 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 102 ); 103 104 /// Compute the values of inertial force & torque depending on quadratic velocity terms, 105 /// that is the gyroscopic torque (null for Euler beam as point-like mass section, might be nonzero if adding 106 /// Rayleigh beam theory) and the centrifugal term (if any). All terms expressed in the material reference, ie. the 107 /// reference in the centerline of the section. 108 virtual void ComputeQuadraticTerms(ChVector<>& mF, ///< centrifugal term (if any) returned here 109 ChVector<>& mT, ///< gyroscopic term returned here 110 const ChVector<>& mW ///< current angular velocity of section, in material frame 111 ) = 0; 112 113 /// Compute the total inertial forces (per unit length). This default implementation falls back to Fi = [Mi]*{xacc,wacc}+{mF,mT} 114 /// where [Mi] is given by ComputeInertiaMatrix() and {F_quad,T_quad} are given by ComputeQuadraticTerms(), i.e. gyro and centrif.terms. 115 /// Note: both force and torque are returned in the basis of the material frame (not the absolute frame!), 116 /// ex. to apply it to a Chrono body, the force must be rotated to absolute basis. 117 /// For faster implementations one can override this, ex. avoid doing the [Mi] matrix product. 118 virtual void ComputeInertialForce(ChVector<>& mFi, ///< total inertial force returned here, in basis of material frame 119 ChVector<>& mTi, ///< total inertial torque returned here, in basis of material frame 120 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 121 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 122 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 123 ); 124 125 /// The Euler beam model has no rotational inertia per each section, assuming mass is concentrated on 126 /// the centerline. However this creates a singular mass matrix, that might end in problems when doing modal 127 /// analysis etc. A solution is to force Jyy and Jzz inertials per unit lengths to be a percent of the mass per unit 128 /// length. By default it is 1/500. Use this function to set such factor. You can also turn it to zero. Note that 129 /// the effect becomes negligible anyway for finer meshing. SetArtificialJyyJzzFactor(double mf)130 void SetArtificialJyyJzzFactor(double mf) { JzzJyy_factor = mf; } GetArtificialJyyJzzFactor()131 double GetArtificialJyyJzzFactor() { return JzzJyy_factor; } 132 133 // DAMPING INTERFACE 134 135 /// Set the "alpha" Rayleigh damping ratio, 136 /// the mass-proportional structural damping in: R = alpha*M + beta*K SetBeamRaleyghDampingAlpha(double malpha)137 virtual void SetBeamRaleyghDampingAlpha(double malpha) { this->rdamping_alpha = malpha; } GetBeamRaleyghDampingAlpha()138 double GetBeamRaleyghDampingAlpha() { return this->rdamping_alpha; } 139 140 /// Set the "beta" Rayleigh damping ratio, 141 /// the stiffness-proportional structural damping in: R = alpha*M + beta*K SetBeamRaleyghDampingBeta(double mbeta)142 virtual void SetBeamRaleyghDampingBeta(double mbeta) { this->rdamping_beta = mbeta; } GetBeamRaleyghDampingBeta()143 double GetBeamRaleyghDampingBeta() { return this->rdamping_beta; } 144 145 /// Set both beta and alpha coefficients in Rayleigh damping model: R = alpha*M + beta*K. 146 /// For backward compatibility, if one provides only the first parameter, this would be the "beta" 147 /// stiffness-proportional term, and the "alpha" mass proportional term would be left to default zero. 148 virtual void SetBeamRaleyghDamping(double mbeta, double malpha = 0) { this->rdamping_beta = mbeta; this->rdamping_alpha = malpha; } 149 150 151 // Optimization flags 152 153 /// Flag that turns on/off the computation of the [Ri] 'gyroscopic' inertial damping matrix. 154 /// If false, Ri=0. Can be used for cpu speedup, profiling, tests. Default: true. 155 bool compute_inertia_damping_matrix = true; 156 157 /// Flag that turns on/off the computation of the [Ki] inertial stiffness matrix. 158 /// If false, Ki=0. Can be used for cpu speedup, profiling, tests. Default: true. 159 bool compute_inertia_stiffness_matrix = true; 160 161 /// Flag for computing the Ri and Ki matrices via numerical differentiation even if 162 /// an analytical expression is provided. Children calsses must take care of this. Default: false. 163 bool compute_Ri_Ki_by_num_diff = false; 164 165 166 protected: 167 double rdamping_beta; 168 double rdamping_alpha; 169 double JzzJyy_factor; 170 }; 171 172 /// Basic section of an Euler-Bernoulli beam in 3D, for a homogeneous density 173 /// and homogeneous elasticity, given basic material properties (Izz and Iyy moments of inertia, 174 /// area, Young modulus, etc.). 175 /// This is a simple section model that assumes the elastic center, the shear center and the mass 176 /// center to be all in the centerline of the beam (section origin); this is the case of symmetric sections for example. 177 /// To be used with ChElementBeamEuler. 178 /// This material can be shared between multiple beams. 179 /// 180 /// \image html "http://www.projectchrono.org/assets/manual/fea_ChElasticityCosseratSimple.png" 181 /// 182 class ChApi ChBeamSectionEulerSimple : public ChBeamSectionEuler { 183 public: 184 double Area; 185 double Iyy; 186 double Izz; 187 double J; 188 double G; 189 double E; 190 double density; 191 double Ks_y; 192 double Ks_z; 193 ChBeamSectionEulerSimple()194 ChBeamSectionEulerSimple() 195 : E(0.01e9), // default E stiffness: (almost rubber) 196 density(1000) // default density: water 197 { 198 SetGwithPoissonRatio(0.3); // default G (low poisson ratio) 199 SetAsRectangularSection(0.01, 0.01); // defaults Area, Ixx, Iyy, Ks_y, Ks_z, J 200 } 201 ~ChBeamSectionEulerSimple()202 virtual ~ChBeamSectionEulerSimple() {} 203 204 /// Set the cross sectional area A of the beam (m^2) SetArea(const double ma)205 void SetArea(const double ma) { this->Area = ma; } GetArea()206 double GetArea() const { return this->Area; } 207 208 /// Set the Iyy moment of inertia of the beam (for flexion about y axis) 209 /// Note: some textbook calls this Iyy as Iz SetIyy(double ma)210 void SetIyy(double ma) { this->Iyy = ma; } GetIyy()211 double GetIyy() const { return this->Iyy; } 212 213 /// Set the Izz moment of inertia of the beam (for flexion about z axis) 214 /// Note: some textbook calls this Izz as Iy SetIzz(double ma)215 void SetIzz(double ma) { this->Izz = ma; } GetIzz()216 double GetIzz() const { return this->Izz; } 217 218 /// Set the J torsion constant of the beam (for torsion about x axis) SetJ(double ma)219 void SetJ(double ma) { this->J = ma; } GetJ()220 double GetJ() const { return this->J; } 221 222 /// Set the Timoshenko shear coefficient Ks for y shear, usually about 0.8, 223 /// (for elements that use this, ex. the Timoshenko beams, or Reddy's beams) SetKsy(double ma)224 void SetKsy(double ma) { this->Ks_y = ma; } GetKsy()225 double GetKsy() const { return this->Ks_y; } 226 227 /// Set the Timoshenko shear coefficient Ks for z shear, usually about 0.8, 228 /// (for elements that use this, ex. the Timoshenko beams, or Reddy's beams) SetKsz(double ma)229 void SetKsz(double ma) { this->Ks_z = ma; } GetKsz()230 double GetKsz() const { return this->Ks_z; } 231 232 /// Shortcut: set Area, Ixx, Iyy, Ksy, Ksz and J torsion constant 233 /// at once, given the y and z widths of the beam assumed 234 /// with rectangular shape. SetAsRectangularSection(double width_y,double width_z)235 void SetAsRectangularSection(double width_y, double width_z) { 236 this->Area = width_y * width_z; 237 this->Izz = (1.0 / 12.0) * width_z * pow(width_y, 3); 238 this->Iyy = (1.0 / 12.0) * width_y * pow(width_z, 3); 239 240 // use Roark's formulas for torsion of rectangular sect: 241 double t = ChMin(width_y, width_z); 242 double b = ChMax(width_y, width_z); 243 this->J = b * pow(t, 3) * ((1.0 / 3.0) - 0.210 * (t / b) * (1.0 - (1.0 / 12.0) * pow((t / b), 4))); 244 245 // set Ks using Timoshenko-Gere formula for solid rect.shapes 246 double poisson = this->E / (2.0 * this->G) - 1.0; 247 this->Ks_y = 10.0 * (1.0 + poisson) / (12.0 + 11.0 * poisson); 248 this->Ks_z = this->Ks_y; 249 250 this->SetDrawThickness(width_y, width_z); 251 } 252 253 /// Shortcut: set Area, Ixx, Iyy, Ksy, Ksz and J torsion constant 254 /// at once, given the diameter of the beam assumed 255 /// with circular shape. SetAsCircularSection(double diameter)256 void SetAsCircularSection(double diameter) { 257 this->Area = CH_C_PI * pow((0.5 * diameter), 2); 258 this->Izz = (CH_C_PI / 4.0) * pow((0.5 * diameter), 4); 259 this->Iyy = Izz; 260 261 // exact expression for circular beam J = Ixx , 262 // where for polar theorem Ixx = Izz+Iyy 263 this->J = Izz + Iyy; 264 265 // set Ks using Timoshenko-Gere formula for solid circular shape 266 double poisson = this->E / (2.0 * this->G) - 1.0; 267 this->Ks_y = 6.0 * (1.0 + poisson) / (7.0 + 6.0 * poisson); 268 this->Ks_z = this->Ks_y; 269 270 this->SetDrawCircularRadius(diameter / 2); 271 } 272 273 /// Set the density of the beam (kg/m^3) SetDensity(double md)274 void SetDensity(double md) { this->density = md; } GetDensity()275 double GetDensity() const { return this->density; } 276 277 /// Set E, the Young elastic modulus (N/m^2) SetYoungModulus(double mE)278 void SetYoungModulus(double mE) { this->E = mE; } GetYoungModulus()279 double GetYoungModulus() const { return this->E; } 280 281 /// Set G, the shear modulus, used for computing the torsion rigidity = J*G SetGshearModulus(double mG)282 void SetGshearModulus(double mG) { this->G = mG; } GetGshearModulus()283 double GetGshearModulus() const { return this->G; } 284 285 /// Set G, the shear modulus, given current E and the specified Poisson ratio SetGwithPoissonRatio(double mpoisson)286 void SetGwithPoissonRatio(double mpoisson) { this->G = this->E / (2.0 * (1.0 + mpoisson)); } 287 288 // INTERFACES 289 290 /// Gets the axial rigidity, usually A*E, but might be ad hoc GetAxialRigidity()291 virtual double GetAxialRigidity() const override { return this->Area * this->E; } 292 293 /// Gets the torsion rigidity, for torsion about X axis at elastic center, usually J*G, but might be ad hoc GetXtorsionRigidity()294 virtual double GetXtorsionRigidity() const override { return this->J * this->G; } 295 296 /// Gets the bending rigidity, for bending about Y axis at elastic center, usually Iyy*E, but might be ad hoc GetYbendingRigidity()297 virtual double GetYbendingRigidity() const override { return this->Iyy * this->E; } 298 299 /// Gets the bending rigidity, for bending about Z axis at elastic center, usually Izz*E, but might be ad hoc GetZbendingRigidity()300 virtual double GetZbendingRigidity() const override { return this->Izz * this->E; } 301 302 /// Set the rotation of the Y Z section axes for which the YbendingRigidity and ZbendingRigidity are defined. GetSectionRotation()303 virtual double GetSectionRotation() const override { return 0; } 304 305 /// Gets the Y position of the elastic center respect to centerline. GetCentroidY()306 virtual double GetCentroidY() const override { return 0; } 307 /// Gets the Z position of the elastic center respect to centerline. GetCentroidZ()308 virtual double GetCentroidZ() const override { return 0; } 309 310 /// Gets the Y position of the shear center respect to centerline. GetShearCenterY()311 virtual double GetShearCenterY() const override { return 0; } 312 /// Gets the Z position of the shear center respect to centerline. GetShearCenterZ()313 virtual double GetShearCenterZ() const override { return 0; } 314 315 /// Compute the 6x6 sectional inertia matrix, as in {x_momentum,w_momentum}=[Mm]{xvel,wvel} 316 virtual void ComputeInertiaMatrix(ChMatrixNM<double, 6, 6>& M) override; 317 318 /// Compute the 6x6 sectional inertia damping matrix [Ri] (gyroscopic matrix damping) 319 virtual void ComputeInertiaDampingMatrix(ChMatrixNM<double, 6, 6>& Ri, ///< 6x6 sectional inertial-damping (gyroscopic damping) matrix values here 320 const ChVector<>& mW ///< current angular velocity of section, in material frame 321 ) override; 322 323 /// Compute the 6x6 sectional inertia stiffness matrix [Ki^] 324 virtual void ComputeInertiaStiffnessMatrix(ChMatrixNM<double, 6, 6>& Ki, ///< 6x6 sectional inertial-stiffness matrix [Ki^] values here 325 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 326 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 327 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 328 ) override; 329 330 /// Compute the centrifugal term and gyroscopic term 331 virtual void ComputeQuadraticTerms(ChVector<>& mF, ChVector<>& mT, const ChVector<>& mW) override; 332 333 /// Get mass per unit length, ex.SI units [kg/m] GetMassPerUnitLength()334 virtual double GetMassPerUnitLength() const override { return this->Area * this->density; } 335 336 /// Get the Jxx component of the inertia per unit length (polar inertia) in the Y Z unrotated reference 337 /// frame of the section at centerline. Note: it automatically follows Jxx=Jyy+Jzz for the polar theorem. Also, 338 /// Jxx=density*Ixx if constant density. GetInertiaJxxPerUnitLength()339 virtual double GetInertiaJxxPerUnitLength() const override { return (this->Iyy + this->Izz) * this->density; } 340 }; 341 342 // for backward compatibility - note it WILL BE DEPRECATED 343 using ChBeamSectionBasic = ChBeamSectionEulerSimple; 344 345 /// Advanced section of an Euler-Bernoulli beam in 3D, for a homogeneous density 346 /// and homogeneous elasticity, given basic material properties (Izz and Iyy moments of inertia, 347 /// area, Young modulus, etc.), but also supporting the advanced case of 348 /// Iyy and Izz axes rotated respect reference, elastic center with offset 349 /// from centerline reference, and shear center with offset from centerline reference. 350 /// To be used with ChElementBeamEuler. 351 /// This material can be shared between multiple beams. 352 /// 353 /// \image html "http://www.projectchrono.org/assets/manual/fea_ChElementBeamEuler_section.png" 354 /// 355 class ChApi ChBeamSectionEulerAdvanced : public ChBeamSectionEulerSimple { 356 public: 357 double alpha; // Rotation of Izz Iyy respect to reference line x 358 double Cy; // Centroid (elastic center, tension center) 359 double Cz; 360 double Sy; // Shear center 361 double Sz; 362 ChBeamSectionEulerAdvanced()363 ChBeamSectionEulerAdvanced() : alpha(0), Cy(0), Cz(0), Sy(0), Sz(0) {} 364 ~ChBeamSectionEulerAdvanced()365 virtual ~ChBeamSectionEulerAdvanced() {} 366 367 /// Set the rotation in [rad], about elastic center, of the Y Z axes for which the 368 /// Iyy and Izz are computed. SetSectionRotation(double ma)369 void SetSectionRotation(double ma) { this->alpha = ma; } 370 371 /// Set the displacement of the centroid C (i.e. the elastic center, 372 /// or tension center) with respect to the reference beam line. SetCentroid(double my,double mz)373 void SetCentroid(double my, double mz) { 374 this->Cy = my; 375 this->Cz = mz; 376 } 377 378 /// Set the displacement of the shear center S with respect to the reference beam line. 379 /// For shapes like rectangles, rotated rectangles, etc., it corresponds to the centroid C, 380 /// but for "L" shaped or "U" shaped beams this is not always true, and the shear center 381 /// accounts for torsion effects when a shear force is applied. SetShearCenter(double my,double mz)382 void SetShearCenter(double my, double mz) { 383 this->Sy = my; 384 this->Sz = mz; 385 } 386 387 // INTERFACES 388 GetSectionRotation()389 virtual double GetSectionRotation() const override { return this->alpha; } 390 GetCentroidY()391 virtual double GetCentroidY() const override { return this->Cy; } GetCentroidZ()392 virtual double GetCentroidZ() const override { return this->Cz; } 393 GetShearCenterY()394 virtual double GetShearCenterY() const override { return this->Sy; } GetShearCenterZ()395 virtual double GetShearCenterZ() const override { return this->Sz; } 396 }; 397 398 // for backward compatibility - note it WILL BE DEPRECATED 399 using ChBeamSectionAdvanced = ChBeamSectionEulerAdvanced; 400 401 /// General purpose section of an Euler-Bernoulli beam in 3D, not assuming homogeneous density 402 /// or homogeneous elasticity, given basic material properties. This is the case where 403 /// one uses a FEA preprocessor to compute the rigidity of a complex beam made with multi-layered 404 /// reinforcements with different elasticity and different density - in such a case you could not 405 /// use ChBeamSectionEulerAdvanced because you do not have a single E or single density, but you rather 406 /// have collective values of bending rigidities, and collective mass per unit length. This class 407 /// allows using these values directly, bypassing any knowledge of area, density, Izz Iyy, E young modulus, etc. 408 /// To be used with ChElementBeamEuler. 409 /// The center of mass of the section can have an offset respect to the centerline. 410 /// This material can be shared between multiple beams. 411 /// 412 /// \image html "http://www.projectchrono.org/assets/manual/fea_ChElementBeamEuler_section.png" 413 /// 414 415 class ChApi ChBeamSectionEulerAdvancedGeneric : public ChBeamSectionEuler { 416 protected: 417 double Ax; // axial rigidity 418 double Txx; // torsion rigidity 419 double Byy; // bending about yy rigidity 420 double Bzz; // bending about zz rigidity 421 double alpha; // section rotation about elastic center 422 double Cy; // Centroid (elastic center, tension center) 423 double Cz; 424 double Sy; // Shear center 425 double Sz; 426 double mu; // mass per unit length 427 double Jxx; // inertia per unit length 428 double My; // Mass center 429 double Mz; 430 431 public: ChBeamSectionEulerAdvancedGeneric()432 ChBeamSectionEulerAdvancedGeneric() 433 : Ax(1), Txx(1), Byy(1), Bzz(1), alpha(0), Cy(0), Cz(0), Sy(0), Sz(0), mu(1000), Jxx(1), My(0), Mz(0) {} 434 435 ChBeamSectionEulerAdvancedGeneric( 436 const double mAx, ///< axial rigidity 437 const double mTxx, ///< torsion rigidity 438 const double mByy, ///< bending regidity about yy 439 const double mBzz, ///< bending rigidity about zz 440 const double malpha, ///< section rotation about elastic center [rad] 441 const double mCy, ///< elastic center y displacement respect to centerline 442 const double mCz, ///< elastic center z displacement respect to centerline 443 const double mSy, ///< shear center y displacement respect to centerline 444 const double mSz, ///< shear center z displacement respect to centerline 445 const double mmu, ///< mass per unit length 446 const double mJxx, ///< polar inertia Jxx per unit lenght, measured respect to centerline 447 const double mMy = 0, ///< mass center y displacement respect to centerline 448 const double mMz = 0 ///< mass center z displacement respect to centerline 449 ) Ax(mAx)450 : Ax(mAx), 451 Txx(mTxx), 452 Byy(mByy), 453 Bzz(mBzz), 454 alpha(malpha), 455 Cy(mCy), 456 Cz(mCz), 457 Sy(mSy), 458 Sz(mSz), 459 mu(mmu), 460 Jxx(mJxx), 461 My(mMy), 462 Mz(mMz) {} 463 ~ChBeamSectionEulerAdvancedGeneric()464 virtual ~ChBeamSectionEulerAdvancedGeneric() {} 465 466 /// Sets the axial rigidity, usually A*E for uniform elasticity, but for nonuniform elasticity 467 /// here you can put a value ad-hoc from a preprocessor SetAxialRigidity(const double mv)468 virtual void SetAxialRigidity(const double mv) { Ax = mv; } 469 470 /// Sets the torsion rigidity, for torsion about X axis, at elastic center, 471 /// usually J*G for uniform elasticity, but for nonuniform elasticity 472 /// here you can put a value ad-hoc from a preprocessor SetXtorsionRigidity(const double mv)473 virtual void SetXtorsionRigidity(const double mv) { Txx = mv; } 474 475 /// Sets the bending rigidity, for bending about Y axis, at elastic center, 476 /// usually Iyy*E for uniform elasticity, but for nonuniform elasticity 477 /// here you can put a value ad-hoc from a preprocessor SetYbendingRigidity(const double mv)478 virtual void SetYbendingRigidity(const double mv) { Byy = mv; } 479 480 /// Sets the bending rigidity, for bending about Z axis, at elastic center, 481 /// usually Izz*E for uniform elasticity, but for nonuniform elasticity 482 /// here you can put a value ad-hoc from a preprocessor SetZbendingRigidity(const double mv)483 virtual void SetZbendingRigidity(const double mv) { Bzz = mv; } 484 485 /// Set the rotation in [rad], abour elastic center, of the Y Z axes for which the 486 /// YbendingRigidity and ZbendingRigidity values are defined. SetSectionRotation(const double mv)487 virtual void SetSectionRotation(const double mv) { alpha = mv; } 488 489 /// Sets the Y position of the elastic center respect to centerline. SetCentroidY(const double mv)490 virtual void SetCentroidY(const double mv) { Cy = mv; } 491 /// Sets the Z position of the elastic center respect to centerline. SetCentroidZ(const double mv)492 virtual void SetCentroidZ(const double mv) { Cz = mv; } 493 494 /// Sets the Y position of the shear center respect to centerline. SetShearCenterY(const double mv)495 virtual void SetShearCenterY(const double mv) { Sy = mv; } 496 /// Sets the Z position of the shear center respect to centerline. SetShearCenterZ(const double mv)497 virtual void SetShearCenterZ(const double mv) { Sz = mv; } 498 499 /// Set mass per unit length, ex.SI units [kg/m] 500 /// For uniform density it would be A*density, but for nonuniform density 501 /// here you can put a value ad-hoc from a preprocessor SetMassPerUnitLength(const double mv)502 virtual void SetMassPerUnitLength(const double mv) { mu = mv; } 503 504 /// Set the Jxx component of the inertia per unit length (polar inertia), computed at centerline. 505 /// For uniform density it would be Ixx*density or, by polar theorem, (Izz+Iyy)*density, but for 506 /// nonuniform density here you can put a value ad-hoc from a preprocessor SetInertiaJxxPerUnitLength(const double mv)507 virtual void SetInertiaJxxPerUnitLength(const double mv) { Jxx = mv; } 508 509 /// Set inertia moment per unit length Jxx_massref, as assumed computed in the "mass reference" 510 /// frame, ie. centered at the center of mass. Call this after you set SetCenterOfMass() and SetMassPerUnitLength() SetInertiaJxxPerUnitLengthInMassReference(const double mv)511 virtual void SetInertiaJxxPerUnitLengthInMassReference(const double mv) { 512 Jxx = mv + this->mu * this->Mz * this->Mz + this->mu * this->My * this->My; 513 } 514 515 /// Get inertia moment per unit length Jxx_massref, as assumed computed in the "mass reference" 516 /// frame, ie. centered at the center of mass GetInertiaJxxPerUnitLengthInMassReference()517 virtual double GetInertiaJxxPerUnitLengthInMassReference() { 518 return this->Jxx - this->mu * this->Mz * this->Mz - this->mu * this->My * this->My; 519 } 520 521 /// "mass reference": set the displacement of the center of mass respect to 522 /// the section centerline reference. SetCenterOfMass(double my,double mz)523 void SetCenterOfMass(double my, double mz) { 524 this->My = my; 525 this->Mz = mz; 526 } GetCenterOfMassY()527 double GetCenterOfMassY() { return this->My; } GetCenterOfMassZ()528 double GetCenterOfMassZ() { return this->Mz; } 529 530 // INTERFACES 531 532 /// Gets the axial rigidity, usually A*E, but might be ad hoc GetAxialRigidity()533 virtual double GetAxialRigidity() const override { return this->Ax; } 534 535 /// Gets the torsion rigidity, for torsion about X axis at elastic center, usually J*G, but might be ad hoc GetXtorsionRigidity()536 virtual double GetXtorsionRigidity() const override { return this->Txx; } 537 538 /// Gets the bending rigidity, for bending about Y axis at elastic center, usually Iyy*E, but might be ad hoc GetYbendingRigidity()539 virtual double GetYbendingRigidity() const override { return this->Byy; } 540 541 /// Gets the bending rigidity, for bending about Z axis at elastic center, usually Izz*E, but might be ad hoc GetZbendingRigidity()542 virtual double GetZbendingRigidity() const override { return this->Bzz; } 543 544 /// Set the rotation of the Y Z section axes for which the YbendingRigidity and ZbendingRigidity are defined. GetSectionRotation()545 virtual double GetSectionRotation() const override { return this->alpha; } 546 547 /// Gets the Y position of the elastic center respect to centerline. GetCentroidY()548 virtual double GetCentroidY() const override { return this->Cy; } 549 /// Gets the Z position of the elastic center respect to centerline. GetCentroidZ()550 virtual double GetCentroidZ() const override { return this->Cz; } 551 552 /// Gets the Y position of the shear center respect to centerline. GetShearCenterY()553 virtual double GetShearCenterY() const override { return this->Sy; } 554 /// Gets the Z position of the shear center respect to centerline. GetShearCenterZ()555 virtual double GetShearCenterZ() const override { return this->Sz; } 556 557 /// Compute the 6x6 sectional inertia matrix, as in {x_momentum,w_momentum}=[Mm]{xvel,wvel} 558 virtual void ComputeInertiaMatrix(ChMatrixNM<double, 6, 6>& M) override; 559 560 /// Compute the 6x6 sectional inertia damping matrix [Ri] (gyroscopic matrix damping) 561 virtual void ComputeInertiaDampingMatrix(ChMatrixNM<double, 6, 6>& Ri, ///< 6x6 sectional inertial-damping (gyroscopic damping) matrix values here 562 const ChVector<>& mW ///< current angular velocity of section, in material frame 563 ) override; 564 565 /// Compute the 6x6 sectional inertia stiffness matrix [Ki^] 566 virtual void ComputeInertiaStiffnessMatrix(ChMatrixNM<double, 6, 6>& Ki, ///< 6x6 sectional inertial-stiffness matrix [Ki^] values here 567 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 568 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 569 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 570 ) override; 571 572 /// Compute the centrifugal term and gyroscopic term 573 virtual void ComputeQuadraticTerms(ChVector<>& mF, ChVector<>& mT, const ChVector<>& mW) override; 574 575 /// Get mass per unit length, ex.SI units [kg/m] GetMassPerUnitLength()576 virtual double GetMassPerUnitLength() const override { return this->mu; } 577 578 /// Get the Jxx component of the inertia per unit length (polar inertia), at centerline. GetInertiaJxxPerUnitLength()579 virtual double GetInertiaJxxPerUnitLength() const override { return this->Jxx; } 580 }; 581 582 /// A simple specialization of ChBeamSectionEuler if you just need the simplest model 583 /// for a rectangular centered beam, with uniform elasticity and uniform density. 584 /// This section automatically itializes at construction: 585 /// - elasticity as rectangular section 586 /// - inertia as rectangular section 587 /// - damping: none - you can set it later 588 class ChApi ChBeamSectionEulerEasyRectangular : public ChBeamSectionEulerSimple { 589 public: 590 ChBeamSectionEulerEasyRectangular(double width_y, ///< width of section in y direction 591 double width_z, ///< width of section in z direction 592 double E, ///< Young modulus 593 double G, ///< Shear modulus (only needed for the torsion) 594 double density ///< volumetric density (ex. in SI units: [kg/m^3]) 595 ); 596 }; 597 598 /// A simple specialization of ChBeamSectionEuler if you just need the simplest model 599 /// for a beam with circular centered section, with uniform elasticity and uniform density. 600 /// This section automatically itializes at construction: 601 /// - elasticity as circular section 602 /// - inertia as circular section 603 /// - damping: none - you can set it later 604 class ChApi ChBeamSectionEulerEasyCircular : public ChBeamSectionEulerSimple { 605 public: 606 ChBeamSectionEulerEasyCircular(double diameter, ///< diameter of circular section 607 double E, ///< Young modulus 608 double G, ///< Shear modulus (only needed for the torsion) 609 double density ///< volumetric density (ex. in SI units: [kg/m^3]) 610 ); 611 }; 612 613 614 615 616 /////////////////////////////////////////////////////////////////////////////////////////////////////// 617 // Rayleigh beam sections, like Euler sections but adding the effect of Jyy Jzz rotational inertias 618 619 620 621 /// This works exactly as ChBeamSectionEulerSimple, but adds the effect of Jyy Jzz rotational sectional inertias, 622 /// whereas the conventional Euler theory would assume the mass to be concentrated in the center of mass, hence Jyy Jzz =0. 623 /// For wide sections, Jyy Jzz can become not negligible. 624 /// In this simple symmetric case with homogeneous density, the values of Jyy Jzz are computed automatically as 625 /// \f$ J_{yy} = \rho I_{yy} \f$, \f$ J_{zz} = \rho I_{zz} \f$ 626 /// This is a simple section model that assumes the elastic center, the shear center and the mass 627 /// center to be all in the centerline of the beam (section origin); this is the case of symmetric sections for example. 628 /// 629 /// To be used with ChElementBeamEuler. 630 /// This material can be shared between multiple beams. 631 /// 632 /// \image html "http://www.projectchrono.org/assets/manual/fea_ChElasticityCosseratSimple.png" 633 /// 634 class ChApi ChBeamSectionRayleighSimple : public ChBeamSectionEulerSimple { 635 public: 636 ChBeamSectionRayleighSimple()637 ChBeamSectionRayleighSimple() {} 638 ~ChBeamSectionRayleighSimple()639 virtual ~ChBeamSectionRayleighSimple() {} 640 641 /// Compute the 6x6 sectional inertia matrix, as in {x_momentum,w_momentum}=[Mm]{xvel,wvel} 642 virtual void ComputeInertiaMatrix(ChMatrixNM<double, 6, 6>& M) override; 643 644 /// Compute the 6x6 sectional inertia damping matrix [Ri] (gyroscopic matrix damping) 645 virtual void ComputeInertiaDampingMatrix(ChMatrixNM<double, 6, 6>& Ri, ///< 6x6 sectional inertial-damping (gyroscopic damping) matrix values here 646 const ChVector<>& mW ///< current angular velocity of section, in material frame 647 ) override; 648 649 /// Compute the 6x6 sectional inertia stiffness matrix [Ki^] 650 virtual void ComputeInertiaStiffnessMatrix(ChMatrixNM<double, 6, 6>& Ki, ///< 6x6 sectional inertial-stiffness matrix [Ki^] values here 651 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 652 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 653 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 654 ) override; 655 656 /// Compute the centrifugal term and gyroscopic term 657 virtual void ComputeQuadraticTerms(ChVector<>& mF, ChVector<>& mT, const ChVector<>& mW) override; 658 }; 659 660 661 /// This works exactly as ChBeamSectionEulerEasyRectangular, 662 /// but adds the effect of Jyy Jzz rotational sectional inertias. 663 class ChApi ChBeamSectionRayleighEasyRectangular : public ChBeamSectionRayleighSimple { 664 public: 665 ChBeamSectionRayleighEasyRectangular(double width_y, ///< width of section in y direction 666 double width_z, ///< width of section in z direction 667 double E, ///< Young modulus 668 double G, ///< Shear modulus (only needed for the torsion) 669 double density ///< volumetric density (ex. in SI units: [kg/m^3]) 670 ); 671 }; 672 673 /// This works exactly as ChBeamSectionEulerEasyCircular, 674 /// but adds the effect of Jyy Jzz rotational sectional inertias. 675 class ChApi ChBeamSectionRayleighEasyCircular : public ChBeamSectionRayleighSimple { 676 public: 677 ChBeamSectionRayleighEasyCircular(double diameter, ///< diameter of circular section 678 double E, ///< Young modulus 679 double G, ///< Shear modulus (only needed for the torsion) 680 double density ///< volumetric density (ex. in SI units: [kg/m^3]) 681 ); 682 }; 683 684 685 /// This works exactly as ChBeamSectionEulerAdvancedGeneric, 686 /// but adds the effect of Jyy Jzz rotational sectional inertias. 687 /// The Jxx inertia of the Euler base class is automatically computed from Jyy Jzz by the polar theorem. 688 class ChApi ChBeamSectionRayleighAdvancedGeneric : public ChBeamSectionEulerAdvancedGeneric { 689 protected: 690 double Jzz; // sectional inertia per unit length, in centerline reference, measured along centerline main axes 691 double Jyy; // sectional inertia per unit length, in centerline reference, measured along centerline main axes 692 double Jyz; // sectional inertia per unit length, in centerline reference, measured along centerline main axes 693 public: ChBeamSectionRayleighAdvancedGeneric()694 ChBeamSectionRayleighAdvancedGeneric() 695 : Jzz(0.5), Jyy(0.5), Jyz(0) {} 696 697 ChBeamSectionRayleighAdvancedGeneric( 698 const double mAx, ///< axial rigidity 699 const double mTxx, ///< torsion rigidity 700 const double mByy, ///< bending regidity about yy 701 const double mBzz, ///< bending rigidity about zz 702 const double malpha, ///< section rotation about elastic center [rad] 703 const double mCy, ///< elastic center y displacement respect to centerline 704 const double mCz, ///< elastic center z displacement respect to centerline 705 const double mSy, ///< shear center y displacement respect to centerline 706 const double mSz, ///< shear center z displacement respect to centerline 707 const double mmu, ///< mass per unit length 708 const double mJyy, ///< inertia Jyy per unit lenght, in centerline reference, measured along centerline main axes 709 const double mJzz, ///< inertia Jzz per unit lenght, in centerline reference, measured along centerline main axes 710 const double mJyz, ///< inertia Jyz per unit lenght, in centerline reference, measured along centerline main axes 711 const double mMy = 0, ///< mass center y displacement respect to centerline 712 const double mMz = 0 ///< mass center z displacement respect to centerline 713 ) 714 : ChBeamSectionEulerAdvancedGeneric(mAx, 715 mTxx, 716 mByy, 717 mBzz, 718 malpha, 719 mCy, 720 mCz, 721 mSy, 722 mSz, 723 mmu, 724 (mJyy + mJzz), 725 mMy, 726 mMz), 727 Jzz(mJzz), 728 Jyy(mJyy), 729 Jyz(mJyz) {} 730 ~ChBeamSectionRayleighAdvancedGeneric()731 virtual ~ChBeamSectionRayleighAdvancedGeneric() {} 732 733 734 /// Set the Jyy Jzz Jyz components of the sectional inertia per unit length, 735 /// in centerline reference, measured along centerline main axes. 736 /// These are defined as: 737 /// \f$ J_{yy} = \int_\Omega \rho z^2 d\Omega \f$, also Jyy = Mm(4,4) 738 /// \f$ J_{zz} = \int_\Omega \rho y^2 d\Omega \f$, also Jzz = Mm(5,5) 739 /// \f$ J_{yz} = \int_\Omega \rho y z d\Omega \f$, also Jyz = -Mm(4,5) = -Mm(5,4) 740 /// It is not needed to enter also Jxx because Jxx=(Jzz+Jyy) by the polar theorem. 741 virtual void SetInertiasPerUnitLength(const double mJyy, const double mJzz, const double mJyz); 742 743 744 /// Set inertia moments, per unit length, as assumed computed in the Ym Zm "mass reference" 745 /// frame, ie. centered at the center of mass and rotated by phi angle to match the main axes of inertia: 746 /// \f$ Jm_{yy} = \int_\Omega \rho z_{m}^2 d\Omega \f$, 747 /// \f$ Jm_{zz} = \int_\Omega \rho y_{m}^2 d\Omega \f$. 748 /// Assuming the center of mass is already set. 749 virtual void SetMainInertiasInMassReference(double Jmyy, double Jmzz, double phi); 750 751 /// Get inertia moments, per unit length, as assumed computed in the Ym Zm "mass reference" frame, and the rotation phi of that frame, 752 /// ie. inertias centered at the center of mass and rotated by phi angle to match the main axes of inertia: 753 /// \f$ Jm_{yy} = \int_\Omega \rho z_{m}^2 d\Omega \f$, 754 /// \f$ Jm_{zz} = \int_\Omega \rho y_{m}^2 d\Omega \f$. 755 /// Assuming the center of mass is already set. 756 virtual void GetMainInertiasInMassReference(double& Jmyy, double& Jmzz, double& phi); 757 758 759 760 // INTERFACES 761 762 /// Compute the 6x6 sectional inertia matrix, as in {x_momentum,w_momentum}=[Mm]{xvel,wvel} 763 virtual void ComputeInertiaMatrix(ChMatrixNM<double, 6, 6>& M) override; 764 765 /// Compute the 6x6 sectional inertia damping matrix [Ri] (gyroscopic matrix damping) 766 virtual void ComputeInertiaDampingMatrix(ChMatrixNM<double, 6, 6>& Ri, ///< 6x6 sectional inertial-damping (gyroscopic damping) matrix values here 767 const ChVector<>& mW ///< current angular velocity of section, in material frame 768 ) override; 769 770 /// Compute the 6x6 sectional inertia stiffness matrix [Ki^] 771 virtual void ComputeInertiaStiffnessMatrix(ChMatrixNM<double, 6, 6>& Ki, ///< 6x6 sectional inertial-stiffness matrix [Ki^] values here 772 const ChVector<>& mWvel, ///< current angular velocity of section, in material frame 773 const ChVector<>& mWacc, ///< current angular acceleration of section, in material frame 774 const ChVector<>& mXacc ///< current acceleration of section, in material frame (not absolute!) 775 ) override; 776 777 /// Compute the centrifugal term and gyroscopic term 778 virtual void ComputeQuadraticTerms(ChVector<>& mF, ChVector<>& mT, const ChVector<>& mW) override; 779 }; 780 781 782 783 784 /// @} fea_utils 785 786 } // end namespace fea 787 } // end namespace chrono 788 789 #endif 790