ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 859
Committed: Mon Nov 10 21:50:36 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 13601 byte(s)
Log Message:
reordered the rcut/ecr/boxSize initialization

removed the rcut/ecr shrink and grow algorithm. the simulation will now exit when it runs into rcut or ecr.

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