ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 618
Committed: Tue Jul 15 21:34:56 2003 UTC (20 years, 11 months ago) by mmeineke
File size: 9973 byte(s)
Log Message:
working on fixing ssd bug

File Contents

# Content
1 #include <cstdlib>
2 #include <cstring>
3 #include <cmath>
4
5 #include <iostream>
6 using namespace std;
7
8 #include "SimInfo.hpp"
9 #define __C
10 #include "fSimulation.h"
11 #include "simError.h"
12
13 #include "fortranWrappers.hpp"
14
15 #ifdef IS_MPI
16 #include "mpiSimulation.hpp"
17 #endif
18
19 inline double roundMe( double x ){
20 return ( x >= 0 ) ? floor( x + 0.5 ) : ceil( x - 0.5 );
21 }
22
23
24 SimInfo* currentInfo;
25
26 SimInfo::SimInfo(){
27 excludes = NULL;
28 n_constraints = 0;
29 n_oriented = 0;
30 n_dipoles = 0;
31 ndf = 0;
32 ndfRaw = 0;
33 the_integrator = NULL;
34 setTemp = 0;
35 thermalTime = 0.0;
36 rCut = 0.0;
37 ecr = 0.0;
38
39 usePBC = 0;
40 useLJ = 0;
41 useSticky = 0;
42 useDipole = 0;
43 useReactionField = 0;
44 useGB = 0;
45 useEAM = 0;
46
47 wrapMeSimInfo( this );
48 }
49
50 void SimInfo::setBox(double newBox[3]) {
51
52 int i, j;
53 double tempMat[3][3];
54
55 for(i=0; i<3; i++)
56 for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
57
58 tempMat[0][0] = newBox[0];
59 tempMat[1][1] = newBox[1];
60 tempMat[2][2] = newBox[2];
61
62 setBoxM( tempMat );
63
64 }
65
66 void SimInfo::setBoxM( double theBox[3][3] ){
67
68 int i, j, status;
69 double smallestBoxL, maxCutoff;
70 double FortranHmat[9]; // to preserve compatibility with Fortran the
71 // ordering in the array is as follows:
72 // [ 0 3 6 ]
73 // [ 1 4 7 ]
74 // [ 2 5 8 ]
75 double FortranHmatInv[9]; // the inverted Hmat (for Fortran);
76
77
78 for(i=0; i < 3; i++)
79 for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
80
81 // cerr
82 // << "setting Hmat ->\n"
83 // << "[ " << Hmat[0][0] << ", " << Hmat[0][1] << ", " << Hmat[0][2] << " ]\n"
84 // << "[ " << Hmat[1][0] << ", " << Hmat[1][1] << ", " << Hmat[1][2] << " ]\n"
85 // << "[ " << Hmat[2][0] << ", " << Hmat[2][1] << ", " << Hmat[2][2] << " ]\n";
86
87 calcBoxL();
88 calcHmatInv();
89
90 for(i=0; i < 3; i++) {
91 for (j=0; j < 3; j++) {
92 FortranHmat[3*j + i] = Hmat[i][j];
93 FortranHmatInv[3*j + i] = HmatInv[i][j];
94 }
95 }
96
97 setFortranBoxSize(FortranHmat, FortranHmatInv, &orthoRhombic);
98
99 smallestBoxL = boxLx;
100 if (boxLy < smallestBoxL) smallestBoxL = boxLy;
101 if (boxLz < smallestBoxL) smallestBoxL = boxLz;
102
103 maxCutoff = smallestBoxL / 2.0;
104
105 if (rList > maxCutoff) {
106 sprintf( painCave.errMsg,
107 "New Box size is forcing neighborlist radius down to %lf\n",
108 maxCutoff );
109 painCave.isFatal = 0;
110 simError();
111
112 rList = maxCutoff;
113
114 sprintf( painCave.errMsg,
115 "New Box size is forcing cutoff radius down to %lf\n",
116 maxCutoff - 1.0 );
117 painCave.isFatal = 0;
118 simError();
119
120 rCut = rList - 1.0;
121
122 // list radius changed so we have to refresh the simulation structure.
123 refreshSim();
124 }
125
126 if( ecr > maxCutoff ){
127
128 sprintf( painCave.errMsg,
129 "New Box size is forcing electrostatic cutoff radius "
130 "down to %lf\n",
131 maxCutoff );
132 painCave.isFatal = 0;
133 simError();
134
135 ecr = maxCutoff;
136 est = 0.05 * ecr;
137
138 refreshSim();
139 }
140
141 }
142
143
144 void SimInfo::getBoxM (double theBox[3][3]) {
145
146 int i, j;
147 for(i=0; i<3; i++)
148 for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j];
149 }
150
151
152 void SimInfo::scaleBox(double scale) {
153 double theBox[3][3];
154 int i, j;
155
156 // cerr << "Scaling box by " << scale << "\n";
157
158 for(i=0; i<3; i++)
159 for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j]*scale;
160
161 setBoxM(theBox);
162
163 }
164
165 void SimInfo::calcHmatInv( void ) {
166
167 int i,j;
168 double smallDiag;
169 double tol;
170 double sanity[3][3];
171
172 invertMat3( Hmat, HmatInv );
173
174 // Check the inverse to make sure it is sane:
175
176 matMul3( Hmat, HmatInv, sanity );
177
178 // check to see if Hmat is orthorhombic
179
180 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
185 orthoRhombic = 1;
186
187 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 }
195 }
196 }
197
198 double SimInfo::matDet3(double a[3][3]) {
199 int i, j, k;
200 double determinant;
201
202 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 }
210
211 return determinant;
212 }
213
214 void SimInfo::invertMat3(double a[3][3], double b[3][3]) {
215
216 int i, j, k, l, m, n;
217 double determinant;
218
219 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 }
237 }
238 }
239
240 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
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
286 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 void SimInfo::calcBoxL( void ){
303
304 double dx, dy, dz, dsq;
305 int i;
306
307 // boxVol = Determinant of Hmat
308
309 boxVol = matDet3( Hmat );
310
311 // boxLx
312
313 dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
314 dsq = dx*dx + dy*dy + dz*dz;
315 boxLx = sqrt( dsq );
316
317 // boxLy
318
319 dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
320 dsq = dx*dx + dy*dy + dz*dz;
321 boxLy = sqrt( dsq );
322
323 // boxLz
324
325 dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
326 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 if( !orthoRhombic ){
338 // calc the scaled coordinates.
339
340
341 matVecMul3(HmatInv, thePos, scaled);
342
343 for(i=0; i<3; i++)
344 scaled[i] -= roundMe(scaled[i]);
345
346 // calc the wrapped real coordinates from the wrapped scaled coordinates
347
348 matVecMul3(Hmat, scaled, thePos);
349
350 }
351 else{
352 // calc the scaled coordinates.
353
354 for(i=0; i<3; i++)
355 scaled[i] = thePos[i]*HmatInv[i][i];
356
357 // wrap the scaled coordinates
358
359 for(i=0; i<3; i++)
360 scaled[i] -= roundMe(scaled[i]);
361
362 // calc the wrapped real coordinates from the wrapped scaled coordinates
363
364 for(i=0; i<3; i++)
365 thePos[i] = scaled[i]*Hmat[i][i];
366 }
367
368 }
369
370
371 int SimInfo::getNDF(){
372 int ndf_local, ndf;
373
374 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 void SimInfo::refreshSim(){
403
404 simtype fInfo;
405 int isError;
406 int n_global;
407 int* excl;
408
409 fInfo.rrf = 0.0;
410 fInfo.rt = 0.0;
411 fInfo.dielect = 0.0;
412
413 fInfo.rlist = rList;
414 fInfo.rcut = rCut;
415
416 if( useDipole ){
417 fInfo.rrf = ecr;
418 fInfo.rt = ecr - est;
419 if( useReactionField )fInfo.dielect = dielectric;
420 }
421
422 fInfo.SIM_uses_PBC = usePBC;
423 //fInfo.SIM_uses_LJ = 0;
424 fInfo.SIM_uses_LJ = useLJ;
425 fInfo.SIM_uses_sticky = useSticky;
426 //fInfo.SIM_uses_sticky = 0;
427 fInfo.SIM_uses_dipoles = useDipole;
428 //fInfo.SIM_uses_dipoles = 0;
429 //fInfo.SIM_uses_RF = useReactionField;
430 fInfo.SIM_uses_RF = 0;
431 fInfo.SIM_uses_GB = useGB;
432 fInfo.SIM_uses_EAM = useEAM;
433
434 excl = Exclude::getArray();
435
436 #ifdef IS_MPI
437 n_global = mpiSim->getTotAtoms();
438 #else
439 n_global = n_atoms;
440 #endif
441
442 isError = 0;
443
444 setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
445 &nGlobalExcludes, globalExcludes, molMembershipArray,
446 &isError );
447
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
462 this->ndf = this->getNDF();
463 this->ndfRaw = this->getNDFraw();
464
465 }
466