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 <sofa/simulation/common/MechanicalVisitor.h>
00026 #include <sofa/simulation/common/Node.h>
00027 #include <iostream>
00028 using std::cerr;
00029 using std::endl;
00030
00031 namespace sofa
00032 {
00033
00034 namespace simulation
00035 {
00036
00037
00038 Visitor::Result MechanicalVisitor::processNodeTopDown(simulation::Node* node)
00039 {
00040 Result res = RESULT_CONTINUE;
00041
00042
00043
00044
00045
00046 for (unsigned i=0; i<node->solver.size() && res!=RESULT_PRUNE; i++ ) {
00047 ctime_t t0 = begin(node, node->solver[i]);
00048 res = this->fwdOdeSolver(node, node->solver[i]);
00049 end(node, node->solver[i], t0);
00050 }
00051 if (res != RESULT_PRUNE) {
00052 if (node->mechanicalState != NULL) {
00053 if (node->mechanicalMapping != NULL) {
00054
00055 if (!node->mechanicalMapping->isMechanical())
00056 {
00057 return RESULT_PRUNE;
00058 }
00059 Result res2;
00060 ctime_t t0 = begin(node, node->mechanicalMapping);
00061 res = this->fwdMechanicalMapping(node, node->mechanicalMapping);
00062 end(node, node->mechanicalMapping, t0);
00063 t0 = begin(node, node->mechanicalState);
00064 res2 = this->fwdMappedMechanicalState(node, node->mechanicalState);
00065 end(node, node->mechanicalState, t0);
00066 if (res2 == RESULT_PRUNE)
00067 res = res2;
00068 } else {
00069
00070 ctime_t t0 = begin(node, node->mechanicalState);
00071 res = this->fwdMechanicalState(node, node->mechanicalState);
00072 end(node, node->mechanicalState, t0);
00073 }
00074 }
00075 }
00076 if (res != RESULT_PRUNE) {
00077 if (node->mass != NULL) {
00078 ctime_t t0 = begin(node, node->mass);
00079 res = this->fwdMass(node, node->mass);
00080 end(node, node->mass, t0);
00081 }
00082 }
00083 if (res != RESULT_PRUNE) {
00084 res = for_each_r(this, node, node->forceField, &MechanicalVisitor::fwdForceField);
00085 }
00086 if (res != RESULT_PRUNE) {
00087 res = for_each_r(this, node, node->interactionForceField, &MechanicalVisitor::fwdInteractionForceField);
00088 }
00089 if (res != RESULT_PRUNE) {
00090 res = for_each_r(this, node, node->constraint, &MechanicalVisitor::fwdConstraint);
00091 }
00092 return res;
00093 }
00094
00095 void MechanicalVisitor::processNodeBottomUp(simulation::Node* node)
00096 {
00097 for_each(this, node, node->constraint, &MechanicalVisitor::bwdConstraint);
00098 if (node->mechanicalState != NULL) {
00099 if (node->mechanicalMapping != NULL) {
00100 if (node->mechanicalMapping->isMechanical()) {
00101 ctime_t t0 = begin(node, node->mechanicalState);
00102 this->bwdMappedMechanicalState(node, node->mechanicalState);
00103 end(node, node->mechanicalState, t0);
00104 t0 = begin(node, node->mechanicalMapping);
00105 this->bwdMechanicalMapping(node, node->mechanicalMapping);
00106 end(node, node->mechanicalMapping, t0);
00107 }
00108 } else {
00109 ctime_t t0 = begin(node, node->mechanicalState);
00110 this->bwdMechanicalState(node, node->mechanicalState);
00111 end(node, node->mechanicalState, t0);
00112 }
00113 }
00114
00115
00116
00117
00118
00119 for (unsigned i=0; i<node->solver.size(); i++ ) {
00120 ctime_t t0 = begin(node, node->solver[i]);
00121 this->bwdOdeSolver(node, node->solver[i]);
00122 end(node, node->solver[i], t0);
00123 }
00124 }
00125
00126
00127 Visitor::Result MechanicalIntegrationVisitor::fwdOdeSolver(simulation::Node* node, core::componentmodel::behavior::OdeSolver* obj)
00128 {
00129 double nextTime = node->getTime() + dt;
00130 MechanicalBeginIntegrationVisitor beginVisitor(dt);
00131 node->execute(&beginVisitor);
00132
00133
00134 obj->solve(dt);
00135
00136 obj->propagatePositionAndVelocity(nextTime,core::componentmodel::behavior::OdeSolver::VecId::position(),core::componentmodel::behavior::OdeSolver::VecId::velocity());
00137
00138 MechanicalEndIntegrationVisitor endVisitor(dt);
00139 node->execute(&endVisitor);
00140 return RESULT_PRUNE;
00141 }
00142
00143
00144
00145 Visitor::Result MechanicalVAvailVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00146 {
00147 mm->vAvail(v);
00148 return RESULT_CONTINUE;
00149 }
00150
00151 Visitor::Result MechanicalVAllocVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00152 {
00153 mm->vAlloc(v);
00154 return RESULT_CONTINUE;
00155 }
00156
00157 Visitor::Result MechanicalVFreeVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00158 {
00159 mm->vFree(v);
00160 return RESULT_CONTINUE;
00161 }
00162
00163
00164 Visitor::Result MechanicalVOpVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00165 {
00166
00167 mm->vOp(v,a,b,f);
00168 return RESULT_CONTINUE;
00169 }
00170 Visitor::Result MechanicalVOpVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00171 {
00172
00173
00174 return RESULT_CONTINUE;
00175 }
00176
00177
00178 Visitor::Result MechanicalVMultiOpVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00179 {
00180
00181 mm->vMultiOp(ops);
00182 return RESULT_CONTINUE;
00183 }
00184 Visitor::Result MechanicalVMultiOpVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00185 {
00186
00187
00188 return RESULT_CONTINUE;
00189 }
00190
00192 Visitor::Result MechanicalVDotVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00193 {
00194 *total += mm->vDot(a,b);
00195 return RESULT_CONTINUE;
00196 }
00197
00199 Visitor::Result MechanicalVDotVisitor::processNodeTopDown(simulation::Node* node, LocalStorage* stack)
00200 {
00201 double* localTotal = new double(0.0);
00202 stack->push(localTotal);
00203 if (node->mechanicalState && !node->mechanicalMapping)
00204 {
00205 core::componentmodel::behavior::BaseMechanicalState* mm = node->mechanicalState;
00206 *localTotal += mm->vDot(a,b);
00207 }
00208 return RESULT_CONTINUE;
00209 }
00210
00212 void MechanicalVDotVisitor::processNodeBottomUp(simulation::Node* , LocalStorage* stack)
00213 {
00214 double* localTotal = static_cast<double*>(stack->pop());
00215 double* parentTotal = static_cast<double*>(stack->top());
00216 if (!parentTotal)
00217 *total += *localTotal;
00218 else
00219 *parentTotal += *localTotal;
00220 delete localTotal;
00221 }
00222
00223
00224 Visitor::Result MechanicalPropagateDxVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00225 {
00226 mm->setDx(dx);
00227 return RESULT_CONTINUE;
00228 }
00229 Visitor::Result MechanicalPropagateDxVisitor::fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00230 {
00231 map->propagateDx();
00232 return RESULT_CONTINUE;
00233 }
00234
00235 Visitor::Result MechanicalPropagateDxAndResetForceVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00236 {
00237 mm->setDx(dx);
00238 mm->setF(f);
00239 mm->resetForce();
00240 return RESULT_CONTINUE;
00241 }
00242 Visitor::Result MechanicalPropagateDxAndResetForceVisitor::fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00243 {
00244 map->propagateDx();
00245 return RESULT_CONTINUE;
00246 }
00247 Visitor::Result MechanicalPropagateDxAndResetForceVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00248 {
00249 mm->resetForce();
00250 return RESULT_CONTINUE;
00251 }
00252
00253 Visitor::Result MechanicalPropagateAndAddDxVisitor::fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00254 {
00255 map->propagateDx();
00256 return RESULT_CONTINUE;
00257 }
00258 Visitor::Result MechanicalPropagateAndAddDxVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00259 {
00260
00261 mm->addDxToCollisionModel();
00262 return RESULT_CONTINUE;
00263 }
00264
00265 Visitor::Result MechanicalAddMDxVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00266 {
00267 mm->setF(res);
00268 if (!dx.isNull())
00269 mm->setDx(dx);
00270 return RESULT_CONTINUE;
00271 }
00272 Visitor::Result MechanicalAddMDxVisitor::fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass)
00273 {
00274 mass->addMDx(factor);
00275 return RESULT_PRUNE;
00276 }
00277 Visitor::Result MechanicalAccFromFVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00278 {
00279 mm->setDx(a);
00280 mm->setF(f);
00282 return RESULT_CONTINUE;
00283 }
00284 Visitor::Result MechanicalAccFromFVisitor::fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass)
00285 {
00286 mass->accFromF();
00287 return RESULT_CONTINUE;
00288 }
00289
00290
00291 MechanicalPropagatePositionAndVelocityVisitor::MechanicalPropagatePositionAndVelocityVisitor(double t, VecId x, VecId v) : t(t), x(x), v(v)
00292 {
00293
00294 }
00295
00296
00297 Visitor::Result MechanicalPropagatePositionAndVelocityVisitor::processNodeTopDown(simulation::Node* node)
00298 {
00299
00300 node->setTime(t);
00301 node->updateSimulationContext();
00302 return MechanicalVisitor::processNodeTopDown( node);
00303 }
00304
00305 void MechanicalPropagatePositionAndVelocityVisitor::processNodeBottomUp(simulation::Node* node)
00306 {
00307
00308
00309 MechanicalVisitor::processNodeBottomUp( node);
00310
00311 }
00312
00313
00314 Visitor::Result MechanicalPropagatePositionAndVelocityVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00315 {
00316 mm->setX(x);
00317 mm->setV(v);
00318 return RESULT_CONTINUE;
00319 }
00320 Visitor::Result MechanicalPropagatePositionAndVelocityVisitor::fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00321 {
00322 map->propagateX();
00323 map->propagateV();
00324 return RESULT_CONTINUE;
00325 }
00326 Visitor::Result MechanicalPropagatePositionAndVelocityVisitor::fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00327 {
00328 c->projectPosition();
00329 c->projectVelocity();
00330 return RESULT_CONTINUE;
00331 }
00332
00333 Visitor::Result MechanicalPropagateFreePositionVisitor::processNodeTopDown(simulation::Node* node)
00334 {
00335 node->setTime(t);
00336 node->updateSimulationContext();
00337 return MechanicalVisitor::processNodeTopDown( node);
00338 }
00339 Visitor::Result MechanicalPropagateFreePositionVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00340 {
00341 mm->setXfree(x);
00342 mm->setVfree(v);
00343 return RESULT_CONTINUE;
00344 }
00345 Visitor::Result MechanicalPropagateFreePositionVisitor::fwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00346 {
00347 map->propagateXfree();
00348 return RESULT_CONTINUE;
00349 }
00350 Visitor::Result MechanicalPropagateFreePositionVisitor::fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00351 {
00352 c->projectFreePosition();
00353 c->projectFreeVelocity();
00354 return RESULT_CONTINUE;
00355 }
00356
00357
00358 Visitor::Result MechanicalResetForceVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00359 {
00360 mm->setF(res);
00361 if (!onlyMapped)
00362 mm->resetForce();
00363 return RESULT_CONTINUE;
00364 }
00365 Visitor::Result MechanicalResetForceVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00366 {
00367 mm->resetForce();
00368 return RESULT_CONTINUE;
00369 }
00370
00371 Visitor::Result MechanicalComputeForceVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00372 {
00373 mm->setF(res);
00374 mm->accumulateForce();
00375 return RESULT_CONTINUE;
00376 }
00377 Visitor::Result MechanicalComputeForceVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00378 {
00379 mm->accumulateForce();
00380 return RESULT_CONTINUE;
00381 }
00382
00383 Visitor::Result MechanicalComputeForceVisitor::fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff)
00384 {
00385
00386 ff->addForce();
00387 return RESULT_CONTINUE;
00388 }
00389
00390 void MechanicalComputeForceVisitor::bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00391 {
00392
00393 if (accumulate)
00394 map->accumulateForce();
00395 }
00396
00397 Visitor::Result MechanicalComputeDfVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00398 {
00399 mm->setF(res);
00400 mm->accumulateDf();
00401 return RESULT_CONTINUE;
00402 }
00403 Visitor::Result MechanicalComputeDfVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00404 {
00405 mm->accumulateDf();
00406 return RESULT_CONTINUE;
00407 }
00408 Visitor::Result MechanicalComputeDfVisitor::fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff)
00409 {
00410 if (useV)
00411 ff->addDForceV();
00412 else
00413 ff->addDForce();
00414 return RESULT_CONTINUE;
00415 }
00416 void MechanicalComputeDfVisitor::bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00417 {
00418 if (accumulate)
00419 map->accumulateDf();
00420 }
00421
00422
00423
00424 Visitor::Result MechanicalAddMBKdxVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00425 {
00426 mm->setF(res);
00427 mm->accumulateDf();
00428 return RESULT_CONTINUE;
00429 }
00430 Visitor::Result MechanicalAddMBKdxVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00431 {
00432 mm->accumulateDf();
00433 return RESULT_CONTINUE;
00434 }
00435 Visitor::Result MechanicalAddMBKdxVisitor::fwdForceField(simulation::Node* , core::componentmodel::behavior::BaseForceField* ff)
00436 {
00437 if (useV)
00438 ff->addMBKv(mFactor, bFactor, kFactor);
00439 else
00440 ff->addMBKdx(mFactor, bFactor, kFactor);
00441 return RESULT_CONTINUE;
00442 }
00443
00444 void MechanicalAddMBKdxVisitor::bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00445 {
00446 if (accumulate)
00447 map->accumulateDf();
00448 }
00449
00450 Visitor::Result MechanicalResetConstraintVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00451 {
00452
00453 mm->resetConstraint();
00454 return RESULT_CONTINUE;
00455 }
00456
00457 Visitor::Result MechanicalResetConstraintVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00458 {
00459 mm->resetConstraint();
00460 return RESULT_CONTINUE;
00461 }
00462
00463 Visitor::Result MechanicalAccumulateConstraint::fwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00464 {
00465 c->applyConstraint(contactId, mu);
00466 return RESULT_CONTINUE;
00467 }
00468
00469 void MechanicalAccumulateConstraint::bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00470 {
00471 map->accumulateConstraint();
00472 }
00473
00474
00475 Visitor::Result MechanicalApplyConstraintsVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00476 {
00477 mm->setDx(res);
00478
00479 return RESULT_CONTINUE;
00480 }
00481 Visitor::Result MechanicalApplyConstraintsVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* )
00482 {
00483
00484 return RESULT_CONTINUE;
00485 }
00486
00487 void MechanicalApplyConstraintsVisitor::bwdConstraint(simulation::Node* , core::componentmodel::behavior::BaseConstraint* c)
00488 {
00489 c->projectResponse();
00490
00491 if (W != NULL)
00492 {
00493 c->projectResponse(W);
00494 }
00495 }
00496
00497 Visitor::Result MechanicalBeginIntegrationVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00498 {
00499 mm->beginIntegration(dt);
00500 return RESULT_CONTINUE;
00501 }
00502 Visitor::Result MechanicalBeginIntegrationVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00503 {
00504 mm->beginIntegration(dt);
00505 return RESULT_CONTINUE;
00506 }
00507
00508
00509 Visitor::Result MechanicalEndIntegrationVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00510 {
00511 mm->endIntegration(dt);
00512 return RESULT_CONTINUE;
00513 }
00514 Visitor::Result MechanicalEndIntegrationVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00515 {
00516 mm->endIntegration(dt);
00517 return RESULT_CONTINUE;
00518 }
00519
00520 Visitor::Result MechanicalComputeComplianceVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00521 {
00522 ms->getCompliance(_W);
00523 return RESULT_PRUNE;
00524 }
00525 Visitor::Result MechanicalComputeComplianceVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* ms)
00526 {
00527 ms->getCompliance(_W);
00528 return RESULT_CONTINUE;
00529 }
00530 Visitor::Result MechanicalComputeContactForceVisitor::fwdMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00531 {
00532 mm->setF(res);
00533 mm->accumulateForce();
00534 return RESULT_PRUNE;
00535 }
00536
00537 Visitor::Result MechanicalComputeContactForceVisitor::fwdMappedMechanicalState(simulation::Node* , core::componentmodel::behavior::BaseMechanicalState* mm)
00538 {
00539 mm->accumulateForce();
00540 return RESULT_CONTINUE;
00541 }
00542
00543 void MechanicalComputeContactForceVisitor::bwdMechanicalMapping(simulation::Node* , core::componentmodel::behavior::BaseMechanicalMapping* map)
00544 {
00545 map->accumulateForce();
00546 }
00547
00548 Visitor::Result MechanicalAddSeparateGravityVisitor::fwdMass(simulation::Node* , core::componentmodel::behavior::BaseMass* mass)
00549 {
00550 if( mass->m_separateGravity.getValue() )
00551 mass->addGravityToV(dt);
00552
00553 return RESULT_CONTINUE;
00554 }
00555
00556 }
00557
00558 }
00559