ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 1116
Committed: Thu Apr 15 22:15:21 2004 UTC (20 years, 5 months ago) by tim
File size: 51625 byte(s)
Log Message:
fix a bug in setting exclude list

File Contents

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