00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_COMPONENT_FORCEFIELD_BEAMFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_BEAMFEMFORCEFIELD_H
00027
00028 #include <sofa/component/topology/EdgeData.inl>
00029 #include <sofa/core/componentmodel/behavior/ForceField.h>
00030 #include <sofa/component/MechanicalObject.h>
00031 #include <sofa/helper/vector.h>
00032 #include <sofa/defaulttype/Vec.h>
00033 #include <sofa/defaulttype/Mat.h>
00034 #include <sofa/component/StiffnessContainer.h>
00035 #include <sofa/component/PoissonContainer.h>
00036 #include <sofa/component/LengthContainer.h>
00037 #include <sofa/component/RadiusContainer.h>
00038 #include <newmat/newmat.h>
00039
00040
00041
00042 namespace sofa
00043 {
00044
00045 namespace component
00046 {
00047
00048 namespace forcefield
00049 {
00050
00051 using namespace sofa::defaulttype;
00052 using sofa::helper::vector;
00053
00056 template<class DataTypes>
00057 class BeamFEMForceField : public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00058 {
00059 public:
00060 typedef typename DataTypes::VecCoord VecCoord;
00061 typedef typename DataTypes::VecDeriv VecDeriv;
00062 typedef typename DataTypes::VecReal VecReal;
00063 typedef VecCoord Vector;
00064 typedef typename DataTypes::Coord Coord;
00065 typedef typename DataTypes::Deriv Deriv;
00066 typedef typename Coord::value_type Real;
00067
00068 typedef unsigned int Index;
00069 typedef topology::Edge Element;
00070 typedef sofa::helper::vector<topology::Edge> VecElement;
00071
00072
00073 protected:
00074
00075
00076 typedef Vec<12, Real> Displacement;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 typedef Mat<3, 3, Real> Transformation;
00087
00088
00089 typedef Mat<12, 12, Real> StiffnessMatrix;
00090
00091
00092
00093 struct BeamInfo {
00094
00095 double _E0,_E;
00096 double _nu;
00097 double _L;
00098 double _r;
00099 double _G;
00100 double _Iy;
00101 double _Iz;
00102 double _J;
00103 double _A;
00104 double _Asy;
00105 double _Asz;
00106 StiffnessMatrix _k_loc;
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 Quat quat;
00127
00128
00129 void init(double E, double L, double nu, double r);
00130 };
00131
00132
00133 VecDeriv _forces;
00134
00135 topology::EdgeData<BeamInfo> beamsData;
00136
00137 const VecElement *_indexedElements;
00138 Data< VecCoord > _initialPoints;
00139 int _method;
00140 Data<Real> _poissonRatio;
00141 Data<Real> _youngModulus;
00142 Data<bool> _timoshenko;
00143 Data<Real> _radius;
00144 bool _updateStiffnessMatrix;
00145 bool _assembling;
00146
00147 StiffnessContainer* stiffnessContainer;
00148 LengthContainer* lengthContainer;
00149 PoissonContainer* poissonContainer;
00150 RadiusContainer* radiusContainer;
00151
00152 Quat& beamQuat(int i) { return beamsData[i].quat; }
00153
00154 sofa::core::componentmodel::topology::BaseMeshTopology* _topology;
00155
00156 public:
00157 BeamFEMForceField()
00158 : _indexedElements(NULL)
00159 , _initialPoints(initData(&_initialPoints, "initialPoints", "Initial Position"))
00160 , _method(0)
00161 , _poissonRatio(initData(&_poissonRatio,(Real)0.49f,"poissonRatio","Potion Ratio"))
00162 , _youngModulus(initData(&_youngModulus,(Real)5000,"youngModulus","Young Modulus"))
00163 , _timoshenko(initData(&_timoshenko,true,"timoshenko","use Timoshenko beam (non-null section shear area)"))
00164 , _radius(initData(&_radius,(Real)0.1,"radius","radius of the section"))
00165 , _updateStiffnessMatrix(true)
00166 , _assembling(false)
00167 {
00168
00169 }
00170
00171 void setUpdateStiffnessMatrix(bool val) { this->_updateStiffnessMatrix = val; }
00172
00173 void setComputeGlobalMatrix(bool val) { this->_assembling= val; }
00174
00175
00176
00177 virtual void init();
00178 virtual void reinit();
00179 virtual void reinitBeam(unsigned int i);
00180 virtual void handleTopologyChange();
00181
00182 virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00183
00184 virtual void addDForce (VecDeriv& df, const VecDeriv& dx);
00185
00186 virtual double getPotentialEnergy(const VecCoord&) { return 0; }
00187
00188 void addKToMatrix(sofa::defaulttype::BaseMatrix *mat, SReal k, unsigned int &offset);
00189
00190 void draw();
00191
00192 void setBeam(unsigned int i, double E, double L, double nu, double r);
00193 void initBeams(unsigned int size);
00194
00195 protected:
00196
00197
00198 Real peudo_determinant_for_coef ( const Mat<2, 3, Real>& M );
00199
00200
00201
00202
00203 void computeStiffness(int i, Index a, Index b);
00204
00205
00206
00208
00209
00210 vector<Transformation> _nodeRotations;
00211
00212 void initLarge(int i, Index a, Index b);
00213
00214 void accumulateForceLarge( VecDeriv& f, const VecCoord& x, int i, Index a, Index b);
00215
00216 void applyStiffnessLarge( VecDeriv& f, const VecDeriv& x, int i, Index a, Index b );
00217
00218
00219
00220 static void BeamFEMEdgeCreationFunction(int edgeIndex, void* param, BeamInfo &ei,
00221 const topology::Edge& , const sofa::helper::vector< unsigned int > &,
00222 const sofa::helper::vector< double >&);
00223
00224 };
00225
00226 }
00227
00228 }
00229
00230 }
00231
00232 #endif