ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Roll.cpp
Revision: 1284
Committed: Mon Jun 21 18:52:21 2004 UTC (20 years, 10 months ago) by tim
File size: 14149 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 //forceScalar = 1 / forceScalar;
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 double mass;
133 double dt;
134
135 dt = info->dt;
136 sd = consAtom->getStuntDouble();
137
138 sd->getVel(vel.vec);
139 sd->getPos(pos.vec);
140
141 mass = sd->getMass();
142
143 tempVel = dt/mass * force;
144 tempPos = dt * tempVel;
145
146 vel += tempVel;
147 pos += tempPos;
148
149 sd->setVel(vel.vec);
150 sd->setPos(pos.vec);
151 }
152
153 int DCRollAFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
154 Vector3d posA;
155 Vector3d posB;
156 Vector3d oldPosA;
157 Vector3d oldPosB;
158 Vector3d velA;
159 Vector3d velB;
160 Vector3d pab;
161 Vector3d tempPab;
162 Vector3d rab;
163 Vector3d zetaA;
164 Vector3d zetaB;
165 Vector3d zeta;
166 Vector3d consForce;
167 Vector3d bondDirUnitVec;
168 double dx, dy, dz;
169 double rpab;
170 double rabsq, pabsq, rpabsq;
171 double diffsq;
172 double gab;
173 double dt;
174 double pabDotZeta;
175 double pabDotZeta2;
176 double zeta2;
177 double forceScalar;
178
179 const int conRBMaxIter = 100;
180
181 dt = info->dt;
182
183 consRB1->getOldAtomPos(oldPosA.vec);
184 consRB2->getOldAtomPos(oldPosB.vec);
185
186
187 for(int i=0 ; i < conRBMaxIter; i++){
188 consRB1->getCurAtomPos(posA.vec);
189 consRB2->getCurAtomPos(posB.vec);
190
191 //discard the vector convention in alan tidesley's code
192 //rij = rj - ri;
193 pab = posB - posA;
194
195 //periodic boundary condition
196
197 info->wrapVector(pab.vec);
198
199 pabsq = dotProduct(pab, pab);
200
201 rabsq = curPair->getBondLength2();
202 diffsq = pabsq -rabsq;
203
204 if (fabs(diffsq) > (consTolerance * rabsq * 2)){
205 rab = oldPosB - oldPosA;
206 info->wrapVector(rab.vec);
207
208 bondDirUnitVec = rab;
209 bondDirUnitVec.normalize();
210
211 calcZeta(consRB1, bondDirUnitVec, zetaA);
212
213 calcZeta(consRB2, bondDirUnitVec, zetaB);
214
215 zeta = zetaA + zetaB;
216 zeta2 = dotProduct(zeta, zeta);
217
218 pabDotZeta = dotProduct(pab, zeta);
219 pabDotZeta2 = pabDotZeta * pabDotZeta;
220
221 //solve quadratic equation
222 //dt^4 * zeta^2 * G^2 + 2* h^2 * pab * zeta * G + pab^2 - d^2
223 //dt : time step
224 // pab :
225 //G : constraint force scalar
226 //d: equilibrium bond length
227
228 if (pabDotZeta2 - zeta2 * diffsq < 0){
229 cerr << "DCRollAFunctor::operator() Error: Constraint Fail at " << info->getTime() << endl;
230 return consFail;
231 }
232 //if pabDotZeta is close to 0, we can't neglect the square term
233 if(fabs(pabDotZeta) < consTolerance)
234 forceScalar = (pabDotZeta - sqrt(pabDotZeta2 - zeta2 * diffsq)) / dt * dt * zeta2;
235 else
236 forceScalar = diffsq / (2 * dt * dt * pabDotZeta);
237
238 //
239 consForce = forceScalar * bondDirUnitVec;
240 //integrate consRB1 using constraint force;
241 integrate(consRB1, consForce);
242
243 //integrate consRB2 using constraint force;
244 integrate(consRB2, -consForce);
245
246 }
247 else{
248 if (i ==0)
249 return consAlready;
250 else
251 return consSuccess;
252 }
253 }
254
255 cerr << "DCRollAFunctor::operator() Error: can not constrain the bond within maximum iteration at " << info->getTime() << endl;
256 return consExceedMaxIter;
257
258 }
259
260 void DCRollAFunctor::calcZeta(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& zeta){
261 double invMass;
262 Vector3d tempVec1;
263 Vector3d tempVec2;
264 Vector3d refCoor;
265 Vector3d refCrossBond;
266 Mat3x3d IBody;
267 Mat3x3d invIBody;
268 Mat3x3d invILab;
269 Mat3x3d a;
270 Mat3x3d aTrans;
271
272 invMass = 1.0 / consRB ->getMass();
273
274 zeta = invMass * bondDir;
275
276 consRB->getRefCoor(refCoor.vec);
277 consRB->getA(a.element);
278 consRB->getI(IBody.element);
279
280 aTrans = a.transpose();
281 invIBody = IBody.inverse();
282
283 invILab = aTrans * invIBody * a;
284
285 refCrossBond = crossProduct(refCoor, bondDir);
286
287 tempVec1 = invILab * refCrossBond;
288 tempVec2 = crossProduct(tempVec1, refCoor);
289
290 zeta += tempVec2;
291
292 }
293
294 void DCRollAFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
295 StuntDouble* sd;
296 Vector3d vel;
297 Vector3d pos;
298 Vector3d Tb;
299 Vector3d ji;
300 Vector3d tempPos;
301 Vector3d tempVel;
302 Vector3d tempTrqLab;
303 Vector3d tempTrqBody;
304 Vector3d tempJi;
305 Vector3d refCoor;
306 double mass;
307 Mat3x3d oldA;
308 double dt;
309 double dtOver2;
310 dt = info->dt;
311 dtOver2 = dt /2;
312
313 consRB->getOldA(oldA.element);
314 sd = consRB->getStuntDouble();
315
316 sd->getVel(vel.vec);
317 sd->getPos(pos.vec);
318
319 mass = sd->getMass();
320
321 tempVel = dtOver2/mass * force;
322 tempPos = dt * tempVel;
323
324 vel += tempVel;
325 pos += tempPos;
326
327 sd->setVel(vel.vec);
328 sd->setPos(pos.vec);
329
330 if (sd->isDirectional()){
331
332 consRB->getRefCoor(refCoor.vec);
333 tempTrqLab = crossProduct(refCoor, force);
334
335 //convert torque in lab frame to torque in body frame using old rotation matrix
336 //tempTrqBody = oldA * tempTrqLab;
337
338 //tempJi = dtOver2 * tempTrqBody;
339 sd->lab2Body(tempTrqLab.vec);
340 tempJi = dtOver2 * tempTrqLab;
341 rotationPropagation( sd, tempJi.vec);
342
343 sd->getJ(ji.vec);
344
345 ji += tempJi;
346
347 sd->setJ(ji.vec);
348 }
349
350
351 }
352
353 void DCRollAFunctor::rotationPropagation(StuntDouble* sd, double ji[3]){
354 double angle;
355 double A[3][3], I[3][3];
356 int i, j, k;
357 double dtOver2;
358
359 dtOver2 = info->dt /2;
360 // use the angular velocities to propagate the rotation matrix a
361 // full time step
362
363 sd->getA(A);
364 sd->getI(I);
365
366 if (sd->isLinear()) {
367 i = sd->linearAxis();
368 j = (i+1)%3;
369 k = (i+2)%3;
370
371 angle = dtOver2 * ji[j] / I[j][j];
372 this->rotate( k, i, angle, ji, A );
373
374 angle = dtOver2 * ji[k] / I[k][k];
375 this->rotate( i, j, angle, ji, A);
376
377 angle = dtOver2 * ji[j] / I[j][j];
378 this->rotate( k, i, angle, ji, A );
379
380 } else {
381 // rotate about the x-axis
382 angle = dtOver2 * ji[0] / I[0][0];
383 this->rotate( 1, 2, angle, ji, A );
384
385 // rotate about the y-axis
386 angle = dtOver2 * ji[1] / I[1][1];
387 this->rotate( 2, 0, angle, ji, A );
388
389 // rotate about the z-axis
390 angle = dtOver2 * ji[2] / I[2][2];
391 sd->addZangle(angle);
392 this->rotate( 0, 1, angle, ji, A);
393
394 // rotate about the y-axis
395 angle = dtOver2 * ji[1] / I[1][1];
396 this->rotate( 2, 0, angle, ji, A );
397
398 // rotate about the x-axis
399 angle = dtOver2 * ji[0] / I[0][0];
400 this->rotate( 1, 2, angle, ji, A );
401
402 }
403 sd->setA( A );
404 }
405
406 void DCRollAFunctor::rotate(int axes1, int axes2, double angle, double ji[3], double A[3][3]){
407 int i, j, k;
408 double sinAngle;
409 double cosAngle;
410 double angleSqr;
411 double angleSqrOver4;
412 double top, bottom;
413 double rot[3][3];
414 double tempA[3][3];
415 double tempJ[3];
416
417 // initialize the tempA
418
419 for (i = 0; i < 3; i++){
420 for (j = 0; j < 3; j++){
421 tempA[j][i] = A[i][j];
422 }
423 }
424
425 // initialize the tempJ
426
427 for (i = 0; i < 3; i++)
428 tempJ[i] = ji[i];
429
430 // initalize rot as a unit matrix
431
432 rot[0][0] = 1.0;
433 rot[0][1] = 0.0;
434 rot[0][2] = 0.0;
435
436 rot[1][0] = 0.0;
437 rot[1][1] = 1.0;
438 rot[1][2] = 0.0;
439
440 rot[2][0] = 0.0;
441 rot[2][1] = 0.0;
442 rot[2][2] = 1.0;
443
444 // use a small angle aproximation for sin and cosine
445
446 angleSqr = angle * angle;
447 angleSqrOver4 = angleSqr / 4.0;
448 top = 1.0 - angleSqrOver4;
449 bottom = 1.0 + angleSqrOver4;
450
451 cosAngle = top / bottom;
452 sinAngle = angle / bottom;
453
454 rot[axes1][axes1] = cosAngle;
455 rot[axes2][axes2] = cosAngle;
456
457 rot[axes1][axes2] = sinAngle;
458 rot[axes2][axes1] = -sinAngle;
459
460 // rotate the momentum acoording to: ji[] = rot[][] * ji[]
461
462 for (i = 0; i < 3; i++){
463 ji[i] = 0.0;
464 for (k = 0; k < 3; k++){
465 ji[i] += rot[i][k] * tempJ[k];
466 }
467 }
468
469 // rotate the Rotation matrix acording to:
470 // A[][] = A[][] * transpose(rot[][])
471
472
473 // NOte for as yet unknown reason, we are performing the
474 // calculation as:
475 // transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
476
477 for (i = 0; i < 3; i++){
478 for (j = 0; j < 3; j++){
479 A[j][i] = 0.0;
480 for (k = 0; k < 3; k++){
481 A[j][i] += tempA[i][k] * rot[j][k];
482 }
483 }
484 }
485 }
486 ////////////////////////////////////////////////////////////////////////////////
487 //Implementation of DCRollBFunctor
488 ////////////////////////////////////////////////////////////////////////////////
489 int DCRollBFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
490 Vector3d posA;
491 Vector3d posB;
492 Vector3d velA;
493 Vector3d velB;
494 Vector3d pab;
495 Vector3d rab;
496 Vector3d vab;
497 Vector3d zetaA;
498 Vector3d zetaB;
499 Vector3d zeta;
500 Vector3d consForce;
501 Vector3d bondDirUnitVec;
502 double dt;
503 double pabDotvab;
504 double pabDotZeta;
505 double pvab;
506
507 const int conRBMaxIter = 100;
508
509 dt = info->dt;
510
511 for(int i=0 ; i < conRBMaxIter; i++){
512 consRB1->getCurAtomPos(posA.vec);
513 consRB2->getCurAtomPos(posB.vec);
514 pab = posB - posA;
515
516 //periodic boundary condition
517 info->wrapVector(pab.vec);
518
519 consRB1->getCurAtomVel(velA.vec);
520 consRB2->getCurAtomVel(velB.vec);
521 vab = velB -velA;
522
523 pvab = dotProduct(pab, vab);
524
525 if (fabs(pvab) > consTolerance ){
526
527
528 bondDirUnitVec = pab;
529 bondDirUnitVec.normalize();
530
531 getZeta(consRB1, bondDirUnitVec, zetaA);
532 getZeta(consRB2, bondDirUnitVec, zetaB);
533 zeta = zetaA + zetaB;
534
535 pabDotZeta = dotProduct(pab, zeta);
536
537 consForce = pvab / (dt * pabDotZeta) * bondDirUnitVec;
538 //integrate consRB1 using constraint force;
539 integrate(consRB1, consForce);
540
541 //integrate consRB2 using constraint force;
542 integrate(consRB2, -consForce);
543
544 }
545 else{
546 if (i ==0)
547 return consAlready;
548 else
549 return consSuccess;
550 }
551 }
552
553 cerr << "DCRollBFunctor::operator() Error: can not constrain the bond within maximum iteration at " << info->getTime() << endl;
554 return consExceedMaxIter;
555
556 }
557
558 void DCRollBFunctor::getZeta(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& zeta){
559 double invMass;
560 Vector3d tempVec1;
561 Vector3d tempVec2;
562 Vector3d refCoor;
563 Vector3d refCrossBond;
564 Mat3x3d IBody;
565 Mat3x3d ILab;
566 Mat3x3d invIBody;
567 Mat3x3d invILab;
568 Mat3x3d a;
569 Mat3x3d aTrans;
570
571 invMass = 1.0 / consRB ->getMass();
572
573 zeta = invMass * bondDir;
574
575 consRB->getRefCoor(refCoor.vec);
576 consRB->getA(a.element);
577 consRB->getI(IBody.element);
578
579 aTrans = a.transpose();
580 invIBody = IBody.inverse();
581
582 invILab = aTrans * invIBody * a;
583
584 refCrossBond = crossProduct(refCoor, bondDir);
585
586 tempVec1 = invILab * refCrossBond;
587 tempVec2 = crossProduct(tempVec1, refCoor);
588
589 zeta += tempVec2;
590 }
591
592 void DCRollBFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
593 Vector3d vel;
594 Vector3d ji;
595 Vector3d tempJi;
596 Vector3d tempTrq;
597 Vector3d refCoor;
598 double mass;
599 double dtOver2;
600 StuntDouble* sd;
601
602 sd = consRB->getStuntDouble();
603 dtOver2 = info->dt/2;
604
605 sd->getVel(vel.vec);
606 mass = sd->getMass();
607 vel +=dtOver2 /mass * force;
608 sd->setVel(vel.vec);
609
610 if (sd->isDirectional()){
611 tempTrq = crossProduct(refCoor, force);
612 sd->lab2Body(tempTrq.vec);
613 tempJi = dtOver2* tempTrq;
614 sd->getJ(ji.vec);
615 ji += tempJi;
616 sd->setJ(ji.vec);
617 }
618
619 }

Properties

Name Value
svn:executable *