ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1097
Committed: Mon Apr 12 20:32:20 2004 UTC (20 years, 3 months ago) by gezelter
File size: 50497 byte(s)
Log Message:
Changes for RigidBody dynamics (Somewhat extensive)

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