ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 860
Committed: Tue Nov 11 17:20:12 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 13671 byte(s)
Log Message:
added a routine to SimInfo.cpp to inline a min function.

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