CudaTetrahedronFEMForceField.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_CUDATETRAHEDRONFEMFORCEFIELD_H
00026 #define SOFA_GPU_CUDA_CUDATETRAHEDRONFEMFORCEFIELD_H
00027 
00028 #include "CudaTypes.h"
00029 #include <sofa/component/forcefield/TetrahedronFEMForceField.h>
00030 
00031 
00032 namespace sofa
00033 {
00034 
00035 namespace gpu
00036 {
00037 
00038 namespace cuda
00039 {
00040 
00041 template<class DataTypes>
00042 class CudaKernelsTetrahedronFEMForceField;
00043 
00044 } // namespace cuda
00045 
00046 } // namespace gpu
00047 
00048 
00049 namespace component
00050 {
00051 
00052 namespace forcefield
00053 {
00054 
00055 using namespace sofa::defaulttype;
00056 
00057 template <class TCoord, class TDeriv, class TReal>
00058 class TetrahedronFEMForceFieldInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >
00059 {
00060 public:
00061     typedef gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> DataTypes;
00062     typedef TetrahedronFEMForceField<DataTypes> Main;
00063     typedef TetrahedronFEMForceFieldInternalData<DataTypes> Data;
00064     typedef typename DataTypes::VecCoord VecCoord;
00065     typedef typename DataTypes::VecDeriv VecDeriv;
00066     typedef typename DataTypes::Coord Coord;
00067     typedef typename DataTypes::Deriv Deriv;
00068     typedef typename DataTypes::Real Real;
00069 
00070     typedef typename Main::Element Element;
00071     typedef typename Main::VecElement VecElement;
00072     typedef typename Main::Index Index;
00073     typedef Mat<6, 6, Real> MaterialStiffness;
00074     typedef Mat<12, 6, Real> StrainDisplacement;
00075 
00076     typedef gpu::cuda::CudaKernelsTetrahedronFEMForceField<DataTypes> Kernels;
00077 
00155     struct GPUElement
00156     {
00159         //Vec<4,int> tetra;
00160         int ia[BSIZE],ib[BSIZE],ic[BSIZE],id[BSIZE];
00162 
00165         //Mat<6,6,Real> K;
00166         Real gamma_bx2[BSIZE], mu2_bx2[BSIZE];
00168 
00171         //Vec3f initpos[4];
00172         Real bx[BSIZE],cx[BSIZE];
00173         Real cy[BSIZE],dx[BSIZE],dy[BSIZE],dz[BSIZE];
00175 
00178         //Mat<12,6,Real> J;
00179         Real Jbx_bx[BSIZE],Jby_bx[BSIZE],Jbz_bx[BSIZE];
00181     };
00182 
00183     gpu::cuda::CudaVector<GPUElement> elems;
00184 
00186     struct GPUElementState
00187     {
00189         Mat<3,3,Real> Rt;
00191         Vec<6,Real> S;
00193         Real dummy;
00194     };
00195 
00197     struct GPUElementForce
00198     {
00199         Vec<4,Real> fA,fB,fC,fD;
00200     };
00201 
00202     gpu::cuda::CudaVector<GPUElementState> state;
00203     gpu::cuda::CudaVector<GPUElementForce> eforce;
00204     int nbElement; 
00205     int vertex0; 
00206     int nbVertex; 
00207     int nbElementPerVertex; 
00208 
00209 
00210     gpu::cuda::CudaVector<int> velems;
00211     TetrahedronFEMForceFieldInternalData() : nbElement(0), vertex0(0), nbVertex(0), nbElementPerVertex(0) {}
00212     void init(int nbe, int v0, int nbv, int nbelemperv)
00213     {
00214         elems.clear();
00215         state.clear();
00216         eforce.clear();
00217         velems.clear();
00218         nbElement = nbe;
00219         elems.resize((nbe+BSIZE-1)/BSIZE);
00220         state.resize(nbe);
00221         eforce.resize(nbe);
00222         vertex0 = v0;
00223         nbVertex = nbv;
00224         nbElementPerVertex = nbelemperv;
00225         int nbloc = (nbVertex+BSIZE-1)/BSIZE;
00226         velems.resize(nbloc*nbElementPerVertex*BSIZE);
00227         for (unsigned int i=0;i<velems.size();i++)
00228             velems[i] = 0;
00229     }
00230     int size() const { return nbElement; }
00231     void setV(int vertex, int num, int index)
00232     {
00233         vertex -= vertex0;
00234         int bloc = vertex/BSIZE;
00235         int b_x  = vertex%BSIZE;
00236         velems[ bloc*BSIZE*nbElementPerVertex // start of the bloc
00237               + num*BSIZE                     // offset to the element
00238               + b_x                           // offset to the vertex
00239               ] = index+1;
00240     }
00241 
00242     void setE(int i, const Element& indices, const Coord& /*a*/, const Coord& b, const Coord& c, const Coord& d, const MaterialStiffness& K, const StrainDisplacement& /*J*/)
00243     {
00244         /*std::cout << "CPU Info:\n a = "<<a<<"\n b = "<<b<<"\n c = "<<c<<"\n d = "<<d<<"\n K = "
00245             <<K[0]<<"\n     "<<K[1]<<"\n     "<<K[2]<<"\n     "
00246             <<K[3]<<"\n     "<<K[4]<<"\n     "<<K[5]<<"\n J="
00247             <<J[0]<<"\n     "<<J[1]<<"\n     "<<J[2]<<"\n     "
00248             <<J[3]<<"\n     "<<J[4]<<"\n     "<<J[5]<<"\n     "
00249             <<J[6]<<"\n     "<<J[7]<<"\n     "<<J[8]<<"\n     "
00250             <<J[9]<<"\n     "<<J[10]<<"\n     "<<J[11]<<std::endl;*/
00251         GPUElement& e = elems[i/BSIZE]; i = i%BSIZE;
00252         e.ia[i] = indices[0] - vertex0;
00253         e.ib[i] = indices[1] - vertex0;
00254         e.ic[i] = indices[2] - vertex0;
00255         e.id[i] = indices[3] - vertex0;
00256         e.bx[i] = b[0];
00257         e.cx[i] = c[0]; e.cy[i] = c[1];
00258         e.dx[i] = d[0]; e.dy[i] = d[1]; e.dz[i] = d[2];
00259         Real bx2 = e.bx[i] * e.bx[i];
00260         e.gamma_bx2[i] = K[0][1] * bx2;
00261         e.mu2_bx2[i] = 2*K[3][3] * bx2;
00262         e.Jbx_bx[i] = (e.cy[i] * e.dz[i]) / e.bx[i];
00263         e.Jby_bx[i] = (-e.cx[i] * e.dz[i]) / e.bx[i];
00264         e.Jbz_bx[i] = (e.cx[i]*e.dy[i] - e.cy[i]*e.dx[i]) / e.bx[i];
00265         //e.dummy[i] = 0;
00266         /*std::cout << "GPU Info:\n b = "<<e.bx<<"\n c = "<<e.cx<<" "<<e.cy<<"\n d = "<<e.dx<<" "<<e.dy<<" "<<e.dz<<"\n K = "
00267             <<(e.gamma_bx2+e.mu2_bx2)/bx2<<" "<<(e.gamma_bx2)/bx2<<" "<<(e.gamma_bx2)/bx2<<" 0 0 0\n     "
00268             <<(e.gamma_bx2)/bx2<<" "<<(e.gamma_bx2+e.mu2_bx2)/bx2<<" "<<(e.gamma_bx2)/bx2<<" 0 0 0\n     "
00269             <<(e.gamma_bx2)/bx2<<" "<<(e.gamma_bx2)/bx2<<" "<<(e.gamma_bx2+e.mu2_bx2)/bx2<<" 0 0 0\n     "
00270 
00271             <<"0 0 0 "<<(e.mu2_bx2/2)/bx2<<" 0 0\n     "
00272             <<"0 0 0 0 "<<(e.mu2_bx2/2)/bx2<<" 0\n     "
00273             <<"0 0 0 0 0 "<<(e.mu2_bx2/2)/bx2<<"\n J = "
00274 
00275             <<(-e.Jbx_bx)*e.bx<<" 0 0 "<<(-e.Jby_bx-e.dz)*e.bx<<" 0 "<<(-e.Jbz_bx+e.dy-e.cy)*e.bx<<"\n     "
00276             <<"0 "<<(-e.Jby_bx-e.dz)*e.bx<<" 0 "<<(-e.Jbx_bx)*e.bx<<" "<<(-e.Jbz_bx+e.dy-e.cy)*e.bx<<" 0\n     "
00277             <<"0 0 "<<(-e.Jbz_bx+e.dy-e.cy)*e.bx<<" 0 "<<(-e.Jby_bx-e.dz)*e.bx<<" "<<(-e.Jbx_bx)*e.bx<<"\n     "
00278 
00279             <<(e.Jbx_bx)*e.bx<<" 0 0 "<<(e.Jby_bx)*e.bx<<" 0 "<<(e.Jbz_bx)*e.bx<<"\n     "
00280             <<"0 "<<(e.Jby_bx)*e.bx<<" 0 "<<(e.Jbx_bx)*e.bx<<" "<<(e.Jbz_bx)*e.bx<<" 0\n     "
00281             <<"0 0 "<<(e.Jbz_bx)*e.bx<<" 0 "<<(e.Jby_bx)*e.bx<<" "<<(e.Jbx_bx)*e.bx<<"\n     "
00282             
00283             <<(0)*e.bx<<" 0 0 "<<(e.dz)*e.bx<<" 0 "<<(-e.dy)*e.bx<<"\n     "
00284             <<"0 "<<(e.dz)*e.bx<<" 0 "<<(0)*e.bx<<" "<<(-e.dy)*e.bx<<" 0\n     "
00285             <<"0 0 "<<(-e.dy)*e.bx<<" 0 "<<(e.dz)*e.bx<<" "<<(0)*e.bx<<"\n     "
00286 
00287             <<(0)*e.bx<<" 0 0 "<<(0)*e.bx<<" 0 "<<(e.cy)*e.bx<<"\n     "
00288             <<"0 "<<(0)*e.bx<<" 0 "<<(0)*e.bx<<" "<<(e.cy)*e.bx<<" 0\n     "
00289             <<"0 0 "<<(e.cy)*e.bx<<" 0 "<<(0)*e.bx<<" "<<(0)*e.bx<<std::endl;*/
00290     }
00291 
00292     static void reinit(Main* m);
00293     static void addForce(Main* m, VecDeriv& f, const VecCoord& x, const VecDeriv& /*v*/);
00294     static void addDForce (Main* m, VecDeriv& df, const VecDeriv& dx, double kFactor, double bFactor);
00295 };
00296 
00297 //
00298 // TetrahedronFEMForceField
00299 //
00300 
00301 // I know using macros is bad design but this is the only way not to repeat the code for all CUDA types
00302 #define CudaTetrahedronFEMForceField_DeclMethods(T) \
00303     template<> void TetrahedronFEMForceField< T >::reinit(); \
00304     template<> void TetrahedronFEMForceField< T >::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v); \
00305     template<> void TetrahedronFEMForceField< T >::addDForce(VecDeriv& df, const VecDeriv& dx, double kFactor, double bFactor);
00306 
00307 CudaTetrahedronFEMForceField_DeclMethods(gpu::cuda::CudaVec3fTypes);
00308 CudaTetrahedronFEMForceField_DeclMethods(gpu::cuda::CudaVec3f1Types);
00309 
00310 
00311 #undef CudaTetrahedronFEMForceField_DeclMethods
00312 
00313 } // namespace forcefield
00314 
00315 } // namespace component
00316 
00317 } // namespace sofa
00318 
00319 #endif

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