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
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
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& , VecDeriv& , const VecDeriv& , const VecDeriv& )
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 )
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
00220
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
00233
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 }
00251
00252 }
00253
00254 }
00255
00256 }
00257
00258 #endif