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 CHELEMENTSPRING_H
16 #define CHELEMENTSPRING_H
17 
18 #include "chrono/fea/ChElementGeneric.h"
19 #include "chrono/fea/ChNodeFEAxyz.h"
20 
21 namespace chrono {
22 namespace fea {
23 
24 /// @addtogroup fea_elements
25 /// @{
26 
27 /// Simple finite element with two nodes and a spring/damper between the two nodes.
28 /// This element is mass-less, so if used in dynamic analysis, the two nodes must
29 /// be set with non-zero point mass.
30 class ChApi ChElementSpring : public ChElementGeneric {
31   public:
32     ChElementSpring();
33     ~ChElementSpring();
34 
GetNnodes()35     virtual int GetNnodes() override { return 2; }
GetNdofs()36     virtual int GetNdofs() override { return 2 * 3; }
GetNodeNdofs(int n)37     virtual int GetNodeNdofs(int n) override { return 3; }
38 
GetNodeN(int n)39     virtual std::shared_ptr<ChNodeFEAbase> GetNodeN(int n) override { return nodes[n]; }
40 
41     virtual void SetNodes(std::shared_ptr<ChNodeFEAxyz> nodeA, std::shared_ptr<ChNodeFEAxyz> nodeB);
42 
43     //
44     // FEA functions
45     //
46 
47     /// Fills the D vector with the current field values at the nodes of the element, with proper ordering.
48     /// If the D vector has not the size of this->GetNdofs(), it will be resized.
49     virtual void GetStateBlock(ChVectorDynamic<>& mD) override;
50 
51     /// Sets H as the global stiffness matrix K, scaled  by Kfactor. Optionally, also
52     /// superimposes global damping matrix R, scaled by Rfactor, and global mass matrix M multiplied by Mfactor.
53     /// (For the spring matrix there is no need to corotate local matrices: we already know a closed form expression.)
54     virtual void ComputeKRMmatricesGlobal(ChMatrixRef H,
55                                           double Kfactor,
56                                           double Rfactor = 0,
57                                           double Mfactor = 0) override;
58 
59     /// Computes the internal forces (ex. the actual position of nodes is not in relaxed reference position) and set
60     /// values in the Fi vector.
61     virtual void ComputeInternalForces(ChVectorDynamic<>& Fi) override;
62 
63     //
64     // Custom properties functions
65     //
66 
67     /// Set the stiffness of the spring that connects the two nodes (N/m)
SetSpringK(double ms)68     virtual void SetSpringK(double ms) { spring_k = ms; }
GetSpringK()69     virtual double GetSpringK() { return spring_k; }
70 
71     /// Set the damping of the damper that connects the two nodes (Ns/M)
SetDamperR(double md)72     virtual void SetDamperR(double md) { damper_r = md; }
GetDamperR()73     virtual double GetDamperR() { return damper_r; }
74 
75 	/// Get the current force transmitted along the spring direction,
76 	/// including the effect of the damper. Positive if pulled. (N)
77 	virtual double GetCurrentForce();
78 
79     //
80     // Functions for interfacing to the solver
81     //            (***not needed, thank to bookkeeping in parent class ChElementGeneric)
82 
83   private:
84     /// Initial setup.
85     /// No override needed for the spring element because global K is computed on-the-fly in ComputeAddKRmatricesGlobal()
86     ////virtual void SetupInitial(ChSystem* system) override {}
87 
88 	std::vector<std::shared_ptr<ChNodeFEAxyz> > nodes;
89     double spring_k;
90     double damper_r;
91 };
92 
93 /// @} fea_elements
94 
95 }  // end namespace fea
96 }  // end namespace chrono
97 
98 #endif
99