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_TETRAHEDRALCOROTATIONALFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_TETRAHEDRALCOROTATIONALFEMFORCEFIELD_H
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.h>
00029 #include <sofa/component/MechanicalObject.h>
00030 #include <sofa/component/topology/TetrahedronData.h>
00031 #include <sofa/helper/vector.h>
00032 #include <sofa/defaulttype/Vec.h>
00033 #include <sofa/defaulttype/Mat.h>
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 namespace sofa
00050 {
00051
00052 namespace component
00053 {
00054
00055 namespace forcefield
00056 {
00057
00058 using namespace sofa::defaulttype;
00059 using sofa::helper::vector;
00060 using namespace sofa::component::topology;
00061
00062
00063
00066 template<class DataTypes>
00067 class TetrahedralCorotationalFEMForceField : public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00068 {
00069 public:
00070 typedef typename DataTypes::VecCoord VecCoord;
00071 typedef typename DataTypes::VecDeriv VecDeriv;
00072 typedef typename DataTypes::VecReal VecReal;
00073 typedef VecCoord Vector;
00074 typedef typename DataTypes::Coord Coord;
00075 typedef typename DataTypes::Deriv Deriv;
00076 typedef typename Coord::value_type Real;
00077
00078
00079 enum { SMALL = 0,
00080 LARGE = 1,
00081 POLAR = 2
00082 };
00083 protected:
00084
00087
00089 typedef VecNoInit<12, Real> Displacement;
00090
00092 typedef Mat<6, 6, Real> MaterialStiffness;
00093
00095 typedef Mat<12, 6, Real> StrainDisplacement;
00096
00098 typedef MatNoInit<3, 3, Real> Transformation;
00099
00101 typedef Mat<12, 12, Real> StiffnessMatrix;
00102
00104
00106 class TetrahedronInformation
00107 {
00108 public:
00110 MaterialStiffness materialMatrix;
00112 StrainDisplacement strainDisplacementMatrix;
00114 helper::fixed_array<Coord,4> rotatedInitialElements;
00115 Transformation rotation;
00117 Transformation initialTransformation;
00118
00119 TetrahedronInformation() {
00120 }
00121 };
00123 TetrahedronData<TetrahedronInformation> tetrahedronInfo;
00124
00127
00128 typedef std::pair<int,Real> Col_Value;
00129 typedef vector< Col_Value > CompressedValue;
00130 typedef vector< CompressedValue > CompressedMatrix;
00131 typedef unsigned int Index;
00132
00133 CompressedMatrix _stiffnesses;
00135
00136 double m_potentialEnergy;
00137
00138 sofa::core::componentmodel::topology::BaseMeshTopology* _topology;
00139
00140 public:
00141 int method;
00142 Data<std::string> f_method;
00143 Real _poissonRatio;
00144 DataPtr<Real> f_poissonRatio;
00145 Real _youngModulus;
00146 DataPtr<Real> f_youngModulus;
00147 VecReal _localStiffnessFactor;
00148 DataPtr<VecReal> f_localStiffnessFactor;
00149 bool _updateStiffnessMatrix;
00150 DataPtr<bool> f_updateStiffnessMatrix;
00151 bool _assembling;
00152 DataPtr<bool> f_assembling;
00153
00154 TetrahedralCorotationalFEMForceField()
00155 : f_method(initData(&f_method,std::string("large"),"method","\"small\", \"large\" (by QR) or \"polar\" displacements"))
00156 , _poissonRatio((Real)0.45f)
00157 , f_poissonRatio(initDataPtr(&f_poissonRatio,&_poissonRatio,"poissonRatio","FEM Poisson Ratio"))
00158 , _youngModulus((Real)5000)
00159 , f_youngModulus(initDataPtr(&f_youngModulus,&_youngModulus,"youngModulus","FEM Young Modulus"))
00160 , f_localStiffnessFactor(initDataPtr(&f_localStiffnessFactor,&_localStiffnessFactor,"localStiffnessFactor","Allow specification of different stiffness per element. If there are N element and M values are specified, the youngModulus factor for element i would be localStiffnessFactor[i*M/N]"))
00161 , _updateStiffnessMatrix(false)
00162 , f_updateStiffnessMatrix(initDataPtr(&f_updateStiffnessMatrix,&_updateStiffnessMatrix,"updateStiffnessMatrix",""))
00163 , _assembling(false)
00164 , f_assembling(initDataPtr(&f_assembling,&_assembling,"assembling",""))
00165 {}
00166
00167 void parse(core::objectmodel::BaseObjectDescription* arg);
00168
00169 void setPoissonRatio(Real val) { this->f_poissonRatio.setValue(val); }
00170
00171 void setYoungModulus(Real val) { this->f_youngModulus.setValue(val); }
00172
00173 void setMethod(int val) { method = val; }
00174
00175 void setUpdateStiffnessMatrix(bool val) { this->f_updateStiffnessMatrix.setValue(val); }
00176
00177 void setComputeGlobalMatrix(bool val) { this->f_assembling.setValue(val); }
00178
00179 virtual void init();
00180 virtual void reinit();
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& x);
00187
00188 virtual void addKToMatrix(sofa::defaulttype::BaseMatrix *, SReal, unsigned int &);
00189
00190
00191 virtual void handleTopologyChange();
00192
00193 void draw();
00194
00195 protected:
00196
00197 void computeStrainDisplacement( StrainDisplacement &J, Coord a, Coord b, Coord c, Coord d );
00198 Real peudo_determinant_for_coef ( const Mat<2, 3, Real>& M );
00199
00200 void computeStiffnessMatrix( StiffnessMatrix& S,StiffnessMatrix& SR,const MaterialStiffness &K, const StrainDisplacement &J, const Transformation& Rot );
00201
00202 void computeMaterialStiffness(int i, Index&a, Index&b, Index&c, Index&d);
00203
00204 void computeForce( Displacement &F, const Displacement &Depl, const MaterialStiffness &K, const StrainDisplacement &J );
00205
00207 void initSmall(int i, Index&a, Index&b, Index&c, Index&d);
00208 void accumulateForceSmall( Vector& f, const Vector & p, Index elementIndex );
00209 void applyStiffnessSmall( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3 );
00210
00212 void initLarge(int i, Index&a, Index&b, Index&c, Index&d);
00213 void computeRotationLarge( Transformation &r, const Vector &p, const Index &a, const Index &b, const Index &c);
00214 void accumulateForceLarge( Vector& f, const Vector & p, Index elementIndex );
00215 void applyStiffnessLarge( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3 );
00216
00218 void initPolar(int i, Index&a, Index&b, Index&c, Index&d);
00219 void accumulateForcePolar( Vector& f, const Vector & p,Index elementIndex );
00220 void applyStiffnessPolar( Vector& f, const Vector& x, int i=0, Index a=0,Index b=1,Index c=2,Index d=3 );
00221
00223 static void CFTetrahedronCreationFunction (int , void* ,
00224 TetrahedronInformation &,
00225 const Tetrahedron& , const helper::vector< unsigned int > &, const helper::vector< double >&);
00226
00227
00228
00229 };
00230
00231 }
00232
00233 }
00234
00235 }
00236
00237 #endif