ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1229
Committed: Thu Jun 3 20:02:25 2004 UTC (20 years, 3 months ago) by gezelter
File size: 62480 byte(s)
Log Message:
Fixed groupOffset bug

File Contents

# User Rev Content
1 tim 658 #include <algorithm>
2 gezelter 829 #include <stdlib.h>
3 mmeineke 377 #include <iostream>
4 gezelter 829 #include <math.h>
5 tim 658 #include <string>
6 tim 722 #include <sprng.h>
7 mmeineke 377 #include "SimSetup.hpp"
8 tim 689 #include "ReadWrite.hpp"
9 mmeineke 377 #include "parse_me.h"
10     #include "Integrator.hpp"
11     #include "simError.h"
12 gezelter 1097 #include "RigidBody.hpp"
13 tim 1064 #include "OOPSEMinimizer.hpp"
14 tim 1211 //#include "ConstraintElement.hpp"
15     //#include "ConstraintPair.hpp"
16 mmeineke 377
17     #ifdef IS_MPI
18     #include "mpiBASS.h"
19     #include "mpiSimulation.hpp"
20     #endif
21    
22 mmeineke 557 // some defines for ensemble and Forcefield cases
23    
24 tim 660 #define NVE_ENS 0
25     #define NVT_ENS 1
26     #define NPTi_ENS 2
27     #define NPTf_ENS 3
28 mmeineke 812 #define NPTxyz_ENS 4
29 mmeineke 557
30 mmeineke 812
31 chrisfen 999 #define FF_DUFF 0
32     #define FF_LJ 1
33     #define FF_EAM 2
34 chrisfen 1041 #define FF_H2O 3
35 mmeineke 557
36 tim 658 using namespace std;
37    
38 tim 962 /**
39     * Check whether dividend is divisble by divisor or not
40     */
41     bool isDivisible(double dividend, double divisor){
42     double tolerance = 0.000001;
43     double quotient;
44     double diff;
45     int intQuotient;
46    
47     quotient = dividend / divisor;
48    
49     if (quotient < 0)
50     quotient = -quotient;
51    
52     intQuotient = int (quotient + tolerance);
53    
54     diff = fabs(fabs(dividend) - intQuotient * fabs(divisor));
55    
56     if (diff <= tolerance)
57     return true;
58     else
59     return false;
60     }
61    
62 mmeineke 377 SimSetup::SimSetup(){
63 mmeineke 823
64     initSuspend = false;
65 mmeineke 656 isInfoArray = 0;
66     nInfo = 1;
67 tim 722
68 mmeineke 377 stamps = new MakeStamps();
69     globals = new Globals();
70 tim 722
71    
72 mmeineke 377 #ifdef IS_MPI
73 tim 722 strcpy(checkPointMsg, "SimSetup creation successful");
74 mmeineke 377 MPIcheckPoint();
75     #endif // IS_MPI
76     }
77    
78     SimSetup::~SimSetup(){
79     delete stamps;
80     delete globals;
81     }
82    
83 tim 722 void SimSetup::setSimInfo(SimInfo* the_info, int theNinfo){
84     info = the_info;
85     nInfo = theNinfo;
86     isInfoArray = 1;
87 mmeineke 823 initSuspend = true;
88 mmeineke 670 }
89 mmeineke 656
90    
91 tim 722 void SimSetup::parseFile(char* fileName){
92 mmeineke 377 #ifdef IS_MPI
93 tim 722 if (worldRank == 0){
94 mmeineke 377 #endif // is_mpi
95 tim 722
96 mmeineke 377 inFileName = fileName;
97 tim 722 set_interface_stamps(stamps, globals);
98    
99 mmeineke 377 #ifdef IS_MPI
100     mpiEventInit();
101     #endif
102    
103 tim 722 yacc_BASS(fileName);
104 mmeineke 377
105     #ifdef IS_MPI
106     throwMPIEvent(NULL);
107     }
108 tim 722 else{
109     receiveParse();
110     }
111 mmeineke 377 #endif
112    
113     }
114    
115     #ifdef IS_MPI
116     void SimSetup::receiveParse(void){
117 tim 722 set_interface_stamps(stamps, globals);
118     mpiEventInit();
119     MPIcheckPoint();
120     mpiEventLoop();
121 mmeineke 377 }
122    
123     #endif // is_mpi
124    
125 mmeineke 670 void SimSetup::createSim(void){
126 mmeineke 377
127 mmeineke 614 // gather all of the information from the Bass file
128 tim 689
129 mmeineke 614 gatherInfo();
130 mmeineke 377
131 mmeineke 614 // creation of complex system objects
132 mmeineke 377
133 mmeineke 614 sysObjectsCreation();
134 mmeineke 377
135 mmeineke 859 // check on the post processing info
136    
137     finalInfoCheck();
138    
139 mmeineke 614 // initialize the system coordinates
140 mmeineke 377
141 mmeineke 823 if ( !initSuspend ){
142 tim 722 initSystemCoords();
143 mmeineke 811
144     if( !(globals->getUseInitTime()) )
145     info[0].currentTime = 0.0;
146 tim 722 }
147 mmeineke 377
148 mmeineke 614 // make the output filenames
149 mmeineke 377
150 mmeineke 614 makeOutNames();
151 tim 1113
152     #ifdef IS_MPI
153     mpiSim->mpiRefresh();
154     #endif
155 tim 722
156 tim 1113 // initialize the Fortran
157    
158     initFortran();
159    
160 tim 1031 if (globals->haveMinimizer())
161     // make minimizer
162     makeMinimizer();
163     else
164     // make the integrator
165     makeIntegrator();
166 mmeineke 377
167     }
168    
169 mmeineke 407
170 tim 722 void SimSetup::makeMolecules(void){
171 gezelter 1097 int i, j, k;
172 gezelter 1104 int exI, exJ, exK, exL, slI, slJ;
173 gezelter 1097 int tempI, tempJ, tempK, tempL;
174 gezelter 1214 int molI, globalID;
175     int stampID, atomOffset, rbOffset, groupOffset;
176 mmeineke 616 molInit molInfo;
177 mmeineke 407 DirectionalAtom* dAtom;
178 gezelter 1097 RigidBody* myRB;
179     StuntDouble* mySD;
180 mmeineke 412 LinkedAssign* extras;
181     LinkedAssign* current_extra;
182 mmeineke 407 AtomStamp* currentAtom;
183     BondStamp* currentBond;
184     BendStamp* currentBend;
185     TorsionStamp* currentTorsion;
186 gezelter 1097 RigidBodyStamp* currentRigidBody;
187 tim 1157 CutoffGroupStamp* currentCutoffGroup;
188     CutoffGroup* myCutoffGroup;
189 tim 1167 int nCutoffGroups;// number of cutoff group of a molecule defined in mdl file
190     set<int> cutoffAtomSet; //atoms belong to cutoffgroup defined at mdl file
191    
192 mmeineke 427 bond_pair* theBonds;
193     bend_set* theBends;
194     torsion_set* theTorsions;
195    
196 gezelter 1097 set<int> skipList;
197    
198     double phi, theta, psi;
199 tim 1108 char* molName;
200     char rbName[100];
201 gezelter 1097
202 tim 1211 //ConstraintPair* consPair; //constraint pair
203     //ConstraintElement* consElement1; //first element of constraint pair
204     //ConstraintElement* consElement2; //second element of constraint pair
205     //int whichRigidBody;
206     //int consAtomIndex; //index of constraint atom in rigid body's atom array
207     //vector<pair<int, int> > jointAtoms;
208 mmeineke 407 //init the forceField paramters
209    
210     the_ff->readParams();
211    
212 mmeineke 427 // init the atoms
213 mmeineke 407
214 gezelter 1097 int nMembers, nNew, rb1, rb2;
215 mmeineke 407
216 tim 722 for (k = 0; k < nInfo; k++){
217     the_ff->setSimInfo(&(info[k]));
218    
219 gezelter 1214 #ifdef IS_MPI
220     info[k].globalGroupMembership = new int[mpiSim->getNAtomsGlobal()];
221     for (i = 0; i < mpiSim->getNAtomsGlobal(); i++)
222     info[k].globalGroupMembership[i] = 0;
223     #else
224     info[k].globalGroupMembership = new int[info[k].n_atoms];
225     for (i = 0; i < info[k].n_atoms; i++)
226     info[k].globalGroupMembership[i] = 0;
227     #endif
228    
229 mmeineke 670 atomOffset = 0;
230 tim 1211 groupOffset = 0;
231 gezelter 1097
232 tim 722 for (i = 0; i < info[k].n_mol; i++){
233 mmeineke 670 stampID = info[k].molecules[i].getStampID();
234 tim 1108 molName = comp_stamps[stampID]->getID();
235 mmeineke 412
236 tim 722 molInfo.nAtoms = comp_stamps[stampID]->getNAtoms();
237     molInfo.nBonds = comp_stamps[stampID]->getNBonds();
238     molInfo.nBends = comp_stamps[stampID]->getNBends();
239 mmeineke 670 molInfo.nTorsions = comp_stamps[stampID]->getNTorsions();
240 gezelter 1097 molInfo.nRigidBodies = comp_stamps[stampID]->getNRigidBodies();
241 tim 1167
242     nCutoffGroups = comp_stamps[stampID]->getNCutoffGroups();
243 gezelter 1097
244 mmeineke 670 molInfo.myAtoms = &(info[k].atoms[atomOffset]);
245 mmeineke 407
246 gezelter 1097 if (molInfo.nBonds > 0)
247 gezelter 1174 molInfo.myBonds = new Bond*[molInfo.nBonds];
248 gezelter 1097 else
249     molInfo.myBonds = NULL;
250    
251     if (molInfo.nBends > 0)
252 gezelter 1174 molInfo.myBends = new Bend*[molInfo.nBends];
253 gezelter 1097 else
254     molInfo.myBends = NULL;
255    
256     if (molInfo.nTorsions > 0)
257 gezelter 1174 molInfo.myTorsions = new Torsion *[molInfo.nTorsions];
258 gezelter 1097 else
259     molInfo.myTorsions = NULL;
260    
261 mmeineke 670 theBonds = new bond_pair[molInfo.nBonds];
262     theBends = new bend_set[molInfo.nBends];
263     theTorsions = new torsion_set[molInfo.nTorsions];
264 gezelter 1097
265 mmeineke 670 // make the Atoms
266 tim 722
267     for (j = 0; j < molInfo.nAtoms; j++){
268     currentAtom = comp_stamps[stampID]->getAtom(j);
269 gezelter 1097
270 tim 722 if (currentAtom->haveOrientation()){
271     dAtom = new DirectionalAtom((j + atomOffset),
272     info[k].getConfiguration());
273     info[k].n_oriented++;
274     molInfo.myAtoms[j] = dAtom;
275    
276 gezelter 983 // Directional Atoms have standard unit vectors which are oriented
277     // in space using the three Euler angles. We assume the standard
278     // unit vector was originally along the z axis below.
279 tim 722
280 gezelter 984 phi = currentAtom->getEulerPhi() * M_PI / 180.0;
281     theta = currentAtom->getEulerTheta() * M_PI / 180.0;
282     psi = currentAtom->getEulerPsi()* M_PI / 180.0;
283 gezelter 1097
284     dAtom->setUnitFrameFromEuler(phi, theta, psi);
285 gezelter 983
286 tim 722 }
287     else{
288 gezelter 1097
289     molInfo.myAtoms[j] = new Atom((j + atomOffset), info[k].getConfiguration());
290 tim 1113
291 tim 722 }
292 gezelter 1097
293 tim 722 molInfo.myAtoms[j]->setType(currentAtom->getType());
294 mmeineke 407 #ifdef IS_MPI
295 tim 1108 molInfo.myAtoms[j]->setGlobalIndex(globalAtomIndex[j + atomOffset]);
296 mmeineke 407 #endif // is_mpi
297 mmeineke 670 }
298 tim 722
299     // make the bonds
300     for (j = 0; j < molInfo.nBonds; j++){
301     currentBond = comp_stamps[stampID]->getBond(j);
302     theBonds[j].a = currentBond->getA() + atomOffset;
303     theBonds[j].b = currentBond->getB() + atomOffset;
304    
305 gezelter 1097 tempI = theBonds[j].a;
306     tempJ = theBonds[j].b;
307 tim 722
308 mmeineke 670 #ifdef IS_MPI
309 gezelter 1097 exI = info[k].atoms[tempI]->getGlobalIndex() + 1;
310     exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1;
311     #else
312     exI = tempI + 1;
313     exJ = tempJ + 1;
314     #endif
315 tim 722
316 gezelter 1097 info[k].excludes->addPair(exI, exJ);
317 mmeineke 670 }
318 tim 722
319 mmeineke 670 //make the bends
320 tim 722 for (j = 0; j < molInfo.nBends; j++){
321     currentBend = comp_stamps[stampID]->getBend(j);
322     theBends[j].a = currentBend->getA() + atomOffset;
323     theBends[j].b = currentBend->getB() + atomOffset;
324     theBends[j].c = currentBend->getC() + atomOffset;
325    
326     if (currentBend->haveExtras()){
327     extras = currentBend->getExtras();
328     current_extra = extras;
329    
330     while (current_extra != NULL){
331     if (!strcmp(current_extra->getlhs(), "ghostVectorSource")){
332     switch (current_extra->getType()){
333     case 0:
334     theBends[j].ghost = current_extra->getInt() + atomOffset;
335     theBends[j].isGhost = 1;
336     break;
337    
338     case 1:
339     theBends[j].ghost = (int) current_extra->getDouble() +
340     atomOffset;
341     theBends[j].isGhost = 1;
342     break;
343    
344     default:
345     sprintf(painCave.errMsg,
346     "SimSetup Error: ghostVectorSource was neither a "
347     "double nor an int.\n"
348     "-->Bend[%d] in %s\n",
349     j, comp_stamps[stampID]->getID());
350     painCave.isFatal = 1;
351     simError();
352     }
353     }
354     else{
355     sprintf(painCave.errMsg,
356     "SimSetup Error: unhandled bend assignment:\n"
357     " -->%s in Bend[%d] in %s\n",
358     current_extra->getlhs(), j, comp_stamps[stampID]->getID());
359     painCave.isFatal = 1;
360     simError();
361     }
362    
363     current_extra = current_extra->getNext();
364     }
365 tim 701 }
366 tim 722
367 gezelter 1097 if (theBends[j].isGhost) {
368    
369     tempI = theBends[j].a;
370     tempJ = theBends[j].b;
371    
372     #ifdef IS_MPI
373     exI = info[k].atoms[tempI]->getGlobalIndex() + 1;
374     exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1;
375     #else
376     exI = tempI + 1;
377     exJ = tempJ + 1;
378     #endif
379     info[k].excludes->addPair(exI, exJ);
380 tim 722
381 gezelter 1097 } else {
382    
383     tempI = theBends[j].a;
384     tempJ = theBends[j].b;
385     tempK = theBends[j].c;
386    
387     #ifdef IS_MPI
388     exI = info[k].atoms[tempI]->getGlobalIndex() + 1;
389     exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1;
390     exK = info[k].atoms[tempK]->getGlobalIndex() + 1;
391     #else
392     exI = tempI + 1;
393     exJ = tempJ + 1;
394     exK = tempK + 1;
395     #endif
396    
397     info[k].excludes->addPair(exI, exK);
398     info[k].excludes->addPair(exI, exJ);
399     info[k].excludes->addPair(exJ, exK);
400 tim 722 }
401 mmeineke 412 }
402 tim 722
403     for (j = 0; j < molInfo.nTorsions; j++){
404     currentTorsion = comp_stamps[stampID]->getTorsion(j);
405     theTorsions[j].a = currentTorsion->getA() + atomOffset;
406     theTorsions[j].b = currentTorsion->getB() + atomOffset;
407     theTorsions[j].c = currentTorsion->getC() + atomOffset;
408     theTorsions[j].d = currentTorsion->getD() + atomOffset;
409    
410 gezelter 1097 tempI = theTorsions[j].a;
411     tempJ = theTorsions[j].b;
412     tempK = theTorsions[j].c;
413     tempL = theTorsions[j].d;
414 tim 722
415 mmeineke 670 #ifdef IS_MPI
416 gezelter 1097 exI = info[k].atoms[tempI]->getGlobalIndex() + 1;
417     exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1;
418     exK = info[k].atoms[tempK]->getGlobalIndex() + 1;
419     exL = info[k].atoms[tempL]->getGlobalIndex() + 1;
420     #else
421     exI = tempI + 1;
422     exJ = tempJ + 1;
423     exK = tempK + 1;
424     exL = tempL + 1;
425     #endif
426 tim 722
427 gezelter 1097 info[k].excludes->addPair(exI, exJ);
428     info[k].excludes->addPair(exI, exK);
429     info[k].excludes->addPair(exI, exL);
430     info[k].excludes->addPair(exJ, exK);
431     info[k].excludes->addPair(exJ, exL);
432     info[k].excludes->addPair(exK, exL);
433 mmeineke 670 }
434 tim 722
435 tim 1113
436     molInfo.myRigidBodies.clear();
437    
438 gezelter 1097 for (j = 0; j < molInfo.nRigidBodies; j++){
439 tim 722
440 gezelter 1097 currentRigidBody = comp_stamps[stampID]->getRigidBody(j);
441     nMembers = currentRigidBody->getNMembers();
442    
443     // Create the Rigid Body:
444    
445     myRB = new RigidBody();
446 tim 1108
447 tim 1113 sprintf(rbName,"%s_RB_%d", molName, j);
448 tim 1108 myRB->setType(rbName);
449 gezelter 1097
450     for (rb1 = 0; rb1 < nMembers; rb1++) {
451    
452     // molI is atom numbering inside this molecule
453     molI = currentRigidBody->getMember(rb1);
454    
455     // tempI is atom numbering on local processor
456     tempI = molI + atomOffset;
457    
458     // currentAtom is the AtomStamp (which we need for
459     // rigid body reference positions)
460     currentAtom = comp_stamps[stampID]->getAtom(molI);
461    
462     // When we add to the rigid body, add the atom itself and
463     // the stamp info:
464    
465     myRB->addAtom(info[k].atoms[tempI], currentAtom);
466    
467     // Add this atom to the Skip List for the integrators
468     #ifdef IS_MPI
469     slI = info[k].atoms[tempI]->getGlobalIndex();
470     #else
471     slI = tempI;
472     #endif
473     skipList.insert(slI);
474    
475     }
476    
477     for(rb1 = 0; rb1 < nMembers - 1; rb1++) {
478     for(rb2 = rb1+1; rb2 < nMembers; rb2++) {
479    
480     tempI = currentRigidBody->getMember(rb1);
481     tempJ = currentRigidBody->getMember(rb2);
482    
483     // Some explanation is required here.
484     // Fortran indexing starts at 1, while c indexing starts at 0
485     // Also, in parallel computations, the GlobalIndex is
486     // used for the exclude list:
487    
488     #ifdef IS_MPI
489 tim 1116 exI = molInfo.myAtoms[tempI]->getGlobalIndex() + 1;
490     exJ = molInfo.myAtoms[tempJ]->getGlobalIndex() + 1;
491 gezelter 1097 #else
492 tim 1116 exI = molInfo.myAtoms[tempI]->getIndex() + 1;
493     exJ = molInfo.myAtoms[tempJ]->getIndex() + 1;
494 gezelter 1097 #endif
495    
496     info[k].excludes->addPair(exI, exJ);
497    
498     }
499     }
500 gezelter 1104
501     molInfo.myRigidBodies.push_back(myRB);
502     info[k].rigidBodies.push_back(myRB);
503 gezelter 1097 }
504    
505 gezelter 1104
506 gezelter 1163 //create cutoff group for molecule
507 tim 1167
508     cutoffAtomSet.clear();
509 tim 1157 molInfo.myCutoffGroups.clear();
510 tim 1167
511     for (j = 0; j < nCutoffGroups; j++){
512 tim 1157
513     currentCutoffGroup = comp_stamps[stampID]->getCutoffGroup(j);
514     nMembers = currentCutoffGroup->getNMembers();
515    
516     myCutoffGroup = new CutoffGroup();
517 gezelter 1214
518     #ifdef IS_MPI
519 gezelter 1229 myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]);
520 gezelter 1214 #else
521 gezelter 1229 myCutoffGroup->setGlobalIndex(groupOffset);
522 gezelter 1214 #endif
523 tim 1157
524     for (int cg = 0; cg < nMembers; cg++) {
525    
526     // molI is atom numbering inside this molecule
527     molI = currentCutoffGroup->getMember(cg);
528    
529     // tempI is atom numbering on local processor
530     tempI = molI + atomOffset;
531 tim 1211
532     #ifdef IS_MPI
533 gezelter 1214 globalID = info[k].atoms[tempI]->getGlobalIndex();
534 gezelter 1229 info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset];
535 tim 1211 #else
536     globalID = info[k].atoms[tempI]->getIndex();
537 gezelter 1229 info[k].globalGroupMembership[globalID] = groupOffset;
538     #endif
539     myCutoffGroup->addAtom(info[k].atoms[tempI]);
540 tim 1167 cutoffAtomSet.insert(tempI);
541 tim 1157 }
542 gezelter 1214
543 tim 1211 molInfo.myCutoffGroups.push_back(myCutoffGroup);
544     groupOffset++;
545 tim 1157
546     }//end for (j = 0; j < molInfo.nCutoffGroups; j++)
547 gezelter 1214
548    
549 gezelter 1229 // create a cutoff group for every atom in current molecule which
550     // does not belong to cutoffgroup defined at mdl file
551    
552 tim 1167 for(j = 0; j < molInfo.nAtoms; j++){
553 gezelter 1214
554 tim 1167 if(cutoffAtomSet.find(molInfo.myAtoms[j]->getIndex()) == cutoffAtomSet.end()){
555     myCutoffGroup = new CutoffGroup();
556     myCutoffGroup->addAtom(molInfo.myAtoms[j]);
557 gezelter 1229
558 gezelter 1214 #ifdef IS_MPI
559 gezelter 1229 myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]);
560 gezelter 1214 globalID = info[k].atoms[atomOffset + j]->getGlobalIndex();
561 gezelter 1229 info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset];
562 gezelter 1214 #else
563 gezelter 1229 myCutoffGroup->setGlobalIndex(groupOffset);
564 tim 1211 globalID = info[k].atoms[atomOffset + j]->getIndex();
565 gezelter 1229 info[k].globalGroupMembership[globalID] = groupOffset;
566 tim 1211 #endif
567 tim 1167 molInfo.myCutoffGroups.push_back(myCutoffGroup);
568 tim 1211 groupOffset++;
569 gezelter 1229 }
570 tim 1167 }
571    
572 gezelter 1104 // After this is all set up, scan through the atoms to
573     // see if they can be added to the integrableObjects:
574    
575 tim 1113 molInfo.myIntegrableObjects.clear();
576    
577    
578 gezelter 1104 for (j = 0; j < molInfo.nAtoms; j++){
579    
580     #ifdef IS_MPI
581     slJ = molInfo.myAtoms[j]->getGlobalIndex();
582     #else
583     slJ = j+atomOffset;
584     #endif
585    
586     // if they aren't on the skip list, then they can be integrated
587    
588     if (skipList.find(slJ) == skipList.end()) {
589     mySD = (StuntDouble *) molInfo.myAtoms[j];
590     info[k].integrableObjects.push_back(mySD);
591     molInfo.myIntegrableObjects.push_back(mySD);
592     }
593     }
594    
595     // all rigid bodies are integrated:
596    
597     for (j = 0; j < molInfo.nRigidBodies; j++) {
598     mySD = (StuntDouble *) molInfo.myRigidBodies[j];
599     info[k].integrableObjects.push_back(mySD);
600     molInfo.myIntegrableObjects.push_back(mySD);
601     }
602 tim 1211
603    
604     /*
605    
606     //creat ConstraintPair.
607     molInfo.myConstraintPair.clear();
608 gezelter 1104
609 tim 1211 for (j = 0; j < molInfo.nBonds; j++){
610    
611     //if both atoms are in the same rigid body, just skip it
612     currentBond = comp_stamps[stampID]->getBond(j);
613     if(!comp_stamps[stampID]->isBondInSameRigidBody(currentBond)){
614    
615     tempI = currentBond->getA() + atomOffset;
616     if( comp_stamps[stampID]->isAtomInRigidBody(currentBond->getA(), whichRigidBody, consAtomIndex))
617     consElement1 = new ConstraintRigidBody(molInfo.myRigidBodies[whichRigidBody], consAtomIndex);
618     else
619     consElement1 = new ConstraintAtom(info[k].atoms[tempI]);
620    
621     tempJ = currentBond->getB() + atomOffset;
622     if(comp_stamps[stampID]->isAtomInRigidBody(currentBond->getB(), whichRigidBody, consAtomIndex))
623     consElement2 = new ConstraintRigidBody(molInfo.myRigidBodies[whichRigidBody], consAtomIndex);
624     else
625     consElement2 = new ConstraintAtom(info[k].atoms[tempJ]);
626    
627     consPair = new DistanceConstraintPair(consElement1, consElement2);
628     molInfo.myConstraintPairs.push_back(consPair);
629     }
630     }
631    
632     //loop over rigid bodies, if two rigid bodies share same joint, creat a HingeConstraintPair
633     for (int rb1 = 0; rb1 < molInfo.nRigidBodies -1 ; rb1++){
634     for (int rb2 = rb1 + 1; rb2 < molInfo.nRigidBodies ; rb2++){
635    
636     jointAtoms = comp_stamps[stampID]->getJointAtoms(rb1, rb2);
637    
638     for(size_t m = 0; m < jointAtoms.size(); m++){
639     consElement1 = new ConstraintRigidBody(molInfo.myRigidBodies[rb1], jointAtoms[m].first);
640     consElement2 = new ConstraintRigidBody(molInfo.myRigidBodies[rb2], jointAtoms[m].second);
641    
642     consPair = new JointConstraintPair(consElement1, consElement2);
643     molInfo.myConstraintPairs.push_back(consPair);
644     }
645    
646     }
647     }
648    
649     */
650 mmeineke 670 // send the arrays off to the forceField for init.
651 gezelter 1097
652 tim 722 the_ff->initializeAtoms(molInfo.nAtoms, molInfo.myAtoms);
653     the_ff->initializeBonds(molInfo.nBonds, molInfo.myBonds, theBonds);
654     the_ff->initializeBends(molInfo.nBends, molInfo.myBends, theBends);
655     the_ff->initializeTorsions(molInfo.nTorsions, molInfo.myTorsions,
656     theTorsions);
657    
658     info[k].molecules[i].initialize(molInfo);
659 gezelter 1214
660    
661 mmeineke 670 atomOffset += molInfo.nAtoms;
662     delete[] theBonds;
663     delete[] theBends;
664     delete[] theTorsions;
665 gezelter 1214 }
666    
667    
668    
669     #ifdef IS_MPI
670     // Since the globalGroupMembership has been zero filled and we've only
671     // poked values into the atoms we know, we can do an Allreduce
672     // to get the full globalGroupMembership array (We think).
673     // This would be prettier if we could use MPI_IN_PLACE like the MPI-2
674     // docs said we could.
675    
676     int* ggMjunk = new int[mpiSim->getNAtomsGlobal()];
677    
678     MPI_Allreduce(info[k].globalGroupMembership,
679     ggMjunk,
680     mpiSim->getNAtomsGlobal(),
681     MPI_INT, MPI_SUM, MPI_COMM_WORLD);
682    
683     for (i = 0; i < mpiSim->getNAtomsGlobal(); i++)
684     info[k].globalGroupMembership[i] = ggMjunk[i];
685    
686     delete[] ggMjunk;
687    
688     #endif
689    
690    
691    
692 mmeineke 414 }
693 tim 722
694 chuckv 434 #ifdef IS_MPI
695 tim 722 sprintf(checkPointMsg, "all molecules initialized succesfully");
696 chuckv 434 MPIcheckPoint();
697     #endif // is_mpi
698 tim 722
699 mmeineke 414 }
700 mmeineke 407
701 tim 722 void SimSetup::initFromBass(void){
702 mmeineke 377 int i, j, k;
703     int n_cells;
704     double cellx, celly, cellz;
705     double temp1, temp2, temp3;
706     int n_per_extra;
707     int n_extra;
708     int have_extra, done;
709    
710 mmeineke 670 double vel[3];
711     vel[0] = 0.0;
712     vel[1] = 0.0;
713     vel[2] = 0.0;
714    
715 tim 722 temp1 = (double) tot_nmol / 4.0;
716     temp2 = pow(temp1, (1.0 / 3.0));
717     temp3 = ceil(temp2);
718 mmeineke 377
719 tim 722 have_extra = 0;
720     if (temp2 < temp3){
721     // we have a non-complete lattice
722     have_extra = 1;
723 mmeineke 377
724 tim 722 n_cells = (int) temp3 - 1;
725 mmeineke 670 cellx = info[0].boxL[0] / temp3;
726     celly = info[0].boxL[1] / temp3;
727     cellz = info[0].boxL[2] / temp3;
728 tim 722 n_extra = tot_nmol - (4 * n_cells * n_cells * n_cells);
729     temp1 = ((double) n_extra) / (pow(temp3, 3.0) - pow(n_cells, 3.0));
730     n_per_extra = (int) ceil(temp1);
731 mmeineke 377
732 tim 722 if (n_per_extra > 4){
733     sprintf(painCave.errMsg,
734     "SimSetup error. There has been an error in constructing"
735     " the non-complete lattice.\n");
736 mmeineke 377 painCave.isFatal = 1;
737     simError();
738     }
739     }
740     else{
741 tim 722 n_cells = (int) temp3;
742 mmeineke 670 cellx = info[0].boxL[0] / temp3;
743     celly = info[0].boxL[1] / temp3;
744     cellz = info[0].boxL[2] / temp3;
745 mmeineke 377 }
746    
747     current_mol = 0;
748     current_comp_mol = 0;
749     current_comp = 0;
750     current_atom_ndx = 0;
751    
752 tim 722 for (i = 0; i < n_cells ; i++){
753     for (j = 0; j < n_cells; j++){
754     for (k = 0; k < n_cells; k++){
755     makeElement(i * cellx, j * celly, k * cellz);
756 mmeineke 377
757 tim 722 makeElement(i * cellx + 0.5 * cellx, j * celly + 0.5 * celly, k * cellz);
758 mmeineke 377
759 tim 722 makeElement(i * cellx, j * celly + 0.5 * celly, k * cellz + 0.5 * cellz);
760 mmeineke 377
761 tim 722 makeElement(i * cellx + 0.5 * cellx, j * celly, k * cellz + 0.5 * cellz);
762 mmeineke 377 }
763     }
764     }
765    
766 tim 722 if (have_extra){
767 mmeineke 377 done = 0;
768    
769     int start_ndx;
770 tim 722 for (i = 0; i < (n_cells + 1) && !done; i++){
771     for (j = 0; j < (n_cells + 1) && !done; j++){
772     if (i < n_cells){
773     if (j < n_cells){
774     start_ndx = n_cells;
775     }
776     else
777     start_ndx = 0;
778     }
779     else
780     start_ndx = 0;
781 mmeineke 377
782 tim 722 for (k = start_ndx; k < (n_cells + 1) && !done; k++){
783     makeElement(i * cellx, j * celly, k * cellz);
784     done = (current_mol >= tot_nmol);
785 mmeineke 377
786 tim 722 if (!done && n_per_extra > 1){
787     makeElement(i * cellx + 0.5 * cellx, j * celly + 0.5 * celly,
788     k * cellz);
789     done = (current_mol >= tot_nmol);
790     }
791 mmeineke 377
792 tim 722 if (!done && n_per_extra > 2){
793     makeElement(i * cellx, j * celly + 0.5 * celly,
794     k * cellz + 0.5 * cellz);
795     done = (current_mol >= tot_nmol);
796     }
797 mmeineke 377
798 tim 722 if (!done && n_per_extra > 3){
799     makeElement(i * cellx + 0.5 * cellx, j * celly,
800     k * cellz + 0.5 * cellz);
801     done = (current_mol >= tot_nmol);
802     }
803     }
804 mmeineke 377 }
805     }
806     }
807    
808 tim 722 for (i = 0; i < info[0].n_atoms; i++){
809     info[0].atoms[i]->setVel(vel);
810 mmeineke 377 }
811     }
812    
813 tim 722 void SimSetup::makeElement(double x, double y, double z){
814 mmeineke 377 int k;
815     AtomStamp* current_atom;
816     DirectionalAtom* dAtom;
817     double rotMat[3][3];
818 mmeineke 670 double pos[3];
819 mmeineke 377
820 tim 722 for (k = 0; k < comp_stamps[current_comp]->getNAtoms(); k++){
821     current_atom = comp_stamps[current_comp]->getAtom(k);
822     if (!current_atom->havePosition()){
823     sprintf(painCave.errMsg,
824     "SimSetup:initFromBass error.\n"
825     "\tComponent %s, atom %s does not have a position specified.\n"
826     "\tThe initialization routine is unable to give a start"
827     " position.\n",
828     comp_stamps[current_comp]->getID(), current_atom->getType());
829 mmeineke 377 painCave.isFatal = 1;
830     simError();
831     }
832 tim 722
833 mmeineke 670 pos[0] = x + current_atom->getPosX();
834     pos[1] = y + current_atom->getPosY();
835     pos[2] = z + current_atom->getPosZ();
836 mmeineke 377
837 tim 722 info[0].atoms[current_atom_ndx]->setPos(pos);
838 mmeineke 377
839 tim 722 if (info[0].atoms[current_atom_ndx]->isDirectional()){
840     dAtom = (DirectionalAtom *) info[0].atoms[current_atom_ndx];
841 mmeineke 377
842     rotMat[0][0] = 1.0;
843     rotMat[0][1] = 0.0;
844     rotMat[0][2] = 0.0;
845    
846     rotMat[1][0] = 0.0;
847     rotMat[1][1] = 1.0;
848     rotMat[1][2] = 0.0;
849    
850     rotMat[2][0] = 0.0;
851     rotMat[2][1] = 0.0;
852     rotMat[2][2] = 1.0;
853    
854 tim 722 dAtom->setA(rotMat);
855 mmeineke 377 }
856    
857     current_atom_ndx++;
858     }
859    
860     current_mol++;
861     current_comp_mol++;
862    
863 tim 722 if (current_comp_mol >= components_nmol[current_comp]){
864 mmeineke 377 current_comp_mol = 0;
865     current_comp++;
866     }
867     }
868 mmeineke 614
869    
870 tim 722 void SimSetup::gatherInfo(void){
871 mmeineke 787 int i;
872 mmeineke 614
873     ensembleCase = -1;
874     ffCase = -1;
875    
876 mmeineke 670 // set the easy ones first
877 mmeineke 614
878 tim 722 for (i = 0; i < nInfo; i++){
879 mmeineke 670 info[i].target_temp = globals->getTargetTemp();
880     info[i].dt = globals->getDt();
881     info[i].run_time = globals->getRunTime();
882     }
883 mmeineke 616 n_components = globals->getNComponents();
884 mmeineke 614
885    
886     // get the forceField
887    
888 tim 722 strcpy(force_field, globals->getForceField());
889 mmeineke 614
890 tim 722 if (!strcasecmp(force_field, "DUFF")){
891     ffCase = FF_DUFF;
892     }
893     else if (!strcasecmp(force_field, "LJ")){
894     ffCase = FF_LJ;
895     }
896     else if (!strcasecmp(force_field, "EAM")){
897     ffCase = FF_EAM;
898     }
899 chrisfen 999 else if (!strcasecmp(force_field, "WATER")){
900     ffCase = FF_H2O;
901     }
902 mmeineke 614 else{
903 tim 722 sprintf(painCave.errMsg, "SimSetup Error. Unrecognized force field -> %s\n",
904     force_field);
905     painCave.isFatal = 1;
906     simError();
907 mmeineke 614 }
908    
909 tim 722 // get the ensemble
910 mmeineke 614
911 tim 722 strcpy(ensemble, globals->getEnsemble());
912 mmeineke 614
913 tim 722 if (!strcasecmp(ensemble, "NVE")){
914     ensembleCase = NVE_ENS;
915     }
916     else if (!strcasecmp(ensemble, "NVT")){
917     ensembleCase = NVT_ENS;
918     }
919     else if (!strcasecmp(ensemble, "NPTi") || !strcasecmp(ensemble, "NPT")){
920 mmeineke 614 ensembleCase = NPTi_ENS;
921 tim 722 }
922     else if (!strcasecmp(ensemble, "NPTf")){
923     ensembleCase = NPTf_ENS;
924     }
925 mmeineke 812 else if (!strcasecmp(ensemble, "NPTxyz")){
926     ensembleCase = NPTxyz_ENS;
927     }
928 mmeineke 614 else{
929 tim 722 sprintf(painCave.errMsg,
930 gezelter 965 "SimSetup Warning. Unrecognized Ensemble -> %s \n"
931     "\treverting to NVE for this simulation.\n",
932 tim 722 ensemble);
933     painCave.isFatal = 0;
934     simError();
935     strcpy(ensemble, "NVE");
936     ensembleCase = NVE_ENS;
937 mmeineke 614 }
938    
939 tim 722 for (i = 0; i < nInfo; i++){
940     strcpy(info[i].ensemble, ensemble);
941    
942 mmeineke 670 // get the mixing rule
943 mmeineke 614
944 tim 722 strcpy(info[i].mixingRule, globals->getMixingRule());
945 mmeineke 670 info[i].usePBC = globals->getPBC();
946     }
947 tim 722
948 mmeineke 614 // get the components and calculate the tot_nMol and indvidual n_mol
949 tim 722
950 mmeineke 616 the_components = globals->getComponents();
951 mmeineke 614 components_nmol = new int[n_components];
952    
953    
954 tim 722 if (!globals->haveNMol()){
955 mmeineke 614 // we don't have the total number of molecules, so we assume it is
956     // given in each component
957    
958     tot_nmol = 0;
959 tim 722 for (i = 0; i < n_components; i++){
960     if (!the_components[i]->haveNMol()){
961     // we have a problem
962     sprintf(painCave.errMsg,
963 gezelter 965 "SimSetup Error. No global NMol or component NMol given.\n"
964     "\tCannot calculate the number of atoms.\n");
965 tim 722 painCave.isFatal = 1;
966     simError();
967 mmeineke 614 }
968    
969     tot_nmol += the_components[i]->getNMol();
970     components_nmol[i] = the_components[i]->getNMol();
971     }
972     }
973     else{
974 tim 722 sprintf(painCave.errMsg,
975     "SimSetup error.\n"
976     "\tSorry, the ability to specify total"
977     " nMols and then give molfractions in the components\n"
978     "\tis not currently supported."
979     " Please give nMol in the components.\n");
980 mmeineke 614 painCave.isFatal = 1;
981     simError();
982     }
983    
984 tim 962 //check whether sample time, status time, thermal time and reset time are divisble by dt
985 tim 1129 if (globals->haveSampleTime() && !isDivisible(globals->getSampleTime(), globals->getDt())){
986 tim 962 sprintf(painCave.errMsg,
987 gezelter 965 "Sample time is not divisible by dt.\n"
988     "\tThis will result in samples that are not uniformly\n"
989     "\tdistributed in time. If this is a problem, change\n"
990     "\tyour sampleTime variable.\n");
991 tim 962 painCave.isFatal = 0;
992     simError();
993     }
994    
995 tim 1129 if (globals->haveStatusTime() && !isDivisible(globals->getStatusTime(), globals->getDt())){
996 tim 962 sprintf(painCave.errMsg,
997 gezelter 965 "Status time is not divisible by dt.\n"
998     "\tThis will result in status reports that are not uniformly\n"
999     "\tdistributed in time. If this is a problem, change \n"
1000     "\tyour statusTime variable.\n");
1001 tim 962 painCave.isFatal = 0;
1002     simError();
1003     }
1004    
1005     if (globals->haveThermalTime() && !isDivisible(globals->getThermalTime(), globals->getDt())){
1006     sprintf(painCave.errMsg,
1007 gezelter 965 "Thermal time is not divisible by dt.\n"
1008     "\tThis will result in thermalizations that are not uniformly\n"
1009     "\tdistributed in time. If this is a problem, change \n"
1010     "\tyour thermalTime variable.\n");
1011 tim 962 painCave.isFatal = 0;
1012     simError();
1013     }
1014    
1015     if (globals->haveResetTime() && !isDivisible(globals->getResetTime(), globals->getDt())){
1016     sprintf(painCave.errMsg,
1017 gezelter 965 "Reset time is not divisible by dt.\n"
1018     "\tThis will result in integrator resets that are not uniformly\n"
1019     "\tdistributed in time. If this is a problem, change\n"
1020     "\tyour resetTime variable.\n");
1021 tim 962 painCave.isFatal = 0;
1022     simError();
1023     }
1024    
1025 mmeineke 614 // set the status, sample, and thermal kick times
1026    
1027 tim 722 for (i = 0; i < nInfo; i++){
1028     if (globals->haveSampleTime()){
1029 mmeineke 670 info[i].sampleTime = globals->getSampleTime();
1030     info[i].statusTime = info[i].sampleTime;
1031     }
1032     else{
1033     info[i].sampleTime = globals->getRunTime();
1034     info[i].statusTime = info[i].sampleTime;
1035     }
1036 tim 722
1037     if (globals->haveStatusTime()){
1038 mmeineke 670 info[i].statusTime = globals->getStatusTime();
1039     }
1040 tim 722
1041     if (globals->haveThermalTime()){
1042 mmeineke 670 info[i].thermalTime = globals->getThermalTime();
1043 tim 1129 } else {
1044     info[i].thermalTime = globals->getRunTime();
1045 mmeineke 670 }
1046 mmeineke 614
1047 mmeineke 746 info[i].resetIntegrator = 0;
1048     if( globals->haveResetTime() ){
1049     info[i].resetTime = globals->getResetTime();
1050     info[i].resetIntegrator = 1;
1051     }
1052    
1053 mmeineke 670 // check for the temperature set flag
1054 mmeineke 841
1055 tim 722 if (globals->haveTempSet())
1056     info[i].setTemp = globals->getTempSet();
1057 mmeineke 855
1058     // check for the extended State init
1059    
1060     info[i].useInitXSstate = globals->getUseInitXSstate();
1061     info[i].orthoTolerance = globals->getOrthoBoxTolerance();
1062 chrisfen 1180
1063     // check for thermodynamic integration
1064 chrisfen 1212 if (globals->getUseSolidThermInt() && !globals->getUseLiquidThermInt()) {
1065 chrisfen 1187 if (globals->haveThermIntLambda() && globals->haveThermIntK()) {
1066 chrisfen 1212 info[i].useSolidThermInt = globals->getUseSolidThermInt();
1067 chrisfen 1187 info[i].thermIntLambda = globals->getThermIntLambda();
1068     info[i].thermIntK = globals->getThermIntK();
1069    
1070     Restraints *myRestraint = new Restraints(tot_nmol, info[i].thermIntLambda, info[i].thermIntK);
1071     info[i].restraint = myRestraint;
1072     }
1073     else {
1074     sprintf(painCave.errMsg,
1075     "SimSetup Error:\n"
1076 chrisfen 1212 "\tKeyword useSolidThermInt was set to 'true' but\n"
1077 chrisfen 1187 "\tthermodynamicIntegrationLambda (and/or\n"
1078     "\tthermodynamicIntegrationK) was not specified.\n"
1079     "\tPlease provide a lambda value and k value in your .bass file.\n");
1080     painCave.isFatal = 1;
1081     simError();
1082     }
1083 chrisfen 1180 }
1084 chrisfen 1212 else if(globals->getUseLiquidThermInt()) {
1085     if (globals->getUseSolidThermInt()) {
1086     sprintf( painCave.errMsg,
1087     "SimSetup Warning: It appears that you have both solid and\n"
1088     "\tliquid thermodynamic integration activated in your .bass\n"
1089     "\tfile. To avoid confusion, specify only one technique in\n"
1090     "\tyour .bass file. Liquid-state thermodynamic integration\n"
1091     "\twill be assumed for the current simulation. If this is not\n"
1092     "\twhat you desire, set useSolidThermInt to 'true' and\n"
1093     "\tuseLiquidThermInt to 'false' in your .bass file.\n");
1094     painCave.isFatal = 0;
1095     simError();
1096     }
1097     if (globals->haveThermIntLambda() && globals->haveThermIntK()) {
1098     info[i].useLiquidThermInt = globals->getUseLiquidThermInt();
1099     info[i].thermIntLambda = globals->getThermIntLambda();
1100     info[i].thermIntK = globals->getThermIntK();
1101     }
1102     else {
1103     sprintf(painCave.errMsg,
1104     "SimSetup Error:\n"
1105     "\tKeyword useLiquidThermInt was set to 'true' but\n"
1106     "\tthermodynamicIntegrationLambda (and/or\n"
1107     "\tthermodynamicIntegrationK) was not specified.\n"
1108     "\tPlease provide a lambda value and k value in your .bass file.\n");
1109     painCave.isFatal = 1;
1110     simError();
1111     }
1112     }
1113 chrisfen 1187 else if(globals->haveThermIntLambda() || globals->haveThermIntK()){
1114     sprintf(painCave.errMsg,
1115     "SimSetup Warning: If you want to use Thermodynamic\n"
1116 chrisfen 1212 "\tIntegration, set useSolidThermInt or useLiquidThermInt to\n"
1117     "\t'true' in your .bass file. These keywords are set to\n"
1118     "\t'false' by default, so your lambda and/or k values are\n"
1119     "\tbeing ignored.\n");
1120 chrisfen 1187 painCave.isFatal = 0;
1121     simError();
1122     }
1123 tim 708 }
1124 mmeineke 841
1125 tim 722 //setup seed for random number generator
1126 tim 708 int seedValue;
1127    
1128 tim 722 if (globals->haveSeed()){
1129 tim 708 seedValue = globals->getSeed();
1130 tim 722
1131     if(seedValue / 1E9 == 0){
1132     sprintf(painCave.errMsg,
1133     "Seed for sprng library should contain at least 9 digits\n"
1134     "OOPSE will generate a seed for user\n");
1135     painCave.isFatal = 0;
1136     simError();
1137    
1138     //using seed generated by system instead of invalid seed set by user
1139     #ifndef IS_MPI
1140     seedValue = make_sprng_seed();
1141     #else
1142     if (worldRank == 0){
1143     seedValue = make_sprng_seed();
1144     }
1145     MPI_Bcast(&seedValue, 1, MPI_INT, 0, MPI_COMM_WORLD);
1146     #endif
1147     }
1148     }//end of if branch of globals->haveSeed()
1149 tim 708 else{
1150 tim 722
1151 tim 708 #ifndef IS_MPI
1152 tim 722 seedValue = make_sprng_seed();
1153 tim 708 #else
1154 tim 722 if (worldRank == 0){
1155     seedValue = make_sprng_seed();
1156 tim 708 }
1157 tim 722 MPI_Bcast(&seedValue, 1, MPI_INT, 0, MPI_COMM_WORLD);
1158 tim 708 #endif
1159 tim 722 }//end of globals->haveSeed()
1160 tim 708
1161 tim 722 for (int i = 0; i < nInfo; i++){
1162 tim 708 info[i].setSeed(seedValue);
1163     }
1164 tim 1031
1165 mmeineke 614 #ifdef IS_MPI
1166 chrisfen 999 strcpy(checkPointMsg, "Successfully gathered all information from Bass\n");
1167 mmeineke 614 MPIcheckPoint();
1168     #endif // is_mpi
1169     }
1170    
1171    
1172 tim 722 void SimSetup::finalInfoCheck(void){
1173 mmeineke 614 int index;
1174     int usesDipoles;
1175 tim 1113 int usesCharges;
1176 mmeineke 670 int i;
1177 mmeineke 614
1178 tim 722 for (i = 0; i < nInfo; i++){
1179 mmeineke 670 // check electrostatic parameters
1180 tim 722
1181 mmeineke 670 index = 0;
1182     usesDipoles = 0;
1183 tim 722 while ((index < info[i].n_atoms) && !usesDipoles){
1184 mmeineke 670 usesDipoles = (info[i].atoms[index])->hasDipole();
1185     index++;
1186     }
1187 tim 1113 index = 0;
1188     usesCharges = 0;
1189     while ((index < info[i].n_atoms) && !usesCharges){
1190     usesCharges= (info[i].atoms[index])->hasCharge();
1191     index++;
1192     }
1193 mmeineke 614 #ifdef IS_MPI
1194 mmeineke 670 int myUse = usesDipoles;
1195 tim 722 MPI_Allreduce(&myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
1196 mmeineke 614 #endif //is_mpi
1197 tim 722
1198 gezelter 1154 double theRcut, theRsw;
1199 tim 722
1200 gezelter 1163 if (globals->haveRcut()) {
1201     theRcut = globals->getRcut();
1202    
1203     if (globals->haveRsw())
1204     theRsw = globals->getRsw();
1205     else
1206     theRsw = theRcut;
1207    
1208     info[i].setDefaultRcut(theRcut, theRsw);
1209    
1210     } else {
1211    
1212     the_ff->calcRcut();
1213     theRcut = info[i].getRcut();
1214    
1215     if (globals->haveRsw())
1216     theRsw = globals->getRsw();
1217     else
1218     theRsw = theRcut;
1219    
1220     info[i].setDefaultRcut(theRcut, theRsw);
1221     }
1222    
1223 tim 722 if (globals->getUseRF()){
1224 mmeineke 670 info[i].useReactionField = 1;
1225 gezelter 1163
1226 gezelter 1154 if (!globals->haveRcut()){
1227 tim 722 sprintf(painCave.errMsg,
1228 gezelter 1154 "SimSetup Warning: No value was set for the cutoffRadius.\n"
1229 gezelter 965 "\tOOPSE will use a default value of 15.0 angstroms"
1230 gezelter 1154 "\tfor the cutoffRadius.\n");
1231 tim 722 painCave.isFatal = 0;
1232     simError();
1233 gezelter 1154 theRcut = 15.0;
1234 mmeineke 614 }
1235 tim 722 else{
1236 gezelter 1154 theRcut = globals->getRcut();
1237 mmeineke 614 }
1238 tim 722
1239 gezelter 1154 if (!globals->haveRsw()){
1240 tim 722 sprintf(painCave.errMsg,
1241 gezelter 1154 "SimSetup Warning: No value was set for switchingRadius.\n"
1242 gezelter 965 "\tOOPSE will use a default value of\n"
1243 gezelter 1154 "\t0.95 * cutoffRadius for the switchingRadius\n");
1244 tim 722 painCave.isFatal = 0;
1245     simError();
1246 gezelter 1154 theRsw = 0.95 * theRcut;
1247 mmeineke 670 }
1248 tim 722 else{
1249 gezelter 1154 theRsw = globals->getRsw();
1250 mmeineke 670 }
1251 tim 722
1252 gezelter 1154 info[i].setDefaultRcut(theRcut, theRsw);
1253 tim 722
1254     if (!globals->haveDielectric()){
1255     sprintf(painCave.errMsg,
1256 gezelter 965 "SimSetup Error: No Dielectric constant was set.\n"
1257     "\tYou are trying to use Reaction Field without"
1258     "\tsetting a dielectric constant!\n");
1259 tim 722 painCave.isFatal = 1;
1260     simError();
1261     }
1262     info[i].dielectric = globals->getDielectric();
1263     }
1264     else{
1265 tim 1113 if (usesDipoles || usesCharges){
1266 gezelter 1154
1267     if (!globals->haveRcut()){
1268 tim 722 sprintf(painCave.errMsg,
1269 gezelter 1154 "SimSetup Warning: No value was set for the cutoffRadius.\n"
1270 gezelter 965 "\tOOPSE will use a default value of 15.0 angstroms"
1271 gezelter 1154 "\tfor the cutoffRadius.\n");
1272     painCave.isFatal = 0;
1273     simError();
1274     theRcut = 15.0;
1275     }
1276 tim 722 else{
1277 gezelter 1154 theRcut = globals->getRcut();
1278 tim 722 }
1279 gezelter 1154
1280     if (!globals->haveRsw()){
1281 tim 722 sprintf(painCave.errMsg,
1282 gezelter 1154 "SimSetup Warning: No value was set for switchingRadius.\n"
1283 gezelter 965 "\tOOPSE will use a default value of\n"
1284 gezelter 1154 "\t0.95 * cutoffRadius for the switchingRadius\n");
1285 tim 722 painCave.isFatal = 0;
1286     simError();
1287 gezelter 1154 theRsw = 0.95 * theRcut;
1288 tim 722 }
1289     else{
1290 gezelter 1154 theRsw = globals->getRsw();
1291 tim 722 }
1292 gezelter 1154
1293     info[i].setDefaultRcut(theRcut, theRsw);
1294 mmeineke 859
1295 tim 722 }
1296     }
1297 mmeineke 670 }
1298 mmeineke 614 #ifdef IS_MPI
1299 tim 722 strcpy(checkPointMsg, "post processing checks out");
1300 mmeineke 614 MPIcheckPoint();
1301     #endif // is_mpi
1302 gezelter 1163
1303     // clean up the forcefield
1304     the_ff->cleanMe();
1305 mmeineke 614 }
1306 mmeineke 859
1307 tim 722 void SimSetup::initSystemCoords(void){
1308 mmeineke 670 int i;
1309 tim 722
1310 tim 689 char* inName;
1311    
1312 tim 722 (info[0].getConfiguration())->createArrays(info[0].n_atoms);
1313 mmeineke 614
1314 tim 722 for (i = 0; i < info[0].n_atoms; i++)
1315     info[0].atoms[i]->setCoords();
1316    
1317     if (globals->haveInitialConfig()){
1318 mmeineke 670 InitializeFromFile* fileInit;
1319 mmeineke 614 #ifdef IS_MPI // is_mpi
1320 tim 722 if (worldRank == 0){
1321 mmeineke 614 #endif //is_mpi
1322 tim 689 inName = globals->getInitialConfig();
1323 tim 722 fileInit = new InitializeFromFile(inName);
1324 mmeineke 614 #ifdef IS_MPI
1325 tim 722 }
1326     else
1327     fileInit = new InitializeFromFile(NULL);
1328 mmeineke 614 #endif
1329 tim 722 fileInit->readInit(info); // default velocities on
1330    
1331 mmeineke 670 delete fileInit;
1332     }
1333     else{
1334 mmeineke 859
1335 mmeineke 670 // no init from bass
1336 mmeineke 859
1337 tim 722 sprintf(painCave.errMsg,
1338 mmeineke 859 "Cannot intialize a simulation without an initial configuration file.\n");
1339 mmeineke 787 painCave.isFatal = 1;;
1340 mmeineke 670 simError();
1341 mmeineke 859
1342 mmeineke 670 }
1343 tim 722
1344 mmeineke 614 #ifdef IS_MPI
1345 tim 722 strcpy(checkPointMsg, "Successfully read in the initial configuration");
1346 mmeineke 614 MPIcheckPoint();
1347     #endif // is_mpi
1348     }
1349    
1350    
1351 tim 722 void SimSetup::makeOutNames(void){
1352 mmeineke 670 int k;
1353 mmeineke 614
1354 mmeineke 670
1355 tim 722 for (k = 0; k < nInfo; k++){
1356 mmeineke 614 #ifdef IS_MPI
1357 tim 722 if (worldRank == 0){
1358 mmeineke 614 #endif // is_mpi
1359 tim 722
1360     if (globals->haveFinalConfig()){
1361     strcpy(info[k].finalName, globals->getFinalConfig());
1362 mmeineke 614 }
1363     else{
1364 tim 722 strcpy(info[k].finalName, inFileName);
1365     char* endTest;
1366     int nameLength = strlen(info[k].finalName);
1367     endTest = &(info[k].finalName[nameLength - 5]);
1368     if (!strcmp(endTest, ".bass")){
1369     strcpy(endTest, ".eor");
1370     }
1371     else if (!strcmp(endTest, ".BASS")){
1372     strcpy(endTest, ".eor");
1373     }
1374     else{
1375     endTest = &(info[k].finalName[nameLength - 4]);
1376     if (!strcmp(endTest, ".bss")){
1377     strcpy(endTest, ".eor");
1378     }
1379     else if (!strcmp(endTest, ".mdl")){
1380     strcpy(endTest, ".eor");
1381     }
1382     else{
1383     strcat(info[k].finalName, ".eor");
1384     }
1385     }
1386 mmeineke 614 }
1387 tim 722
1388 mmeineke 670 // make the sample and status out names
1389 tim 722
1390     strcpy(info[k].sampleName, inFileName);
1391 mmeineke 670 char* endTest;
1392 tim 722 int nameLength = strlen(info[k].sampleName);
1393 mmeineke 670 endTest = &(info[k].sampleName[nameLength - 5]);
1394 tim 722 if (!strcmp(endTest, ".bass")){
1395     strcpy(endTest, ".dump");
1396 mmeineke 614 }
1397 tim 722 else if (!strcmp(endTest, ".BASS")){
1398     strcpy(endTest, ".dump");
1399 mmeineke 614 }
1400     else{
1401 tim 722 endTest = &(info[k].sampleName[nameLength - 4]);
1402     if (!strcmp(endTest, ".bss")){
1403     strcpy(endTest, ".dump");
1404     }
1405     else if (!strcmp(endTest, ".mdl")){
1406     strcpy(endTest, ".dump");
1407     }
1408     else{
1409     strcat(info[k].sampleName, ".dump");
1410     }
1411 mmeineke 614 }
1412 tim 722
1413     strcpy(info[k].statusName, inFileName);
1414     nameLength = strlen(info[k].statusName);
1415 mmeineke 670 endTest = &(info[k].statusName[nameLength - 5]);
1416 tim 722 if (!strcmp(endTest, ".bass")){
1417     strcpy(endTest, ".stat");
1418 mmeineke 614 }
1419 tim 722 else if (!strcmp(endTest, ".BASS")){
1420     strcpy(endTest, ".stat");
1421 mmeineke 614 }
1422     else{
1423 tim 722 endTest = &(info[k].statusName[nameLength - 4]);
1424     if (!strcmp(endTest, ".bss")){
1425     strcpy(endTest, ".stat");
1426     }
1427     else if (!strcmp(endTest, ".mdl")){
1428     strcpy(endTest, ".stat");
1429     }
1430     else{
1431     strcat(info[k].statusName, ".stat");
1432     }
1433 mmeineke 614 }
1434 tim 722
1435 chrisfen 1180 strcpy(info[k].rawPotName, inFileName);
1436     nameLength = strlen(info[k].rawPotName);
1437     endTest = &(info[k].rawPotName[nameLength - 5]);
1438     if (!strcmp(endTest, ".bass")){
1439     strcpy(endTest, ".raw");
1440     }
1441     else if (!strcmp(endTest, ".BASS")){
1442     strcpy(endTest, ".raw");
1443     }
1444     else{
1445     endTest = &(info[k].rawPotName[nameLength - 4]);
1446     if (!strcmp(endTest, ".bss")){
1447     strcpy(endTest, ".raw");
1448     }
1449     else if (!strcmp(endTest, ".mdl")){
1450     strcpy(endTest, ".raw");
1451     }
1452     else{
1453     strcat(info[k].rawPotName, ".raw");
1454     }
1455     }
1456    
1457 mmeineke 670 #ifdef IS_MPI
1458 tim 722
1459 mmeineke 614 }
1460 mmeineke 670 #endif // is_mpi
1461 mmeineke 614 }
1462     }
1463    
1464    
1465 tim 722 void SimSetup::sysObjectsCreation(void){
1466     int i, k;
1467    
1468 mmeineke 614 // create the forceField
1469 tim 689
1470 mmeineke 614 createFF();
1471    
1472     // extract componentList
1473    
1474     compList();
1475    
1476     // calc the number of atoms, bond, bends, and torsions
1477    
1478     calcSysValues();
1479    
1480     #ifdef IS_MPI
1481     // divide the molecules among the processors
1482 tim 722
1483 mmeineke 614 mpiMolDivide();
1484     #endif //is_mpi
1485 tim 722
1486 mmeineke 614 // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1487 tim 722
1488 mmeineke 614 makeSysArrays();
1489    
1490 mmeineke 616 // make and initialize the molecules (all but atomic coordinates)
1491 tim 722
1492 mmeineke 616 makeMolecules();
1493 tim 722
1494     for (k = 0; k < nInfo; k++){
1495 mmeineke 670 info[k].identArray = new int[info[k].n_atoms];
1496 tim 722 for (i = 0; i < info[k].n_atoms; i++){
1497 mmeineke 670 info[k].identArray[i] = info[k].atoms[i]->getIdent();
1498     }
1499 mmeineke 616 }
1500 mmeineke 614 }
1501    
1502    
1503 tim 722 void SimSetup::createFF(void){
1504     switch (ffCase){
1505     case FF_DUFF:
1506     the_ff = new DUFF();
1507     break;
1508 mmeineke 614
1509 tim 722 case FF_LJ:
1510     the_ff = new LJFF();
1511     break;
1512 mmeineke 614
1513 tim 722 case FF_EAM:
1514     the_ff = new EAM_FF();
1515     break;
1516 mmeineke 614
1517 chrisfen 999 case FF_H2O:
1518     the_ff = new WATER();
1519     break;
1520    
1521 tim 722 default:
1522     sprintf(painCave.errMsg,
1523     "SimSetup Error. Unrecognized force field in case statement.\n");
1524     painCave.isFatal = 1;
1525     simError();
1526 mmeineke 614 }
1527    
1528     #ifdef IS_MPI
1529 tim 722 strcpy(checkPointMsg, "ForceField creation successful");
1530 mmeineke 614 MPIcheckPoint();
1531     #endif // is_mpi
1532     }
1533    
1534    
1535 tim 722 void SimSetup::compList(void){
1536 mmeineke 616 int i;
1537 mmeineke 670 char* id;
1538     LinkedMolStamp* headStamp = new LinkedMolStamp();
1539     LinkedMolStamp* currentStamp = NULL;
1540 tim 722 comp_stamps = new MoleculeStamp * [n_components];
1541 tim 1157 bool haveCutoffGroups;
1542 tim 722
1543 tim 1157 haveCutoffGroups = false;
1544    
1545 mmeineke 614 // make an array of molecule stamps that match the components used.
1546     // also extract the used stamps out into a separate linked list
1547 tim 722
1548     for (i = 0; i < nInfo; i++){
1549 mmeineke 670 info[i].nComponents = n_components;
1550     info[i].componentsNmol = components_nmol;
1551     info[i].compStamps = comp_stamps;
1552     info[i].headStamp = headStamp;
1553     }
1554 mmeineke 614
1555    
1556 tim 722 for (i = 0; i < n_components; i++){
1557 mmeineke 614 id = the_components[i]->getType();
1558     comp_stamps[i] = NULL;
1559 tim 722
1560 mmeineke 614 // check to make sure the component isn't already in the list
1561    
1562 tim 722 comp_stamps[i] = headStamp->match(id);
1563     if (comp_stamps[i] == NULL){
1564 mmeineke 614 // extract the component from the list;
1565 tim 722
1566     currentStamp = stamps->extractMolStamp(id);
1567     if (currentStamp == NULL){
1568     sprintf(painCave.errMsg,
1569     "SimSetup error: Component \"%s\" was not found in the "
1570     "list of declared molecules\n",
1571     id);
1572     painCave.isFatal = 1;
1573     simError();
1574 mmeineke 614 }
1575 tim 722
1576     headStamp->add(currentStamp);
1577     comp_stamps[i] = headStamp->match(id);
1578 mmeineke 614 }
1579 tim 1157
1580     if(comp_stamps[i]->getNCutoffGroups() > 0)
1581     haveCutoffGroups = true;
1582 mmeineke 614 }
1583 tim 1157
1584     for (i = 0; i < nInfo; i++)
1585     info[i].haveCutoffGroups = haveCutoffGroups;
1586 mmeineke 614
1587     #ifdef IS_MPI
1588 tim 722 strcpy(checkPointMsg, "Component stamps successfully extracted\n");
1589 mmeineke 614 MPIcheckPoint();
1590     #endif // is_mpi
1591 tim 722 }
1592 mmeineke 614
1593 tim 722 void SimSetup::calcSysValues(void){
1594 gezelter 1203 int i, j;
1595     int ncutgroups, atomsingroups, ngroupsinstamp;
1596 mmeineke 614
1597 tim 722 int* molMembershipArray;
1598 gezelter 1203 CutoffGroupStamp* cg;
1599 mmeineke 614
1600     tot_atoms = 0;
1601     tot_bonds = 0;
1602     tot_bends = 0;
1603     tot_torsions = 0;
1604 gezelter 1097 tot_rigid = 0;
1605 gezelter 1203 tot_groups = 0;
1606 tim 722 for (i = 0; i < n_components; i++){
1607     tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms();
1608     tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds();
1609     tot_bends += components_nmol[i] * comp_stamps[i]->getNBends();
1610 mmeineke 614 tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
1611 gezelter 1097 tot_rigid += components_nmol[i] * comp_stamps[i]->getNRigidBodies();
1612 gezelter 1203
1613     ncutgroups = comp_stamps[i]->getNCutoffGroups();
1614     atomsingroups = 0;
1615     for (j=0; j < ncutgroups; j++) {
1616     cg = comp_stamps[i]->getCutoffGroup(j);
1617     atomsingroups += cg->getNMembers();
1618     }
1619     ngroupsinstamp = comp_stamps[i]->getNAtoms() - atomsingroups + ncutgroups;
1620     tot_groups += components_nmol[i] * ngroupsinstamp;
1621 mmeineke 614 }
1622 gezelter 1097
1623 mmeineke 614 tot_SRI = tot_bonds + tot_bends + tot_torsions;
1624 mmeineke 670 molMembershipArray = new int[tot_atoms];
1625 tim 722
1626     for (i = 0; i < nInfo; i++){
1627 mmeineke 670 info[i].n_atoms = tot_atoms;
1628     info[i].n_bonds = tot_bonds;
1629     info[i].n_bends = tot_bends;
1630     info[i].n_torsions = tot_torsions;
1631     info[i].n_SRI = tot_SRI;
1632     info[i].n_mol = tot_nmol;
1633 gezelter 1203 info[i].ngroup = tot_groups;
1634 mmeineke 670 info[i].molMembershipArray = molMembershipArray;
1635 tim 722 }
1636 mmeineke 614 }
1637    
1638     #ifdef IS_MPI
1639    
1640 tim 722 void SimSetup::mpiMolDivide(void){
1641 mmeineke 616 int i, j, k;
1642 mmeineke 614 int localMol, allMol;
1643     int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
1644 gezelter 1204 int local_rigid, local_groups;
1645 tim 1108 vector<int> globalMolIndex;
1646 gezelter 1204 int ncutgroups, atomsingroups, ngroupsinstamp;
1647     CutoffGroupStamp* cg;
1648 mmeineke 614
1649 tim 722 mpiSim = new mpiSimulation(info);
1650    
1651 tim 1108 mpiSim->divideLabor();
1652     globalAtomIndex = mpiSim->getGlobalAtomIndex();
1653 gezelter 1214 globalGroupIndex = mpiSim->getGlobalGroupIndex();
1654 tim 1129 //globalMolIndex = mpiSim->getGlobalMolIndex();
1655 mmeineke 614
1656     // set up the local variables
1657 tim 722
1658 mmeineke 614 mol2proc = mpiSim->getMolToProcMap();
1659     molCompType = mpiSim->getMolComponentType();
1660 tim 722
1661 mmeineke 614 allMol = 0;
1662     localMol = 0;
1663     local_atoms = 0;
1664     local_bonds = 0;
1665     local_bends = 0;
1666     local_torsions = 0;
1667 gezelter 1097 local_rigid = 0;
1668 gezelter 1204 local_groups = 0;
1669 tim 1108 globalAtomCounter = 0;
1670 mmeineke 614
1671 tim 722 for (i = 0; i < n_components; i++){
1672     for (j = 0; j < components_nmol[i]; j++){
1673     if (mol2proc[allMol] == worldRank){
1674     local_atoms += comp_stamps[i]->getNAtoms();
1675     local_bonds += comp_stamps[i]->getNBonds();
1676     local_bends += comp_stamps[i]->getNBends();
1677     local_torsions += comp_stamps[i]->getNTorsions();
1678 gezelter 1097 local_rigid += comp_stamps[i]->getNRigidBodies();
1679 gezelter 1204
1680     ncutgroups = comp_stamps[i]->getNCutoffGroups();
1681     atomsingroups = 0;
1682     for (k=0; k < ncutgroups; k++) {
1683     cg = comp_stamps[i]->getCutoffGroup(k);
1684     atomsingroups += cg->getNMembers();
1685     }
1686     ngroupsinstamp = comp_stamps[i]->getNAtoms() - atomsingroups +
1687     ncutgroups;
1688     local_groups += ngroupsinstamp;
1689    
1690 tim 722 localMol++;
1691 mmeineke 614 }
1692 tim 722 for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){
1693 tim 1108 info[0].molMembershipArray[globalAtomCounter] = allMol;
1694     globalAtomCounter++;
1695 mmeineke 614 }
1696    
1697 tim 722 allMol++;
1698 mmeineke 614 }
1699     }
1700     local_SRI = local_bonds + local_bends + local_torsions;
1701 tim 722
1702 gezelter 1203 info[0].n_atoms = mpiSim->getNAtomsLocal();
1703 gezelter 1097
1704 tim 722 if (local_atoms != info[0].n_atoms){
1705     sprintf(painCave.errMsg,
1706 gezelter 965 "SimSetup error: mpiSim's localAtom (%d) and SimSetup's\n"
1707     "\tlocalAtom (%d) are not equal.\n",
1708 tim 722 info[0].n_atoms, local_atoms);
1709 mmeineke 614 painCave.isFatal = 1;
1710     simError();
1711     }
1712    
1713 gezelter 1204 info[0].ngroup = mpiSim->getNGroupsLocal();
1714     if (local_groups != info[0].ngroup){
1715     sprintf(painCave.errMsg,
1716     "SimSetup error: mpiSim's localGroups (%d) and SimSetup's\n"
1717     "\tlocalGroups (%d) are not equal.\n",
1718     info[0].ngroup, local_groups);
1719     painCave.isFatal = 1;
1720     simError();
1721     }
1722    
1723 mmeineke 670 info[0].n_bonds = local_bonds;
1724     info[0].n_bends = local_bends;
1725     info[0].n_torsions = local_torsions;
1726     info[0].n_SRI = local_SRI;
1727     info[0].n_mol = localMol;
1728 mmeineke 614
1729 tim 722 strcpy(checkPointMsg, "Passed nlocal consistency check.");
1730 mmeineke 614 MPIcheckPoint();
1731     }
1732 tim 722
1733 mmeineke 614 #endif // is_mpi
1734    
1735    
1736 tim 722 void SimSetup::makeSysArrays(void){
1737 mmeineke 787
1738     #ifndef IS_MPI
1739     int k, j;
1740     #endif // is_mpi
1741     int i, l;
1742 mmeineke 614
1743 mmeineke 670 Atom** the_atoms;
1744     Molecule* the_molecules;
1745 mmeineke 616
1746 tim 722 for (l = 0; l < nInfo; l++){
1747 mmeineke 670 // create the atom and short range interaction arrays
1748 tim 722
1749     the_atoms = new Atom * [info[l].n_atoms];
1750 mmeineke 670 the_molecules = new Molecule[info[l].n_mol];
1751     int molIndex;
1752 mmeineke 614
1753 mmeineke 670 // initialize the molecule's stampID's
1754 tim 722
1755 mmeineke 670 #ifdef IS_MPI
1756 tim 722
1757    
1758 mmeineke 670 molIndex = 0;
1759 gezelter 1203 for (i = 0; i < mpiSim->getNMolGlobal(); i++){
1760 tim 722 if (mol2proc[i] == worldRank){
1761     the_molecules[molIndex].setStampID(molCompType[i]);
1762     the_molecules[molIndex].setMyIndex(molIndex);
1763     the_molecules[molIndex].setGlobalIndex(i);
1764     molIndex++;
1765 mmeineke 670 }
1766 mmeineke 614 }
1767 tim 722
1768 mmeineke 614 #else // is_mpi
1769 tim 722
1770 mmeineke 670 molIndex = 0;
1771 tim 1108 globalAtomCounter = 0;
1772 tim 722 for (i = 0; i < n_components; i++){
1773     for (j = 0; j < components_nmol[i]; j++){
1774     the_molecules[molIndex].setStampID(i);
1775     the_molecules[molIndex].setMyIndex(molIndex);
1776     the_molecules[molIndex].setGlobalIndex(molIndex);
1777     for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){
1778 tim 1108 info[l].molMembershipArray[globalAtomCounter] = molIndex;
1779     globalAtomCounter++;
1780 tim 722 }
1781     molIndex++;
1782 mmeineke 614 }
1783     }
1784 tim 722
1785    
1786 mmeineke 614 #endif // is_mpi
1787    
1788 gezelter 1097 info[l].globalExcludes = new int;
1789     info[l].globalExcludes[0] = 0;
1790    
1791 mmeineke 670 // set the arrays into the SimInfo object
1792 mmeineke 614
1793 mmeineke 670 info[l].atoms = the_atoms;
1794     info[l].molecules = the_molecules;
1795     info[l].nGlobalExcludes = 0;
1796 tim 1157
1797 tim 722 the_ff->setSimInfo(info);
1798 mmeineke 670 }
1799 mmeineke 614 }
1800 mmeineke 616
1801 tim 722 void SimSetup::makeIntegrator(void){
1802 mmeineke 670 int k;
1803    
1804 mmeineke 782 NVE<RealIntegrator>* myNVE = NULL;
1805 tim 722 NVT<RealIntegrator>* myNVT = NULL;
1806 mmeineke 778 NPTi<NPT<RealIntegrator> >* myNPTi = NULL;
1807 mmeineke 780 NPTf<NPT<RealIntegrator> >* myNPTf = NULL;
1808 mmeineke 812 NPTxyz<NPT<RealIntegrator> >* myNPTxyz = NULL;
1809 tim 733
1810 tim 722 for (k = 0; k < nInfo; k++){
1811     switch (ensembleCase){
1812     case NVE_ENS:
1813     if (globals->haveZconstraints()){
1814     setupZConstraint(info[k]);
1815 mmeineke 782 myNVE = new ZConstraint<NVE<RealIntegrator> >(&(info[k]), the_ff);
1816 tim 722 }
1817 mmeineke 782 else{
1818     myNVE = new NVE<RealIntegrator>(&(info[k]), the_ff);
1819     }
1820    
1821     info->the_integrator = myNVE;
1822 tim 722 break;
1823 tim 676
1824 tim 722 case NVT_ENS:
1825     if (globals->haveZconstraints()){
1826     setupZConstraint(info[k]);
1827     myNVT = new ZConstraint<NVT<RealIntegrator> >(&(info[k]), the_ff);
1828     }
1829     else
1830     myNVT = new NVT<RealIntegrator>(&(info[k]), the_ff);
1831    
1832 tim 701 myNVT->setTargetTemp(globals->getTargetTemp());
1833 tim 722
1834     if (globals->haveTauThermostat())
1835 tim 701 myNVT->setTauThermostat(globals->getTauThermostat());
1836 tim 722 else{
1837     sprintf(painCave.errMsg,
1838     "SimSetup error: If you use the NVT\n"
1839 gezelter 965 "\tensemble, you must set tauThermostat.\n");
1840 tim 701 painCave.isFatal = 1;
1841     simError();
1842     }
1843 mmeineke 782
1844     info->the_integrator = myNVT;
1845 tim 701 break;
1846 tim 676
1847 tim 722 case NPTi_ENS:
1848     if (globals->haveZconstraints()){
1849     setupZConstraint(info[k]);
1850 mmeineke 778 myNPTi = new ZConstraint<NPTi<NPT <RealIntegrator> > >(&(info[k]), the_ff);
1851 tim 722 }
1852     else
1853 mmeineke 778 myNPTi = new NPTi<NPT<RealIntegrator> >(&(info[k]), the_ff);
1854 tim 722
1855     myNPTi->setTargetTemp(globals->getTargetTemp());
1856    
1857     if (globals->haveTargetPressure())
1858     myNPTi->setTargetPressure(globals->getTargetPressure());
1859     else{
1860     sprintf(painCave.errMsg,
1861     "SimSetup error: If you use a constant pressure\n"
1862 gezelter 965 "\tensemble, you must set targetPressure in the BASS file.\n");
1863 tim 722 painCave.isFatal = 1;
1864     simError();
1865     }
1866    
1867     if (globals->haveTauThermostat())
1868     myNPTi->setTauThermostat(globals->getTauThermostat());
1869     else{
1870     sprintf(painCave.errMsg,
1871     "SimSetup error: If you use an NPT\n"
1872 gezelter 965 "\tensemble, you must set tauThermostat.\n");
1873 tim 722 painCave.isFatal = 1;
1874     simError();
1875     }
1876    
1877     if (globals->haveTauBarostat())
1878     myNPTi->setTauBarostat(globals->getTauBarostat());
1879     else{
1880     sprintf(painCave.errMsg,
1881 tim 701 "SimSetup error: If you use an NPT\n"
1882 gezelter 965 "\tensemble, you must set tauBarostat.\n");
1883 tim 722 painCave.isFatal = 1;
1884     simError();
1885     }
1886 mmeineke 782
1887     info->the_integrator = myNPTi;
1888 tim 722 break;
1889 tim 676
1890 tim 722 case NPTf_ENS:
1891     if (globals->haveZconstraints()){
1892     setupZConstraint(info[k]);
1893 mmeineke 780 myNPTf = new ZConstraint<NPTf<NPT <RealIntegrator> > >(&(info[k]), the_ff);
1894 tim 722 }
1895     else
1896 mmeineke 780 myNPTf = new NPTf<NPT <RealIntegrator> >(&(info[k]), the_ff);
1897 tim 722
1898     myNPTf->setTargetTemp(globals->getTargetTemp());
1899    
1900     if (globals->haveTargetPressure())
1901     myNPTf->setTargetPressure(globals->getTargetPressure());
1902     else{
1903     sprintf(painCave.errMsg,
1904 tim 701 "SimSetup error: If you use a constant pressure\n"
1905 gezelter 965 "\tensemble, you must set targetPressure in the BASS file.\n");
1906 tim 722 painCave.isFatal = 1;
1907     simError();
1908     }
1909    
1910     if (globals->haveTauThermostat())
1911     myNPTf->setTauThermostat(globals->getTauThermostat());
1912 mmeineke 843
1913 tim 722 else{
1914     sprintf(painCave.errMsg,
1915 tim 701 "SimSetup error: If you use an NPT\n"
1916 gezelter 965 "\tensemble, you must set tauThermostat.\n");
1917 tim 722 painCave.isFatal = 1;
1918     simError();
1919     }
1920    
1921     if (globals->haveTauBarostat())
1922     myNPTf->setTauBarostat(globals->getTauBarostat());
1923 mmeineke 843
1924 tim 722 else{
1925     sprintf(painCave.errMsg,
1926     "SimSetup error: If you use an NPT\n"
1927 gezelter 965 "\tensemble, you must set tauBarostat.\n");
1928 tim 722 painCave.isFatal = 1;
1929     simError();
1930     }
1931 mmeineke 782
1932     info->the_integrator = myNPTf;
1933 tim 722 break;
1934 tim 676
1935 mmeineke 812 case NPTxyz_ENS:
1936     if (globals->haveZconstraints()){
1937     setupZConstraint(info[k]);
1938     myNPTxyz = new ZConstraint<NPTxyz<NPT <RealIntegrator> > >(&(info[k]), the_ff);
1939     }
1940     else
1941     myNPTxyz = new NPTxyz<NPT <RealIntegrator> >(&(info[k]), the_ff);
1942    
1943     myNPTxyz->setTargetTemp(globals->getTargetTemp());
1944    
1945     if (globals->haveTargetPressure())
1946     myNPTxyz->setTargetPressure(globals->getTargetPressure());
1947     else{
1948     sprintf(painCave.errMsg,
1949     "SimSetup error: If you use a constant pressure\n"
1950 gezelter 965 "\tensemble, you must set targetPressure in the BASS file.\n");
1951 mmeineke 812 painCave.isFatal = 1;
1952     simError();
1953     }
1954    
1955     if (globals->haveTauThermostat())
1956     myNPTxyz->setTauThermostat(globals->getTauThermostat());
1957     else{
1958     sprintf(painCave.errMsg,
1959     "SimSetup error: If you use an NPT\n"
1960 gezelter 965 "\tensemble, you must set tauThermostat.\n");
1961 mmeineke 812 painCave.isFatal = 1;
1962     simError();
1963     }
1964    
1965     if (globals->haveTauBarostat())
1966     myNPTxyz->setTauBarostat(globals->getTauBarostat());
1967     else{
1968     sprintf(painCave.errMsg,
1969     "SimSetup error: If you use an NPT\n"
1970 gezelter 965 "\tensemble, you must set tauBarostat.\n");
1971 mmeineke 812 painCave.isFatal = 1;
1972     simError();
1973     }
1974    
1975     info->the_integrator = myNPTxyz;
1976     break;
1977    
1978 tim 722 default:
1979     sprintf(painCave.errMsg,
1980     "SimSetup Error. Unrecognized ensemble in case statement.\n");
1981 tim 701 painCave.isFatal = 1;
1982     simError();
1983 tim 660 }
1984 mmeineke 616 }
1985     }
1986    
1987 tim 722 void SimSetup::initFortran(void){
1988     info[0].refreshSim();
1989 mmeineke 616
1990 tim 722 if (!strcmp(info[0].mixingRule, "standard")){
1991     the_ff->initForceField(LB_MIXING_RULE);
1992 mmeineke 616 }
1993 tim 722 else if (!strcmp(info[0].mixingRule, "explicit")){
1994     the_ff->initForceField(EXPLICIT_MIXING_RULE);
1995 mmeineke 616 }
1996     else{
1997 tim 722 sprintf(painCave.errMsg, "SimSetup Error: unknown mixing rule -> \"%s\"\n",
1998     info[0].mixingRule);
1999 mmeineke 616 painCave.isFatal = 1;
2000     simError();
2001     }
2002    
2003    
2004     #ifdef IS_MPI
2005 tim 722 strcpy(checkPointMsg, "Successfully intialized the mixingRule for Fortran.");
2006 mmeineke 616 MPIcheckPoint();
2007     #endif // is_mpi
2008     }
2009 tim 660
2010 tim 722 void SimSetup::setupZConstraint(SimInfo& theInfo){
2011 tim 701 int nZConstraints;
2012     ZconStamp** zconStamp;
2013 tim 682
2014 tim 722 if (globals->haveZconstraintTime()){
2015 tim 701 //add sample time of z-constraint into SimInfo's property list
2016     DoubleData* zconsTimeProp = new DoubleData();
2017     zconsTimeProp->setID(ZCONSTIME_ID);
2018     zconsTimeProp->setData(globals->getZconsTime());
2019     theInfo.addProperty(zconsTimeProp);
2020     }
2021     else{
2022 tim 722 sprintf(painCave.errMsg,
2023 gezelter 965 "ZConstraint error: If you use a ZConstraint,\n"
2024     "\tyou must set zconsTime.\n");
2025 tim 701 painCave.isFatal = 1;
2026 tim 722 simError();
2027 tim 701 }
2028 tim 682
2029 tim 701 //push zconsTol into siminfo, if user does not specify
2030     //value for zconsTol, a default value will be used
2031     DoubleData* zconsTol = new DoubleData();
2032     zconsTol->setID(ZCONSTOL_ID);
2033 tim 722 if (globals->haveZconsTol()){
2034 tim 701 zconsTol->setData(globals->getZconsTol());
2035     }
2036     else{
2037 tim 722 double defaultZConsTol = 0.01;
2038     sprintf(painCave.errMsg,
2039 gezelter 965 "ZConstraint Warning: Tolerance for z-constraint method is not specified.\n"
2040     "\tOOPSE will use a default value of %f.\n"
2041     "\tTo set the tolerance, use the zconsTol variable.\n",
2042 tim 722 defaultZConsTol);
2043 tim 701 painCave.isFatal = 0;
2044     simError();
2045 tim 699
2046 tim 701 zconsTol->setData(defaultZConsTol);
2047     }
2048     theInfo.addProperty(zconsTol);
2049 tim 699
2050 tim 738 //set Force Subtraction Policy
2051 tim 722 StringData* zconsForcePolicy = new StringData();
2052 tim 701 zconsForcePolicy->setID(ZCONSFORCEPOLICY_ID);
2053 tim 722
2054     if (globals->haveZconsForcePolicy()){
2055 tim 701 zconsForcePolicy->setData(globals->getZconsForcePolicy());
2056 tim 722 }
2057 tim 701 else{
2058 tim 722 sprintf(painCave.errMsg,
2059 gezelter 965 "ZConstraint Warning: No force subtraction policy was set.\n"
2060     "\tOOPSE will use PolicyByMass.\n"
2061     "\tTo set the policy, use the zconsForcePolicy variable.\n");
2062 tim 722 painCave.isFatal = 0;
2063     simError();
2064 tim 736 zconsForcePolicy->setData("BYMASS");
2065 tim 701 }
2066 tim 722
2067     theInfo.addProperty(zconsForcePolicy);
2068    
2069 tim 1091 //set zcons gap
2070     DoubleData* zconsGap = new DoubleData();
2071     zconsGap->setID(ZCONSGAP_ID);
2072    
2073     if (globals->haveZConsGap()){
2074     zconsGap->setData(globals->getZconsGap());
2075     theInfo.addProperty(zconsGap);
2076     }
2077    
2078     //set zcons fixtime
2079     DoubleData* zconsFixtime = new DoubleData();
2080     zconsFixtime->setID(ZCONSFIXTIME_ID);
2081    
2082     if (globals->haveZConsFixTime()){
2083     zconsFixtime->setData(globals->getZconsFixtime());
2084     theInfo.addProperty(zconsFixtime);
2085     }
2086    
2087 tim 1093 //set zconsUsingSMD
2088     IntData* zconsUsingSMD = new IntData();
2089     zconsUsingSMD->setID(ZCONSUSINGSMD_ID);
2090 tim 1091
2091 tim 1093 if (globals->haveZConsUsingSMD()){
2092     zconsUsingSMD->setData(globals->getZconsUsingSMD());
2093     theInfo.addProperty(zconsUsingSMD);
2094     }
2095    
2096 tim 701 //Determine the name of ouput file and add it into SimInfo's property list
2097     //Be careful, do not use inFileName, since it is a pointer which
2098     //point to a string at master node, and slave nodes do not contain that string
2099 tim 722
2100 tim 701 string zconsOutput(theInfo.finalName);
2101 tim 722
2102 tim 701 zconsOutput = zconsOutput.substr(0, zconsOutput.rfind(".")) + ".fz";
2103 tim 722
2104 tim 701 StringData* zconsFilename = new StringData();
2105     zconsFilename->setID(ZCONSFILENAME_ID);
2106     zconsFilename->setData(zconsOutput);
2107 tim 722
2108 tim 701 theInfo.addProperty(zconsFilename);
2109 tim 722
2110 tim 701 //setup index, pos and other parameters of z-constraint molecules
2111     nZConstraints = globals->getNzConstraints();
2112     theInfo.nZconstraints = nZConstraints;
2113    
2114     zconStamp = globals->getZconStamp();
2115     ZConsParaItem tempParaItem;
2116    
2117     ZConsParaData* zconsParaData = new ZConsParaData();
2118     zconsParaData->setID(ZCONSPARADATA_ID);
2119 tim 722
2120     for (int i = 0; i < nZConstraints; i++){
2121 tim 699 tempParaItem.havingZPos = zconStamp[i]->haveZpos();
2122     tempParaItem.zPos = zconStamp[i]->getZpos();
2123     tempParaItem.zconsIndex = zconStamp[i]->getMolIndex();
2124     tempParaItem.kRatio = zconStamp[i]->getKratio();
2125 tim 1093 tempParaItem.havingCantVel = zconStamp[i]->haveCantVel();
2126     tempParaItem.cantVel = zconStamp[i]->getCantVel();
2127 tim 699 zconsParaData->addItem(tempParaItem);
2128 tim 701 }
2129 tim 699
2130 tim 736 //check the uniqueness of index
2131     if(!zconsParaData->isIndexUnique()){
2132     sprintf(painCave.errMsg,
2133 gezelter 965 "ZConstraint Error: molIndex is not unique!\n");
2134 tim 736 painCave.isFatal = 1;
2135     simError();
2136     }
2137    
2138 tim 701 //sort the parameters by index of molecules
2139     zconsParaData->sortByIndex();
2140 tim 736
2141 tim 701 //push data into siminfo, therefore, we can retrieve later
2142     theInfo.addProperty(zconsParaData);
2143 tim 660 }
2144 tim 1031
2145     void SimSetup::makeMinimizer(){
2146 tim 1032
2147 tim 1064 OOPSEMinimizer* myOOPSEMinimizer;
2148 tim 1031 MinimizerParameterSet* param;
2149 tim 1064 char minimizerName[100];
2150 tim 1031
2151     for (int i = 0; i < nInfo; i++){
2152 tim 1064
2153 tim 1031 //prepare parameter set for minimizer
2154     param = new MinimizerParameterSet();
2155     param->setDefaultParameter();
2156    
2157     if (globals->haveMinimizer()){
2158     param->setFTol(globals->getMinFTol());
2159     }
2160    
2161     if (globals->haveMinGTol()){
2162     param->setGTol(globals->getMinGTol());
2163     }
2164    
2165     if (globals->haveMinMaxIter()){
2166     param->setMaxIteration(globals->getMinMaxIter());
2167     }
2168    
2169     if (globals->haveMinWriteFrq()){
2170     param->setMaxIteration(globals->getMinMaxIter());
2171     }
2172    
2173     if (globals->haveMinWriteFrq()){
2174     param->setWriteFrq(globals->getMinWriteFrq());
2175     }
2176    
2177 tim 1064 if (globals->haveMinStepSize()){
2178     param->setStepSize(globals->getMinStepSize());
2179 tim 1031 }
2180    
2181     if (globals->haveMinLSMaxIter()){
2182     param->setLineSearchMaxIteration(globals->getMinLSMaxIter());
2183     }
2184    
2185     if (globals->haveMinLSTol()){
2186     param->setLineSearchTol(globals->getMinLSTol());
2187     }
2188    
2189 tim 1066 strcpy(minimizerName, globals->getMinimizer());
2190 tim 1064
2191     if (!strcasecmp(minimizerName, "CG")){
2192     myOOPSEMinimizer = new PRCGMinimizer(&(info[i]), the_ff, param);
2193     }
2194     else if (!strcasecmp(minimizerName, "SD")){
2195     //myOOPSEMinimizer = MinimizerFactory.creatMinimizer("", &(info[i]), the_ff, param);
2196     myOOPSEMinimizer = new SDMinimizer(&(info[i]), the_ff, param);
2197     }
2198     else{
2199 tim 1066 sprintf(painCave.errMsg,
2200     "SimSetup error: Unrecognized Minimizer, use Conjugate Gradient \n");
2201     painCave.isFatal = 0;
2202     simError();
2203    
2204     myOOPSEMinimizer = new PRCGMinimizer(&(info[i]), the_ff, param);
2205     }
2206 tim 1064 info[i].the_integrator = myOOPSEMinimizer;
2207    
2208 tim 1031 //store the minimizer into simInfo
2209 tim 1064 info[i].the_minimizer = myOOPSEMinimizer;
2210 tim 1031 info[i].has_minimizer = true;
2211     }
2212 tim 1032
2213 tim 1031 }