ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 621
Committed: Wed Jul 16 02:11:02 2003 UTC (20 years, 11 months ago) by gezelter
File size: 35617 byte(s)
Log Message:
more fixes for box changes

File Contents

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