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, Radu Serban
13 // =============================================================================
14 
15 #ifndef CHNODEBASE_H
16 #define CHNODEBASE_H
17 
18 #include "chrono/physics/ChPhysicsItem.h"
19 #include "chrono/solver/ChVariablesBodyOwnMass.h"
20 
21 namespace chrono {
22 
23 /// Class for a node, that has some degrees of freedom and that contain a proxy to the solver.
24 /// It is like a lightweight version of a ChPhysicsItem; often a ChPhysicsItem is used as a
25 /// container for a cluster of these ChNodeBase.
26 class ChApi ChNodeBase {
27   protected:
28     unsigned int offset_x;  ///< offset in vector of state (position part)
29     unsigned int offset_w;  ///< offset in vector of state (speed part)
30 
31   public:
32     ChNodeBase();
33     ChNodeBase(const ChNodeBase& other);
~ChNodeBase()34     virtual ~ChNodeBase() {}
35 
36     ChNodeBase& operator=(const ChNodeBase& other);
37 
38     //
39     // Functions for interfacing to the state bookkeeping
40     //
41 
42     /// Get the number of degrees of freedom
43     virtual int Get_ndof_x() const = 0;
44 
45     /// Get the number of degrees of freedom, derivative
46     /// This might be different from ndof if quaternions are used for rotations,
47     /// as derivative might be angular velocity.
Get_ndof_w()48     virtual int Get_ndof_w() const { return Get_ndof_x(); }
49 
50     /// Get offset in the state vector (position part)
NodeGetOffset_x()51     unsigned int NodeGetOffset_x() { return offset_x; }
52     /// Get offset in the state vector (speed part)
NodeGetOffset_w()53     unsigned int NodeGetOffset_w() { return offset_w; }
54 
55     /// Set offset in the state vector (position part)
NodeSetOffset_x(const unsigned int moff)56     void NodeSetOffset_x(const unsigned int moff) { offset_x = moff; }
57     /// Set offset in the state vector (speed part)
NodeSetOffset_w(const unsigned int moff)58     void NodeSetOffset_w(const unsigned int moff) { offset_w = moff; }
59 
NodeIntStateGather(const unsigned int off_x,ChState & x,const unsigned int off_v,ChStateDelta & v,double & T)60     virtual void NodeIntStateGather(const unsigned int off_x,
61                                     ChState& x,
62                                     const unsigned int off_v,
63                                     ChStateDelta& v,
64                                     double& T) {}
NodeIntStateScatter(const unsigned int off_x,const ChState & x,const unsigned int off_v,const ChStateDelta & v,const double T)65     virtual void NodeIntStateScatter(const unsigned int off_x,
66                                      const ChState& x,
67                                      const unsigned int off_v,
68                                      const ChStateDelta& v,
69                                      const double T) {}
NodeIntStateGatherAcceleration(const unsigned int off_a,ChStateDelta & a)70     virtual void NodeIntStateGatherAcceleration(const unsigned int off_a, ChStateDelta& a) {}
NodeIntStateScatterAcceleration(const unsigned int off_a,const ChStateDelta & a)71     virtual void NodeIntStateScatterAcceleration(const unsigned int off_a, const ChStateDelta& a) {}
NodeIntStateIncrement(const unsigned int off_x,ChState & x_new,const ChState & x,const unsigned int off_v,const ChStateDelta & Dv)72     virtual void NodeIntStateIncrement(const unsigned int off_x,
73                                        ChState& x_new,
74                                        const ChState& x,
75                                        const unsigned int off_v,
76                                        const ChStateDelta& Dv) {
77         for (int i = 0; i < Get_ndof_x(); ++i) {
78             x_new(off_x + i) = x(off_x + i) + Dv(off_v + i);
79         }
80     }
NodeIntLoadResidual_F(const unsigned int off,ChVectorDynamic<> & R,const double c)81     virtual void NodeIntLoadResidual_F(const unsigned int off, ChVectorDynamic<>& R, const double c) {}
NodeIntLoadResidual_Mv(const unsigned int off,ChVectorDynamic<> & R,const ChVectorDynamic<> & w,const double c)82     virtual void NodeIntLoadResidual_Mv(const unsigned int off,
83                                         ChVectorDynamic<>& R,
84                                         const ChVectorDynamic<>& w,
85                                         const double c) {}
NodeIntToDescriptor(const unsigned int off_v,const ChStateDelta & v,const ChVectorDynamic<> & R)86     virtual void NodeIntToDescriptor(const unsigned int off_v, const ChStateDelta& v, const ChVectorDynamic<>& R) {}
NodeIntFromDescriptor(const unsigned int off_v,ChStateDelta & v)87     virtual void NodeIntFromDescriptor(const unsigned int off_v, ChStateDelta& v) {}
88 
89     //
90     // Functions for interfacing to the solver
91     //
92 
93     /// Tell to a system descriptor that there are variables of type
94     /// ChVariables in this object (for further passing it to a solver)
InjectVariables(ChSystemDescriptor & mdescriptor)95     virtual void InjectVariables(ChSystemDescriptor& mdescriptor) {}
96 
97     /// Sets the 'fb' part (the known term) of the encapsulated ChVariables to zero.
VariablesFbReset()98     virtual void VariablesFbReset() {}
99 
100     /// Adds the current forces (applied to node) into the
101     /// encapsulated ChVariables, in the 'fb' part: qf+=forces*factor
102     virtual void VariablesFbLoadForces(double factor = 1) {}
103 
104     /// Initialize the 'qb' part of the ChVariables with the
105     /// current value of speeds.
VariablesQbLoadSpeed()106     virtual void VariablesQbLoadSpeed() {}
107 
108     /// Adds M*q (masses multiplied current 'qb') to Fb, ex. if qb is initialized
109     /// with v_old using VariablesQbLoadSpeed, this method can be used in
110     /// timestepping schemes that do: M*v_new = M*v_old + forces*dt
VariablesFbIncrementMq()111     virtual void VariablesFbIncrementMq() {}
112 
113     /// Fetches the item speed (ex. linear velocity, in xyz nodes) from the
114     /// 'qb' part of the ChVariables and sets it as the current item speed.
115     /// If 'step' is not 0, also should compute the approximate acceleration of
116     /// the item using backward differences, that is  accel=(new_speed-old_speed)/step.
117     /// Mostly used after the solver provided the solution in ChVariables.
118     virtual void VariablesQbSetSpeed(double step = 0) {}
119 
120     /// Increment node positions by the 'qb' part of the ChVariables,
121     /// multiplied by a 'step' factor.
122     ///     pos+=qb*step
123     /// If qb is a speed, this behaves like a single step of 1-st order
124     /// numerical integration (Eulero integration).
VariablesQbIncrementPosition(double step)125     virtual void VariablesQbIncrementPosition(double step) {}
126 
127     /// Method to allow serialization of transient data to archives.
128     virtual void ArchiveOUT(ChArchiveOut& marchive);
129 
130     /// Method to allow de-serialization of transient data from archives.
131     virtual void ArchiveIN(ChArchiveIn& marchive);
132 };
133 
134 CH_CLASS_VERSION(ChNodeBase, 0)
135 
136 }  // end namespace chrono
137 
138 #endif
139