ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Roll.cpp
Revision: 1268
Committed: Fri Jun 11 17:16:21 2004 UTC (20 years, 1 month ago) by tim
File size: 13972 byte(s)
Log Message:
roll in progress

File Contents

# Content
1 #include <cmath>
2 #include "Mat3x3d.hpp"
3 #include "Roll.hpp"
4 #include "SimInfo.hpp"
5
6
7 ////////////////////////////////////////////////////////////////////////////////
8 //Implementation of DCRollAFunctor
9 ////////////////////////////////////////////////////////////////////////////////
10 int DCRollAFunctor::operator()(ConstraintAtom* consAtom1, ConstraintAtom* consAtom2){
11 Vector3d posA;
12 Vector3d posB;
13 Vector3d oldPosA;
14 Vector3d oldPosB;
15 Vector3d velA;
16 Vector3d velB;
17 Vector3d pab;
18 Vector3d tempPab;
19 Vector3d rab;
20 Vector3d zetaA;
21 Vector3d zetaB;
22 Vector3d zeta;
23 Vector3d consForce;
24 Vector3d bondDirUnitVec;
25 double dx, dy, dz;
26 double rpab;
27 double rabsq, pabsq, rpabsq;
28 double diffsq;
29 double gab;
30 double dt;
31 double pabDotZeta;
32 double pabDotZeta2;
33 double zeta2;
34 double forceScalar;
35
36 const int conRBMaxIter = 10;
37
38 dt = info->dt;
39
40 consAtom1->getOldPos(oldPosA.vec);
41 consAtom2->getOldPos(oldPosB.vec);
42
43
44 for(int i=0 ; i < conRBMaxIter; i++){
45 consAtom1->getPos(posA.vec);
46 consAtom2->getPos(posB.vec);
47
48 //discard the vector convention in alan tidesley's code
49 //rij = rj - ri;
50 pab = posB - posA;
51
52 //periodic boundary condition
53
54 info->wrapVector(pab.vec);
55
56 pabsq = dotProduct(pab, pab);
57
58 rabsq = curPair->getBondLength2();
59 diffsq = pabsq -rabsq;
60
61 if (fabs(diffsq) > (consTolerance * rabsq * 2)){
62 rab = oldPosB - oldPosA;
63 info->wrapVector(rab.vec);
64
65 //rpab = dotProduct(rab, pab);
66
67 //rpabsq = rpab * rpab;
68
69
70 //if (rpabsq < (rabsq * -diffsq)){
71 // return consFail;
72 //}
73
74 bondDirUnitVec = pab;
75 bondDirUnitVec.normalize();
76
77 calcZeta(consAtom1, bondDirUnitVec, zetaA);
78
79 calcZeta(consAtom2, bondDirUnitVec, zetaB);
80
81 zeta = zetaA + zetaB;
82 zeta2 = dotProduct(zeta, zeta);
83
84 pabDotZeta = dotProduct(pab, zeta);
85 pabDotZeta2 = pabDotZeta * pabDotZeta;
86
87 //solve quadratic equation
88 //dt^4 * zeta^2 * G^2 + 2* h^2 * pab * zeta * G + pab^2 - d^2
89 //dt : time step
90 // pab :
91 //G : constraint force scalar
92 //d: equilibrium bond length
93
94 if (pabDotZeta2 - zeta2 * diffsq < 0)
95 return consFail;
96
97 //forceScalar = (pabDotZeta + sqrt(pabDotZeta2 - zeta2 * diffsq)) / dt * dt * zeta2;
98 forceScalar = diffsq / (2 * dt * dt * pabDotZeta);
99 //
100 consForce = forceScalar * bondDirUnitVec;
101 //integrate consRB1 using constraint force;
102 integrate(consAtom1, consForce);
103
104 //integrate consRB2 using constraint force;
105 integrate(consAtom2, -consForce);
106
107 }
108 else{
109 if (i ==0)
110 return consAlready;
111 else
112 return consSuccess;
113 }
114 }
115
116 return consExceedMaxIter;
117
118 }
119 void DCRollAFunctor::calcZeta(ConstraintAtom* consAtom, const Vector3d& bondDir, Vector3d&zeta){
120 double invMass;
121 invMass = 1.0 / consAtom ->getMass();
122
123 zeta = invMass * bondDir;
124 }
125
126 void DCRollAFunctor::integrate(ConstraintAtom* consAtom, const Vector3d& force){
127 StuntDouble* sd;
128 Vector3d vel;
129 Vector3d pos;
130 Vector3d tempPos;
131 Vector3d tempVel;
132
133 double mass;
134 double dtOver2;
135 double dt;
136 const double eConvert = 4.184e-4;
137
138 dt = info->dt;
139 dtOver2 = dt /2;
140 sd = consAtom->getStuntDouble();
141
142 sd->getVel(vel.vec);
143 sd->getPos(pos.vec);
144
145 mass = sd->getMass();
146
147 tempVel = eConvert * dtOver2/mass * force;
148 tempPos = dt * tempVel;
149
150 vel += tempVel;
151 pos += tempPos;
152
153 sd->setVel(vel.vec);
154 sd->setPos(pos.vec);
155 }
156
157 int DCRollAFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
158 Vector3d posA;
159 Vector3d posB;
160 Vector3d oldPosA;
161 Vector3d oldPosB;
162 Vector3d velA;
163 Vector3d velB;
164 Vector3d pab;
165 Vector3d tempPab;
166 Vector3d rab;
167 Vector3d zetaA;
168 Vector3d zetaB;
169 Vector3d zeta;
170 Vector3d consForce;
171 Vector3d bondDirUnitVec;
172 double dx, dy, dz;
173 double rpab;
174 double rabsq, pabsq, rpabsq;
175 double diffsq;
176 double gab;
177 double dt;
178 double pabDotZeta;
179 double pabDotZeta2;
180 double zeta2;
181 double forceScalar;
182
183 const int conRBMaxIter = 10;
184
185 dt = info->dt;
186
187 consRB1->getOldAtomPos(oldPosA.vec);
188 consRB2->getOldAtomPos(oldPosB.vec);
189
190
191 for(int i=0 ; i < conRBMaxIter; i++){
192 consRB1->getCurAtomPos(posA.vec);
193 consRB2->getCurAtomPos(posB.vec);
194
195 //discard the vector convention in alan tidesley's code
196 //rij = rj - ri;
197 pab = posB - posA;
198
199 //periodic boundary condition
200
201 info->wrapVector(pab.vec);
202
203 pabsq = dotProduct(pab, pab);
204
205 rabsq = curPair->getBondLength2();
206 diffsq = pabsq -rabsq;
207
208 if (fabs(diffsq) > (consTolerance * rabsq * 2)){
209 rab = oldPosB - oldPosA;
210 info->wrapVector(rab.vec);
211
212 //rpab = dotProduct(rab, pab);
213
214 //rpabsq = rpab * rpab;
215
216
217 //if (rpabsq < (rabsq * -diffsq)){
218 // return consFail;
219 //}
220
221 bondDirUnitVec = pab;
222 bondDirUnitVec.normalize();
223
224 calcZeta(consRB1, bondDirUnitVec, zetaA);
225
226 calcZeta(consRB2, bondDirUnitVec, zetaB);
227
228 zeta = zetaA + zetaB;
229 zeta2 = dotProduct(zeta, zeta);
230
231 pabDotZeta = dotProduct(pab, zeta);
232 pabDotZeta2 = pabDotZeta * pabDotZeta;
233
234 //solve quadratic equation
235 //dt^4 * zeta^2 * G^2 + 2* h^2 * pab * zeta * G + pab^2 - d^2
236 //dt : time step
237 // pab :
238 //G : constraint force scalar
239 //d: equilibrium bond length
240
241 if (pabDotZeta2 - zeta2 * diffsq < 0)
242 return consFail;
243
244 //forceScalar = (pabDotZeta + sqrt(pabDotZeta2 - zeta2 * diffsq)) / dt * dt * zeta2;
245 forceScalar = diffsq / (2 * dt * dt * pabDotZeta);
246 //
247 consForce = forceScalar * bondDirUnitVec;
248 //integrate consRB1 using constraint force;
249 integrate(consRB1, consForce);
250
251 //integrate consRB2 using constraint force;
252 integrate(consRB2, -consForce);
253
254 }
255 else{
256 if (i ==0)
257 return consAlready;
258 else
259 return consSuccess;
260 }
261 }
262
263 return consExceedMaxIter;
264
265 }
266
267 void DCRollAFunctor::calcZeta(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& zeta){
268 double invMass;
269 Vector3d tempVec1;
270 Vector3d tempVec2;
271 Vector3d refCoor;
272 Vector3d refCrossBond;
273 Mat3x3d IBody;
274 Mat3x3d IFrame;
275 Mat3x3d invIBody;
276 Mat3x3d invIFrame;
277 Mat3x3d a;
278 Mat3x3d aTrans;
279
280 invMass = 1.0 / consRB ->getMass();
281
282 zeta = invMass * bondDir;
283
284 consRB->getRefCoor(refCoor.vec);
285 consRB->getA(a.element);
286 consRB->getI(IBody.element);
287
288 aTrans = a.transpose();
289 invIBody = IBody.inverse();
290
291 IFrame = aTrans * invIBody * a;
292
293 refCrossBond = crossProduct(refCoor, bondDir);
294
295 tempVec1 = invIFrame * refCrossBond;
296 tempVec2 = crossProduct(tempVec1, refCoor);
297
298 zeta += tempVec2;
299
300 }
301
302 void DCRollAFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
303 StuntDouble* sd;
304 Vector3d vel;
305 Vector3d pos;
306 Vector3d Tb;
307 Vector3d ji;
308 Vector3d tempPos;
309 Vector3d tempVel;
310 Vector3d tempTrq;
311 Vector3d tempJi;
312 double mass;
313 double dtOver2;
314 double dt;
315 const double eConvert = 4.184e-4;
316
317 dt = info->dt;
318 dtOver2 = dt /2;
319 sd = consRB->getStuntDouble();
320
321 sd->getVel(vel.vec);
322 sd->getPos(pos.vec);
323
324 mass = sd->getMass();
325
326 tempVel = eConvert * dtOver2/mass * force;
327 tempPos = dt * tempVel;
328
329 vel += tempVel;
330 pos += tempPos;
331
332 sd->setVel(vel.vec);
333 sd->setPos(pos.vec);
334
335 if (sd->isDirectional()){
336
337 // get and convert the torque to body frame
338
339 sd->getTrq(Tb.vec);
340 sd->lab2Body(Tb.vec);
341
342 // get the angular momentum, and propagate a half step
343
344 sd->getJ(ji.vec);
345
346 ji += eConvert * dtOver2 * Tb;
347
348 rotationPropagation( sd, ji.vec);
349
350 sd->setJ(ji.vec);
351 }
352
353 }
354
355 void DCRollAFunctor::rotationPropagation(StuntDouble* sd, double ji[3]){
356 double angle;
357 double A[3][3], I[3][3];
358 int i, j, k;
359 double dtOver2;
360
361 dtOver2 = info->dt /2;
362 // use the angular velocities to propagate the rotation matrix a
363 // full time step
364
365 sd->getA(A);
366 sd->getI(I);
367
368 if (sd->isLinear()) {
369 i = sd->linearAxis();
370 j = (i+1)%3;
371 k = (i+2)%3;
372
373 angle = dtOver2 * ji[j] / I[j][j];
374 this->rotate( k, i, angle, ji, A );
375
376 angle = dtOver2 * ji[k] / I[k][k];
377 this->rotate( i, j, angle, ji, A);
378
379 angle = dtOver2 * ji[j] / I[j][j];
380 this->rotate( k, i, angle, ji, A );
381
382 } else {
383 // rotate about the x-axis
384 angle = dtOver2 * ji[0] / I[0][0];
385 this->rotate( 1, 2, angle, ji, A );
386
387 // rotate about the y-axis
388 angle = dtOver2 * ji[1] / I[1][1];
389 this->rotate( 2, 0, angle, ji, A );
390
391 // rotate about the z-axis
392 angle = dtOver2 * ji[2] / I[2][2];
393 sd->addZangle(angle);
394 this->rotate( 0, 1, angle, ji, A);
395
396 // rotate about the y-axis
397 angle = dtOver2 * ji[1] / I[1][1];
398 this->rotate( 2, 0, angle, ji, A );
399
400 // rotate about the x-axis
401 angle = dtOver2 * ji[0] / I[0][0];
402 this->rotate( 1, 2, angle, ji, A );
403
404 }
405 sd->setA( A );
406 }
407
408 void DCRollAFunctor::rotate(int axes1, int axes2, double angle, double ji[3], double A[3][3]){
409 int i, j, k;
410 double sinAngle;
411 double cosAngle;
412 double angleSqr;
413 double angleSqrOver4;
414 double top, bottom;
415 double rot[3][3];
416 double tempA[3][3];
417 double tempJ[3];
418
419 // initialize the tempA
420
421 for (i = 0; i < 3; i++){
422 for (j = 0; j < 3; j++){
423 tempA[j][i] = A[i][j];
424 }
425 }
426
427 // initialize the tempJ
428
429 for (i = 0; i < 3; i++)
430 tempJ[i] = ji[i];
431
432 // initalize rot as a unit matrix
433
434 rot[0][0] = 1.0;
435 rot[0][1] = 0.0;
436 rot[0][2] = 0.0;
437
438 rot[1][0] = 0.0;
439 rot[1][1] = 1.0;
440 rot[1][2] = 0.0;
441
442 rot[2][0] = 0.0;
443 rot[2][1] = 0.0;
444 rot[2][2] = 1.0;
445
446 // use a small angle aproximation for sin and cosine
447
448 angleSqr = angle * angle;
449 angleSqrOver4 = angleSqr / 4.0;
450 top = 1.0 - angleSqrOver4;
451 bottom = 1.0 + angleSqrOver4;
452
453 cosAngle = top / bottom;
454 sinAngle = angle / bottom;
455
456 rot[axes1][axes1] = cosAngle;
457 rot[axes2][axes2] = cosAngle;
458
459 rot[axes1][axes2] = sinAngle;
460 rot[axes2][axes1] = -sinAngle;
461
462 // rotate the momentum acoording to: ji[] = rot[][] * ji[]
463
464 for (i = 0; i < 3; i++){
465 ji[i] = 0.0;
466 for (k = 0; k < 3; k++){
467 ji[i] += rot[i][k] * tempJ[k];
468 }
469 }
470
471 // rotate the Rotation matrix acording to:
472 // A[][] = A[][] * transpose(rot[][])
473
474
475 // NOte for as yet unknown reason, we are performing the
476 // calculation as:
477 // transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
478
479 for (i = 0; i < 3; i++){
480 for (j = 0; j < 3; j++){
481 A[j][i] = 0.0;
482 for (k = 0; k < 3; k++){
483 A[j][i] += tempA[i][k] * rot[j][k];
484 }
485 }
486 }
487 }
488 ////////////////////////////////////////////////////////////////////////////////
489 //Implementation of DCRollBFunctor
490 ////////////////////////////////////////////////////////////////////////////////
491 int DCRollBFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
492 Vector3d posA;
493 Vector3d posB;
494 Vector3d velA;
495 Vector3d velB;
496 Vector3d pab;
497 Vector3d rab;
498 Vector3d vab;
499 Vector3d rma;
500 Vector3d rmb;
501 Vector3d consForce;
502 Vector3d bondDirUnitVec;
503 double dx, dy, dz;
504 double rpab;
505 double rabsq, pabsq, rpabsq;
506 double diffsq;
507 double gab;
508 double dt;
509 double pabcDotvab;
510 double pabDotInvMassVec;
511
512
513 const int conRBMaxIter = 10;
514
515 dt = info->dt;
516
517 for(int i=0 ; i < conRBMaxIter; i++){
518 consRB1->getCurAtomPos(posA.vec);
519 consRB2->getCurAtomPos(posB.vec);
520 pab = posA - posB;
521
522 consRB1->getVel(velA.vec);
523 consRB2->getVel(velB.vec);
524 vab = velA -velB;
525
526 //periodic boundary condition
527
528 info->wrapVector(pab.vec);
529
530 pabsq = pab.length2();
531
532 rabsq = curPair->getBondLength2();
533 diffsq = rabsq - pabsq;
534
535 if (fabs(diffsq) > (consTolerance * rabsq * 2)){
536
537
538 bondDirUnitVec = pab;
539 bondDirUnitVec.normalize();
540
541 getEffInvMassVec(consRB1, bondDirUnitVec, rma);
542
543 getEffInvMassVec(consRB2, bondDirUnitVec, rmb);
544
545 pabcDotvab = dotProduct(pab, vab);
546 pabDotInvMassVec = dotProduct(pab, rma + rmb);
547
548 consForce = pabcDotvab /(2 * dt * pabDotInvMassVec) * bondDirUnitVec;
549 //integrate consRB1 using constraint force;
550 integrate(consRB1,consForce);
551
552 //integrate consRB2 using constraint force;
553 integrate(consRB2, -consForce);
554
555 }
556 else{
557 if (i ==0)
558 return consAlready;
559 else
560 return consSuccess;
561 }
562 }
563
564 return consExceedMaxIter;
565
566 }
567
568 void DCRollBFunctor::getEffInvMassVec(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& invMassVec){
569 double invMass;
570 Vector3d tempVec1;
571 Vector3d tempVec2;
572 Vector3d refCoor;
573 Vector3d refCrossBond;
574 Mat3x3d IBody;
575 Mat3x3d IFrame;
576 Mat3x3d invIBody;
577 Mat3x3d invIFrame;
578 Mat3x3d a;
579 Mat3x3d aTrans;
580
581 invMass = 1.0 / consRB ->getMass();
582
583 invMassVec = invMass * bondDir;
584
585 consRB->getRefCoor(refCoor.vec);
586 consRB->getA(a.element);
587 consRB->getI(IBody.element);
588
589 aTrans = a.transpose();
590 invIBody = IBody.inverse();
591
592 IFrame = aTrans * invIBody * a;
593
594 refCrossBond = crossProduct(refCoor, bondDir);
595
596 tempVec1 = invIFrame * refCrossBond;
597 tempVec2 = crossProduct(tempVec1, refCoor);
598
599 invMassVec += tempVec2;
600 }
601
602 void DCRollBFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
603 const double eConvert = 4.184e-4;
604 Vector3d vel;
605 Vector3d pos;
606 Vector3d Tb;
607 Vector3d ji;
608 double mass;
609 double dtOver2;
610 StuntDouble* sd;
611
612 sd = consRB->getStuntDouble();
613 dtOver2 = info->dt/2;
614
615 mass = sd->getMass();
616
617 // velocity half step
618
619 vel += eConvert * dtOver2 /mass * force;
620
621 sd->setVel(vel.vec);
622
623 if (sd->isDirectional()){
624
625 // get and convert the torque to body frame
626
627 sd->getTrq(Tb.vec);
628 sd->lab2Body(Tb.vec);
629
630 // get the angular momentum, and propagate a half step
631
632 sd->getJ(ji.vec);
633
634 ji += eConvert * dtOver2* Tb;
635
636 sd->setJ(ji.vec);
637 }
638
639 }

Properties

Name Value
svn:executable *