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: Andrea Favali, Alessandro Tasora, Radu Serban
13 // =============================================================================
14 
15 #ifndef CHNODEFEAXYZD_H
16 #define CHNODEFEAXYZD_H
17 
18 #include "chrono/solver/ChVariablesGenericDiagonalMass.h"
19 #include "chrono/fea/ChNodeFEAxyz.h"
20 
21 namespace chrono {
22 namespace fea {
23 
24 /// @addtogroup fea_nodes
25 /// @{
26 
27 /// Class for a generic 3D finite element node, with x,y,z displacement and a direction.
28 /// The direction D represents a gradient vector to be used in ANCF elements.
29 class ChApi ChNodeFEAxyzD : public ChNodeFEAxyz {
30   public:
31     ChNodeFEAxyzD(ChVector<> initial_pos = VNULL, ChVector<> initial_dir = VECT_X);
32     ChNodeFEAxyzD(const ChNodeFEAxyzD& other);
33     ~ChNodeFEAxyzD();
34 
35     ChNodeFEAxyzD& operator=(const ChNodeFEAxyzD& other);
36 
37     /// Set the direction
SetD(ChVector<> mD)38     void SetD(ChVector<> mD) { D = mD; }
39     /// Get the direction
GetD()40     const ChVector<>& GetD() const { return D; }
41 
42     /// Set the direction speed
SetD_dt(ChVector<> mD)43     void SetD_dt(ChVector<> mD) { D_dt = mD; }
44     /// Get the direction speed
GetD_dt()45     const ChVector<>& GetD_dt() const { return D_dt; }
46 
47     /// Set the direction acceleration
SetD_dtdt(ChVector<> mD)48     void SetD_dtdt(ChVector<> mD) { D_dtdt = mD; }
49     /// Get the direction acceleration
GetD_dtdt()50     const ChVector<>& GetD_dtdt() const { return D_dtdt; }
51 
Variables_D()52     ChVariables& Variables_D() { return *variables_D; }
53 
54     /// Reset to no speed and acceleration.
55     virtual void SetNoSpeedNoAcceleration() override;
56 
57     /// Get mass of the node.
GetMassDiagonal()58     virtual ChVectorDynamic<>& GetMassDiagonal() { return variables_D->GetMassDiagonal(); }
59 
60     /// Sets the 'fixed' state of the node. If true, it does not move
61     /// respect to the absolute world, despite constraints, forces, etc.
62     virtual void SetFixed(bool mev) override;
63     /// Gets the 'fixed' state of the node.
GetFixed()64     virtual bool GetFixed() override { return variables_D->IsDisabled(); }
65 
66     /// Get the number of degrees of freedom
Get_ndof_x()67     virtual int Get_ndof_x() const override { return 6; }
68 
69     //
70     // Functions for interfacing to the state bookkeeping
71     //
72 
73     virtual void NodeIntStateGather(const unsigned int off_x,
74                                     ChState& x,
75                                     const unsigned int off_v,
76                                     ChStateDelta& v,
77                                     double& T) override;
78     virtual void NodeIntStateScatter(const unsigned int off_x,
79                                      const ChState& x,
80                                      const unsigned int off_v,
81                                      const ChStateDelta& v,
82                                      const double T) override;
83     virtual void NodeIntStateGatherAcceleration(const unsigned int off_a, ChStateDelta& a) override;
84     virtual void NodeIntStateScatterAcceleration(const unsigned int off_a, const ChStateDelta& a) override;
85     virtual void NodeIntStateIncrement(const unsigned int off_x,
86                                        ChState& x_new,
87                                        const ChState& x,
88                                        const unsigned int off_v,
89                                        const ChStateDelta& Dv) override;
90     virtual void NodeIntLoadResidual_F(const unsigned int off, ChVectorDynamic<>& R, const double c) override;
91     virtual void NodeIntLoadResidual_Mv(const unsigned int off,
92                                         ChVectorDynamic<>& R,
93                                         const ChVectorDynamic<>& w,
94                                         const double c) override;
95     virtual void NodeIntToDescriptor(const unsigned int off_v,
96                                      const ChStateDelta& v,
97                                      const ChVectorDynamic<>& R) override;
98     virtual void NodeIntFromDescriptor(const unsigned int off_v, ChStateDelta& v) override;
99 
100     //
101     // Functions for interfacing to the solver
102     //
103 
104     virtual void InjectVariables(ChSystemDescriptor& mdescriptor) override;
105     virtual void VariablesFbReset() override;
106     virtual void VariablesFbLoadForces(double factor = 1) override;
107     virtual void VariablesQbLoadSpeed() override;
108     virtual void VariablesQbSetSpeed(double step = 0) override;
109     virtual void VariablesFbIncrementMq() override;
110     virtual void VariablesQbIncrementPosition(double step) override;
111 
112     //
113     // INTERFACE to ChLoadable
114     //
115 
116     /// Gets the number of DOFs affected by this element (position part)
LoadableGet_ndof_x()117     virtual int LoadableGet_ndof_x() override { return 6; }
118 
119     /// Gets the number of DOFs affected by this element (speed part)
LoadableGet_ndof_w()120     virtual int LoadableGet_ndof_w() override { return 6; }
121 
122     /// Gets all the DOFs packed in a single vector (position part)
LoadableGetStateBlock_x(int block_offset,ChState & mD)123     virtual void LoadableGetStateBlock_x(int block_offset, ChState& mD) override {
124         mD.segment(block_offset + 0, 3) = pos.eigen();
125         mD.segment(block_offset + 3, 3) = D.eigen();
126     }
127 
128     /// Gets all the DOFs packed in a single vector (speed part)
LoadableGetStateBlock_w(int block_offset,ChStateDelta & mD)129     virtual void LoadableGetStateBlock_w(int block_offset, ChStateDelta& mD) override {
130         mD.segment(block_offset + 0, 3) = pos_dt.eigen();
131         mD.segment(block_offset + 3, 3) = D_dt.eigen();
132     }
133 
134     /// Increment all DOFs using a delta.
LoadableStateIncrement(const unsigned int off_x,ChState & x_new,const ChState & x,const unsigned int off_v,const ChStateDelta & Dv)135     virtual void LoadableStateIncrement(const unsigned int off_x, ChState& x_new, const ChState& x, const unsigned int off_v, const ChStateDelta& Dv) override {
136         this->NodeIntStateIncrement(off_x, x_new, x, off_v, Dv);
137     }
138 
139     /// Number of coordinates in the interpolated field, ex=3 for a
140     /// tetrahedron finite element or a cable, etc. Here is 6: xyz displ + xyz rots
Get_field_ncoords()141     virtual int Get_field_ncoords() override { return 6; }
142 
143     /// Get the size of the i-th sub-block of DOFs in global vector
GetSubBlockSize(int nblock)144     virtual unsigned int GetSubBlockSize(int nblock) override { return 6; }
145 
146     /// Get the pointers to the contained ChVariables, appending to the mvars vector.
LoadableGetVariables(std::vector<ChVariables * > & mvars)147     virtual void LoadableGetVariables(std::vector<ChVariables*>& mvars) override {
148         mvars.push_back(&Variables());
149         mvars.push_back(&Variables_D());
150     }
151 
152     /// Evaluate Q=N'*F , for Q generalized lagrangian load, where N is some type of matrix
153     /// evaluated at point P(U,V,W) assumed in absolute coordinates, and
154     /// F is a load assumed in absolute coordinates.
155     /// The det[J] is unused.
156     virtual void ComputeNF(
157         const double U,              ///< x coordinate of application point in absolute space
158         const double V,              ///< y coordinate of application point in absolute space
159         const double W,              ///< z coordinate of application point in absolute space
160         ChVectorDynamic<>& Qi,       ///< Return result of N'*F  here, maybe with offset block_offset
161         double& detJ,                ///< Return det[J] here
162         const ChVectorDynamic<>& F,  ///< Input F vector, containing Force xyz in absolute coords and a 'pseudo' torque.
163         ChVectorDynamic<>* state_x,  ///< if != 0, update state (pos. part) to this, then evaluate Q
164         ChVectorDynamic<>* state_w   ///< if != 0, update state (speed part) to this, then evaluate Q
165         ) override;
166 
167     //
168     // SERIALIZATION
169     //
170 
171     virtual void ArchiveOUT(ChArchiveOut& marchive) override;
172     virtual void ArchiveIN(ChArchiveIn& marchive) override;
173 
174   private:
175     /// 3D node variable - the direction part: Dx,Dy,Dz (the position part is in parent class)
176     ChVariablesGenericDiagonalMass* variables_D;
177 
178   public:
179     ChVector<> D;
180     ChVector<> D_dt;
181     ChVector<> D_dtdt;
182 };
183 
184 /// @} fea_nodes
185 
186 }  // end namespace fea
187 }  // end namespace chrono
188 
189 #endif
190