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