ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 829
Committed: Tue Oct 28 16:03:37 2003 UTC (20 years, 8 months ago) by gezelter
File size: 14325 byte(s)
Log Message:
replace c++ header stuff with more portable c header stuff
Also, mod file fixes and portability changes
Some fortran changes will need to be reversed.

File Contents

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