PairInteractionForceField.inl

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 :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #ifndef SOFA_CORE_COMPONENTMODEL_BEHAVIOR_PAIRINTERACTIONFORCEFIELD_INL
00028 #define SOFA_CORE_COMPONENTMODEL_BEHAVIOR_PAIRINTERACTIONFORCEFIELD_INL
00029 
00030 #include <sofa/core/objectmodel/DataPtr.h>
00031 #include "PairInteractionForceField.h"
00032 #include <sofa/core/objectmodel/BaseContext.h>
00033 #include <sofa/core/objectmodel/BaseNode.h>
00034 #include <iostream>
00035 using std::cerr;
00036 using std::endl;
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace core
00042 {
00043 
00044 namespace componentmodel
00045 {
00046 
00047 namespace behavior
00048 {
00049 
00050 template<class DataTypes>
00051 PairInteractionForceField<DataTypes>::PairInteractionForceField(MechanicalState<DataTypes> *mm1, MechanicalState<DataTypes> *mm2)
00052 : _object1(initData(&_object1, "object1", "First object in interaction")),
00053   _object2(initData(&_object2, "object2", "Second object in interaction")),      
00054   mstate1(mm1), mstate2(mm2)
00055 {  
00056 }
00057 
00058 template<class DataTypes>
00059 PairInteractionForceField<DataTypes>::~PairInteractionForceField()
00060 {
00061 }
00062 
00063 
00064 template<class DataTypes>
00065 BaseMechanicalState*  PairInteractionForceField<DataTypes>::getMState(sofa::core::objectmodel::BaseContext* context, std::string path)
00066 {
00067   std::string::size_type pos_slash = path.find("/");
00068   
00069   sofa::core::objectmodel::BaseNode* currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(context);
00070   if (pos_slash == std::string::npos)
00071   {
00072     if (path.empty()) 
00073     {
00074       BaseMechanicalState *result;
00075       context->get(result, sofa::core::objectmodel::BaseContext::SearchDown);
00076       return result;
00077     }
00078       sofa::helper::vector< sofa::core::objectmodel::BaseNode* > list_child = currentNode->getChildren();
00079     
00080       for (unsigned int i=0;i< list_child.size();++i)
00081       {
00082     if (list_child[i]->getName() == path)
00083     {     
00084       sofa::core::objectmodel::BaseContext *c = list_child[i]->getContext();
00085       BaseMechanicalState *result;
00086       c->get(result, sofa::core::objectmodel::BaseContext::SearchDown);
00087       return result;
00088     }
00089       }
00090   }
00091   else
00092   {
00093     std::string name_expected = path.substr(0,pos_slash); 
00094     path = path.substr(pos_slash+1);
00095     sofa::helper::vector< sofa::core::objectmodel::BaseNode* > list_child = currentNode->getChildren();
00096     
00097     for (unsigned int i=0;i< list_child.size();++i)
00098     {
00099       if (list_child[i]->getName() == name_expected)
00100     return getMState(list_child[i]->getContext(), path);
00101     }    
00102   }
00103   return NULL;
00104 }
00105 
00106 template<class DataTypes>
00107     void PairInteractionForceField<DataTypes>::init()
00108 {
00109   InteractionForceField::init();
00110   if (mstate1 == NULL || mstate2 == NULL)
00111   {
00112     std::string path_object1 = _object1.getValue();
00113     std::string path_object2 = _object2.getValue();
00114   
00115     mstate1 =  dynamic_cast< MechanicalState<DataTypes>* >( getMState(getContext(), path_object1));
00116     mstate2 =  dynamic_cast< MechanicalState<DataTypes>* >( getMState(getContext(), path_object2));
00117     if (mstate1 == NULL || mstate2 == NULL) 
00118     {
00119       std::cerr<< "Init of PairInteractionForceField " << getContext()->getName() << " failed!\n";
00120       getContext()->removeObject(this);
00121       return;
00122     }
00123   }
00124   else
00125   {
00126    //Interaction created by passing Mechanical State directly, need to find the name of the path to be able to save the scene eventually
00127     
00128     
00129     if (mstate1->getContext() != getContext())
00130     {
00131       sofa::core::objectmodel::BaseContext *context = NULL;
00132       sofa::core::objectmodel::BaseNode*    currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(mstate1->getContext());
00133     
00134       std::string object_name=currentNode->getContext()->getName();
00135       currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(currentNode->getParent());
00136       while (currentNode != NULL)
00137       {      
00138     context = currentNode->getContext();
00139     if (context == this->getContext()) break;
00140     object_name = context->getName() + "/" + object_name;      
00141     currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(currentNode->getParent());
00142       }
00143       if (context != NULL) _object1.setValue(object_name);
00144     }
00145     
00146     
00147     if (mstate2->getContext() != getContext())
00148     {
00149       sofa::core::objectmodel::BaseContext *context = NULL;
00150       sofa::core::objectmodel::BaseNode*    currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(mstate2->getContext());
00151     
00152       std::string object_name=currentNode->getContext()->getName();
00153       currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(currentNode->getParent());
00154       while (currentNode != NULL)
00155       {      
00156     context = currentNode->getContext();
00157     if (context == this->getContext()) break;
00158     object_name = context->getName() + "/" + object_name;      
00159     currentNode = dynamic_cast< sofa::core::objectmodel::BaseNode *>(currentNode->getParent());
00160       }
00161       if (context != NULL) _object2.setValue(object_name);
00162     }
00163   }
00164   
00165 }
00166 
00167 template<class DataTypes>
00168 void PairInteractionForceField<DataTypes>::addForce()
00169 {
00170     if (mstate1 && mstate2)
00171         addForce(*mstate1->getF(), *mstate2->getF(),
00172                  *mstate1->getX(), *mstate2->getX(),
00173                  *mstate1->getV(), *mstate2->getV());
00174     else cerr<<"PairInteractionForceField<DataTypes>::addForce(), mstate missing"<<endl;
00175 }
00176 
00177 template<class DataTypes>
00178 void PairInteractionForceField<DataTypes>::addDForce(double kFactor, double bFactor)
00179 {
00180     if (mstate1 && mstate2)
00181         addDForce(*mstate1->getF(),  *mstate2->getF(),
00182                   *mstate1->getDx(), *mstate2->getDx(),
00183                   kFactor, bFactor);
00184 }
00185 
00186 template<class DataTypes>
00187 void PairInteractionForceField<DataTypes>::addDForceV(double kFactor, double bFactor)
00188 {
00189     if (mstate1 && mstate2)
00190         addDForce(*mstate1->getF(),  *mstate2->getF(),
00191                   *mstate1->getV(), *mstate2->getV(),
00192                   kFactor, bFactor);
00193 }
00194 
00195 template<class DataTypes>
00196 void PairInteractionForceField<DataTypes>::addDForce(VecDeriv& /*df1*/, VecDeriv& /*df2*/, const VecDeriv& /*dx1*/, const VecDeriv& /*dx2*/)
00197 {
00198     std::cerr << "ERROR("<<getClassName()<<"): addDForce not implemented.\n";
00199 }
00200 
00201 template<class DataTypes>
00202 void PairInteractionForceField<DataTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double /*bFactor*/)
00203 {
00204     if (kFactor == 1.0)
00205         addDForce(df1, df2, dx1, dx2);
00206     else if (kFactor != 0.0)
00207     {
00208     BaseMechanicalState::VecId vtmp1(BaseMechanicalState::VecId::V_DERIV,BaseMechanicalState::VecId::V_FIRST_DYNAMIC_INDEX);
00209     mstate1->vAvail(vtmp1);
00210     mstate1->vAlloc(vtmp1);
00211     BaseMechanicalState::VecId vdx1(BaseMechanicalState::VecId::V_DERIV,0);
00213     for (vdx1.index=0;vdx1.index<vtmp1.index;++vdx1.index)
00214         if (mstate1->getVecDeriv(vdx1.index) == &dx1)
00215         break;
00216     VecDeriv& dx1scaled = *mstate1->getVecDeriv(vtmp1.index);
00217     dx1scaled.resize(dx1.size());
00218     mstate1->vOp(vtmp1,BaseMechanicalState::VecId::null(),vdx1,kFactor);
00219     //std::cout << "dx1 = "<<dx1<<std::endl;
00220     //std::cout << "dx1*"<<kFactor<<" = "<<dx1scaled<<std::endl;
00221     BaseMechanicalState::VecId vtmp2(BaseMechanicalState::VecId::V_DERIV,BaseMechanicalState::VecId::V_FIRST_DYNAMIC_INDEX);
00222     mstate2->vAvail(vtmp2);
00223     mstate2->vAlloc(vtmp2);
00224     BaseMechanicalState::VecId vdx2(BaseMechanicalState::VecId::V_DERIV,0);
00226     for (vdx2.index=0;vdx2.index<vtmp2.index;++vdx2.index)
00227         if (mstate2->getVecDeriv(vdx2.index) == &dx2)
00228         break;
00229     VecDeriv& dx2scaled = *mstate2->getVecDeriv(vtmp2.index);
00230     dx2scaled.resize(dx2.size());
00231     mstate2->vOp(vtmp2,BaseMechanicalState::VecId::null(),vdx2,kFactor);
00232     //std::cout << "dx2 = "<<dx2<<std::endl;
00233     //std::cout << "dx2*"<<kFactor<<" = "<<dx2scaled<<std::endl;
00234 
00235         addDForce(df1, df2, dx1scaled, dx2scaled);
00236 
00237     mstate1->vFree(vtmp1);
00238     mstate2->vFree(vtmp2);
00239     }
00240 }
00241 
00242 template<class DataTypes>
00243 double PairInteractionForceField<DataTypes>::getPotentialEnergy()
00244 {
00245     if (mstate1 && mstate2)
00246         return getPotentialEnergy(*mstate1->getX(), *mstate2->getX());
00247     else return 0;
00248 }
00249 
00250 } // namespace behavior
00251 
00252 } // namespace componentmodel
00253 
00254 } // namespace core
00255 
00256 } // namespace sofa
00257 
00258 #endif

Generated on Sun Nov 23 02:29:22 2008 for Sofa by  doxygen 1.5.7.1