ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimInfo.cpp
Revision: 588
Committed: Thu Jul 10 17:10:56 2003 UTC (21 years ago) by gezelter
File size: 9527 byte(s)
Log Message:
Bunch of 1-d array -> 2-d array stuff

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
38 usePBC = 0;
39 useLJ = 0;
40 useSticky = 0;
41 useDipole = 0;
42 useReactionField = 0;
43 useGB = 0;
44 useEAM = 0;
45
46 wrapMeSimInfo( this );
47 }
48
49 void SimInfo::setBox(double newBox[3]) {
50
51 int i, j;
52 double tempMat[3][3];
53
54 for(i=0; i<3; i++)
55 for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
56
57 tempMat[0][0] = newBox[0];
58 tempMat[1][1] = newBox[1];
59 tempMat[2][2] = newBox[2];
60
61 setBoxM( tempMat );
62
63 }
64
65 void SimInfo::setBoxM( double theBox[3][3] ){
66
67 int i, j, status;
68 double smallestBoxL, maxCutoff;
69 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
76
77 for(i=0; i < 3; i++)
78 for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
79
80 cerr
81 << "setting Hmat ->\n"
82 << "[ " << 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
86 calcBoxL();
87 calcHmatInv();
88
89 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
96 setFortranBoxSize(FortranHmat, FortranHmatI, &orthoRhombic);
97
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 }
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 double smallDiag;
168 double tol;
169 double sanity[3][3];
170
171 invertMat3( Hmat, HmatInv );
172
173 // Check the inverse to make sure it is sane:
174
175 matMul3( Hmat, HmatInv, sanity );
176
177 cerr << "sanity => \n"
178 << sanity[0][0] << "\t" << sanity[0][1] << "\t" << sanity [0][2] << "\n"
179 << sanity[1][0] << "\t" << sanity[1][1] << "\t" << sanity [1][2] << "\n"
180 << sanity[2][0] << "\t" << sanity[2][1] << "\t" << sanity [2][2]
181 << "\n";
182
183 // check to see if Hmat is orthorhombic
184
185 smallDiag = Hmat[0][0];
186 if(smallDiag > Hmat[1][1]) smallDiag = Hmat[1][1];
187 if(smallDiag > Hmat[2][2]) smallDiag = Hmat[2][2];
188 tol = smallDiag * 1E-6;
189
190 orthoRhombic = 1;
191
192 for (i = 0; i < 3; i++ ) {
193 for (j = 0 ; j < 3; j++) {
194 if (i != j) {
195 if (orthoRhombic) {
196 if (Hmat[i][j] >= tol) orthoRhombic = 0;
197 }
198 }
199 }
200 }
201 }
202
203 double SimInfo::matDet3(double a[3][3]) {
204 int i, j, k;
205 double determinant;
206
207 determinant = 0.0;
208
209 for(i = 0; i < 3; i++) {
210 j = (i+1)%3;
211 k = (i+2)%3;
212
213 determinant += a[0][i] * (a[1][j]*a[2][k] - a[1][k]*a[2][j]);
214 }
215
216 return determinant;
217 }
218
219 void SimInfo::invertMat3(double a[3][3], double b[3][3]) {
220
221 int i, j, k, l, m, n;
222 double determinant;
223
224 determinant = matDet3( a );
225
226 if (determinant == 0.0) {
227 sprintf( painCave.errMsg,
228 "Can't invert a matrix with a zero determinant!\n");
229 painCave.isFatal = 1;
230 simError();
231 }
232
233 for (i=0; i < 3; i++) {
234 j = (i+1)%3;
235 k = (i+2)%3;
236 for(l = 0; l < 3; l++) {
237 m = (l+1)%3;
238 n = (l+2)%3;
239
240 b[l][i] = (a[j][m]*a[k][n] - a[j][n]*a[k][m]) / determinant;
241 }
242 }
243 }
244
245 void SimInfo::matMul3(double a[3][3], double b[3][3], double c[3][3]) {
246 double r00, r01, r02, r10, r11, r12, r20, r21, r22;
247
248 r00 = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0];
249 r01 = a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1];
250 r02 = a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2];
251
252 r10 = a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0];
253 r11 = a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1];
254 r12 = a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2];
255
256 r20 = a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0];
257 r21 = a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1];
258 r22 = a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2];
259
260 c[0][0] = r00; c[0][1] = r01; c[0][2] = r02;
261 c[1][0] = r10; c[1][1] = r11; c[1][2] = r12;
262 c[2][0] = r20; c[2][1] = r21; c[2][2] = r22;
263 }
264
265 void SimInfo::matVecMul3(double m[3][3], double inVec[3], double outVec[3]) {
266 double a0, a1, a2;
267
268 a0 = inVec[0]; a1 = inVec[1]; a2 = inVec[2];
269
270 outVec[0] = m[0][0]*a0 + m[0][1]*a1 + m[0][2]*a2;
271 outVec[1] = m[1][0]*a0 + m[1][1]*a1 + m[1][2]*a2;
272 outVec[2] = m[2][0]*a0 + m[2][1]*a1 + m[2][2]*a2;
273 }
274
275 void SimInfo::calcBoxL( void ){
276
277 double dx, dy, dz, dsq;
278 int i;
279
280 // boxVol = Determinant of Hmat
281
282 boxVol = matDet3( Hmat );
283
284 // boxLx
285
286 dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
287 dsq = dx*dx + dy*dy + dz*dz;
288 boxLx = sqrt( dsq );
289
290 // boxLy
291
292 dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
293 dsq = dx*dx + dy*dy + dz*dz;
294 boxLy = sqrt( dsq );
295
296 // boxLz
297
298 dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
299 dsq = dx*dx + dy*dy + dz*dz;
300 boxLz = sqrt( dsq );
301
302 }
303
304
305 void SimInfo::wrapVector( double thePos[3] ){
306
307 int i, j, k;
308 double scaled[3];
309
310 if( !orthoRhombic ){
311 // calc the scaled coordinates.
312
313
314 matVecMul3(HmatInv, thePos, scaled);
315
316 for(i=0; i<3; i++)
317 scaled[i] -= roundMe(scaled[i]);
318
319 // calc the wrapped real coordinates from the wrapped scaled coordinates
320
321 matVecMul3(Hmat, scaled, thePos);
322
323 }
324 else{
325 // calc the scaled coordinates.
326
327 for(i=0; i<3; i++)
328 scaled[i] = thePos[i]*HmatInv[i][i];
329
330 // wrap the scaled coordinates
331
332 for(i=0; i<3; i++)
333 scaled[i] -= roundMe(scaled[i]);
334
335 // calc the wrapped real coordinates from the wrapped scaled coordinates
336
337 for(i=0; i<3; i++)
338 thePos[i] = scaled[i]*Hmat[i][i];
339 }
340
341 }
342
343
344 int SimInfo::getNDF(){
345 int ndf_local, ndf;
346
347 ndf_local = 3 * n_atoms + 3 * n_oriented - n_constraints;
348
349 #ifdef IS_MPI
350 MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
351 #else
352 ndf = ndf_local;
353 #endif
354
355 ndf = ndf - 3;
356
357 return ndf;
358 }
359
360 int SimInfo::getNDFraw() {
361 int ndfRaw_local, ndfRaw;
362
363 // Raw degrees of freedom that we have to set
364 ndfRaw_local = 3 * n_atoms + 3 * n_oriented;
365
366 #ifdef IS_MPI
367 MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
368 #else
369 ndfRaw = ndfRaw_local;
370 #endif
371
372 return ndfRaw;
373 }
374
375 void SimInfo::refreshSim(){
376
377 simtype fInfo;
378 int isError;
379 int n_global;
380 int* excl;
381
382 fInfo.rrf = 0.0;
383 fInfo.rt = 0.0;
384 fInfo.dielect = 0.0;
385
386 fInfo.rlist = rList;
387 fInfo.rcut = rCut;
388
389 if( useDipole ){
390 fInfo.rrf = ecr;
391 fInfo.rt = ecr - est;
392 if( useReactionField )fInfo.dielect = dielectric;
393 }
394
395 fInfo.SIM_uses_PBC = usePBC;
396 //fInfo.SIM_uses_LJ = 0;
397 fInfo.SIM_uses_LJ = useLJ;
398 fInfo.SIM_uses_sticky = useSticky;
399 //fInfo.SIM_uses_sticky = 0;
400 fInfo.SIM_uses_dipoles = useDipole;
401 //fInfo.SIM_uses_dipoles = 0;
402 //fInfo.SIM_uses_RF = useReactionField;
403 fInfo.SIM_uses_RF = 0;
404 fInfo.SIM_uses_GB = useGB;
405 fInfo.SIM_uses_EAM = useEAM;
406
407 excl = Exclude::getArray();
408
409 #ifdef IS_MPI
410 n_global = mpiSim->getTotAtoms();
411 #else
412 n_global = n_atoms;
413 #endif
414
415 isError = 0;
416
417 setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
418 &nGlobalExcludes, globalExcludes, molMembershipArray,
419 &isError );
420
421 if( isError ){
422
423 sprintf( painCave.errMsg,
424 "There was an error setting the simulation information in fortran.\n" );
425 painCave.isFatal = 1;
426 simError();
427 }
428
429 #ifdef IS_MPI
430 sprintf( checkPointMsg,
431 "succesfully sent the simulation information to fortran.\n");
432 MPIcheckPoint();
433 #endif // is_mpi
434
435 this->ndf = this->getNDF();
436 this->ndfRaw = this->getNDFraw();
437
438 }
439