ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 658
Committed: Thu Jul 31 15:35:07 2003 UTC (20 years, 11 months ago) by tim
File size: 11823 byte(s)
Log Message:
 Added Z constraint.

File Contents

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