UniformMass.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_UNIFORMMASS_INL
00026 #define SOFA_COMPONENT_MASS_UNIFORMMASS_INL
00027 
00028 #include <sofa/component/mass/UniformMass.h>
00029 #include <sofa/core/componentmodel/behavior/Mass.inl>
00030 #include <sofa/core/objectmodel/Context.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <sofa/defaulttype/RigidTypes.h>
00033 #include <sofa/defaulttype/DataTypeInfo.h>
00034 #include <sofa/component/mass/AddMToMatrixFunctor.h>
00035 #include <iostream>
00036 #include <string.h> 
00037 
00038 using std::cerr;
00039 using std::endl;
00040 
00041 namespace sofa
00042 {
00043 
00044 namespace component
00045 {
00046 
00047 namespace mass
00048 {
00049 
00050 using namespace sofa::defaulttype;
00051 
00052 
00053 template <class DataTypes, class MassType>
00054 UniformMass<DataTypes, MassType>::UniformMass()
00055 : mass( initData(&mass, MassType(1.0f), "mass", "Mass of each particle") )
00056 , totalMass( initData(&totalMass, 0.0, "totalmass", "Sum of the particles' masses") )
00057 , showCenterOfGravity( initData(&showCenterOfGravity, false, "showGravityCenter", "display the center of gravity of the system" ) )
00058 , showAxisSize( initData(&showAxisSize, 1.0f, "showAxisSizeFactor", "factor length of the axis displayed (only used for rigids)" ) )
00059 {}
00060 
00061 template <class DataTypes, class MassType>
00062 UniformMass<DataTypes, MassType>::~UniformMass()
00063 {}
00064 
00065 template <class DataTypes, class MassType>
00066 void UniformMass<DataTypes, MassType>::setMass(const MassType& m)
00067 {
00068     this->mass.setValue(m);
00069 }
00070 
00071 template <class DataTypes, class MassType>
00072 void UniformMass<DataTypes, MassType>::setTotalMass(double m)
00073 {
00074     this->totalMass.setValue(m);
00075 }
00076 
00077 template <class DataTypes, class MassType>
00078 void UniformMass<DataTypes, MassType>::init()
00079 {
00080     this->core::componentmodel::behavior::Mass<DataTypes>::init();
00081     if (this->totalMass.getValue()>0 && this->mstate!=NULL)
00082     {
00083         MassType* m = this->mass.beginEdit();
00084         *m = ((typename DataTypes::Real)this->totalMass.getValue() / this->mstate->getX()->size());
00085         this->mass.endEdit();
00086     }
00087 }
00088 
00089 // -- Mass interface
00090 template <class DataTypes, class MassType>
00091     void UniformMass<DataTypes, MassType>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00092 {
00093     MassType m = mass.getValue();
00094     if (factor != 1.0)
00095         m *= (typename DataTypes::Real)factor;
00096     for (unsigned int i=0;i<dx.size();i++)
00097     {
00098       res[i] += dx[i] * m;
00099     }
00100 }
00101 
00102 template <class DataTypes, class MassType>
00103 void UniformMass<DataTypes, MassType>::accFromF(VecDeriv& a, const VecDeriv& f)
00104 {
00105     const MassType& m = mass.getValue();
00106     for (unsigned int i=0;i<f.size();i++)
00107     {
00108       a[i] = f[i] / m;
00109     }
00110 }
00111 
00112 
00113 template <class DataTypes, class MassType>
00114     void UniformMass<DataTypes, MassType>::addMDxToVector(defaulttype::BaseVector * /*resVect*/, const VecDeriv* /*dx*/, SReal /*mFact*/, unsigned int& /*offset*/)
00115 {
00116 
00117 }
00118 
00119 template <class DataTypes, class MassType>
00120 void UniformMass<DataTypes, MassType>::addGravityToV(double dt)
00121 {
00122     if (this->mstate){
00123         VecDeriv& v = *this->mstate->getV();
00124         const SReal* g = this->getContext()->getLocalGravity().ptr();
00125         Deriv theGravity;
00126         DataTypes::set( theGravity, g[0], g[1], g[2]);
00127         Deriv hg = theGravity * (Real)dt;
00128         if (this->f_printLog.getValue())
00129             std::cerr << "UniformMass::addGravityToV hg = "<<theGravity<<"*"<<dt<<"="<<hg<<std::endl;
00130         for (unsigned int i=0;i<v.size();i++)   {
00131             v[i] += hg;
00132         }
00133     }
00134 }
00135 
00136 template <class DataTypes, class MassType>
00137 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00138 void UniformMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00139 #else
00140 void UniformMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& /*x*/, const VecDeriv& /*v*/)
00141 #endif
00142 {
00143     //if gravity was added separately (in solver's "solve" method), then nothing to do here
00144     if(this->m_separateGravity.getValue())
00145         return;
00146 
00147     // weight
00148     const SReal* g = this->getContext()->getLocalGravity().ptr();
00149     Deriv theGravity;
00150     DataTypes::set
00151         ( theGravity, g[0], g[1], g[2]);
00152     const MassType& m = mass.getValue();
00153     Deriv mg = theGravity * m;
00154     if (this->f_printLog.getValue())
00155     cerr<<"UniformMass::addForce, mg = "<<mass<<" * "<<theGravity<<" = "<<mg<<endl;
00156 
00157 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00158     // velocity-based stuff
00159     core::objectmodel::BaseContext::SpatialVector vframe = getContext()->getVelocityInWorld();
00160     core::objectmodel::BaseContext::Vec3 aframe = getContext()->getVelocityBasedLinearAccelerationInWorld() ;
00161 //     cerr<<"UniformMass<DataTypes, MassType>::computeForce(), vFrame in world coordinates = "<<vframe<<endl;
00162      //cerr<<"UniformMass<DataTypes, MassType>::computeForce(), aFrame in world coordinates = "<<aframe<<endl;
00163 //     cerr<<"UniformMass<DataTypes, MassType>::computeForce(), getContext()->getLocalToWorld() = "<<getContext()->getPositionInWorld()<<endl;
00164 
00165     // project back to local frame
00166     vframe = getContext()->getPositionInWorld() / vframe;
00167     aframe = getContext()->getPositionInWorld().backProjectVector( aframe );
00168 //     cerr<<"UniformMass<DataTypes, MassType>::computeForce(), vFrame in local coordinates= "<<vframe<<endl;
00169 //     cerr<<"UniformMass<DataTypes, MassType>::computeForce(), aFrame in local coordinates= "<<aframe<<endl;
00170 //     cerr<<"UniformMass<DataTypes, MassType>::computeForce(), mg in local coordinates= "<<mg<<endl;
00171 #endif
00172 
00173     // add weight and inertia force
00174     for (unsigned int i=0;i<f.size();i++)
00175     {
00176 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00177     f[i] += mg + core::componentmodel::behavior::inertiaForce(vframe,aframe,m,x[i],v[i]);
00178 #else
00179         f[i] += mg;
00180 #endif
00181         //cerr<<"UniformMass<DataTypes, MassType>::computeForce(), vframe = "<<vframe<<", aframe = "<<aframe<<", x = "<<x[i]<<", v = "<<v[i]<<endl;
00182         //cerr<<"UniformMass<DataTypes, MassType>::computeForce() = "<<mg + Core::inertiaForce(vframe,aframe,mass,x[i],v[i])<<endl;
00183     }
00184 
00185 }
00186 
00187 template <class DataTypes, class MassType>
00188     double UniformMass<DataTypes, MassType>::getKineticEnergy( const VecDeriv& v )
00189 {
00190     double e=0;
00191     const MassType& m = mass.getValue();
00192     for (unsigned int i=0;i<v.size();i++)
00193     {
00194       e+= v[i]*m*v[i];
00195     }
00196     //cerr<<"UniformMass<DataTypes, MassType>::getKineticEnergy = "<<e/2<<endl;
00197     return e/2;
00198 }
00199 
00200 template <class DataTypes, class MassType>
00201     double UniformMass<DataTypes, MassType>::getPotentialEnergy( const VecCoord& x )
00202 {
00203     double e = 0;
00204     const MassType& m = mass.getValue();
00205     // gravity
00206     Vec3d g ( this->getContext()->getLocalGravity() );
00207     Deriv theGravity;
00208     DataTypes::set
00209             ( theGravity, g[0], g[1], g[2]);
00210     Deriv mg = theGravity * m;
00211     //cerr<<"UniformMass<DataTypes, MassType>::getPotentialEnergy, theGravity = "<<theGravity<<endl;
00212     for (unsigned int i=0;i<x.size();i++)
00213     {
00214 /*        cerr<<"UniformMass<DataTypes, MassType>::getPotentialEnergy, mass = "<<mass<<endl;
00215         cerr<<"UniformMass<DataTypes, MassType>::getPotentialEnergy, x = "<<x[i]<<endl;
00216         cerr<<"UniformMass<DataTypes, MassType>::getPotentialEnergy, remove "<<theGravity*mass*x[i]<<endl;*/
00217       e -= mg*x[i]; 
00218     }
00219     return e;
00220 }
00221 
00223 template <class DataTypes, class MassType>
00224 void UniformMass<DataTypes, MassType>::addMToMatrix(defaulttype::BaseMatrix * mat, double mFact, unsigned int &offset)
00225 {
00226     const MassType& m = mass.getValue();
00227     const int N = defaulttype::DataTypeInfo<Deriv>::size();
00228     const unsigned int size = this->mstate->getSize();
00229     AddMToMatrixFunctor<Deriv,MassType> calc;
00230     for (unsigned int i=0;i<size;i++)
00231         calc(mat, m, offset + N*i, mFact);
00232 }
00233 
00234 
00235 template <class DataTypes, class MassType>
00236     double UniformMass<DataTypes, MassType>::getElementMass(unsigned int )
00237 {
00238   return (double)(mass.getValue());
00239 }
00240 
00241 
00242 template <class DataTypes, class MassType>
00243 void UniformMass<DataTypes, MassType>::draw()
00244 {
00245     if (!getContext()->getShowBehaviorModels())
00246         return;
00247     const VecCoord& x = *this->mstate->getX();
00248     //cerr<<"UniformMass<DataTypes, MassType>::draw() "<<x<<endl;
00249     Coord gravityCenter;
00250     glDisable (GL_LIGHTING);
00251     glPointSize(2);
00252     glColor4f (1,1,1,1);
00253     glBegin (GL_POINTS);
00254     for (unsigned int i=0; i<x.size(); i++)
00255     {
00256         helper::gl::glVertexT(x[i]);
00257         gravityCenter += x[i];
00258     }
00259     glEnd();
00260 
00261     if(showCenterOfGravity.getValue()){
00262         glBegin (GL_LINES);
00263         glColor4f (1,1,0,1);
00264         gravityCenter /= x.size();
00265         for(unsigned int i=0 ; i<Coord::static_size ; i++){
00266             Coord v;
00267             v[i] = showAxisSize.getValue();
00268             helper::gl::glVertexT(gravityCenter-v);
00269             helper::gl::glVertexT(gravityCenter+v);
00270         }
00271         glEnd();
00272     }
00273 }
00274 
00275 template <class DataTypes, class MassType>
00276     bool UniformMass<DataTypes, MassType>::addBBox(double* minBBox, double* maxBBox)
00277 {
00278     const VecCoord& x = *this->mstate->getX();
00279     for (unsigned int i=0; i<x.size(); i++)
00280     {
00281         //const Coord& p = x[i];
00282         Real p[3] = {0.0, 0.0, 0.0};
00283         DataTypes::get(p[0],p[1],p[2],x[i]);
00284         for (int c=0;c<3;c++)
00285         {
00286             if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00287             if (p[c] < minBBox[c]) minBBox[c] = p[c];
00288         }
00289     }  
00290     return true;
00291 }
00292 
00293 template<class DataTypes, class MassType>
00294 void UniformMass<DataTypes, MassType>::parse(core::objectmodel::BaseObjectDescription* arg)
00295 {
00296   Inherited::parse(arg);
00297   /*
00298   if (arg->getAttribute("mass"))
00299     {
00300       this->setMass((MassType)atof(arg->getAttribute("mass")));
00301     }
00302     if (arg->getAttribute("totalmass"))
00303     {
00304       this->setTotalMass(atof(arg->getAttribute("totalmass")));
00305     }
00306   */
00307 }
00308 
00309 
00310 //Specialization for rigids
00311 #ifndef SOFA_FLOAT
00312 
00313 template<>
00314     void UniformMass<Rigid3dTypes, Rigid3dMass>::parse(core::objectmodel::BaseObjectDescription* arg);
00315 template <>
00316     void UniformMass<Rigid3dTypes, Rigid3dMass>::draw();
00317 template <>
00318     void UniformMass<Rigid2dTypes, Rigid2dMass>::draw();
00319 template <>
00320     double UniformMass<Rigid3dTypes,Rigid3dMass>::getPotentialEnergy( const VecCoord& x );
00321 template <>
00322     double UniformMass<Rigid2dTypes,Rigid2dMass>::getPotentialEnergy( const VecCoord& x );
00323 template <>
00324     void UniformMass<Vec6dTypes,double>::draw();
00325 #endif
00326 #ifndef SOFA_DOUBLE
00327 template<>
00328     void UniformMass<Rigid3fTypes, Rigid3fMass>::parse(core::objectmodel::BaseObjectDescription* arg);
00329 template <>
00330     void UniformMass<Rigid3fTypes, Rigid3fMass>::draw();
00331 template <>
00332     void UniformMass<Rigid2fTypes, Rigid2fMass>::draw();
00333 template <>
00334     double UniformMass<Rigid3fTypes,Rigid3fMass>::getPotentialEnergy( const VecCoord& x );
00335 template <>
00336     double UniformMass<Rigid2fTypes,Rigid2fMass>::getPotentialEnergy( const VecCoord& x );
00337 template <>
00338     void UniformMass<Vec6fTypes,float>::draw();
00339 #endif
00340 
00341 
00342 
00343 } // namespace mass
00344 
00345 } // namespace component
00346 
00347 } // namespace sofa
00348 
00349 #endif
00350 
00351 
00352 

Generated on Sun Nov 23 03:40:18 2008 for Sofa by  doxygen 1.5.7.1