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 #include "CudaTestForceField.h"
00026 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00027 #include <sofa/core/ObjectFactory.h>
00028
00029 namespace sofa
00030 {
00031
00032 namespace gpu
00033 {
00034
00035 namespace cuda
00036 {
00037
00038 SOFA_DECL_CLASS(CudaTestForceField)
00039
00040 int CudaTestForceFieldCudaClass = core::RegisterObject("GPU-side test forcefield using CUDA")
00041 .add< CudaTestForceField >()
00042 ;
00043
00044 extern "C"
00045 {
00046 void CudaTestForceField3f_addForce(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* elems, void* state, const void* velems, void* f, const void* x, const void* v);
00047 void CudaTestForceField3f_addDForce(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* elems, void* state, const void* velems, void* df, const void* dx);
00048 }
00049
00050 CudaTestForceField::CudaTestForceField()
00051 : nbVertex(0), nbElementPerVertex(0)
00052 {
00053 }
00054
00055 void CudaTestForceField::init()
00056 {
00057 core::componentmodel::behavior::ForceField<CudaVec3fTypes>::init();
00058 reinit();
00059 }
00060
00061 void CudaTestForceField::reinit()
00062 {
00063 sofa::core::componentmodel::topology::BaseMeshTopology* topology = getContext()->get<sofa::core::componentmodel::topology::BaseMeshTopology>();
00064 #ifdef SOFA_NEW_HEXA
00065 if (topology==NULL || topology->getNbHexas()==0)
00066 #else
00067 if (topology==NULL || topology->getNbCubes()==0)
00068 #endif
00069 {
00070 std::cerr << "ERROR(CudaTestForceField): no elements found.\n";
00071 return;
00072 }
00073 #ifdef SOFA_NEW_HEXA
00074 const VecElement& inputElems = topology->getHexas();
00075 #else
00076 const VecElement& inputElems = topology->getCubes();
00077 #endif
00078 std::map<int,int> nelems;
00079 for (unsigned int i=0;i<inputElems.size();i++)
00080 {
00081 const Element& e = inputElems[i];
00082 for (unsigned int j=0;j<e.size();j++)
00083 ++nelems[e[j]];
00084 }
00085 int nmax = 0;
00086 for (std::map<int,int>::const_iterator it = nelems.begin(); it != nelems.end(); ++it)
00087 if (it->second > nmax)
00088 nmax = it->second;
00089 int nbv = 0;
00090 if (!nelems.empty())
00091 {
00092 nbv = nelems.rbegin()->first + 1;
00093 }
00094 std::cout << "CudaTestForceField: "<<inputElems.size()<<" elements, "<<nbv<<" nodes, max "<<nmax<<" elements per node."<<std::endl;
00095 init(inputElems.size(), nbv, nmax);
00096 std::cout << "CudaTestForceField: precomputations..."<<std::endl;
00097 const VecCoord&x = *this->mstate->getX();
00098 nelems.clear();
00099 for (unsigned int i=0;i<inputElems.size();i++)
00100 {
00101 const Element& e = inputElems[i];
00102
00103 Coord center;
00104 center = x[e[0]];
00105 for (unsigned int j=1;j<e.size();++j)
00106 center += x[e[1]];
00107 center /= e.size();
00108 float r = 0;
00109 for (unsigned int j=0;j<e.size();++j)
00110 r += (x[e[j]]-center).norm();
00111 r /= e.size();
00112 std::cout << "E["<<i<<"]: center="<<center<<" r="<<r<<std::endl;
00113 setE(i, e, 1, r, 10, 10);
00114 for (unsigned int j=0;j<e.size();j++)
00115 setV(e[j], nelems[e[j]]++, i*e.size()+j);
00116 }
00117 std::cout << "CudaTestForceField::reinit() DONE."<<std::endl;
00118 }
00119
00120 void CudaTestForceField::addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00121 {
00122 f.resize(x.size());
00123 CudaTestForceField3f_addForce(
00124 elems.size(),
00125 nbVertex,
00126 nbElementPerVertex,
00127 elems.deviceRead(),
00128 state.deviceWrite(),
00129 velems.deviceRead(),
00130 f.deviceWrite(),
00131 x.deviceRead(),
00132 v.deviceRead());
00133 }
00134
00135 void CudaTestForceField::addDForce (VecDeriv& df, const VecDeriv& dx)
00136 {
00137 df.resize(dx.size());
00138 CudaTestForceField3f_addDForce(
00139 elems.size(),
00140 nbVertex,
00141 nbElementPerVertex,
00142 elems.deviceRead(),
00143 state.deviceWrite(),
00144 velems.deviceRead(),
00145 df.deviceWrite(),
00146 dx.deviceRead());
00147 }
00148
00149 }
00150
00151 }
00152
00153 }