CudaSpringForceField.h

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_CUDASPRINGFORCEFIELD_H
00026 #define SOFA_GPU_CUDA_CUDASPRINGFORCEFIELD_H
00027 
00028 #include "CudaTypes.h"
00029 #include <sofa/component/forcefield/SpringForceField.h>
00030 #include <sofa/component/forcefield/StiffSpringForceField.h>
00031 #include <sofa/component/forcefield/MeshSpringForceField.h>
00032 
00033 
00034 namespace sofa
00035 {
00036 
00037 namespace gpu
00038 {
00039 
00040 namespace cuda
00041 {
00042 
00043 template<class DataTypes>
00044 class CudaKernelsSpringForceField;
00045 
00046 } // namespace cuda
00047 
00048 } // namespace gpu
00049 
00050 namespace component
00051 {
00052 
00053 namespace forcefield
00054 {
00055 
00056 template <class TCoord, class TDeriv, class TReal>
00057 class SpringForceFieldInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >
00058 {
00059 public:
00060     typedef gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> DataTypes;
00061     typedef SpringForceField<DataTypes> Main;
00062     typedef typename Main::Inherit Inherit;
00063     typedef typename Main::Spring Spring;
00064     typedef SpringForceFieldInternalData<DataTypes> Data;
00065     typedef typename DataTypes::VecCoord VecCoord;
00066     typedef typename DataTypes::VecDeriv VecDeriv;
00067     typedef typename DataTypes::Coord Coord;
00068     typedef typename DataTypes::Deriv Deriv;
00069     typedef typename DataTypes::Real Real;
00070 
00071     typedef gpu::cuda::CudaKernelsSpringForceField<DataTypes> Kernels;
00072 
00073     //enum { BSIZE=16 };
00074     struct GPUSpring
00075     {
00076         int index; 
00077         //float initpos;
00078         float ks;
00079         //float kd;
00080         GPUSpring() : index(0), /*initpos(0),*/ ks(0)/*, kd(0)*/ {}
00081         void set(int index, float /*initpos*/, float ks, float /*kd*/)
00082         {
00083             this->index = index+1;
00084             //this->initpos = initpos;
00085             this->ks = ks;
00086             //this->kd = kd;
00087         }
00088     };
00089     struct GPUSpring2
00090     {
00091         //int index; ///< 0 if no spring
00092         float initpos;
00093         //float ks;
00094         float kd;
00095         GPUSpring2() : /*index(0),*/ initpos(0), /*ks(0),*/ kd(0) {}
00096         void set(int /*index*/, float initpos, float /*ks*/, float kd)
00097         {
00098             //this->index = index+1;
00099             this->initpos = initpos;
00100             //this->ks = ks;
00101             this->kd = kd;
00102         }
00103     };
00104     struct GPUSpringSet
00105     {
00106         int vertex0; 
00107         int nbVertex; 
00108         int nbSpringPerVertex; 
00109         gpu::cuda::CudaVector<GPUSpring> springs; 
00110         gpu::cuda::CudaVector<Real> dfdx; 
00111         GPUSpringSet() : vertex0(0), nbVertex(0), nbSpringPerVertex(0) {}
00112         void init(int v0, int nbv, int nbsperv)
00113         {
00114             vertex0 = v0;
00115             nbVertex = nbv;
00116             nbSpringPerVertex = nbsperv;
00117             int nbloc = (nbVertex+BSIZE-1)/BSIZE;
00118             springs.resize(2*nbloc*nbSpringPerVertex*BSIZE);
00119         }
00120         void set(int vertex, int spring, int index, float initpos, float ks, float kd)
00121         {
00122             int bloc = vertex/BSIZE;
00123             int b_x  = vertex%BSIZE;
00124             springs[ 2*bloc*BSIZE*nbSpringPerVertex // start of the bloc
00125                    + 2*spring*BSIZE                 // offset to the spring
00126                    + b_x                          // offset to the vertex
00127                    ].set(index, initpos, ks, kd);
00128                         (*(GPUSpring2*)&(springs[ 2*bloc*BSIZE*nbSpringPerVertex // start of the bloc
00129                                 + 2*spring*BSIZE                 // offset to the spring
00130                                 + b_x+BSIZE                    // offset to the vertex
00131                                ])).set(index, initpos, ks, kd);
00132                 }
00133     };
00134     GPUSpringSet springs1; 
00135     GPUSpringSet springs2; 
00136 
00137     static void init(Main* m, bool stiff);
00138     static void addForce(Main* m, bool stiff, VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2);
00139     static void addDForce (Main* m, bool stiff, VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double bFactor);
00140 };
00141 
00142 //
00143 // SpringForceField
00144 //
00145 
00146 // I know using macros is bad design but this is the only way not to repeat the code for all CUDA types
00147 #define CudaSpringForceField_DeclMethods(T) \
00148     template<> void SpringForceField< T >::init(); \
00149     template<> void SpringForceField< T >::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2); \
00150     template<> void StiffSpringForceField< T >::init(); \
00151     template<> void StiffSpringForceField< T >::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2); \
00152     template<> void StiffSpringForceField< T >::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double bFactor);
00153 
00154 CudaSpringForceField_DeclMethods(gpu::cuda::CudaVec3fTypes);
00155 CudaSpringForceField_DeclMethods(gpu::cuda::CudaVec3f1Types);
00156 
00157 
00158 #undef CudaSpringForceField_DeclMethods
00159 
00160 } // namespace forcefield
00161 
00162 } // namespace component
00163 
00164 } // namespace sofa
00165 
00166 #endif

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