00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
00045
00046 }
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
00160 int ia[BSIZE],ib[BSIZE],ic[BSIZE],id[BSIZE];
00162
00165
00166 Real gamma_bx2[BSIZE], mu2_bx2[BSIZE];
00168
00171
00172 Real bx[BSIZE],cx[BSIZE];
00173 Real cy[BSIZE],dx[BSIZE],dy[BSIZE],dz[BSIZE];
00175
00178
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
00237 + num*BSIZE
00238 + b_x
00239 ] = index+1;
00240 }
00241
00242 void setE(int i, const Element& indices, const Coord& , const Coord& b, const Coord& c, const Coord& d, const MaterialStiffness& K, const StrainDisplacement& )
00243 {
00244
00245
00246
00247
00248
00249
00250
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
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 }
00291
00292 static void reinit(Main* m);
00293 static void addForce(Main* m, VecDeriv& f, const VecCoord& x, const VecDeriv& );
00294 static void addDForce (Main* m, VecDeriv& df, const VecDeriv& dx, double kFactor, double bFactor);
00295 };
00296
00297
00298
00299
00300
00301
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 }
00314
00315 }
00316
00317 }
00318
00319 #endif