MatrixMass.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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 // -- Mass interface
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         // gravity
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         // add weight and inertia force
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     //if gravity was added separately (in solver's "solve" method), then nothing to do here
00154     if(this->m_separateGravity.getValue())
00155         return;
00156 
00157     const VecMass &masses= *_usedMassMatrices;
00158 
00159     // gravity
00160     Vec3d g ( this->getContext()->getLocalGravity() );
00161     Deriv theGravity;
00162     DataTypes::set ( theGravity, g[0], g[1], g[2]);
00163     
00164     // velocity-based stuff
00165     core::objectmodel::BaseContext::SpatialVector vframe = this->getContext()->getVelocityInWorld();
00166     core::objectmodel::BaseContext::Vec3 aframe = this->getContext()->getVelocityBasedLinearAccelerationInWorld() ;
00167 
00168     // project back to local frame
00169     vframe = this->getContext()->getPositionInWorld() / vframe;
00170     aframe = this->getContext()->getPositionInWorld().backProjectVector( aframe );
00171     
00172     // add weight and inertia force
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 /*index*/)
00191 {
00192     //NOT IMPLEMENTED YET
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 ) // in case where defaultValue is modified
00234     {
00235         clear();
00236         defaultDiagonalMatrices();
00237     }
00238 
00239     if( this->_lumped.getValue() ) // in case of _lumped is modified
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 } // namespace mass
00295 
00296 } // namespace component
00297 
00298 } // namespace sofa
00299 
00300 #endif

Generated on Sun Nov 23 03:37:46 2008 for Sofa by  doxygen 1.5.7.1