ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 701
Committed: Wed Aug 20 14:34:04 2003 UTC (20 years, 10 months ago) by tim
File size: 42241 byte(s)
Log Message:
reformmating ZConstraint and fixe bug of error msg printing

File Contents

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