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