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_MASS_MATRIXMASS_INL
00026 #define SOFA_COMPONENT_MASS_MATRIXMASS_INL
00027
00028 #include <sofa/component/mass/MatrixMass.h>
00029 #include <sofa/defaulttype/RigidTypes.h>
00030 #include <sofa/defaulttype/DataTypeInfo.h>
00031 #include <sofa/component/mass/AddMToMatrixFunctor.h>
00032
00033 #include <sofa/helper/gl/template.h>
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace mass
00042 {
00043
00044 using namespace sofa::component::topology;
00045 using namespace core::componentmodel::topology;
00046 using namespace sofa::defaulttype;
00047 using namespace sofa::core::componentmodel::behavior;
00048
00049 using std::cerr;
00050 using std::endl;
00051
00052
00053
00054
00055
00056 template <class DataTypes, class MassType>
00057 MatrixMass<DataTypes, MassType>::~MatrixMass()
00058 {
00059 }
00060
00061
00063
00064
00065 template <class DataTypes, class MassType>
00066 void MatrixMass<DataTypes, MassType>::clear()
00067 {
00068 VecMass& masses = *f_mass.beginEdit();
00069 masses.clear();
00070 f_mass.endEdit();
00071 }
00072
00073
00074 template <class DataTypes, class MassType>
00075 void MatrixMass<DataTypes, MassType>::resize(int vsize)
00076 {
00077 VecMass& masses = *f_mass.beginEdit();
00078 masses.resize(vsize);
00079 f_mass.endEdit();
00080 }
00081
00082
00083
00085
00086
00087
00088
00089
00090 template <class DataTypes, class MassType>
00091 void MatrixMass<DataTypes, MassType>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00092 {
00093 const VecMass &masses= *_usedMassMatrices;
00094
00095 if (factor == 1.0)
00096 {
00097 for (unsigned int i=0;i<dx.size();i++)
00098 {
00099 res[i] += masses[i] * dx[i];
00100 }
00101 }
00102 else
00103 for (unsigned int i=0;i<dx.size();i++)
00104 {
00105 res[i] += masses[i] * dx[i] * factor;
00106 }
00107
00108 }
00109
00110 template <class DataTypes, class MassType>
00111 void MatrixMass<DataTypes, MassType>::accFromF(VecDeriv& , const VecDeriv& )
00112 {
00113 cerr<<"void MatrixMass<DataTypes, MassType>::accFromF(VecDeriv& a, const VecDeriv& f) not yet implemented (need the matrix assembly and inversion)\n";
00114 }
00115
00116 template <class DataTypes, class MassType>
00117 double MatrixMass<DataTypes, MassType>::getKineticEnergy( const VecDeriv& )
00118 {
00119 cerr<<"void MatrixMass<DataTypes, MassType>::getKineticEnergy not yet implemented\n";
00120 return 0;
00121 }
00122
00123 template <class DataTypes, class MassType>
00124 double MatrixMass<DataTypes, MassType>::getPotentialEnergy( const VecCoord& )
00125 {
00126 cerr<<"void MatrixMass<DataTypes, MassType>::getPotentialEnergy not yet implemented\n";
00127 return 0;
00128 }
00129
00130
00131 template <class DataTypes, class MassType>
00132 void MatrixMass<DataTypes, MassType>::addGravityToV(double dt)
00133 {
00134 if(this->mstate){
00135 VecDeriv& v = *this->mstate->getV();
00136
00137
00138 Vec3d g ( this->getContext()->getLocalGravity() * dt );
00139 Deriv theGravity;
00140 DataTypes::set ( theGravity, g[0], g[1], g[2]);
00141 Deriv hg = theGravity * dt;
00142
00143
00144 for (unsigned int i=0;i<v.size();i++) {
00145 v[i] += hg;
00146 }
00147 }
00148 }
00149
00150 template <class DataTypes, class MassType>
00151 void MatrixMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00152 {
00153
00154 if(this->m_separateGravity.getValue())
00155 return;
00156
00157 const VecMass &masses= *_usedMassMatrices;
00158
00159
00160 Vec3d g ( this->getContext()->getLocalGravity() );
00161 Deriv theGravity;
00162 DataTypes::set ( theGravity, g[0], g[1], g[2]);
00163
00164
00165 core::objectmodel::BaseContext::SpatialVector vframe = this->getContext()->getVelocityInWorld();
00166 core::objectmodel::BaseContext::Vec3 aframe = this->getContext()->getVelocityBasedLinearAccelerationInWorld() ;
00167
00168
00169 vframe = this->getContext()->getPositionInWorld() / vframe;
00170 aframe = this->getContext()->getPositionInWorld().backProjectVector( aframe );
00171
00172
00173 for (unsigned int i=0;i<masses.size();i++) {
00174 f[i] += masses[i]*theGravity + core::componentmodel::behavior::inertiaForce(vframe,aframe,masses[i],x[i],v[i]);
00175 }
00176 }
00177
00178 template <class DataTypes, class MassType>
00179 void MatrixMass<DataTypes, MassType>::addMToMatrix(defaulttype::BaseMatrix * mat, double mFact, unsigned int &offset)
00180 {
00181 const VecMass &masses= *_usedMassMatrices;
00182 const int N = defaulttype::DataTypeInfo<Deriv>::size();
00183 AddMToMatrixFunctor<Deriv,MassType> calc;
00184 for (unsigned int i=0;i<masses.size();i++)
00185 calc(mat, masses[i], offset + N*i, mFact);
00186 }
00187
00188
00189 template <class DataTypes, class MassType>
00190 double MatrixMass<DataTypes, MassType>::getElementMass(unsigned int )
00191 {
00192
00193 return (sofa::defaulttype::Vector3::value_type)(_defaultValue.getValue());
00194 }
00195
00196
00197
00198
00199
00200
00202
00203
00204
00205 template <class DataTypes, class MassType>
00206 void MatrixMass<DataTypes, MassType>::init()
00207 {
00208 Inherited::init();
00209
00210 if (f_mass.getValue().empty())
00211 {
00212 clear();
00213 defaultDiagonalMatrices();
00214 _usingDefaultDiagonalMatrices=true;
00215 }
00216
00217 assert( f_mass.getValue().size() == this->mstate->getX()->size() );
00218
00219 if( this->_lumped.getValue() )
00220 {
00221 lumpMatrices();
00222 _usedMassMatrices = &_lumpedMasses;
00223 }
00224 else
00225 {
00226 _usedMassMatrices = &f_mass.getValue();
00227 }
00228 }
00229
00230 template <class DataTypes, class MassType>
00231 void MatrixMass<DataTypes, MassType>::reinit()
00232 {
00233 if( _usingDefaultDiagonalMatrices )
00234 {
00235 clear();
00236 defaultDiagonalMatrices();
00237 }
00238
00239 if( this->_lumped.getValue() )
00240 {
00241 lumpMatrices();
00242 _usedMassMatrices = &_lumpedMasses;
00243 }
00244 else
00245 {
00246 _usedMassMatrices = &f_mass.getValue();
00247 }
00248 }
00249
00250 template <class DataTypes, class MassType>
00251 MassType MatrixMass<DataTypes, MassType>::diagonalMass( const Real& m )
00252 {
00253 MassType diagonalMatrixMass;
00254 diagonalMatrixMass.identity();
00255 return diagonalMatrixMass*m;
00256 }
00257
00258 template <class DataTypes, class MassType>
00259 MassType MatrixMass<DataTypes, MassType>::lump( const MassType& m )
00260 {
00261 MassType lumpedM;
00262 lumpedM.fill(0);
00263 for (int i=0;i<m.getNbLines();i++)
00264 {
00265 lumpedM[i][i] = m.line(i).sum();
00266 }
00267 return lumpedM;
00268 }
00269
00270 template <class DataTypes, class MassType>
00271 void MatrixMass<DataTypes, MassType>::lumpMatrices( )
00272 {
00273 _lumpedMasses.clear();
00274 for (unsigned i=0;i<f_mass.getValue().size();++i)
00275 {
00276 _lumpedMasses.push_back( lump( f_mass.getValue()[i] ) );
00277 }
00278 }
00279
00280 template <class DataTypes, class MassType>
00281 void MatrixMass<DataTypes, MassType>::defaultDiagonalMatrices( )
00282 {
00283 VecMass& masses = *f_mass.beginEdit();
00284 masses.resize(this->mstate->getX()->size());
00285 MassType diagonalMatrixMass = diagonalMass( _defaultValue.getValue() );
00286 for (unsigned i=0;i<masses.size();++i)
00287 {
00288 masses[i] = diagonalMatrixMass;
00289 }
00290 _usingDefaultDiagonalMatrices=true;
00291 f_mass.endEdit();
00292 }
00293
00294 }
00295
00296 }
00297
00298 }
00299
00300 #endif