ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 781
Committed: Mon Sep 22 23:07:57 2003 UTC (20 years, 9 months ago) by tim
File size: 14402 byte(s)
Log Message:
fix bug in calculating maxCutoff

File Contents

# User Rev Content
1 mmeineke 377 #include <cstdlib>
2     #include <cstring>
3 mmeineke 568 #include <cmath>
4 mmeineke 377
5 mmeineke 572 #include <iostream>
6     using namespace std;
7 mmeineke 377
8     #include "SimInfo.hpp"
9     #define __C
10     #include "fSimulation.h"
11     #include "simError.h"
12    
13     #include "fortranWrappers.hpp"
14    
15 gezelter 490 #ifdef IS_MPI
16     #include "mpiSimulation.hpp"
17     #endif
18    
19 mmeineke 572 inline double roundMe( double x ){
20     return ( x >= 0 ) ? floor( x + 0.5 ) : ceil( x - 0.5 );
21     }
22    
23    
24 mmeineke 377 SimInfo* currentInfo;
25    
26     SimInfo::SimInfo(){
27     excludes = NULL;
28     n_constraints = 0;
29 tim 699 nZconstraints = 0;
30 mmeineke 377 n_oriented = 0;
31     n_dipoles = 0;
32 gezelter 458 ndf = 0;
33     ndfRaw = 0;
34 mmeineke 674 nZconstraints = 0;
35 mmeineke 377 the_integrator = NULL;
36     setTemp = 0;
37     thermalTime = 0.0;
38 mmeineke 642 currentTime = 0.0;
39 mmeineke 420 rCut = 0.0;
40 mmeineke 690 origRcut = -1.0;
41 mmeineke 618 ecr = 0.0;
42 mmeineke 690 origEcr = -1.0;
43 mmeineke 619 est = 0.0;
44 mmeineke 626 oldEcr = 0.0;
45     oldRcut = 0.0;
46 mmeineke 377
47 mmeineke 626 haveOrigRcut = 0;
48     haveOrigEcr = 0;
49     boxIsInit = 0;
50    
51 tim 781 resetTime = 1e99;
52 mmeineke 626
53    
54 mmeineke 377 usePBC = 0;
55     useLJ = 0;
56     useSticky = 0;
57     useDipole = 0;
58     useReactionField = 0;
59     useGB = 0;
60     useEAM = 0;
61    
62 mmeineke 670 myConfiguration = new SimState();
63    
64 gezelter 457 wrapMeSimInfo( this );
65     }
66 mmeineke 377
67 mmeineke 670
68 tim 660 SimInfo::~SimInfo(){
69    
70 mmeineke 670 delete myConfiguration;
71    
72 tim 660 map<string, GenericData*>::iterator i;
73    
74     for(i = properties.begin(); i != properties.end(); i++)
75     delete (*i).second;
76 mmeineke 670
77 tim 660 }
78    
79 gezelter 457 void SimInfo::setBox(double newBox[3]) {
80 mmeineke 586
81 gezelter 588 int i, j;
82     double tempMat[3][3];
83 gezelter 463
84 gezelter 588 for(i=0; i<3; i++)
85     for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
86 gezelter 463
87 gezelter 588 tempMat[0][0] = newBox[0];
88     tempMat[1][1] = newBox[1];
89     tempMat[2][2] = newBox[2];
90 gezelter 463
91 mmeineke 586 setBoxM( tempMat );
92 mmeineke 568
93 gezelter 457 }
94 mmeineke 377
95 gezelter 588 void SimInfo::setBoxM( double theBox[3][3] ){
96 mmeineke 568
97 gezelter 588 int i, j, status;
98 mmeineke 568 double smallestBoxL, maxCutoff;
99 gezelter 588 double FortranHmat[9]; // to preserve compatibility with Fortran the
100     // ordering in the array is as follows:
101     // [ 0 3 6 ]
102     // [ 1 4 7 ]
103     // [ 2 5 8 ]
104     double FortranHmatInv[9]; // the inverted Hmat (for Fortran);
105 mmeineke 568
106 mmeineke 626
107     if( !boxIsInit ) boxIsInit = 1;
108 mmeineke 586
109 gezelter 588 for(i=0; i < 3; i++)
110     for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
111    
112 mmeineke 568 calcBoxL();
113 gezelter 588 calcHmatInv();
114 mmeineke 568
115 gezelter 588 for(i=0; i < 3; i++) {
116     for (j=0; j < 3; j++) {
117     FortranHmat[3*j + i] = Hmat[i][j];
118     FortranHmatInv[3*j + i] = HmatInv[i][j];
119     }
120     }
121 mmeineke 586
122 mmeineke 590 setFortranBoxSize(FortranHmat, FortranHmatInv, &orthoRhombic);
123 mmeineke 568
124 mmeineke 377 }
125 gezelter 458
126 mmeineke 568
127 gezelter 588 void SimInfo::getBoxM (double theBox[3][3]) {
128 mmeineke 568
129 gezelter 588 int i, j;
130     for(i=0; i<3; i++)
131     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j];
132 mmeineke 568 }
133    
134 gezelter 574
135     void SimInfo::scaleBox(double scale) {
136 gezelter 588 double theBox[3][3];
137     int i, j;
138 gezelter 574
139 gezelter 617 // cerr << "Scaling box by " << scale << "\n";
140 mmeineke 586
141 gezelter 588 for(i=0; i<3; i++)
142     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j]*scale;
143 gezelter 574
144     setBoxM(theBox);
145    
146     }
147    
148 gezelter 588 void SimInfo::calcHmatInv( void ) {
149 mmeineke 590
150     int i,j;
151 mmeineke 569 double smallDiag;
152     double tol;
153     double sanity[3][3];
154 mmeineke 568
155 gezelter 588 invertMat3( Hmat, HmatInv );
156 mmeineke 568
157 gezelter 588 // Check the inverse to make sure it is sane:
158 mmeineke 568
159 gezelter 588 matMul3( Hmat, HmatInv, sanity );
160    
161     // check to see if Hmat is orthorhombic
162 mmeineke 568
163 gezelter 588 smallDiag = Hmat[0][0];
164     if(smallDiag > Hmat[1][1]) smallDiag = Hmat[1][1];
165     if(smallDiag > Hmat[2][2]) smallDiag = Hmat[2][2];
166     tol = smallDiag * 1E-6;
167 mmeineke 568
168 gezelter 588 orthoRhombic = 1;
169 mmeineke 568
170 gezelter 588 for (i = 0; i < 3; i++ ) {
171     for (j = 0 ; j < 3; j++) {
172     if (i != j) {
173     if (orthoRhombic) {
174     if (Hmat[i][j] >= tol) orthoRhombic = 0;
175     }
176     }
177 mmeineke 568 }
178     }
179 gezelter 588 }
180 mmeineke 569
181 gezelter 588 double SimInfo::matDet3(double a[3][3]) {
182     int i, j, k;
183     double determinant;
184 mmeineke 569
185 gezelter 588 determinant = 0.0;
186    
187     for(i = 0; i < 3; i++) {
188     j = (i+1)%3;
189     k = (i+2)%3;
190    
191     determinant += a[0][i] * (a[1][j]*a[2][k] - a[1][k]*a[2][j]);
192 mmeineke 569 }
193    
194 gezelter 588 return determinant;
195     }
196 mmeineke 569
197 gezelter 588 void SimInfo::invertMat3(double a[3][3], double b[3][3]) {
198 mmeineke 569
199 gezelter 588 int i, j, k, l, m, n;
200     double determinant;
201 mmeineke 569
202 gezelter 588 determinant = matDet3( a );
203    
204     if (determinant == 0.0) {
205     sprintf( painCave.errMsg,
206     "Can't invert a matrix with a zero determinant!\n");
207     painCave.isFatal = 1;
208     simError();
209     }
210    
211     for (i=0; i < 3; i++) {
212     j = (i+1)%3;
213     k = (i+2)%3;
214     for(l = 0; l < 3; l++) {
215     m = (l+1)%3;
216     n = (l+2)%3;
217    
218     b[l][i] = (a[j][m]*a[k][n] - a[j][n]*a[k][m]) / determinant;
219 mmeineke 569 }
220     }
221 mmeineke 568 }
222    
223 gezelter 588 void SimInfo::matMul3(double a[3][3], double b[3][3], double c[3][3]) {
224     double r00, r01, r02, r10, r11, r12, r20, r21, r22;
225    
226     r00 = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0];
227     r01 = a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1];
228     r02 = a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2];
229    
230     r10 = a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0];
231     r11 = a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1];
232     r12 = a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2];
233    
234     r20 = a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0];
235     r21 = a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1];
236     r22 = a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2];
237    
238     c[0][0] = r00; c[0][1] = r01; c[0][2] = r02;
239     c[1][0] = r10; c[1][1] = r11; c[1][2] = r12;
240     c[2][0] = r20; c[2][1] = r21; c[2][2] = r22;
241     }
242    
243     void SimInfo::matVecMul3(double m[3][3], double inVec[3], double outVec[3]) {
244     double a0, a1, a2;
245    
246     a0 = inVec[0]; a1 = inVec[1]; a2 = inVec[2];
247    
248     outVec[0] = m[0][0]*a0 + m[0][1]*a1 + m[0][2]*a2;
249     outVec[1] = m[1][0]*a0 + m[1][1]*a1 + m[1][2]*a2;
250     outVec[2] = m[2][0]*a0 + m[2][1]*a1 + m[2][2]*a2;
251     }
252 mmeineke 597
253     void SimInfo::transposeMat3(double in[3][3], double out[3][3]) {
254     double temp[3][3];
255     int i, j;
256    
257     for (i = 0; i < 3; i++) {
258     for (j = 0; j < 3; j++) {
259     temp[j][i] = in[i][j];
260     }
261     }
262     for (i = 0; i < 3; i++) {
263     for (j = 0; j < 3; j++) {
264     out[i][j] = temp[i][j];
265     }
266     }
267     }
268 gezelter 588
269 mmeineke 597 void SimInfo::printMat3(double A[3][3] ){
270    
271     std::cerr
272     << "[ " << A[0][0] << ", " << A[0][1] << ", " << A[0][2] << " ]\n"
273     << "[ " << A[1][0] << ", " << A[1][1] << ", " << A[1][2] << " ]\n"
274     << "[ " << A[2][0] << ", " << A[2][1] << ", " << A[2][2] << " ]\n";
275     }
276    
277     void SimInfo::printMat9(double A[9] ){
278    
279     std::cerr
280     << "[ " << A[0] << ", " << A[1] << ", " << A[2] << " ]\n"
281     << "[ " << A[3] << ", " << A[4] << ", " << A[5] << " ]\n"
282     << "[ " << A[6] << ", " << A[7] << ", " << A[8] << " ]\n";
283     }
284    
285 tim 781
286     void SimInfo::crossProduct3(double a[3],double b[3], double out[3]){
287    
288     out[0] = a[1] * b[2] - a[2] * b[1];
289     out[1] = a[2] * b[0] - a[0] * b[2] ;
290     out[2] = a[0] * b[1] - a[1] * b[0];
291    
292     }
293    
294     double SimInfo::dotProduct3(double a[3], double b[3]){
295     return a[0]*b[0] + a[1]*b[1]+ a[2]*b[2];
296     }
297    
298     double SimInfo::length3(double a[3]){
299     return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
300     }
301    
302 mmeineke 568 void SimInfo::calcBoxL( void ){
303    
304     double dx, dy, dz, dsq;
305     int i;
306    
307 gezelter 588 // boxVol = Determinant of Hmat
308 mmeineke 568
309 gezelter 588 boxVol = matDet3( Hmat );
310 mmeineke 568
311     // boxLx
312    
313 gezelter 588 dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
314 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
315 gezelter 621 boxL[0] = sqrt( dsq );
316 tim 781 //maxCutoff = 0.5 * boxL[0];
317 mmeineke 568
318     // boxLy
319    
320 gezelter 588 dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
321 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
322 gezelter 621 boxL[1] = sqrt( dsq );
323 tim 781 //if( (0.5 * boxL[1]) < maxCutoff ) maxCutoff = 0.5 * boxL[1];
324 mmeineke 568
325 tim 781
326 mmeineke 568 // boxLz
327    
328 gezelter 588 dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
329 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
330 gezelter 621 boxL[2] = sqrt( dsq );
331 tim 781 //if( (0.5 * boxL[2]) < maxCutoff ) maxCutoff = 0.5 * boxL[2];
332    
333     //calculate the max cutoff
334     maxCutoff = calcMaxCutOff();
335 chuckv 669
336     checkCutOffs();
337 mmeineke 626
338 mmeineke 568 }
339    
340    
341 tim 781 double SimInfo::calcMaxCutOff(){
342    
343     double ri[3], rj[3], rk[3];
344     double rij[3], rjk[3], rki[3];
345     double minDist;
346    
347     ri[0] = Hmat[0][0];
348     ri[1] = Hmat[1][0];
349     ri[2] = Hmat[2][0];
350    
351     rj[0] = Hmat[0][1];
352     rj[1] = Hmat[1][1];
353     rj[2] = Hmat[2][1];
354    
355     rk[0] = Hmat[0][2];
356     rk[1] = Hmat[1][2];
357     rk[2] = Hmat[2][2];
358    
359     crossProduct3(ri,rj, rij);
360     distXY = dotProduct3(rk,rij) / length3(rij);
361    
362     crossProduct3(rj,rk, rjk);
363     distYZ = dotProduct3(ri,rjk) / length3(rjk);
364    
365     crossProduct3(rk,ri, rki);
366     distZX = dotProduct3(rj,rki) / length3(rki);
367    
368     minDist = min(min(distXY, distYZ), distZX);
369     return minDist/2;
370    
371     }
372    
373 mmeineke 568 void SimInfo::wrapVector( double thePos[3] ){
374    
375     int i, j, k;
376     double scaled[3];
377    
378 mmeineke 569 if( !orthoRhombic ){
379     // calc the scaled coordinates.
380 gezelter 588
381    
382     matVecMul3(HmatInv, thePos, scaled);
383 mmeineke 569
384     for(i=0; i<3; i++)
385 mmeineke 572 scaled[i] -= roundMe(scaled[i]);
386 mmeineke 569
387     // calc the wrapped real coordinates from the wrapped scaled coordinates
388    
389 gezelter 588 matVecMul3(Hmat, scaled, thePos);
390    
391 mmeineke 569 }
392     else{
393     // calc the scaled coordinates.
394    
395     for(i=0; i<3; i++)
396 gezelter 588 scaled[i] = thePos[i]*HmatInv[i][i];
397 mmeineke 569
398     // wrap the scaled coordinates
399    
400     for(i=0; i<3; i++)
401 mmeineke 572 scaled[i] -= roundMe(scaled[i]);
402 mmeineke 569
403     // calc the wrapped real coordinates from the wrapped scaled coordinates
404    
405     for(i=0; i<3; i++)
406 gezelter 588 thePos[i] = scaled[i]*Hmat[i][i];
407 mmeineke 569 }
408    
409 mmeineke 568 }
410    
411    
412 gezelter 458 int SimInfo::getNDF(){
413     int ndf_local, ndf;
414 gezelter 457
415 gezelter 458 ndf_local = 3 * n_atoms + 3 * n_oriented - n_constraints;
416    
417     #ifdef IS_MPI
418     MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
419     #else
420     ndf = ndf_local;
421     #endif
422    
423 mmeineke 674 ndf = ndf - 3 - nZconstraints;
424 gezelter 458
425     return ndf;
426     }
427    
428     int SimInfo::getNDFraw() {
429     int ndfRaw_local, ndfRaw;
430    
431     // Raw degrees of freedom that we have to set
432     ndfRaw_local = 3 * n_atoms + 3 * n_oriented;
433    
434     #ifdef IS_MPI
435     MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
436     #else
437     ndfRaw = ndfRaw_local;
438     #endif
439    
440     return ndfRaw;
441     }
442 tim 767
443     int SimInfo::getNDFtranslational() {
444     int ndfTrans_local, ndfTrans;
445    
446     ndfTrans_local = 3 * n_atoms - n_constraints;
447    
448     #ifdef IS_MPI
449     MPI_Allreduce(&ndfTrans_local,&ndfTrans,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
450     #else
451     ndfTrans = ndfTrans_local;
452     #endif
453    
454     ndfTrans = ndfTrans - 3 - nZconstraints;
455    
456     return ndfTrans;
457     }
458    
459 mmeineke 377 void SimInfo::refreshSim(){
460    
461     simtype fInfo;
462     int isError;
463 gezelter 490 int n_global;
464 mmeineke 424 int* excl;
465 mmeineke 626
466 mmeineke 469 fInfo.dielect = 0.0;
467 mmeineke 377
468 mmeineke 469 if( useDipole ){
469     if( useReactionField )fInfo.dielect = dielectric;
470     }
471    
472 mmeineke 377 fInfo.SIM_uses_PBC = usePBC;
473 mmeineke 443 //fInfo.SIM_uses_LJ = 0;
474 chuckv 439 fInfo.SIM_uses_LJ = useLJ;
475 mmeineke 443 fInfo.SIM_uses_sticky = useSticky;
476     //fInfo.SIM_uses_sticky = 0;
477 chuckv 482 fInfo.SIM_uses_dipoles = useDipole;
478     //fInfo.SIM_uses_dipoles = 0;
479 mmeineke 443 //fInfo.SIM_uses_RF = useReactionField;
480     fInfo.SIM_uses_RF = 0;
481 mmeineke 377 fInfo.SIM_uses_GB = useGB;
482     fInfo.SIM_uses_EAM = useEAM;
483    
484 mmeineke 424 excl = Exclude::getArray();
485 mmeineke 377
486 gezelter 490 #ifdef IS_MPI
487     n_global = mpiSim->getTotAtoms();
488     #else
489     n_global = n_atoms;
490     #endif
491    
492 mmeineke 377 isError = 0;
493    
494 gezelter 490 setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
495 gezelter 483 &nGlobalExcludes, globalExcludes, molMembershipArray,
496     &isError );
497 mmeineke 377
498     if( isError ){
499    
500     sprintf( painCave.errMsg,
501     "There was an error setting the simulation information in fortran.\n" );
502     painCave.isFatal = 1;
503     simError();
504     }
505    
506     #ifdef IS_MPI
507     sprintf( checkPointMsg,
508     "succesfully sent the simulation information to fortran.\n");
509     MPIcheckPoint();
510     #endif // is_mpi
511 gezelter 458
512 gezelter 474 this->ndf = this->getNDF();
513     this->ndfRaw = this->getNDFraw();
514 tim 767 this->ndfTrans = this->getNDFtranslational();
515 mmeineke 377 }
516    
517 mmeineke 626
518     void SimInfo::setRcut( double theRcut ){
519    
520     if( !haveOrigRcut ){
521     haveOrigRcut = 1;
522     origRcut = theRcut;
523     }
524    
525     rCut = theRcut;
526     checkCutOffs();
527     }
528    
529     void SimInfo::setEcr( double theEcr ){
530    
531     if( !haveOrigEcr ){
532     haveOrigEcr = 1;
533     origEcr = theEcr;
534     }
535    
536     ecr = theEcr;
537     checkCutOffs();
538     }
539    
540     void SimInfo::setEcr( double theEcr, double theEst ){
541    
542     est = theEst;
543     setEcr( theEcr );
544     }
545    
546    
547     void SimInfo::checkCutOffs( void ){
548    
549     int cutChanged = 0;
550 gezelter 770
551 mmeineke 626 if( boxIsInit ){
552    
553     //we need to check cutOffs against the box
554 tim 781
555     //detect the change of rCut
556 chuckv 669 if(( maxCutoff > rCut )&&(usePBC)){
557 mmeineke 626 if( rCut < origRcut ){
558 tim 781 rCut = origRcut;
559    
560     if (rCut > maxCutoff)
561     rCut = maxCutoff;
562    
563     sprintf( painCave.errMsg,
564     "New Box size is setting the long range cutoff radius "
565     "to %lf at time %lf\n",
566     rCut, currentTime );
567     painCave.isFatal = 0;
568     simError();
569 mmeineke 626 }
570     }
571 tim 781 else if ((rCut > maxCutoff)&&(usePBC)) {
572 mmeineke 626 sprintf( painCave.errMsg,
573     "New Box size is setting the long range cutoff radius "
574 tim 781 "to %lf at time %lf\n",
575 gezelter 770 maxCutoff, currentTime );
576 mmeineke 626 painCave.isFatal = 0;
577     simError();
578     rCut = maxCutoff;
579     }
580 tim 781
581    
582     //detect the change of ecr
583     if( maxCutoff > ecr ){
584     if( ecr < origEcr ){
585     ecr = origEcr;
586     if (ecr > maxCutoff) ecr = maxCutoff;
587    
588     sprintf( painCave.errMsg,
589     "New Box size is setting the electrostaticCutoffRadius "
590     "to %lf at time %lf\n",
591     ecr, currentTime );
592     painCave.isFatal = 0;
593     simError();
594     }
595     }
596     else if( ecr > maxCutoff){
597 mmeineke 626 sprintf( painCave.errMsg,
598     "New Box size is setting the electrostaticCutoffRadius "
599 gezelter 770 "to %lf at time %lf\n",
600     maxCutoff, currentTime );
601 mmeineke 626 painCave.isFatal = 0;
602     simError();
603     ecr = maxCutoff;
604     }
605    
606 tim 767 if( (oldEcr != ecr) || ( oldRcut != rCut ) ) cutChanged = 1;
607 gezelter 770
608 tim 767 // rlist is the 1.0 plus max( rcut, ecr )
609 mmeineke 626
610 tim 767 ( rCut > ecr )? rList = rCut + 1.0: rList = ecr + 1.0;
611    
612     if( cutChanged ){
613    
614     notifyFortranCutOffs( &rCut, &rList, &ecr, &est );
615     }
616    
617     oldEcr = ecr;
618     oldRcut = rCut;
619 gezelter 770
620 tim 767 } else {
621     // initialize this stuff before using it, OK?
622 gezelter 770 sprintf( painCave.errMsg,
623     "Trying to check cutoffs without a box. Be smarter.\n" );
624     painCave.isFatal = 1;
625     simError();
626 mmeineke 626 }
627 gezelter 770
628 mmeineke 626 }
629 tim 658
630     void SimInfo::addProperty(GenericData* prop){
631    
632     map<string, GenericData*>::iterator result;
633     result = properties.find(prop->getID());
634    
635     //we can't simply use properties[prop->getID()] = prop,
636     //it will cause memory leak if we already contain a propery which has the same name of prop
637    
638     if(result != properties.end()){
639    
640     delete (*result).second;
641     (*result).second = prop;
642    
643     }
644     else{
645    
646     properties[prop->getID()] = prop;
647    
648     }
649    
650     }
651    
652     GenericData* SimInfo::getProperty(const string& propName){
653    
654     map<string, GenericData*>::iterator result;
655    
656     //string lowerCaseName = ();
657    
658     result = properties.find(propName);
659    
660     if(result != properties.end())
661     return (*result).second;
662     else
663     return NULL;
664     }
665    
666     vector<GenericData*> SimInfo::getProperties(){
667    
668     vector<GenericData*> result;
669     map<string, GenericData*>::iterator i;
670    
671     for(i = properties.begin(); i != properties.end(); i++)
672     result.push_back((*i).second);
673    
674     return result;
675     }
676    
677 tim 763 double SimInfo::matTrace3(double m[3][3]){
678     double trace;
679     trace = m[0][0] + m[1][1] + m[2][2];
680 tim 658
681 tim 763 return trace;
682     }