CudaUniformMass.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_GPU_CUDA_CUDAUNIFORMMASS_INL
00026 #define SOFA_GPU_CUDA_CUDAUNIFORMMASS_INL
00027 
00028 #include "CudaUniformMass.h"
00029 #include <sofa/component/mass/UniformMass.inl>
00030 #include <sofa/helper/gl/Axis.h>
00031 
00032 namespace sofa
00033 {
00034 
00035 namespace gpu
00036 {
00037 
00038 namespace cuda
00039 {
00040 
00041 extern "C"
00042 {
00043 void UniformMassCuda3f_addMDx(unsigned int size, float mass, void* res, const void* dx);
00044 void UniformMassCuda3f_accFromF(unsigned int size, float mass, void* a, const void* f);
00045 void UniformMassCuda3f_addForce(unsigned int size, const float *mg, void* f);
00046 
00047 void UniformMassCuda3f1_addMDx(unsigned int size, float mass, void* res, const void* dx);
00048 void UniformMassCuda3f1_accFromF(unsigned int size, float mass, void* a, const void* f);
00049 void UniformMassCuda3f1_addForce(unsigned int size, const float *mg, void* f);
00050 
00051 }
00052 
00053 } // namespace cuda
00054 
00055 } // namespace gpu
00056 
00057 namespace component
00058 {
00059 
00060 namespace mass
00061 {
00062 
00063 using namespace gpu::cuda;
00064 
00065 // -- Mass interface
00066 template <>
00067 void UniformMass<CudaVec3fTypes, float>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00068 {
00069     UniformMassCuda3f_addMDx(dx.size(), (float)(mass.getValue()*factor), res.deviceWrite(), dx.deviceRead());
00070 }
00071 
00072 template <>
00073 void UniformMass<CudaVec3fTypes, float>::accFromF(VecDeriv& a, const VecDeriv& f)
00074 {
00075     UniformMassCuda3f_accFromF(f.size(), mass.getValue(), a.deviceWrite(), f.deviceRead());
00076 }
00077 
00078 template <>
00079 void UniformMass<CudaVec3fTypes, float>::addForce(VecDeriv& f, const VecCoord&, const VecDeriv&)
00080 {
00081     // weight
00082     Vec3d g ( this->getContext()->getLocalGravity() );
00083     Deriv theGravity;
00084     DataTypes::set( theGravity, g[0], g[1], g[2]);
00085     Deriv mg = theGravity * mass.getValue();
00086     UniformMassCuda3f_addForce(f.size(), mg.ptr(), f.deviceWrite());
00087 }
00088 
00089 template <>
00090 bool UniformMass<gpu::cuda::CudaVec3fTypes, float>::addBBox(double* minBBox, double* maxBBox)
00091 {
00092     const VecCoord& x = *this->mstate->getX();
00093     //if (!x.isHostValid()) return false; // Do not recompute bounding box if it requires to transfer data from device
00094     for (unsigned int i=0; i<x.size(); i++)
00095     {
00096         //const Coord& p = x[i];
00097         const Coord& p = x.getCached(i);
00098         for (int c=0;c<3;c++)
00099         {
00100             if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00101             if (p[c] < minBBox[c]) minBBox[c] = p[c];
00102         }
00103     }  
00104     return true;
00105 }
00106 
00107 template <>
00108 void UniformMass<CudaVec3f1Types, float>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00109 {
00110     UniformMassCuda3f1_addMDx(dx.size(), (float)(mass.getValue()*factor), res.deviceWrite(), dx.deviceRead());
00111 }
00112 
00113 template <>
00114 void UniformMass<CudaVec3f1Types, float>::accFromF(VecDeriv& a, const VecDeriv& f)
00115 {
00116     UniformMassCuda3f1_accFromF(f.size(), mass.getValue(), a.deviceWrite(), f.deviceRead());
00117 }
00118 
00119 template <>
00120 void UniformMass<CudaVec3f1Types, float>::addForce(VecDeriv& f, const VecCoord&, const VecDeriv&)
00121 {
00122     // weight
00123     Vec3d g ( this->getContext()->getLocalGravity() );
00124     Deriv theGravity;
00125     DataTypes::set( theGravity, g[0], g[1], g[2]);
00126     Deriv mg = theGravity * mass.getValue();
00127     UniformMassCuda3f1_addForce(f.size(), mg.ptr(), f.deviceWrite());
00128 }
00129 
00130 template <>
00131 bool UniformMass<gpu::cuda::CudaVec3f1Types, float>::addBBox(double* minBBox, double* maxBBox)
00132 {
00133     const VecCoord& x = *this->mstate->getX();
00134     //if (!x.isHostValid()) return false; // Do not recompute bounding box if it requires to transfer data from device
00135     for (unsigned int i=0; i<x.size(); i++)
00136     {
00137         //const Coord& p = x[i];
00138         const Coord& p = x.getCached(i);
00139         for (int c=0;c<3;c++)
00140         {
00141             if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00142             if (p[c] < minBBox[c]) minBBox[c] = p[c];
00143         }
00144     }
00145     return true;
00146 }
00147 
00148 template <>
00149 double UniformMass<gpu::cuda::CudaRigid3fTypes,sofa::defaulttype::Rigid3fMass>::getPotentialEnergy( const VecCoord& x )
00150 {
00151     double e = 0;
00152     // gravity
00153     Vec3d g ( this->getContext()->getLocalGravity() );
00154     for (unsigned int i=0;i<x.size();i++)
00155     {
00156       e += g*mass.getValue().mass*x[i].getCenter();
00157     }
00158     return e;
00159 }
00160 
00161 template <>
00162 double UniformMass<gpu::cuda::CudaRigid3fTypes,sofa::defaulttype::Rigid3fMass>::getElementMass(unsigned int )
00163 {
00164   return (double)(mass.getValue().mass);
00165 }
00166 
00167 template <>
00168 void UniformMass<gpu::cuda::CudaRigid3fTypes, Rigid3fMass>::draw()
00169 {
00170     if (!getContext()->getShowBehaviorModels())
00171         return;
00172     const VecCoord& x = *mstate->getX();
00173     defaulttype::Vec3d len;
00174 
00175     // The moment of inertia of a box is:
00176     //   m->_I(0,0) = M/REAL(12.0) * (ly*ly + lz*lz);
00177     //   m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz);
00178     //   m->_I(2,2) = M/REAL(12.0) * (lx*lx + ly*ly);
00179     // So to get lx,ly,lz back we need to do
00180     //   lx = sqrt(12/M * (m->_I(1,1)+m->_I(2,2)-m->_I(0,0)))
00181     // Note that RigidMass inertiaMatrix is already divided by M
00182     double m00 = mass.getValue().inertiaMatrix[0][0];
00183     double m11 = mass.getValue().inertiaMatrix[1][1];
00184     double m22 = mass.getValue().inertiaMatrix[2][2];
00185     len[0] = sqrt(m11+m22-m00);
00186     len[1] = sqrt(m00+m22-m11);
00187     len[2] = sqrt(m00+m11-m22);
00188 
00189     for (unsigned int i=0; i<x.size(); i++)
00190     {
00191         helper::gl::Axis::draw(x[i].getCenter(), x[i].getOrientation(), len);
00192     }
00193 }
00194 
00195 
00196 
00197 } // namespace mass
00198 
00199 } // namespace component
00200 
00201 } // namespace sofa
00202 
00203 #endif

Generated on Sun Nov 23 04:04:17 2008 for Sofa by  doxygen 1.5.7.1