ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/brains/SimInfo.cpp
Revision: 1492
Committed: Fri Sep 24 16:27:58 2004 UTC (19 years, 9 months ago) by tim
File size: 13763 byte(s)
Log Message:
change the #include in source files

File Contents

# User Rev Content
1 gezelter 1490 #include <stdlib.h>
2     #include <string.h>
3     #include <math.h>
4    
5     #include <iostream>
6     using namespace std;
7    
8 tim 1492 #include "brains/SimInfo.hpp"
9 gezelter 1490 #define __C
10 tim 1492 #include "brains/fSimulation.h"
11     #include "utils/simError.h"
12 gezelter 1490
13 tim 1492 #include "UseTheForce/fortranWrappers.hpp"
14 gezelter 1490
15 tim 1492 #include "math/MatVec3.h"
16 gezelter 1490
17     #ifdef IS_MPI
18 tim 1492 #include "brains/mpiSimulation.hpp"
19 gezelter 1490 #endif
20    
21     inline double roundMe( double x ){
22     return ( x >= 0 ) ? floor( x + 0.5 ) : ceil( x - 0.5 );
23     }
24    
25     inline double min( double a, double b ){
26     return (a < b ) ? a : b;
27     }
28    
29     SimInfo* currentInfo;
30    
31     SimInfo::SimInfo(){
32    
33     n_constraints = 0;
34     nZconstraints = 0;
35     n_oriented = 0;
36     n_dipoles = 0;
37     ndf = 0;
38     ndfRaw = 0;
39     nZconstraints = 0;
40     the_integrator = NULL;
41     setTemp = 0;
42     thermalTime = 0.0;
43     currentTime = 0.0;
44     rCut = 0.0;
45     rSw = 0.0;
46    
47     haveRcut = 0;
48     haveRsw = 0;
49     boxIsInit = 0;
50    
51     resetTime = 1e99;
52    
53     orthoRhombic = 0;
54     orthoTolerance = 1E-6;
55     useInitXSstate = true;
56    
57     usePBC = 0;
58     useLJ = 0;
59     useSticky = 0;
60     useCharges = 0;
61     useDipoles = 0;
62     useReactionField = 0;
63     useGB = 0;
64     useEAM = 0;
65     useSolidThermInt = 0;
66     useLiquidThermInt = 0;
67    
68     haveCutoffGroups = false;
69    
70     excludes = Exclude::Instance();
71    
72     myConfiguration = new SimState();
73    
74     has_minimizer = false;
75     the_minimizer =NULL;
76    
77     ngroup = 0;
78    
79     wrapMeSimInfo( this );
80     }
81    
82    
83     SimInfo::~SimInfo(){
84    
85     delete myConfiguration;
86    
87     map<string, GenericData*>::iterator i;
88    
89     for(i = properties.begin(); i != properties.end(); i++)
90     delete (*i).second;
91    
92     }
93    
94     void SimInfo::setBox(double newBox[3]) {
95    
96     int i, j;
97     double tempMat[3][3];
98    
99     for(i=0; i<3; i++)
100     for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
101    
102     tempMat[0][0] = newBox[0];
103     tempMat[1][1] = newBox[1];
104     tempMat[2][2] = newBox[2];
105    
106     setBoxM( tempMat );
107    
108     }
109    
110     void SimInfo::setBoxM( double theBox[3][3] ){
111    
112     int i, j;
113     double FortranHmat[9]; // to preserve compatibility with Fortran the
114     // ordering in the array is as follows:
115     // [ 0 3 6 ]
116     // [ 1 4 7 ]
117     // [ 2 5 8 ]
118     double FortranHmatInv[9]; // the inverted Hmat (for Fortran);
119    
120     if( !boxIsInit ) boxIsInit = 1;
121    
122     for(i=0; i < 3; i++)
123     for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
124    
125     calcBoxL();
126     calcHmatInv();
127    
128     for(i=0; i < 3; i++) {
129     for (j=0; j < 3; j++) {
130     FortranHmat[3*j + i] = Hmat[i][j];
131     FortranHmatInv[3*j + i] = HmatInv[i][j];
132     }
133     }
134    
135     setFortranBoxSize(FortranHmat, FortranHmatInv, &orthoRhombic);
136    
137     }
138    
139    
140     void SimInfo::getBoxM (double theBox[3][3]) {
141    
142     int i, j;
143     for(i=0; i<3; i++)
144     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j];
145     }
146    
147    
148     void SimInfo::scaleBox(double scale) {
149     double theBox[3][3];
150     int i, j;
151    
152     // cerr << "Scaling box by " << scale << "\n";
153    
154     for(i=0; i<3; i++)
155     for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j]*scale;
156    
157     setBoxM(theBox);
158    
159     }
160    
161     void SimInfo::calcHmatInv( void ) {
162    
163     int oldOrtho;
164     int i,j;
165     double smallDiag;
166     double tol;
167     double sanity[3][3];
168    
169     invertMat3( Hmat, HmatInv );
170    
171     // check to see if Hmat is orthorhombic
172    
173     oldOrtho = orthoRhombic;
174    
175     smallDiag = fabs(Hmat[0][0]);
176     if(smallDiag > fabs(Hmat[1][1])) smallDiag = fabs(Hmat[1][1]);
177     if(smallDiag > fabs(Hmat[2][2])) smallDiag = fabs(Hmat[2][2]);
178     tol = smallDiag * orthoTolerance;
179    
180     orthoRhombic = 1;
181    
182     for (i = 0; i < 3; i++ ) {
183     for (j = 0 ; j < 3; j++) {
184     if (i != j) {
185     if (orthoRhombic) {
186     if ( fabs(Hmat[i][j]) >= tol) orthoRhombic = 0;
187     }
188     }
189     }
190     }
191    
192     if( oldOrtho != orthoRhombic ){
193    
194     if( orthoRhombic ) {
195     sprintf( painCave.errMsg,
196     "OOPSE is switching from the default Non-Orthorhombic\n"
197     "\tto the faster Orthorhombic periodic boundary computations.\n"
198     "\tThis is usually a good thing, but if you wan't the\n"
199     "\tNon-Orthorhombic computations, make the orthoBoxTolerance\n"
200     "\tvariable ( currently set to %G ) smaller.\n",
201     orthoTolerance);
202     painCave.severity = OOPSE_INFO;
203     simError();
204     }
205     else {
206     sprintf( painCave.errMsg,
207     "OOPSE is switching from the faster Orthorhombic to the more\n"
208     "\tflexible Non-Orthorhombic periodic boundary computations.\n"
209     "\tThis is usually because the box has deformed under\n"
210     "\tNPTf integration. If you wan't to live on the edge with\n"
211     "\tthe Orthorhombic computations, make the orthoBoxTolerance\n"
212     "\tvariable ( currently set to %G ) larger.\n",
213     orthoTolerance);
214     painCave.severity = OOPSE_WARNING;
215     simError();
216     }
217     }
218     }
219    
220     void SimInfo::calcBoxL( void ){
221    
222     double dx, dy, dz, dsq;
223    
224     // boxVol = Determinant of Hmat
225    
226     boxVol = matDet3( Hmat );
227    
228     // boxLx
229    
230     dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
231     dsq = dx*dx + dy*dy + dz*dz;
232     boxL[0] = sqrt( dsq );
233     //maxCutoff = 0.5 * boxL[0];
234    
235     // boxLy
236    
237     dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
238     dsq = dx*dx + dy*dy + dz*dz;
239     boxL[1] = sqrt( dsq );
240     //if( (0.5 * boxL[1]) < maxCutoff ) maxCutoff = 0.5 * boxL[1];
241    
242    
243     // boxLz
244    
245     dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
246     dsq = dx*dx + dy*dy + dz*dz;
247     boxL[2] = sqrt( dsq );
248     //if( (0.5 * boxL[2]) < maxCutoff ) maxCutoff = 0.5 * boxL[2];
249    
250     //calculate the max cutoff
251     maxCutoff = calcMaxCutOff();
252    
253     checkCutOffs();
254    
255     }
256    
257    
258     double SimInfo::calcMaxCutOff(){
259    
260     double ri[3], rj[3], rk[3];
261     double rij[3], rjk[3], rki[3];
262     double minDist;
263    
264     ri[0] = Hmat[0][0];
265     ri[1] = Hmat[1][0];
266     ri[2] = Hmat[2][0];
267    
268     rj[0] = Hmat[0][1];
269     rj[1] = Hmat[1][1];
270     rj[2] = Hmat[2][1];
271    
272     rk[0] = Hmat[0][2];
273     rk[1] = Hmat[1][2];
274     rk[2] = Hmat[2][2];
275    
276     crossProduct3(ri, rj, rij);
277     distXY = dotProduct3(rk,rij) / norm3(rij);
278    
279     crossProduct3(rj,rk, rjk);
280     distYZ = dotProduct3(ri,rjk) / norm3(rjk);
281    
282     crossProduct3(rk,ri, rki);
283     distZX = dotProduct3(rj,rki) / norm3(rki);
284    
285     minDist = min(min(distXY, distYZ), distZX);
286     return minDist/2;
287    
288     }
289    
290     void SimInfo::wrapVector( double thePos[3] ){
291    
292     int i;
293     double scaled[3];
294    
295     if( !orthoRhombic ){
296     // calc the scaled coordinates.
297    
298    
299     matVecMul3(HmatInv, thePos, scaled);
300    
301     for(i=0; i<3; i++)
302     scaled[i] -= roundMe(scaled[i]);
303    
304     // calc the wrapped real coordinates from the wrapped scaled coordinates
305    
306     matVecMul3(Hmat, scaled, thePos);
307    
308     }
309     else{
310     // calc the scaled coordinates.
311    
312     for(i=0; i<3; i++)
313     scaled[i] = thePos[i]*HmatInv[i][i];
314    
315     // wrap the scaled coordinates
316    
317     for(i=0; i<3; i++)
318     scaled[i] -= roundMe(scaled[i]);
319    
320     // calc the wrapped real coordinates from the wrapped scaled coordinates
321    
322     for(i=0; i<3; i++)
323     thePos[i] = scaled[i]*Hmat[i][i];
324     }
325    
326     }
327    
328    
329     int SimInfo::getNDF(){
330     int ndf_local;
331    
332     ndf_local = 0;
333    
334     for(int i = 0; i < integrableObjects.size(); i++){
335     ndf_local += 3;
336     if (integrableObjects[i]->isDirectional()) {
337     if (integrableObjects[i]->isLinear())
338     ndf_local += 2;
339     else
340     ndf_local += 3;
341     }
342     }
343    
344     // n_constraints is local, so subtract them on each processor:
345    
346     ndf_local -= n_constraints;
347    
348     #ifdef IS_MPI
349     MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
350     #else
351     ndf = ndf_local;
352     #endif
353    
354     // nZconstraints is global, as are the 3 COM translations for the
355     // entire system:
356    
357     ndf = ndf - 3 - nZconstraints;
358    
359     return ndf;
360     }
361    
362     int SimInfo::getNDFraw() {
363     int ndfRaw_local;
364    
365     // Raw degrees of freedom that we have to set
366     ndfRaw_local = 0;
367    
368     for(int i = 0; i < integrableObjects.size(); i++){
369     ndfRaw_local += 3;
370     if (integrableObjects[i]->isDirectional()) {
371     if (integrableObjects[i]->isLinear())
372     ndfRaw_local += 2;
373     else
374     ndfRaw_local += 3;
375     }
376     }
377    
378     #ifdef IS_MPI
379     MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
380     #else
381     ndfRaw = ndfRaw_local;
382     #endif
383    
384     return ndfRaw;
385     }
386    
387     int SimInfo::getNDFtranslational() {
388     int ndfTrans_local;
389    
390     ndfTrans_local = 3 * integrableObjects.size() - n_constraints;
391    
392    
393     #ifdef IS_MPI
394     MPI_Allreduce(&ndfTrans_local,&ndfTrans,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
395     #else
396     ndfTrans = ndfTrans_local;
397     #endif
398    
399     ndfTrans = ndfTrans - 3 - nZconstraints;
400    
401     return ndfTrans;
402     }
403    
404     int SimInfo::getTotIntegrableObjects() {
405     int nObjs_local;
406     int nObjs;
407    
408     nObjs_local = integrableObjects.size();
409    
410    
411     #ifdef IS_MPI
412     MPI_Allreduce(&nObjs_local,&nObjs,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
413     #else
414     nObjs = nObjs_local;
415     #endif
416    
417    
418     return nObjs;
419     }
420    
421     void SimInfo::refreshSim(){
422    
423     simtype fInfo;
424     int isError;
425     int n_global;
426     int* excl;
427    
428     fInfo.dielect = 0.0;
429    
430     if( useDipoles ){
431     if( useReactionField )fInfo.dielect = dielectric;
432     }
433    
434     fInfo.SIM_uses_PBC = usePBC;
435     //fInfo.SIM_uses_LJ = 0;
436     fInfo.SIM_uses_LJ = useLJ;
437     fInfo.SIM_uses_sticky = useSticky;
438     //fInfo.SIM_uses_sticky = 0;
439     fInfo.SIM_uses_charges = useCharges;
440     fInfo.SIM_uses_dipoles = useDipoles;
441     //fInfo.SIM_uses_dipoles = 0;
442     fInfo.SIM_uses_RF = useReactionField;
443     //fInfo.SIM_uses_RF = 0;
444     fInfo.SIM_uses_GB = useGB;
445     fInfo.SIM_uses_EAM = useEAM;
446    
447     n_exclude = excludes->getSize();
448     excl = excludes->getFortranArray();
449    
450     #ifdef IS_MPI
451     n_global = mpiSim->getNAtomsGlobal();
452     #else
453     n_global = n_atoms;
454     #endif
455    
456     isError = 0;
457    
458     getFortranGroupArrays(this, FglobalGroupMembership, mfact);
459     //it may not be a good idea to pass the address of first element in vector
460     //since c++ standard does not require vector to be stored continuously in meomory
461     //Most of the compilers will organize the memory of vector continuously
462     setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
463     &nGlobalExcludes, globalExcludes, molMembershipArray,
464     &mfact[0], &ngroup, &FglobalGroupMembership[0], &isError);
465    
466     if( isError ){
467    
468     sprintf( painCave.errMsg,
469     "There was an error setting the simulation information in fortran.\n" );
470     painCave.isFatal = 1;
471     painCave.severity = OOPSE_ERROR;
472     simError();
473     }
474    
475     #ifdef IS_MPI
476     sprintf( checkPointMsg,
477     "succesfully sent the simulation information to fortran.\n");
478     MPIcheckPoint();
479     #endif // is_mpi
480    
481     this->ndf = this->getNDF();
482     this->ndfRaw = this->getNDFraw();
483     this->ndfTrans = this->getNDFtranslational();
484     }
485    
486     void SimInfo::setDefaultRcut( double theRcut ){
487    
488     haveRcut = 1;
489     rCut = theRcut;
490     rList = rCut + 1.0;
491    
492     notifyFortranCutOffs( &rCut, &rSw, &rList );
493     }
494    
495     void SimInfo::setDefaultRcut( double theRcut, double theRsw ){
496    
497     rSw = theRsw;
498     setDefaultRcut( theRcut );
499     }
500    
501    
502     void SimInfo::checkCutOffs( void ){
503    
504     if( boxIsInit ){
505    
506     //we need to check cutOffs against the box
507    
508     if( rCut > maxCutoff ){
509     sprintf( painCave.errMsg,
510     "cutoffRadius is too large for the current periodic box.\n"
511     "\tCurrent Value of cutoffRadius = %G at time %G\n "
512     "\tThis is larger than half of at least one of the\n"
513     "\tperiodic box vectors. Right now, the Box matrix is:\n"
514     "\n"
515     "\t[ %G %G %G ]\n"
516     "\t[ %G %G %G ]\n"
517     "\t[ %G %G %G ]\n",
518     rCut, currentTime,
519     Hmat[0][0], Hmat[0][1], Hmat[0][2],
520     Hmat[1][0], Hmat[1][1], Hmat[1][2],
521     Hmat[2][0], Hmat[2][1], Hmat[2][2]);
522     painCave.severity = OOPSE_ERROR;
523     painCave.isFatal = 1;
524     simError();
525     }
526     } else {
527     // initialize this stuff before using it, OK?
528     sprintf( painCave.errMsg,
529     "Trying to check cutoffs without a box.\n"
530     "\tOOPSE should have better programmers than that.\n" );
531     painCave.severity = OOPSE_ERROR;
532     painCave.isFatal = 1;
533     simError();
534     }
535    
536     }
537    
538     void SimInfo::addProperty(GenericData* prop){
539    
540     map<string, GenericData*>::iterator result;
541     result = properties.find(prop->getID());
542    
543     //we can't simply use properties[prop->getID()] = prop,
544     //it will cause memory leak if we already contain a propery which has the same name of prop
545    
546     if(result != properties.end()){
547    
548     delete (*result).second;
549     (*result).second = prop;
550    
551     }
552     else{
553    
554     properties[prop->getID()] = prop;
555    
556     }
557    
558     }
559    
560     GenericData* SimInfo::getProperty(const string& propName){
561    
562     map<string, GenericData*>::iterator result;
563    
564     //string lowerCaseName = ();
565    
566     result = properties.find(propName);
567    
568     if(result != properties.end())
569     return (*result).second;
570     else
571     return NULL;
572     }
573    
574    
575     void SimInfo::getFortranGroupArrays(SimInfo* info,
576     vector<int>& FglobalGroupMembership,
577     vector<double>& mfact){
578    
579     Molecule* myMols;
580     Atom** myAtoms;
581     int numAtom;
582     double mtot;
583     int numMol;
584     int numCutoffGroups;
585     CutoffGroup* myCutoffGroup;
586     vector<CutoffGroup*>::iterator iterCutoff;
587     Atom* cutoffAtom;
588     vector<Atom*>::iterator iterAtom;
589     int atomIndex;
590     double totalMass;
591    
592     mfact.clear();
593     FglobalGroupMembership.clear();
594    
595    
596     // Fix the silly fortran indexing problem
597     #ifdef IS_MPI
598     numAtom = mpiSim->getNAtomsGlobal();
599     #else
600     numAtom = n_atoms;
601     #endif
602     for (int i = 0; i < numAtom; i++)
603     FglobalGroupMembership.push_back(globalGroupMembership[i] + 1);
604    
605    
606     myMols = info->molecules;
607     numMol = info->n_mol;
608     for(int i = 0; i < numMol; i++){
609     numCutoffGroups = myMols[i].getNCutoffGroups();
610     for(myCutoffGroup =myMols[i].beginCutoffGroup(iterCutoff);
611     myCutoffGroup != NULL;
612     myCutoffGroup =myMols[i].nextCutoffGroup(iterCutoff)){
613    
614     totalMass = myCutoffGroup->getMass();
615    
616     for(cutoffAtom = myCutoffGroup->beginAtom(iterAtom);
617     cutoffAtom != NULL;
618     cutoffAtom = myCutoffGroup->nextAtom(iterAtom)){
619     mfact.push_back(cutoffAtom->getMass()/totalMass);
620     }
621     }
622     }
623    
624     }