ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 853
Committed: Thu Nov 6 19:11:38 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 15212 byte(s)
Log Message:
did a merge by hand from the new-templateless branch to the main trunk.

bug Fixes include:
  * fixed the switching function from ortho to non-ortho box.
         !!!!! THis was responsible for all of the sudden deaths we saw.
  * some formating in the string when we write out the extended system state.
  * added NPT.cpp to the makefile.in

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