ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new-templateless/OOPSE/libmdtools/SimInfo.cpp
Revision: 850
Committed: Mon Nov 3 22:07:17 2003 UTC (21 years, 6 months ago) by mmeineke
File size: 13762 byte(s)
Log Message:
begun work on removing templates and most of standard template library from OOPSE.

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