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_HEXAHEDRONFEMFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_HEXAHEDRONFEMFORCEFIELD_H
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.h>
00029 #include <sofa/component/MechanicalObject.h>
00030 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00031 #include <sofa/component/topology/SparseGridTopology.h>
00032 #include <sofa/helper/vector.h>
00033 #include <sofa/defaulttype/Vec.h>
00034 #include <sofa/defaulttype/Mat.h>
00035
00036 namespace sofa
00037 {
00038
00039 namespace component
00040 {
00041
00042 namespace forcefield
00043 {
00044
00045 using namespace sofa::defaulttype;
00046 using sofa::helper::vector;
00047
00073 template<class DataTypes>
00074 class HexahedronFEMForceField : virtual public core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00075 {
00076 public:
00077 typedef typename DataTypes::VecCoord VecCoord;
00078 typedef typename DataTypes::VecDeriv VecDeriv;
00079 typedef VecCoord Vector;
00080 typedef typename DataTypes::Coord Coord;
00081 typedef typename DataTypes::Deriv Deriv;
00082 typedef typename Coord::value_type Real;
00083
00084 typedef core::componentmodel::topology::BaseMeshTopology::index_type Index;
00085 #ifdef SOFA_NEW_HEXA
00086 typedef core::componentmodel::topology::BaseMeshTopology::Hexa Element;
00087 typedef core::componentmodel::topology::BaseMeshTopology::SeqHexas VecElement;
00088 #else
00089 typedef core::componentmodel::topology::BaseMeshTopology::Cube Element;
00090 typedef core::componentmodel::topology::BaseMeshTopology::SeqCubes VecElement;
00091 #endif
00092
00093 static const int LARGE = 0;
00094 static const int POLAR = 1;
00095
00096
00097
00098
00099 protected:
00100
00101
00102
00103 typedef Vec<24, Real> Displacement;
00104
00105 typedef Mat<6, 6, Real> MaterialStiffness;
00106 typedef vector<MaterialStiffness> VecMaterialStiffness;
00107 VecMaterialStiffness _materialsStiffnesses;
00108
00109 typedef Mat<24, 24, Real> ElementStiffness;
00110 typedef helper::vector<ElementStiffness> VecElementStiffness;
00111 Data<VecElementStiffness> _elementStiffnesses;
00112
00113 typedef Mat<3, 3, Real> Mat33;
00114 typedef Mat33 Transformation;
00115
00116
00117 typedef std::pair<int,Real> Col_Value;
00118 typedef vector< Col_Value > CompressedValue;
00119 typedef vector< CompressedValue > CompressedMatrix;
00120 CompressedMatrix _stiffnesses;
00121 double m_potentialEnergy;
00122
00123
00124 sofa::core::componentmodel::topology::BaseMeshTopology* _mesh;
00125 topology::SparseGridTopology* _sparseGrid;
00126 const VecElement *_indexedElements;
00127 Data< VecCoord > _initialPoints;
00128
00129
00130 Mat<8,3,int> _coef;
00131 #ifndef SOFA_NEW_HEXA
00132 static const int _indices[8];
00133 #endif
00134
00135 public:
00136
00137 int method;
00138 Data<std::string> f_method;
00139 Data<Real> f_poissonRatio;
00140 Data<Real> f_youngModulus;
00141 Data<bool> f_updateStiffnessMatrix;
00142 Data<bool> f_assembling;
00143
00144
00145 HexahedronFEMForceField()
00146 : _elementStiffnesses(initData(&_elementStiffnesses,"stiffnessMatrices", "Stiffness matrices per element (K_i)"))
00147 , _mesh(NULL)
00148 , _sparseGrid(NULL)
00149 , _indexedElements(NULL)
00150 , _initialPoints(initData(&_initialPoints,"initialPoints", "Initial Position"))
00151 , f_method(initData(&f_method,std::string("large"),"method","\"large\" or \"polar\" displacements"))
00152 , f_poissonRatio(initData(&f_poissonRatio,(Real)0.45f,"poissonRatio",""))
00153 , f_youngModulus(initData(&f_youngModulus,(Real)5000,"youngModulus",""))
00154 , f_updateStiffnessMatrix(initData(&f_updateStiffnessMatrix,false,"updateStiffnessMatrix",""))
00155 , f_assembling(initData(&f_assembling,false,"assembling",""))
00156 {
00157 _coef[0][0]=-1;
00158 _coef[1][0]=1;
00159 _coef[2][0]=1;
00160 _coef[3][0]=-1;
00161 _coef[4][0]=-1;
00162 _coef[5][0]=1;
00163 _coef[6][0]=1;
00164 _coef[7][0]=-1;
00165 _coef[0][1]=-1;
00166 _coef[1][1]=-1;
00167 _coef[2][1]=1;
00168 _coef[3][1]=1;
00169 _coef[4][1]=-1;
00170 _coef[5][1]=-1;
00171 _coef[6][1]=1;
00172 _coef[7][1]=1;
00173 _coef[0][2]=-1;
00174 _coef[1][2]=-1;
00175 _coef[2][2]=-1;
00176 _coef[3][2]=-1;
00177 _coef[4][2]=1;
00178 _coef[5][2]=1;
00179 _coef[6][2]=1;
00180 _coef[7][2]=1;
00181
00182 _alreadyInit=false;
00183
00184 }
00185
00186 void parse(core::objectmodel::BaseObjectDescription* arg);
00187
00188 void setPoissonRatio(Real val) { this->f_poissonRatio.setValue(val); }
00189
00190 void setYoungModulus(Real val) { this->f_youngModulus.setValue(val); }
00191
00192 void setMethod(int val)
00193 {
00194 method = val;
00195 switch(val)
00196 {
00197 case POLAR: f_method.setValue("polar"); break;
00198 default : f_method.setValue("large");
00199 };
00200 }
00201
00202 void setUpdateStiffnessMatrix(bool val) { this->f_updateStiffnessMatrix.setValue(val); }
00203
00204 void setComputeGlobalMatrix(bool val) { this->f_assembling.setValue(val); }
00205
00206
00207
00208 virtual void init();
00209 virtual void reinit();
00210
00211 virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00212
00213 virtual void addDForce (VecDeriv& df, const VecDeriv& dx);
00214
00215 virtual double getPotentialEnergy(const VecCoord& x);
00216
00217 void addKToMatrix(sofa::defaulttype::BaseMatrix *mat, SReal k, unsigned int &offset);
00218
00219
00220 void draw();
00221
00222 protected:
00223
00224
00225 virtual void computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const helper::fixed_array<Coord,8> &nodes, const int elementIndice, double stiffnessFactor=1.0);
00226 Mat33 integrateStiffness( int signx0, int signy0, int signz0, int signx1, int signy1, int signz1, const Real u, const Real v, const Real w, const Mat33& J_1 );
00227
00228 void computeMaterialStiffness(int i);
00229
00230 void computeForce( Displacement &F, const Displacement &Depl, const ElementStiffness &K );
00231
00232
00234 vector<helper::fixed_array<Coord,8> > _rotatedInitialElements;
00235 vector<Transformation> _rotations;
00236 void initLarge(int i, const Element&elem);
00237 void computeRotationLarge( Transformation &r, Coord &edgex, Coord &edgey);
00238 virtual void accumulateForceLarge( Vector& f, const Vector & p, int i, const Element&elem );
00239
00241 void initPolar(int i, const Element&elem);
00242 void computeRotationPolar( Transformation &r, Vec<8,Coord> &nodes);
00243 virtual void accumulateForcePolar( Vector& f, const Vector & p, int i, const Element&elem );
00244
00245
00246
00247 bool _alreadyInit;
00248 };
00249
00250 }
00251
00252 }
00253
00254 }
00255
00256 #endif