UncoupledConstraintCorrection.inl
Go to the documentation of this file.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_COMPONENT_CONSTRAINT_UNCOUPLEDCONSTRAINTCORRECTION_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_UNCOUPLEDCONSTRAINTCORRECTION_INL
00027
00028 #include "UncoupledConstraintCorrection.h"
00029 #include <sofa/defaulttype/RigidTypes.h>
00030 #include <sofa/simulation/tree/GNode.h>
00031 #include <sofa/component/mass/UniformMass.h>
00032 #include <sofa/simulation/common/MechanicalVisitor.h>
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace constraint
00041 {
00042
00043 template<class DataTypes>
00044 UncoupledConstraintCorrection<DataTypes>::UncoupledConstraintCorrection(behavior::MechanicalState<DataTypes> *mm)
00045 : mstate(mm)
00046 {
00047 }
00048
00049 template<class DataTypes>
00050 UncoupledConstraintCorrection<DataTypes>::~UncoupledConstraintCorrection()
00051 {
00052 }
00053
00054 template<class DataTypes>
00055 void UncoupledConstraintCorrection<DataTypes>::init()
00056 {
00057 mstate = dynamic_cast< behavior::MechanicalState<DataTypes>* >(getContext()->getMechanicalState());
00058 }
00059
00060 #ifndef SOFA_FLOAT
00061 template<>
00062 void UncoupledConstraintCorrection<defaulttype::Rigid3Types>::getCompliance(defaulttype::BaseMatrix*W)
00063 {
00064 const VecConst& constraints = *mstate->getC();
00065 Deriv weighedNormal;
00066 Deriv InvM_wN;
00067
00068 const sofa::defaulttype::Rigid3Mass* massValue;
00069
00070 simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00071
00072 if (node != NULL)
00073 {
00074 core::componentmodel::behavior::BaseMass*_m = node->mass;
00075 component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass>*> (_m);
00076 massValue = &( m->getMass());
00077 }
00078 else
00079 {
00080 massValue = new sofa::defaulttype::Rigid3Mass();
00081 printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00082 }
00083
00084 unsigned int numConstraints = constraints.size();
00085
00086 double dt = this->getContext()->getDt();
00087
00088 for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00089 {
00090 int sizeCurRowConst = constraints[curRowConst].size();
00091 int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00092
00093 for(int i = 0; i < sizeCurRowConst; i++)
00094 {
00095 weighedNormal.getVCenter() = constraints[curRowConst][i].data.getVCenter();
00096 weighedNormal.getVOrientation() = constraints[curRowConst][i].data.getVOrientation();
00097
00098 InvM_wN = weighedNormal / (*massValue);
00099 InvM_wN *= dt*dt;
00100
00101 int indexCurColConst;
00102
00103 for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00104 {
00105 int sizeCurColConst = constraints[curColConst].size();
00106 indexCurColConst = mstate->getConstraintId()[curColConst];
00107
00108 for(int j = 0; j < sizeCurColConst; j++)
00109 {
00110
00111 double w = constraints[curColConst][j].data * InvM_wN;
00112 W->add(indexCurRowConst, indexCurColConst, w);
00113 if (indexCurRowConst != indexCurColConst)
00114 W->add(indexCurColConst, indexCurRowConst, w);
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 }
00125 }
00126 }
00127
00128 template<>
00129 void UncoupledConstraintCorrection<defaulttype::Rigid3Types>::applyContactForce(const defaulttype::BaseVector *f)
00130 {
00131 VecDeriv& force = *mstate->getExternalForces();
00132 const VecConst& constraints = *mstate->getC();
00133 Deriv weighedNormal;
00134
00135 const sofa::defaulttype::Rigid3Mass* massValue;
00136
00137 simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00138
00139 if (node != NULL)
00140 {
00141 core::componentmodel::behavior::BaseMass*_m = node->mass;
00142 component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3Types, defaulttype::Rigid3Mass>*> (_m);
00143 massValue = &( m->getMass());
00144 }
00145 else
00146 {
00147 massValue = new sofa::defaulttype::Rigid3Mass();
00148 printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00149 }
00150
00151
00152 double dt = this->getContext()->getDt();
00153
00154 force.resize(0);
00155 force.resize(1);
00156 force[0] = Deriv();
00157
00158 int numConstraints = constraints.size();
00159
00160 for(int c1 = 0; c1 < numConstraints; c1++)
00161 {
00162 int indexC1 = mstate->getConstraintId()[c1];
00163 double fC1 = f->element(indexC1);
00164
00165 if (fC1 != 0.0)
00166 {
00167 int sizeC1 = constraints[c1].size();
00168 for(int i = 0; i < sizeC1; i++)
00169 {
00170 weighedNormal = constraints[c1][i].data;
00171 force[0].getVCenter() += weighedNormal.getVCenter() * fC1;
00172 force[0].getVOrientation() += weighedNormal.getVOrientation() * fC1;
00173 }
00174 }
00175 }
00176
00177
00178 VecDeriv& dx = *mstate->getDx();
00179 VecCoord& x = *mstate->getX();
00180 VecDeriv& v = *mstate->getV();
00181 VecDeriv& v_free = *mstate->getVfree();
00182 VecCoord& x_free = *mstate->getXfree();
00183
00184
00185
00186
00187 x[0]=x_free[0];
00188 v[0]=v_free[0];
00189
00190
00191 dx.resize(v.size());
00192 dx[0] = force[0] / (*massValue);
00193 dx[0] *= dt;
00194 v[0] += dx[0];
00195 dx[0] *= dt;
00196 x[0] += dx[0];
00197
00198
00199 }
00200
00201 template<>
00202 void UncoupledConstraintCorrection<defaulttype::Vec1dTypes>::getCompliance(defaulttype::BaseMatrix *W)
00203 {
00204 const VecConst& constraints = *mstate->getC();
00205 unsigned int numConstraints = constraints.size();
00206
00207 for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00208 {
00209 int sizeCurRowConst = constraints[curRowConst].size();
00210 int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00211
00212 for(int i = 0; i < sizeCurRowConst; i++)
00213 {
00214 int indexCurColConst;
00215
00216 for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00217 {
00218 int sizeCurColConst = constraints[curColConst].size();
00219 indexCurColConst = mstate->getConstraintId()[curColConst];
00220
00221 for(int j = 0; j < sizeCurColConst; j++)
00222 {
00223 if (constraints[curRowConst][i].index == constraints[curColConst][j].index)
00224 {
00225
00226 double w = (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00227 W->add(indexCurRowConst, indexCurColConst, w);
00228 if (indexCurRowConst != indexCurColConst)
00229 W->add(indexCurColConst, indexCurRowConst, w);
00230 }
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 }
00258
00259 template<>
00260 void UncoupledConstraintCorrection<defaulttype::Vec1dTypes>::applyContactForce(const defaulttype::BaseVector *f){
00261
00262 VecDeriv& force = *mstate->getExternalForces();
00263 const VecConst& constraints = *mstate->getC();
00264 unsigned int numConstraints = constraints.size();
00265
00266 force.resize((*mstate->getX()).size());
00267
00268 for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00269 {
00270 int indexC1 = mstate->getConstraintId()[c1];
00271 double fC1 = f->element(indexC1);
00272 if (fC1 != 0.0)
00273 {
00274 int sizeC1 = constraints[c1].size();
00275 for(int i = 0; i < sizeC1; i++)
00276 {
00277 force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00278 }
00279 }
00280 }
00281
00282 VecDeriv& dx = *mstate->getDx();
00283 VecCoord& x = *mstate->getX();
00284 VecDeriv& v = *mstate->getV();
00285 VecDeriv& v_free = *mstate->getVfree();
00286 VecCoord& x_free = *mstate->getXfree();
00287 double dt = this->getContext()->getDt();
00288
00289
00290
00291 dx.resize(v.size());
00292
00293 for (unsigned int i=0; i<dx.size(); i++)
00294 {
00295 x[i] = x_free[i];
00296 v[i] = v_free[i];
00297 dx[i] = force[i]/10000.0;
00298 x[i] += dx[i];
00299 v[i] += dx[i]/dt;
00300 }
00301 }
00302
00303 #endif
00304 #ifndef SOFA_DOUBLE
00305 template<>
00306 void UncoupledConstraintCorrection<defaulttype::Rigid3fTypes>::getCompliance(defaulttype::BaseMatrix*W)
00307 {
00308 const VecConst& constraints = *mstate->getC();
00309 Deriv weighedNormal;
00310 Deriv InvM_wN;
00311
00312 const sofa::defaulttype::Rigid3fMass* massValue;
00313
00314 simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00315
00316 if (node != NULL)
00317 {
00318 core::componentmodel::behavior::BaseMass*_m = node->mass;
00319 component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass>*> (_m);
00320 massValue = &( m->getMass());
00321 }
00322 else
00323 {
00324 massValue = new sofa::defaulttype::Rigid3fMass();
00325 printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00326 }
00327
00328 unsigned int numConstraints = constraints.size();
00329
00330 double dt = this->getContext()->getDt();
00331
00332 for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00333 {
00334 int sizeCurRowConst = constraints[curRowConst].size();
00335 int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00336
00337 for(int i = 0; i < sizeCurRowConst; i++)
00338 {
00339 weighedNormal.getVCenter() = constraints[curRowConst][i].data.getVCenter();
00340 weighedNormal.getVOrientation() = constraints[curRowConst][i].data.getVOrientation();
00341
00342 InvM_wN = weighedNormal / (*massValue);
00343 InvM_wN *= dt*dt;
00344
00345 int indexCurColConst;
00346
00347 for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00348 {
00349 int sizeCurColConst = constraints[curColConst].size();
00350 indexCurColConst = mstate->getConstraintId()[curColConst];
00351
00352 for(int j = 0; j < sizeCurColConst; j++)
00353 {
00354
00355 double w = constraints[curColConst][j].data * InvM_wN;
00356 W->add(indexCurRowConst, indexCurColConst, w);
00357 if (indexCurRowConst != indexCurColConst)
00358 W->add(indexCurColConst, indexCurRowConst, w);
00359 }
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 }
00369 }
00370 }
00371
00372 template<>
00373 void UncoupledConstraintCorrection<defaulttype::Rigid3fTypes>::applyContactForce(const defaulttype::BaseVector *f)
00374 {
00375 VecDeriv& force = *mstate->getExternalForces();
00376 const VecConst& constraints = *mstate->getC();
00377 Deriv weighedNormal;
00378
00379 const sofa::defaulttype::Rigid3fMass* massValue;
00380
00381 simulation::tree::GNode *node = dynamic_cast<simulation::tree::GNode *>(getContext());
00382
00383 if (node != NULL)
00384 {
00385 core::componentmodel::behavior::BaseMass*_m = node->mass;
00386 component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass> *m = dynamic_cast<component::mass::UniformMass<defaulttype::Rigid3fTypes, defaulttype::Rigid3fMass>*> (_m);
00387 massValue = &( m->getMass());
00388 }
00389 else
00390 {
00391 massValue = new sofa::defaulttype::Rigid3fMass();
00392 printf("\n WARNING : node is not found => massValue could be false in getCompliance function");
00393 }
00394
00395
00396 double dt = this->getContext()->getDt();
00397
00398 force.resize(0);
00399 force.resize(1);
00400 force[0] = Deriv();
00401
00402 int numConstraints = constraints.size();
00403
00404 for(int c1 = 0; c1 < numConstraints; c1++)
00405 {
00406 int indexC1 = mstate->getConstraintId()[c1];
00407 double fC1 = f->element(indexC1);
00408
00409 if (fC1 != 0.0)
00410 {
00411 int sizeC1 = constraints[c1].size();
00412 for(int i = 0; i < sizeC1; i++)
00413 {
00414 weighedNormal = constraints[c1][i].data;
00415 force[0].getVCenter() += weighedNormal.getVCenter() * fC1;
00416 force[0].getVOrientation() += weighedNormal.getVOrientation() * fC1;
00417 }
00418 }
00419 }
00420
00421
00422 VecDeriv& dx = *mstate->getDx();
00423 VecCoord& x = *mstate->getX();
00424 VecDeriv& v = *mstate->getV();
00425 VecDeriv& v_free = *mstate->getVfree();
00426 VecCoord& x_free = *mstate->getXfree();
00427
00428
00429
00430
00431 x[0]=x_free[0];
00432 v[0]=v_free[0];
00433
00434
00435 dx.resize(v.size());
00436 dx[0] = force[0] / (*massValue);
00437 dx[0] *= dt;
00438 v[0] += dx[0];
00439 dx[0] *= dt;
00440 x[0] += dx[0];
00441
00442
00443 }
00444
00445 template<>
00446 void UncoupledConstraintCorrection<defaulttype::Vec1fTypes>::getCompliance(defaulttype::BaseMatrix *W)
00447 {
00448 const VecConst& constraints = *mstate->getC();
00449 unsigned int numConstraints = constraints.size();
00450
00451 for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
00452 {
00453 int sizeCurRowConst = constraints[curRowConst].size();
00454 int indexCurRowConst = mstate->getConstraintId()[curRowConst];
00455
00456 for(int i = 0; i < sizeCurRowConst; i++)
00457 {
00458 int indexCurColConst;
00459
00460 for(unsigned int curColConst = curRowConst; curColConst < numConstraints; curColConst++)
00461 {
00462 int sizeCurColConst = constraints[curColConst].size();
00463 indexCurColConst = mstate->getConstraintId()[curColConst];
00464
00465 for(int j = 0; j < sizeCurColConst; j++)
00466 {
00467 if (constraints[curRowConst][i].index == constraints[curColConst][j].index)
00468 {
00469
00470 double w = (1.0/10000.0) * constraints[curRowConst][i].data.x() * constraints[curColConst][j].data.x();
00471 W->add(indexCurRowConst, indexCurColConst, w);
00472 if (indexCurRowConst != indexCurColConst)
00473 W->add(indexCurColConst, indexCurRowConst, w);
00474 }
00475 }
00476 }
00477
00478
00479
00480
00481
00482
00483
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 }
00502
00503
00504 template<>
00505 void UncoupledConstraintCorrection<defaulttype::Vec1fTypes>::applyContactForce(const defaulttype::BaseVector *f){
00506
00507 VecDeriv& force = *mstate->getExternalForces();
00508 const VecConst& constraints = *mstate->getC();
00509 unsigned int numConstraints = constraints.size();
00510
00511 force.resize((*mstate->getX()).size());
00512
00513 for(unsigned int c1 = 0; c1 < numConstraints; c1++)
00514 {
00515 int indexC1 = mstate->getConstraintId()[c1];
00516 double fC1 = f->element(indexC1);
00517 if (fC1 != 0.0)
00518 {
00519 int sizeC1 = constraints[c1].size();
00520 for(int i = 0; i < sizeC1; i++)
00521 {
00522 force[constraints[c1][i].index] += constraints[c1][i].data * fC1;
00523 }
00524 }
00525 }
00526
00527 VecDeriv& dx = *mstate->getDx();
00528 VecCoord& x = *mstate->getX();
00529 VecDeriv& v = *mstate->getV();
00530 VecDeriv& v_free = *mstate->getVfree();
00531 VecCoord& x_free = *mstate->getXfree();
00532 double dt = this->getContext()->getDt();
00533
00534
00535
00536 dx.resize(v.size());
00537
00538 for (unsigned int i=0; i<dx.size(); i++)
00539 {
00540 x[i] = x_free[i];
00541 v[i] = v_free[i];
00542 dx[i] = force[i]/10000.0;
00543 x[i] += dx[i];
00544 v[i] += dx[i]/dt;
00545 }
00546 }
00547
00548 #endif
00549
00550
00551 template<class DataTypes>
00552 void UncoupledConstraintCorrection<DataTypes>::resetContactForce()
00553 {
00554 VecDeriv& force = *mstate->getExternalForces();
00555 for( unsigned i=0; i<force.size(); ++i )
00556 force[i] = Deriv();
00557 }
00558
00559 }
00560
00561 }
00562
00563 }
00564
00565 #endif