ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1157
Committed: Tue May 11 20:33:41 2004 UTC (20 years, 4 months ago) by tim
File size: 52617 byte(s)
Log Message:
adding cutoffGroup into OOPSE

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