ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 597
Committed: Mon Jul 14 21:28:54 2003 UTC (20 years, 11 months ago) by mmeineke
File size: 10085 byte(s)
Log Message:
found a bug. Unit vectors were not being updated

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 420 rCut = 0.0;
37 mmeineke 377
38     usePBC = 0;
39     useLJ = 0;
40     useSticky = 0;
41     useDipole = 0;
42     useReactionField = 0;
43     useGB = 0;
44     useEAM = 0;
45    
46 gezelter 457 wrapMeSimInfo( this );
47     }
48 mmeineke 377
49 gezelter 457 void SimInfo::setBox(double newBox[3]) {
50 mmeineke 586
51 gezelter 588 int i, j;
52     double tempMat[3][3];
53 gezelter 463
54 gezelter 588 for(i=0; i<3; i++)
55     for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
56 gezelter 463
57 gezelter 588 tempMat[0][0] = newBox[0];
58     tempMat[1][1] = newBox[1];
59     tempMat[2][2] = newBox[2];
60 gezelter 463
61 mmeineke 586 setBoxM( tempMat );
62 mmeineke 568
63 gezelter 457 }
64 mmeineke 377
65 gezelter 588 void SimInfo::setBoxM( double theBox[3][3] ){
66 mmeineke 568
67 gezelter 588 int i, j, status;
68 mmeineke 568 double smallestBoxL, maxCutoff;
69 gezelter 588 double FortranHmat[9]; // to preserve compatibility with Fortran the
70     // ordering in the array is as follows:
71     // [ 0 3 6 ]
72     // [ 1 4 7 ]
73     // [ 2 5 8 ]
74     double FortranHmatInv[9]; // the inverted Hmat (for Fortran);
75 mmeineke 568
76 mmeineke 586
77 gezelter 588 for(i=0; i < 3; i++)
78     for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
79    
80 mmeineke 586 cerr
81     << "setting Hmat ->\n"
82 gezelter 588 << "[ " << Hmat[0][0] << ", " << Hmat[0][1] << ", " << Hmat[0][2] << " ]\n"
83     << "[ " << Hmat[1][0] << ", " << Hmat[1][1] << ", " << Hmat[1][2] << " ]\n"
84     << "[ " << Hmat[2][0] << ", " << Hmat[2][1] << ", " << Hmat[2][2] << " ]\n";
85 mmeineke 586
86 mmeineke 568 calcBoxL();
87 gezelter 588 calcHmatInv();
88 mmeineke 568
89 gezelter 588 for(i=0; i < 3; i++) {
90     for (j=0; j < 3; j++) {
91     FortranHmat[3*j + i] = Hmat[i][j];
92     FortranHmatInv[3*j + i] = HmatInv[i][j];
93     }
94     }
95 mmeineke 586
96 mmeineke 590 setFortranBoxSize(FortranHmat, FortranHmatInv, &orthoRhombic);
97 mmeineke 568
98     smallestBoxL = boxLx;
99     if (boxLy < smallestBoxL) smallestBoxL = boxLy;
100     if (boxLz < smallestBoxL) smallestBoxL = boxLz;
101    
102     maxCutoff = smallestBoxL / 2.0;
103    
104     if (rList > maxCutoff) {
105     sprintf( painCave.errMsg,
106     "New Box size is forcing neighborlist radius down to %lf\n",
107     maxCutoff );
108     painCave.isFatal = 0;
109     simError();
110    
111     rList = maxCutoff;
112    
113     sprintf( painCave.errMsg,
114     "New Box size is forcing cutoff radius down to %lf\n",
115     maxCutoff - 1.0 );
116     painCave.isFatal = 0;
117     simError();
118    
119     rCut = rList - 1.0;
120    
121     // list radius changed so we have to refresh the simulation structure.
122     refreshSim();
123     }
124    
125     if (rCut > maxCutoff) {
126     sprintf( painCave.errMsg,
127     "New Box size is forcing cutoff radius down to %lf\n",
128     maxCutoff );
129     painCave.isFatal = 0;
130     simError();
131    
132     status = 0;
133     LJ_new_rcut(&rCut, &status);
134     if (status != 0) {
135     sprintf( painCave.errMsg,
136     "Error in recomputing LJ shifts based on new rcut\n");
137     painCave.isFatal = 1;
138     simError();
139     }
140     }
141 mmeineke 377 }
142 gezelter 458
143 mmeineke 568
144 gezelter 588 void SimInfo::getBoxM (double theBox[3][3]) {
145 mmeineke 568
146 gezelter 588 int i, j;
147     for(i=0; i<3; i++)
148     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j];
149 mmeineke 568 }
150    
151 gezelter 574
152     void SimInfo::scaleBox(double scale) {
153 gezelter 588 double theBox[3][3];
154     int i, j;
155 gezelter 574
156 mmeineke 586 cerr << "Scaling box by " << scale << "\n";
157    
158 gezelter 588 for(i=0; i<3; i++)
159     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j]*scale;
160 gezelter 574
161     setBoxM(theBox);
162    
163     }
164    
165 gezelter 588 void SimInfo::calcHmatInv( void ) {
166 mmeineke 590
167     int i,j;
168 mmeineke 569 double smallDiag;
169     double tol;
170     double sanity[3][3];
171 mmeineke 568
172 gezelter 588 invertMat3( Hmat, HmatInv );
173 mmeineke 568
174 gezelter 588 // Check the inverse to make sure it is sane:
175 mmeineke 568
176 gezelter 588 matMul3( Hmat, HmatInv, sanity );
177    
178     // check to see if Hmat is orthorhombic
179 mmeineke 568
180 gezelter 588 smallDiag = Hmat[0][0];
181     if(smallDiag > Hmat[1][1]) smallDiag = Hmat[1][1];
182     if(smallDiag > Hmat[2][2]) smallDiag = Hmat[2][2];
183     tol = smallDiag * 1E-6;
184 mmeineke 568
185 gezelter 588 orthoRhombic = 1;
186 mmeineke 568
187 gezelter 588 for (i = 0; i < 3; i++ ) {
188     for (j = 0 ; j < 3; j++) {
189     if (i != j) {
190     if (orthoRhombic) {
191     if (Hmat[i][j] >= tol) orthoRhombic = 0;
192     }
193     }
194 mmeineke 568 }
195     }
196 gezelter 588 }
197 mmeineke 569
198 gezelter 588 double SimInfo::matDet3(double a[3][3]) {
199     int i, j, k;
200     double determinant;
201 mmeineke 569
202 gezelter 588 determinant = 0.0;
203    
204     for(i = 0; i < 3; i++) {
205     j = (i+1)%3;
206     k = (i+2)%3;
207    
208     determinant += a[0][i] * (a[1][j]*a[2][k] - a[1][k]*a[2][j]);
209 mmeineke 569 }
210    
211 gezelter 588 return determinant;
212     }
213 mmeineke 569
214 gezelter 588 void SimInfo::invertMat3(double a[3][3], double b[3][3]) {
215 mmeineke 569
216 gezelter 588 int i, j, k, l, m, n;
217     double determinant;
218 mmeineke 569
219 gezelter 588 determinant = matDet3( a );
220    
221     if (determinant == 0.0) {
222     sprintf( painCave.errMsg,
223     "Can't invert a matrix with a zero determinant!\n");
224     painCave.isFatal = 1;
225     simError();
226     }
227    
228     for (i=0; i < 3; i++) {
229     j = (i+1)%3;
230     k = (i+2)%3;
231     for(l = 0; l < 3; l++) {
232     m = (l+1)%3;
233     n = (l+2)%3;
234    
235     b[l][i] = (a[j][m]*a[k][n] - a[j][n]*a[k][m]) / determinant;
236 mmeineke 569 }
237     }
238 mmeineke 568 }
239    
240 gezelter 588 void SimInfo::matMul3(double a[3][3], double b[3][3], double c[3][3]) {
241     double r00, r01, r02, r10, r11, r12, r20, r21, r22;
242    
243     r00 = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0];
244     r01 = a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1];
245     r02 = a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2];
246    
247     r10 = a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0];
248     r11 = a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1];
249     r12 = a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2];
250    
251     r20 = a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0];
252     r21 = a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1];
253     r22 = a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2];
254    
255     c[0][0] = r00; c[0][1] = r01; c[0][2] = r02;
256     c[1][0] = r10; c[1][1] = r11; c[1][2] = r12;
257     c[2][0] = r20; c[2][1] = r21; c[2][2] = r22;
258     }
259    
260     void SimInfo::matVecMul3(double m[3][3], double inVec[3], double outVec[3]) {
261     double a0, a1, a2;
262    
263     a0 = inVec[0]; a1 = inVec[1]; a2 = inVec[2];
264    
265     outVec[0] = m[0][0]*a0 + m[0][1]*a1 + m[0][2]*a2;
266     outVec[1] = m[1][0]*a0 + m[1][1]*a1 + m[1][2]*a2;
267     outVec[2] = m[2][0]*a0 + m[2][1]*a1 + m[2][2]*a2;
268     }
269 mmeineke 597
270     void SimInfo::transposeMat3(double in[3][3], double out[3][3]) {
271     double temp[3][3];
272     int i, j;
273    
274     for (i = 0; i < 3; i++) {
275     for (j = 0; j < 3; j++) {
276     temp[j][i] = in[i][j];
277     }
278     }
279     for (i = 0; i < 3; i++) {
280     for (j = 0; j < 3; j++) {
281     out[i][j] = temp[i][j];
282     }
283     }
284     }
285 gezelter 588
286 mmeineke 597 void SimInfo::printMat3(double A[3][3] ){
287    
288     std::cerr
289     << "[ " << A[0][0] << ", " << A[0][1] << ", " << A[0][2] << " ]\n"
290     << "[ " << A[1][0] << ", " << A[1][1] << ", " << A[1][2] << " ]\n"
291     << "[ " << A[2][0] << ", " << A[2][1] << ", " << A[2][2] << " ]\n";
292     }
293    
294     void SimInfo::printMat9(double A[9] ){
295    
296     std::cerr
297     << "[ " << A[0] << ", " << A[1] << ", " << A[2] << " ]\n"
298     << "[ " << A[3] << ", " << A[4] << ", " << A[5] << " ]\n"
299     << "[ " << A[6] << ", " << A[7] << ", " << A[8] << " ]\n";
300     }
301    
302 mmeineke 568 void SimInfo::calcBoxL( void ){
303    
304     double dx, dy, dz, dsq;
305     int i;
306    
307 gezelter 588 // boxVol = Determinant of Hmat
308 mmeineke 568
309 gezelter 588 boxVol = matDet3( Hmat );
310 mmeineke 568
311     // boxLx
312    
313 gezelter 588 dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
314 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
315     boxLx = sqrt( dsq );
316    
317     // boxLy
318    
319 gezelter 588 dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
320 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
321     boxLy = sqrt( dsq );
322    
323     // boxLz
324    
325 gezelter 588 dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
326 mmeineke 568 dsq = dx*dx + dy*dy + dz*dz;
327     boxLz = sqrt( dsq );
328    
329     }
330    
331    
332     void SimInfo::wrapVector( double thePos[3] ){
333    
334     int i, j, k;
335     double scaled[3];
336    
337 mmeineke 569 if( !orthoRhombic ){
338     // calc the scaled coordinates.
339 gezelter 588
340    
341     matVecMul3(HmatInv, thePos, scaled);
342 mmeineke 569
343     for(i=0; i<3; i++)
344 mmeineke 572 scaled[i] -= roundMe(scaled[i]);
345 mmeineke 569
346     // calc the wrapped real coordinates from the wrapped scaled coordinates
347    
348 gezelter 588 matVecMul3(Hmat, scaled, thePos);
349    
350 mmeineke 569 }
351     else{
352     // calc the scaled coordinates.
353    
354     for(i=0; i<3; i++)
355 gezelter 588 scaled[i] = thePos[i]*HmatInv[i][i];
356 mmeineke 569
357     // wrap the scaled coordinates
358    
359     for(i=0; i<3; i++)
360 mmeineke 572 scaled[i] -= roundMe(scaled[i]);
361 mmeineke 569
362     // calc the wrapped real coordinates from the wrapped scaled coordinates
363    
364     for(i=0; i<3; i++)
365 gezelter 588 thePos[i] = scaled[i]*Hmat[i][i];
366 mmeineke 569 }
367    
368 mmeineke 568 }
369    
370    
371 gezelter 458 int SimInfo::getNDF(){
372     int ndf_local, ndf;
373 gezelter 457
374 gezelter 458 ndf_local = 3 * n_atoms + 3 * n_oriented - n_constraints;
375    
376     #ifdef IS_MPI
377     MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
378     #else
379     ndf = ndf_local;
380     #endif
381    
382     ndf = ndf - 3;
383    
384     return ndf;
385     }
386    
387     int SimInfo::getNDFraw() {
388     int ndfRaw_local, ndfRaw;
389    
390     // Raw degrees of freedom that we have to set
391     ndfRaw_local = 3 * n_atoms + 3 * n_oriented;
392    
393     #ifdef IS_MPI
394     MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
395     #else
396     ndfRaw = ndfRaw_local;
397     #endif
398    
399     return ndfRaw;
400     }
401    
402 mmeineke 377 void SimInfo::refreshSim(){
403    
404     simtype fInfo;
405     int isError;
406 gezelter 490 int n_global;
407 mmeineke 424 int* excl;
408 mmeineke 469
409     fInfo.rrf = 0.0;
410     fInfo.rt = 0.0;
411     fInfo.dielect = 0.0;
412 mmeineke 377
413     fInfo.rlist = rList;
414     fInfo.rcut = rCut;
415    
416 mmeineke 469 if( useDipole ){
417     fInfo.rrf = ecr;
418     fInfo.rt = ecr - est;
419     if( useReactionField )fInfo.dielect = dielectric;
420     }
421    
422 mmeineke 377 fInfo.SIM_uses_PBC = usePBC;
423 mmeineke 443 //fInfo.SIM_uses_LJ = 0;
424 chuckv 439 fInfo.SIM_uses_LJ = useLJ;
425 mmeineke 443 fInfo.SIM_uses_sticky = useSticky;
426     //fInfo.SIM_uses_sticky = 0;
427 chuckv 482 fInfo.SIM_uses_dipoles = useDipole;
428     //fInfo.SIM_uses_dipoles = 0;
429 mmeineke 443 //fInfo.SIM_uses_RF = useReactionField;
430     fInfo.SIM_uses_RF = 0;
431 mmeineke 377 fInfo.SIM_uses_GB = useGB;
432     fInfo.SIM_uses_EAM = useEAM;
433    
434 mmeineke 424 excl = Exclude::getArray();
435 mmeineke 377
436 gezelter 490 #ifdef IS_MPI
437     n_global = mpiSim->getTotAtoms();
438     #else
439     n_global = n_atoms;
440     #endif
441    
442 mmeineke 377 isError = 0;
443    
444 gezelter 490 setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
445 gezelter 483 &nGlobalExcludes, globalExcludes, molMembershipArray,
446     &isError );
447 mmeineke 377
448     if( isError ){
449    
450     sprintf( painCave.errMsg,
451     "There was an error setting the simulation information in fortran.\n" );
452     painCave.isFatal = 1;
453     simError();
454     }
455    
456     #ifdef IS_MPI
457     sprintf( checkPointMsg,
458     "succesfully sent the simulation information to fortran.\n");
459     MPIcheckPoint();
460     #endif // is_mpi
461 gezelter 458
462 gezelter 474 this->ndf = this->getNDF();
463     this->ndfRaw = this->getNDFraw();
464 gezelter 458
465 mmeineke 377 }
466