| 27 |
|
double diffsq; |
| 28 |
|
double gab; |
| 29 |
|
double dt; |
| 30 |
< |
double dt2; |
| 31 |
< |
double rijcDotInvMassVec; |
| 30 |
> |
double pabDotInvMassVec; |
| 31 |
|
|
| 32 |
|
|
| 33 |
|
const int conRBMaxIter = 10; |
| 34 |
|
|
| 35 |
|
dt = info->dt; |
| 37 |
– |
dt2 = dt * dt; |
| 36 |
|
|
| 37 |
|
consRB1->getOldAtomPos(oldPosA.vec); |
| 38 |
|
consRB2->getOldAtomPos(oldPosB.vec); |
| 73 |
|
|
| 74 |
|
getEffInvMassVec(consRB2, -bondDirUnitVec, rmb); |
| 75 |
|
|
| 76 |
< |
rijcDotInvMassVec = dotProduct(pab, rma + rmb); |
| 76 |
> |
pabDotInvMassVec = dotProduct(pab, rma + rmb); |
| 77 |
|
|
| 78 |
< |
consForce = diffsq /(2 * dt * dt * rijcDotInvMassVec) * bondDirUnitVec; |
| 78 |
> |
consForce = diffsq /(2 * dt * dt * pabDotInvMassVec) * bondDirUnitVec; |
| 79 |
|
//integrate consRB1 using constraint force; |
| 80 |
|
integrate(consRB1,consForce); |
| 81 |
|
|
| 313 |
|
//Implementation of DCRollBFunctor |
| 314 |
|
//////////////////////////////////////////////////////////////////////////////// |
| 315 |
|
int DCRollBFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){ |
| 316 |
< |
return consElemHandlerFail; |
| 316 |
> |
Vector3d posA; |
| 317 |
> |
Vector3d posB; |
| 318 |
> |
Vector3d velA; |
| 319 |
> |
Vector3d velB; |
| 320 |
> |
Vector3d pab; |
| 321 |
> |
Vector3d rab; |
| 322 |
> |
Vector3d vab; |
| 323 |
> |
Vector3d rma; |
| 324 |
> |
Vector3d rmb; |
| 325 |
> |
Vector3d consForce; |
| 326 |
> |
Vector3d bondDirUnitVec; |
| 327 |
> |
double dx, dy, dz; |
| 328 |
> |
double rpab; |
| 329 |
> |
double rabsq, pabsq, rpabsq; |
| 330 |
> |
double diffsq; |
| 331 |
> |
double gab; |
| 332 |
> |
double dt; |
| 333 |
> |
double pabcDotvab; |
| 334 |
> |
double pabDotInvMassVec; |
| 335 |
> |
|
| 336 |
> |
|
| 337 |
> |
const int conRBMaxIter = 10; |
| 338 |
> |
|
| 339 |
> |
dt = info->dt; |
| 340 |
> |
|
| 341 |
> |
for(int i=0 ; i < conRBMaxIter; i++){ |
| 342 |
> |
consRB1->getCurAtomPos(posA.vec); |
| 343 |
> |
consRB2->getCurAtomPos(posB.vec); |
| 344 |
> |
pab = posA - posB; |
| 345 |
> |
|
| 346 |
> |
consRB1->getVel(velA.vec); |
| 347 |
> |
consRB2->getVel(velB.vec); |
| 348 |
> |
vab = velA -velB; |
| 349 |
> |
|
| 350 |
> |
//periodic boundary condition |
| 351 |
> |
|
| 352 |
> |
info->wrapVector(pab.vec); |
| 353 |
> |
|
| 354 |
> |
pabsq = pab.length2(); |
| 355 |
> |
|
| 356 |
> |
rabsq = curPair->getBondLength2(); |
| 357 |
> |
diffsq = rabsq - pabsq; |
| 358 |
> |
|
| 359 |
> |
if (fabs(diffsq) > (consTolerance * rabsq * 2)){ |
| 360 |
> |
|
| 361 |
> |
|
| 362 |
> |
bondDirUnitVec = pab; |
| 363 |
> |
bondDirUnitVec.normalize(); |
| 364 |
> |
|
| 365 |
> |
getEffInvMassVec(consRB1, bondDirUnitVec, rma); |
| 366 |
> |
|
| 367 |
> |
getEffInvMassVec(consRB2, -bondDirUnitVec, rmb); |
| 368 |
> |
|
| 369 |
> |
pabcDotvab = dotProduct(pab, vab); |
| 370 |
> |
pabDotInvMassVec = dotProduct(pab, rma + rmb); |
| 371 |
> |
|
| 372 |
> |
consForce = pabcDotvab /(2 * dt * pabDotInvMassVec) * bondDirUnitVec; |
| 373 |
> |
//integrate consRB1 using constraint force; |
| 374 |
> |
integrate(consRB1,consForce); |
| 375 |
> |
|
| 376 |
> |
//integrate consRB2 using constraint force; |
| 377 |
> |
integrate(consRB2, -consForce); |
| 378 |
> |
|
| 379 |
> |
} |
| 380 |
> |
else{ |
| 381 |
> |
if (i ==0) |
| 382 |
> |
return consAlready; |
| 383 |
> |
else |
| 384 |
> |
return consSuccess; |
| 385 |
> |
} |
| 386 |
> |
} |
| 387 |
> |
|
| 388 |
> |
return consExceedMaxIter; |
| 389 |
> |
|
| 390 |
|
} |
| 391 |
|
|
| 392 |
|
void DCRollBFunctor::getEffInvMassVec(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& invMassVec){ |
| 393 |
+ |
double invMass; |
| 394 |
+ |
Vector3d tempVec1; |
| 395 |
+ |
Vector3d tempVec2; |
| 396 |
+ |
Vector3d refCoor; |
| 397 |
+ |
Vector3d refCrossBond; |
| 398 |
+ |
Mat3x3d IBody; |
| 399 |
+ |
Mat3x3d IFrame; |
| 400 |
+ |
Mat3x3d invIBody; |
| 401 |
+ |
Mat3x3d invIFrame; |
| 402 |
+ |
Mat3x3d a; |
| 403 |
+ |
Mat3x3d aTrans; |
| 404 |
+ |
|
| 405 |
+ |
invMass = 1.0 / consRB ->getMass(); |
| 406 |
|
|
| 407 |
+ |
invMassVec = invMass * bondDir; |
| 408 |
+ |
|
| 409 |
+ |
consRB->getRefCoor(refCoor.vec); |
| 410 |
+ |
consRB->getA(a.element); |
| 411 |
+ |
consRB->getI(IBody.element); |
| 412 |
+ |
|
| 413 |
+ |
aTrans = a.transpose(); |
| 414 |
+ |
invIBody = IBody.inverse(); |
| 415 |
+ |
|
| 416 |
+ |
IFrame = aTrans * invIBody * a; |
| 417 |
+ |
|
| 418 |
+ |
refCrossBond = crossProduct(refCoor, bondDir); |
| 419 |
+ |
|
| 420 |
+ |
tempVec1 = invIFrame * refCrossBond; |
| 421 |
+ |
tempVec2 = crossProduct(tempVec1, refCoor); |
| 422 |
+ |
|
| 423 |
+ |
invMassVec += tempVec2; |
| 424 |
|
} |
| 425 |
|
|
| 426 |
|
void DCRollBFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){ |
| 427 |
+ |
const double eConvert = 4.184e-4; |
| 428 |
+ |
Vector3d vel; |
| 429 |
+ |
Vector3d pos; |
| 430 |
+ |
Vector3d Tb; |
| 431 |
+ |
Vector3d ji; |
| 432 |
+ |
double mass; |
| 433 |
+ |
double dtOver2; |
| 434 |
+ |
StuntDouble* sd; |
| 435 |
+ |
|
| 436 |
+ |
sd = consRB->getStuntDouble(); |
| 437 |
+ |
dtOver2 = info->dt/2; |
| 438 |
|
|
| 439 |
< |
} |
| 439 |
> |
mass = sd->getMass(); |
| 440 |
> |
|
| 441 |
> |
// velocity half step |
| 442 |
> |
|
| 443 |
> |
vel += eConvert * dtOver2 /mass * force; |
| 444 |
> |
|
| 445 |
> |
sd->setVel(vel.vec); |
| 446 |
> |
|
| 447 |
> |
if (sd->isDirectional()){ |
| 448 |
> |
|
| 449 |
> |
// get and convert the torque to body frame |
| 450 |
> |
|
| 451 |
> |
sd->getTrq(Tb.vec); |
| 452 |
> |
sd->lab2Body(Tb.vec); |
| 453 |
> |
|
| 454 |
> |
// get the angular momentum, and propagate a half step |
| 455 |
> |
|
| 456 |
> |
sd->getJ(ji.vec); |
| 457 |
> |
|
| 458 |
> |
ji += eConvert * dtOver2* Tb; |
| 459 |
> |
|
| 460 |
> |
sd->setJ(ji.vec); |
| 461 |
> |
} |
| 462 |
> |
|
| 463 |
> |
} |