ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Roll.cpp
Revision: 1452
Committed: Mon Aug 23 15:11:36 2004 UTC (19 years, 10 months ago) by tim
File size: 14433 byte(s)
Log Message:
*** empty log message ***

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

Properties

Name Value
svn:executable *