ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new-templateless/OOPSE/libmdtools/SimInfo.cpp
Revision: 850
Committed: Mon Nov 3 22:07:17 2003 UTC (20 years, 9 months ago) by mmeineke
File size: 13762 byte(s)
Log Message:
begun work on removing templates and most of standard template library from OOPSE.

File Contents

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