ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1108
Committed: Wed Apr 14 15:37:41 2004 UTC (20 years, 5 months ago) by tim
File size: 51259 byte(s)
Log Message:
Change DumpWriter and InitFromFile

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