ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 569
Committed: Tue Jul 1 21:33:45 2003 UTC (21 years ago) by mmeineke
File size: 8741 byte(s)
Log Message:
working on adding the box matrix to everything.

File Contents

# User Rev Content
1 mmeineke 377 #include <cstdlib>
2     #include <cstring>
3 mmeineke 568 #include <cmath>
4 mmeineke 377
5    
6     #include "SimInfo.hpp"
7     #define __C
8     #include "fSimulation.h"
9     #include "simError.h"
10    
11     #include "fortranWrappers.hpp"
12    
13 gezelter 490 #ifdef IS_MPI
14     #include "mpiSimulation.hpp"
15     #endif
16    
17 mmeineke 377 SimInfo* currentInfo;
18    
19     SimInfo::SimInfo(){
20     excludes = NULL;
21     n_constraints = 0;
22     n_oriented = 0;
23     n_dipoles = 0;
24 gezelter 458 ndf = 0;
25     ndfRaw = 0;
26 mmeineke 377 the_integrator = NULL;
27     setTemp = 0;
28     thermalTime = 0.0;
29 mmeineke 420 rCut = 0.0;
30 mmeineke 377
31     usePBC = 0;
32     useLJ = 0;
33     useSticky = 0;
34     useDipole = 0;
35     useReactionField = 0;
36     useGB = 0;
37     useEAM = 0;
38    
39 gezelter 457 wrapMeSimInfo( this );
40     }
41 mmeineke 377
42 gezelter 457 void SimInfo::setBox(double newBox[3]) {
43 mmeineke 568
44     double smallestBoxL, maxCutoff;
45 gezelter 463 int status;
46 mmeineke 568 int i;
47 gezelter 463
48 mmeineke 568 for(i=0; i<9; i++) Hmat[i] = 0.0;;
49 gezelter 463
50 mmeineke 568 Hmat[0] = newBox[0];
51     Hmat[4] = newBox[1];
52     Hmat[8] = newBox[2];
53 gezelter 463
54 mmeineke 568 calcHmatI();
55     calcBoxL();
56    
57 mmeineke 569 setFortranBoxSize(Hmat, HmatI, &orthoRhombic);
58 mmeineke 568
59     smallestBoxL = boxLx;
60     if (boxLy < smallestBoxL) smallestBoxL = boxLy;
61     if (boxLz < smallestBoxL) smallestBoxL = boxLz;
62    
63     maxCutoff = smallestBoxL / 2.0;
64    
65 gezelter 463 if (rList > maxCutoff) {
66     sprintf( painCave.errMsg,
67     "New Box size is forcing neighborlist radius down to %lf\n",
68     maxCutoff );
69     painCave.isFatal = 0;
70     simError();
71    
72     rList = maxCutoff;
73    
74     sprintf( painCave.errMsg,
75     "New Box size is forcing cutoff radius down to %lf\n",
76     maxCutoff - 1.0 );
77     painCave.isFatal = 0;
78     simError();
79    
80     rCut = rList - 1.0;
81    
82     // list radius changed so we have to refresh the simulation structure.
83     refreshSim();
84     }
85    
86     if (rCut > maxCutoff) {
87     sprintf( painCave.errMsg,
88     "New Box size is forcing cutoff radius down to %lf\n",
89     maxCutoff );
90     painCave.isFatal = 0;
91     simError();
92    
93     status = 0;
94     LJ_new_rcut(&rCut, &status);
95     if (status != 0) {
96     sprintf( painCave.errMsg,
97     "Error in recomputing LJ shifts based on new rcut\n");
98     painCave.isFatal = 1;
99     simError();
100     }
101     }
102 gezelter 457 }
103 mmeineke 377
104 mmeineke 568 void SimInfo::setBoxM( double theBox[9] ){
105    
106     int i, status;
107     double smallestBoxL, maxCutoff;
108    
109     for(i=0; i<9; i++) Hmat[i] = theBox[i];
110     calcHmatI();
111     calcBoxL();
112    
113 mmeineke 569 setFortranBoxSize(Hmat, HmatI, &orthoRhombic);
114 mmeineke 568
115     smallestBoxL = boxLx;
116     if (boxLy < smallestBoxL) smallestBoxL = boxLy;
117     if (boxLz < smallestBoxL) smallestBoxL = boxLz;
118    
119     maxCutoff = smallestBoxL / 2.0;
120    
121     if (rList > maxCutoff) {
122     sprintf( painCave.errMsg,
123     "New Box size is forcing neighborlist radius down to %lf\n",
124     maxCutoff );
125     painCave.isFatal = 0;
126     simError();
127    
128     rList = maxCutoff;
129    
130     sprintf( painCave.errMsg,
131     "New Box size is forcing cutoff radius down to %lf\n",
132     maxCutoff - 1.0 );
133     painCave.isFatal = 0;
134     simError();
135    
136     rCut = rList - 1.0;
137    
138     // list radius changed so we have to refresh the simulation structure.
139     refreshSim();
140     }
141    
142     if (rCut > maxCutoff) {
143     sprintf( painCave.errMsg,
144     "New Box size is forcing cutoff radius down to %lf\n",
145     maxCutoff );
146     painCave.isFatal = 0;
147     simError();
148    
149     status = 0;
150     LJ_new_rcut(&rCut, &status);
151     if (status != 0) {
152     sprintf( painCave.errMsg,
153     "Error in recomputing LJ shifts based on new rcut\n");
154     painCave.isFatal = 1;
155     simError();
156     }
157     }
158 mmeineke 377 }
159 gezelter 458
160 mmeineke 568
161     void SimInfo::getBox(double theBox[9]) {
162    
163     int i;
164     for(i=0; i<9; i++) theBox[i] = Hmat[i];
165     }
166    
167    
168     void SimInfo::calcHmatI( void ) {
169    
170     double C[3][3];
171     double detHmat;
172     int i, j, k;
173 mmeineke 569 double smallDiag;
174     double tol;
175     double sanity[3][3];
176 mmeineke 568
177     // calculate the adjunct of Hmat;
178    
179     C[0][0] = ( Hmat[4]*Hmat[8]) - (Hmat[7]*Hmat[5]);
180     C[1][0] = -( Hmat[1]*Hmat[8]) + (Hmat[7]*Hmat[2]);
181     C[2][0] = ( Hmat[1]*Hmat[5]) - (Hmat[4]*Hmat[2]);
182    
183     C[0][1] = -( Hmat[3]*Hmat[8]) + (Hmat[6]*Hmat[5]);
184     C[1][1] = ( Hmat[0]*Hmat[8]) - (Hmat[6]*Hmat[2]);
185     C[2][1] = -( Hmat[0]*Hmat[5]) + (Hmat[3]*Hmat[2]);
186    
187     C[0][2] = ( Hmat[3]*Hmat[7]) - (Hmat[6]*Hmat[4]);
188     C[1][2] = -( Hmat[0]*Hmat[7]) + (Hmat[6]*Hmat[1]);
189     C[2][2] = ( Hmat[0]*Hmat[4]) - (Hmat[3]*Hmat[1]);
190    
191     // calcutlate the determinant of Hmat
192    
193     detHmat = 0.0;
194     for(i=0; i<3; i++) detHmat += Hmat[i] * C[i][0];
195    
196    
197     // H^-1 = C^T / det(H)
198    
199     i=0;
200     for(j=0; j<3; j++){
201     for(k=0; k<3; k++){
202    
203     HmatI[i] = C[j][k] / detHmat;
204     i++;
205     }
206     }
207 mmeineke 569
208     // sanity check
209    
210     for(i=0; i<3; i++){
211     for(j=0; j<3; j++){
212    
213     sanity[i][j] = 0.0;
214     for(k=0; k<3; k++){
215     sanity[i][j] += Hmat[3*k+i] * HmatI[3*j+k];
216     }
217     }
218     }
219    
220     cerr << "sanity => \n"
221     << sanity[0][0] << "\t" << sanity[0][1] << "\t" << sanity [0][2] << "\n"
222     << sanity[1][0] << "\t" << sanity[1][1] << "\t" << sanity [1][2] << "\n"
223     << sanity[2][0] << "\t" << sanity[2][1] << "\t" << sanity [2][2]
224     << "\n";
225    
226    
227     // check to see if Hmat is orthorhombic
228    
229     smallDiag = Hmat[0];
230     if(smallDiag > Hmat[4]) smallDiag = Hmat[4];
231     if(smallDiag > Hmat[8]) smallDiag = Hmat[8];
232     tol = smallDiag * 1E-6;
233    
234     orthoRhombic = 1;
235     for(i=0; (i<9) && orthoRhombic; i++){
236    
237     if( (i%4) ){ // ignore the diagonals (0, 4, and 8)
238     orthoRhombic = (Hmat[i] <= tol);
239     }
240     }
241    
242 mmeineke 568 }
243    
244     void SimInfo::calcBoxL( void ){
245    
246     double dx, dy, dz, dsq;
247     int i;
248    
249     // boxVol = h1 (dot) h2 (cross) h3
250    
251     boxVol = Hmat[0] * ( (Hmat[4]*Hmat[8]) - (Hmat[7]*Hmat[5]) )
252     + Hmat[1] * ( (Hmat[5]*Hmat[6]) - (Hmat[8]*Hmat[3]) )
253     + Hmat[2] * ( (Hmat[3]*Hmat[7]) - (Hmat[6]*Hmat[4]) );
254    
255    
256     // boxLx
257    
258     dx = Hmat[0]; dy = Hmat[1]; dz = Hmat[2];
259     dsq = dx*dx + dy*dy + dz*dz;
260     boxLx = sqrt( dsq );
261    
262     // boxLy
263    
264     dx = Hmat[3]; dy = Hmat[4]; dz = Hmat[5];
265     dsq = dx*dx + dy*dy + dz*dz;
266     boxLy = sqrt( dsq );
267    
268     // boxLz
269    
270     dx = Hmat[6]; dy = Hmat[7]; dz = Hmat[8];
271     dsq = dx*dx + dy*dy + dz*dz;
272     boxLz = sqrt( dsq );
273    
274     }
275    
276    
277     void SimInfo::wrapVector( double thePos[3] ){
278    
279     int i, j, k;
280     double scaled[3];
281    
282 mmeineke 569 if( !orthoRhombic ){
283     // calc the scaled coordinates.
284    
285     for(i=0; i<3; i++)
286     scaled[i] =
287     thePos[0]*HmatI[i] + thePos[1]*HmatI[i+3] + thePos[3]*HmatI[i+6];
288    
289     // wrap the scaled coordinates
290    
291     for(i=0; i<3; i++)
292     scaled[i] -= round(scaled[i]);
293    
294     // calc the wrapped real coordinates from the wrapped scaled coordinates
295    
296     for(i=0; i<3; i++)
297     thePos[i] =
298     scaled[0]*Hmat[i] + scaled[1]*Hmat[i+3] + scaled[3]*Hmat[i+6];
299     }
300     else{
301     // calc the scaled coordinates.
302    
303     for(i=0; i<3; i++)
304     scaled[i] = thePos[i]*HmatI[i*4];
305    
306     // wrap the scaled coordinates
307    
308     for(i=0; i<3; i++)
309     scaled[i] -= round(scaled[i]);
310    
311     // calc the wrapped real coordinates from the wrapped scaled coordinates
312    
313     for(i=0; i<3; i++)
314     thePos[i] = scaled[i]*Hmat[i*4];
315     }
316    
317    
318 mmeineke 568 }
319    
320    
321 gezelter 458 int SimInfo::getNDF(){
322     int ndf_local, ndf;
323 gezelter 457
324 gezelter 458 ndf_local = 3 * n_atoms + 3 * n_oriented - n_constraints;
325    
326     #ifdef IS_MPI
327     MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
328     #else
329     ndf = ndf_local;
330     #endif
331    
332     ndf = ndf - 3;
333    
334     return ndf;
335     }
336    
337     int SimInfo::getNDFraw() {
338     int ndfRaw_local, ndfRaw;
339    
340     // Raw degrees of freedom that we have to set
341     ndfRaw_local = 3 * n_atoms + 3 * n_oriented;
342    
343     #ifdef IS_MPI
344     MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
345     #else
346     ndfRaw = ndfRaw_local;
347     #endif
348    
349     return ndfRaw;
350     }
351    
352 mmeineke 377 void SimInfo::refreshSim(){
353    
354     simtype fInfo;
355     int isError;
356 gezelter 490 int n_global;
357 mmeineke 424 int* excl;
358 mmeineke 469
359     fInfo.rrf = 0.0;
360     fInfo.rt = 0.0;
361     fInfo.dielect = 0.0;
362 mmeineke 377
363     fInfo.box[0] = box_x;
364     fInfo.box[1] = box_y;
365     fInfo.box[2] = box_z;
366    
367     fInfo.rlist = rList;
368     fInfo.rcut = rCut;
369    
370 mmeineke 469 if( useDipole ){
371     fInfo.rrf = ecr;
372     fInfo.rt = ecr - est;
373     if( useReactionField )fInfo.dielect = dielectric;
374     }
375    
376 mmeineke 377 fInfo.SIM_uses_PBC = usePBC;
377 mmeineke 443 //fInfo.SIM_uses_LJ = 0;
378 chuckv 439 fInfo.SIM_uses_LJ = useLJ;
379 mmeineke 443 fInfo.SIM_uses_sticky = useSticky;
380     //fInfo.SIM_uses_sticky = 0;
381 chuckv 482 fInfo.SIM_uses_dipoles = useDipole;
382     //fInfo.SIM_uses_dipoles = 0;
383 mmeineke 443 //fInfo.SIM_uses_RF = useReactionField;
384     fInfo.SIM_uses_RF = 0;
385 mmeineke 377 fInfo.SIM_uses_GB = useGB;
386     fInfo.SIM_uses_EAM = useEAM;
387    
388 mmeineke 424 excl = Exclude::getArray();
389 mmeineke 377
390 gezelter 490 #ifdef IS_MPI
391     n_global = mpiSim->getTotAtoms();
392     #else
393     n_global = n_atoms;
394     #endif
395    
396 mmeineke 377 isError = 0;
397    
398 gezelter 490 setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
399 gezelter 483 &nGlobalExcludes, globalExcludes, molMembershipArray,
400     &isError );
401 mmeineke 377
402     if( isError ){
403    
404     sprintf( painCave.errMsg,
405     "There was an error setting the simulation information in fortran.\n" );
406     painCave.isFatal = 1;
407     simError();
408     }
409    
410     #ifdef IS_MPI
411     sprintf( checkPointMsg,
412     "succesfully sent the simulation information to fortran.\n");
413     MPIcheckPoint();
414     #endif // is_mpi
415 gezelter 458
416 gezelter 474 this->ndf = this->getNDF();
417     this->ndfRaw = this->getNDFraw();
418 gezelter 458
419 mmeineke 377 }
420