ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/StuntDouble.cpp
Revision: 1234
Committed: Fri Jun 4 03:15:31 2004 UTC (20 years, 1 month ago) by tim
File size: 17079 byte(s)
Log Message:
new rattle algorithm is working

File Contents

# Content
1 #include "StuntDouble.hpp"
2 #include "Atom.hpp"
3 #include "DirectionalAtom.hpp"
4 #include "RigidBody.hpp"
5 #include "simError.h"
6
7 /*
8 "Don't move, or you're dead! Stand up! Captain, we've got them!"
9
10 "Spectacular stunt, my friends, but all for naught. Turn around
11 please. Ha. What a pity. What a pity. So, Princess, you thought
12 you could outwit the imperious forces of...."
13
14 "You idiots! These are not them. You've captured their stunt
15 doubles! Search the area. Find them! Find them!"
16
17 StuntDouble is a very strange idea. A StuntDouble stands in for
18 some object that can be manipulated by the Integrators or
19 Minimizers. Some of the manipulable objects are Atoms, some are
20 DirectionalAtoms, and some are RigidBodies. StuntDouble
21 provides an interface for the Integrators and Minimizers to use,
22 and does some preliminary sanity checking so that the program
23 doesn't try to do something stupid like torque an Atom. (The
24 quotes above are from Spaceballs...)
25
26 */
27
28 StuntDouble::~StuntDouble(){
29 map<string, GenericData*>::iterator iter;
30
31 for(iter = properties.begin(); iter != properties.end(); ){
32 delete iter->second;
33 iter = properties.erase(iter);
34 }
35
36 }
37
38 int StuntDouble::getObjType(){
39 return objType;
40 }
41
42 double StuntDouble::getMass(){
43 switch (objType)
44 {
45 case OT_ATOM :
46 case OT_DATOM:
47 return ((Atom*)this)->getMass();
48 break;
49 case OT_RIGIDBODY:
50 return ((RigidBody*)this)->getMass();
51 break;
52 default:
53 sprintf( painCave.errMsg,
54 "Unrecognized ObjType (%d) in StuntDouble::getMass.\n",
55 objType );
56 painCave.isFatal = 1;
57 simError();
58 return 0.0;
59 }
60 }
61
62
63 void StuntDouble::getPos(double pos[3]){
64 switch (objType)
65 {
66 case OT_ATOM :
67 case OT_DATOM:
68 ((Atom*)this)->getPos(pos);
69 break;
70 case OT_RIGIDBODY:
71 ((RigidBody*)this)->getPos(pos);
72 break;
73 default:
74 sprintf( painCave.errMsg,
75 "Unrecognized ObjType (%d) in StuntDouble::getPos.\n",
76 objType );
77 painCave.isFatal = 1;
78 simError();
79 }
80 }
81
82 void StuntDouble::getVel(double vel[3]){
83 switch (objType)
84 {
85 case OT_ATOM :
86 case OT_DATOM:
87 ((Atom*)this)->getVel(vel);
88 break;
89 case OT_RIGIDBODY:
90 ((RigidBody*)this)->getVel(vel);
91 break;
92 default:
93 sprintf( painCave.errMsg,
94 "Unrecognized ObjType (%d) in StuntDouble::getVel.\n",
95 objType );
96 painCave.isFatal = 1;
97 simError();
98 }
99 }
100
101 void StuntDouble::getFrc(double frc[3]){
102 switch (objType)
103 {
104 case OT_ATOM :
105 case OT_DATOM:
106 ((Atom*)this)->getFrc(frc);
107 break;
108 case OT_RIGIDBODY:
109 ((RigidBody*)this)->getFrc(frc);
110 break;
111 default:
112 sprintf( painCave.errMsg,
113 "Unrecognized ObjType (%d) in StuntDouble::getFrc.\n",
114 objType );
115 painCave.isFatal = 1;
116 simError();
117 }
118 }
119
120
121 void StuntDouble::setPos(double pos[3]){
122 switch (objType)
123 {
124 case OT_ATOM :
125 case OT_DATOM:
126 ((Atom*)this)->setPos(pos);
127 break;
128 case OT_RIGIDBODY:
129 ((RigidBody*)this)->setPos(pos);
130 break;
131 default:
132 sprintf( painCave.errMsg,
133 "Unrecognized ObjType (%d) in StuntDouble::setPos.\n",
134 objType );
135 painCave.isFatal = 1;
136 simError();
137 }
138 }
139
140 void StuntDouble::setVel(double vel[3]){
141 switch (objType)
142 {
143 case OT_ATOM :
144 case OT_DATOM:
145 ((Atom*)this)->setVel(vel);
146 break;
147 case OT_RIGIDBODY:
148 ((RigidBody*)this)->setVel(vel);
149 break;
150 default:
151 sprintf( painCave.errMsg,
152 "Unrecognized ObjType (%d) in StuntDouble::setVel.\n",
153 objType );
154 painCave.isFatal = 1;
155 simError();
156 }
157 }
158
159 void StuntDouble::addFrc(double frc[3]){
160 switch (objType)
161 {
162 case OT_ATOM :
163 case OT_DATOM:
164 ((Atom*)this)->addFrc(frc);
165 break;
166 case OT_RIGIDBODY:
167 ((RigidBody*)this)->addFrc(frc);
168 break;
169 default:
170 sprintf( painCave.errMsg,
171 "Unrecognized ObjType (%d) in StuntDouble::addFrc.\n",
172 objType );
173 painCave.isFatal = 1;
174 simError();
175 }
176 }
177
178 void StuntDouble::getA(double A[3][3]){
179 switch (objType)
180 {
181 case OT_ATOM:
182 sprintf( painCave.errMsg,
183 "StuntDouble::getA was called for a regular atom.\n"
184 "\tRegular Atoms don't have rotation matrices. Be smarter.\n");
185 painCave.isFatal = 0;
186 simError();
187 // Return unit matrix
188 A[0][0] = 1; A[0][1] = 0; A[0][2] = 0;
189 A[1][0] = 0; A[1][1] = 1; A[1][2] = 0;
190 A[2][0] = 0; A[2][1] = 0; A[2][2] = 1;
191 break;
192 case OT_DATOM:
193 ((DirectionalAtom*)this)->getA(A);
194 break;
195 case OT_RIGIDBODY:
196 ((RigidBody*)this)->getA(A);
197 break;
198 default:
199 sprintf( painCave.errMsg,
200 "Unrecognized ObjType (%d) in StuntDouble::getA.\n",
201 objType );
202 painCave.isFatal = 1;
203 simError();
204 }
205 }
206
207 void StuntDouble::setA(double A[3][3]){
208 switch (objType)
209 {
210 case OT_ATOM:
211 sprintf( painCave.errMsg,
212 "StuntDouble::setA was called for a regular atom.\n"
213 "\tRegular Atoms don't have rotation matrices. Be smarter.\n");
214 painCave.isFatal = 1;
215 simError();
216 break;
217 case OT_DATOM:
218 ((DirectionalAtom*)this)->setA(A);
219 break;
220 case OT_RIGIDBODY:
221 ((RigidBody*)this)->setA(A);
222 break;
223 default:
224 sprintf( painCave.errMsg,
225 "Unrecognized ObjType (%d) in StuntDouble::setA.\n",
226 objType );
227 painCave.isFatal = 1;
228 simError();
229 }
230 }
231
232 void StuntDouble::getJ(double j[3]){
233 switch (objType)
234 {
235 case OT_ATOM:
236 sprintf( painCave.errMsg,
237 "StuntDouble::getJ was called for a regular atom.\n"
238 "\tRegular Atoms don't have angular momentum. Be smarter.\n");
239 painCave.isFatal = 0;
240 simError();
241 // Return zeros.
242 j[0] = 0;
243 j[1] = 0;
244 j[2] = 0;
245 break;
246 case OT_DATOM:
247 ((DirectionalAtom*)this)->getJ(j);
248 break;
249 case OT_RIGIDBODY:
250 ((RigidBody*)this)->getJ(j);
251 break;
252 default:
253 sprintf( painCave.errMsg,
254 "Unrecognized ObjType (%d) in StuntDouble::getJ.\n",
255 objType );
256 painCave.isFatal = 1;
257 simError();
258 }
259 }
260
261 void StuntDouble::setJ(double j[3]){
262 switch (objType)
263 {
264 case OT_ATOM:
265 sprintf( painCave.errMsg,
266 "StuntDouble::setJ was called for a regular atom.\n"
267 "\tRegular Atoms don't have angular momentum. Be smarter.\n");
268 painCave.isFatal = 1;
269 simError();
270 break;
271 case OT_DATOM:
272 ((DirectionalAtom*)this)->setJ(j);
273 break;
274 case OT_RIGIDBODY:
275 ((RigidBody*)this)->setJ(j);
276 break;
277 default:
278 sprintf( painCave.errMsg,
279 "Unrecognized ObjType (%d) in StuntDouble::setJ.\n",
280 objType );
281 painCave.isFatal = 1;
282 simError();
283 }
284 }
285
286 void StuntDouble::getQ(double q[4] ){
287 switch (objType)
288 {
289 case OT_ATOM:
290 sprintf( painCave.errMsg,
291 "StuntDouble::getJ was called for a regular atom.\n"
292 "\tRegular Atoms don't have angular momentum. Be smarter.\n");
293 painCave.isFatal = 0;
294 simError();
295 // Return zeros.
296 q[0] = 0;
297 q[1] = 0;
298 q[2] = 0;
299 q[3] = 0;
300 break;
301 case OT_DATOM:
302 ((DirectionalAtom*)this)->getQ(q);
303 break;
304 case OT_RIGIDBODY:
305 ((RigidBody*)this)->getQ(q);
306 break;
307 default:
308 sprintf( painCave.errMsg,
309 "Unrecognized ObjType (%d) in StuntDouble::getJ.\n",
310 objType );
311 painCave.isFatal = 1;
312 simError();
313 }
314 }
315
316 void StuntDouble::setQ(double q[4] ){
317 switch (objType)
318 {
319 case OT_ATOM:
320 sprintf( painCave.errMsg,
321 "StuntDouble::setJ was called for a regular atom.\n"
322 "\tRegular Atoms don't have angular momentum. Be smarter.\n");
323 painCave.isFatal = 1;
324 simError();
325 break;
326 case OT_DATOM:
327 ((DirectionalAtom*)this)->setJ(q);
328 break;
329 case OT_RIGIDBODY:
330 ((RigidBody*)this)->setJ(q);
331 break;
332 default:
333 sprintf( painCave.errMsg,
334 "Unrecognized ObjType (%d) in StuntDouble::setJ.\n",
335 objType );
336 painCave.isFatal = 1;
337 simError();
338 }
339 }
340 void StuntDouble::getTrq(double trq[3]){
341 switch (objType)
342 {
343 case OT_ATOM:
344 sprintf( painCave.errMsg,
345 "StuntDouble::getTrq was called for a regular atom.\n"
346 "\tRegular Atoms don't have torques. Be smarter.\n");
347 painCave.isFatal = 0;
348 simError();
349 // Return zeros.
350 trq[0] = 0;
351 trq[1] = 0;
352 trq[2] = 0;
353 break;
354 case OT_DATOM:
355 ((DirectionalAtom*)this)->getTrq(trq);
356 break;
357 case OT_RIGIDBODY:
358 ((RigidBody*)this)->getTrq(trq);
359 break;
360 default:
361 sprintf( painCave.errMsg,
362 "Unrecognized ObjType (%d) in StuntDouble::getTrq.\n",
363 objType );
364 painCave.isFatal = 1;
365 simError();
366 }
367 }
368
369 void StuntDouble::addTrq(double trq[3]){
370 switch (objType)
371 {
372 case OT_ATOM:
373 sprintf( painCave.errMsg,
374 "StuntDouble::addTrq was called for a regular atom.\n"
375 "\tRegular Atoms don't have torques. Be smarter.\n");
376 painCave.isFatal = 1;
377 simError();
378 break;
379 case OT_DATOM:
380 ((DirectionalAtom*)this)->addTrq(trq);
381 break;
382 case OT_RIGIDBODY:
383 ((RigidBody*)this)->addTrq(trq);
384 break;
385 default:
386 sprintf( painCave.errMsg,
387 "Unrecognized ObjType (%d) in StuntDouble::addTrq.\n",
388 objType );
389 painCave.isFatal = 1;
390 simError();
391 }
392 }
393
394 void StuntDouble::getI(double I[3][3]){
395 switch (objType)
396 {
397 case OT_ATOM:
398 sprintf( painCave.errMsg,
399 "StuntDouble::getI was called for a regular atom.\n"
400 "\tRegular Atoms don't have moments of inertia. Be smarter.\n");
401 painCave.isFatal = 0;
402 simError();
403 // Return zero matrix
404 I[0][0] = 0; I[0][1] = 0; I[0][2] = 0;
405 I[1][0] = 0; I[1][1] = 0; I[1][2] = 0;
406 I[2][0] = 0; I[2][1] = 0; I[2][2] = 0;
407 break;
408 case OT_DATOM:
409 ((DirectionalAtom*)this)->getI(I);
410 break;
411 case OT_RIGIDBODY:
412 ((RigidBody*)this)->getI(I);
413 break;
414 default:
415 sprintf( painCave.errMsg,
416 "Unrecognized ObjType (%d) in StuntDouble::getI.\n",
417 objType );
418 painCave.isFatal = 1;
419 simError();
420 }
421 }
422
423 void StuntDouble::lab2Body(double vec[3]){
424 switch (objType)
425 {
426 case OT_ATOM:
427 sprintf( painCave.errMsg,
428 "StuntDouble::lab2Body was called for a regular atom.\n"
429 "\tRegular Atoms don't have reference frames. Be smarter.\n");
430 painCave.isFatal = 0;
431 simError();
432 break;
433 case OT_DATOM:
434 ((DirectionalAtom*)this)->lab2Body(vec);
435 break;
436 case OT_RIGIDBODY:
437 ((RigidBody*)this)->lab2Body(vec);
438 break;
439 default:
440 sprintf( painCave.errMsg,
441 "Unrecognized ObjType (%d) in StuntDouble::lab2Body.\n",
442 objType );
443 painCave.isFatal = 1;
444 simError();
445 }
446 }
447
448 void StuntDouble::getGrad(double grad[6]){
449 double frc[3];
450
451 switch (objType)
452 {
453 case OT_ATOM:
454 sprintf( painCave.errMsg,
455 "StuntDouble::getGrad was called for a regular atom.\n"
456 "\tRegular Atoms don't have 6 coordinates. Be smarter.\n");
457 painCave.isFatal = 0;
458 simError();
459 ((Atom*)this)->getFrc(frc);
460 grad[0] = -frc[0];
461 grad[1] = -frc[1];
462 grad[2] = -frc[2];
463 grad[3] = 0.0;
464 grad[4] = 0.0;
465 grad[5] = 0.0;
466 break;
467 case OT_DATOM:
468 ((DirectionalAtom*)this)->getGrad(grad);
469 break;
470 case OT_RIGIDBODY:
471 ((RigidBody*)this)->getGrad(grad);
472 break;
473 default:
474 sprintf( painCave.errMsg,
475 "Unrecognized ObjType (%d) in StuntDouble::getGrad.\n",
476 objType );
477 painCave.isFatal = 1;
478 simError();
479 }
480 }
481
482 void StuntDouble::setEuler(double phi, double theta, double psi){
483 switch (objType)
484 {
485 case OT_ATOM:
486 sprintf( painCave.errMsg,
487 "StuntDouble::setEuler was called for a regular atom.\n"
488 "\tRegular Atoms don't have Euler Angles. Be smarter.\n");
489 painCave.isFatal = 1;
490 simError();
491 break;
492 case OT_DATOM:
493 ((DirectionalAtom*)this)->setEuler(phi, theta, psi);
494 break;
495 case OT_RIGIDBODY:
496 ((RigidBody*)this)->setEuler(phi, theta, psi);
497 break;
498 default:
499 sprintf( painCave.errMsg,
500 "Unrecognized ObjType (%d) in StuntDouble::setA.\n",
501 objType );
502 painCave.isFatal = 1;
503 simError();
504 }
505 }
506
507 void StuntDouble::getEulerAngles(double eulers[3]){
508 switch (objType)
509 {
510 case OT_ATOM:
511 sprintf( painCave.errMsg,
512 "StuntDouble::getEulerAngles was called for a regular atom.\n"
513 "\tRegular Atoms don't have Euler angles. Be smarter.\n");
514 painCave.isFatal = 0;
515 simError();
516 // Return zeros.
517 eulers[0] = 0;
518 eulers[1] = 0;
519 eulers[2] = 0;
520 break;
521 case OT_DATOM:
522 ((DirectionalAtom*)this)->getEulerAngles(eulers);
523 break;
524 case OT_RIGIDBODY:
525 ((RigidBody*)this)->getEulerAngles(eulers);
526 break;
527 default:
528 sprintf( painCave.errMsg,
529 "Unrecognized ObjType (%d) in StuntDouble::getEulerAngles.\n",
530 objType );
531 painCave.isFatal = 1;
532 simError();
533 }
534 }
535
536 double StuntDouble::getZangle(){
537 switch (objType)
538 {
539 case OT_ATOM:
540 sprintf( painCave.errMsg,
541 "StuntDouble::getZangle was called for a regular atom.\n"
542 "\tRegular Atoms don't have zAngles. Be smarter.\n");
543 painCave.isFatal = 0;
544 simError();
545 // Return zeros.
546 return 0;
547 break;
548 case OT_DATOM:
549 return ((DirectionalAtom*)this)->getZangle();
550 break;
551 case OT_RIGIDBODY:
552 return ((RigidBody*)this)->getZangle();
553 break;
554 default:
555 sprintf( painCave.errMsg,
556 "Unrecognized ObjType (%d) in StuntDouble::getZangle.\n",
557 objType );
558 painCave.isFatal = 1;
559 simError();
560 return 0;
561 }
562 }
563
564 void StuntDouble::setZangle(double zAngle){
565 switch (objType)
566 {
567 case OT_ATOM:
568 sprintf( painCave.errMsg,
569 "StuntDouble::setZangle was called for a regular atom.\n"
570 "\tRegular Atoms don't have zAngles. Be smarter.\n");
571 painCave.isFatal = 1;
572 simError();
573 break;
574 case OT_DATOM:
575 ((DirectionalAtom*)this)->setZangle(zAngle);
576 break;
577 case OT_RIGIDBODY:
578 ((RigidBody*)this)->setZangle(zAngle);
579 break;
580 default:
581 sprintf( painCave.errMsg,
582 "Unrecognized ObjType (%d) in StuntDouble::setZangle.\n",
583 objType );
584 painCave.isFatal = 1;
585 simError();
586 }
587 }
588
589 void StuntDouble::addZangle(double zAngle){
590 switch (objType)
591 {
592 case OT_ATOM:
593 sprintf( painCave.errMsg,
594 "StuntDouble::addZangle was called for a regular atom.\n"
595 "\tRegular Atoms don't have zAngles. Be smarter.\n");
596 painCave.isFatal = 1;
597 simError();
598 break;
599 case OT_DATOM:
600 ((DirectionalAtom*)this)->addZangle(zAngle);
601 break;
602 case OT_RIGIDBODY:
603 ((RigidBody*)this)->addZangle(zAngle);
604 break;
605 default:
606 sprintf( painCave.errMsg,
607 "Unrecognized ObjType (%d) in StuntDouble::addZangle.\n",
608 objType );
609 painCave.isFatal = 1;
610 simError();
611 }
612 }
613
614 void StuntDouble::addProperty(GenericData* data){
615 map<string, GenericData*>::iterator result;
616 result = properties.find(data->getID());
617
618 //we can't simply use properties[prop->getID()] = prop,
619 //it will cause memory leak if we already contain a propery which has the same name of prop
620
621 if(result != properties.end()){
622 delete (*result).second;
623 (*result).second = data;
624 }
625 else
626 properties[data->getID()] = data;
627
628
629 }
630 void StuntDouble::removeProperty(const string& propName){
631 map<string, GenericData*>::iterator result;
632
633 result = properties.find(propName);
634
635 if(result != properties.end()){
636 delete result->second;
637 properties.erase(result);
638
639 }
640
641 }
642 GenericData* StuntDouble::getProperty(const string& propName){
643 map<string, GenericData*>::iterator result;
644
645
646 result = properties.find(propName);
647
648 if(result != properties.end())
649 return (*result).second;
650 else
651 return NULL;
652 }

Properties

Name Value
svn:executable *