CudaTestForceField.cpp

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 #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; // number of elements attached to each node
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     //computeMaterialStiffness(i,e);
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 } // namespace cuda
00150 
00151 } // namespace gpu
00152 
00153 } // namespace sofa

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