ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1187
Committed: Sat May 22 18:16:18 2004 UTC (20 years, 3 months ago) by chrisfen
File size: 55439 byte(s)
Log Message:
Fixed Thermodynamic integration code.

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