ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 644
Committed: Tue Jul 22 16:41:08 2003 UTC (20 years, 11 months ago) by mmeineke
File size: 35462 byte(s)
Log Message:
Fixed a current time initialization bug in InitFromFile.

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 mmeineke 626 double theEcr, theEst;
766 mmeineke 614
767 mmeineke 616 if (globals->getUseRF() ) {
768 mmeineke 614 info->useReactionField = 1;
769    
770 mmeineke 616 if( !globals->haveECR() ){
771 mmeineke 614 sprintf( painCave.errMsg,
772     "SimSetup Warning: using default value of 1/2 the smallest "
773     "box length for the electrostaticCutoffRadius.\n"
774     "I hope you have a very fast processor!\n");
775     painCave.isFatal = 0;
776     simError();
777     double smallest;
778 gezelter 621 smallest = info->boxL[0];
779     if (info->boxL[1] <= smallest) smallest = info->boxL[1];
780     if (info->boxL[2] <= smallest) smallest = info->boxL[2];
781 mmeineke 626 theEcr = 0.5 * smallest;
782 mmeineke 614 } else {
783 mmeineke 626 theEcr = globals->getECR();
784 mmeineke 614 }
785    
786 mmeineke 616 if( !globals->haveEST() ){
787 mmeineke 614 sprintf( painCave.errMsg,
788     "SimSetup Warning: using default value of 0.05 * the "
789     "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
790     );
791     painCave.isFatal = 0;
792     simError();
793 mmeineke 626 theEst = 0.05 * theEcr;
794 mmeineke 614 } else {
795 mmeineke 626 theEst= globals->getEST();
796 mmeineke 614 }
797 mmeineke 626
798     info->setEcr( theEcr, theEst );
799 mmeineke 614
800 mmeineke 616 if(!globals->haveDielectric() ){
801 mmeineke 614 sprintf( painCave.errMsg,
802     "SimSetup Error: You are trying to use Reaction Field without"
803     "setting a dielectric constant!\n"
804     );
805     painCave.isFatal = 1;
806     simError();
807     }
808 mmeineke 616 info->dielectric = globals->getDielectric();
809 mmeineke 614 }
810     else {
811     if (usesDipoles) {
812    
813 mmeineke 616 if( !globals->haveECR() ){
814 mmeineke 626 sprintf( painCave.errMsg,
815     "SimSetup Warning: using default value of 1/2 the smallest "
816     "box length for the electrostaticCutoffRadius.\n"
817     "I hope you have a very fast processor!\n");
818     painCave.isFatal = 0;
819     simError();
820     double smallest;
821     smallest = info->boxL[0];
822     if (info->boxL[1] <= smallest) smallest = info->boxL[1];
823     if (info->boxL[2] <= smallest) smallest = info->boxL[2];
824     theEcr = 0.5 * smallest;
825 mmeineke 614 } else {
826 mmeineke 626 theEcr = globals->getECR();
827 mmeineke 614 }
828    
829 mmeineke 616 if( !globals->haveEST() ){
830 mmeineke 626 sprintf( painCave.errMsg,
831     "SimSetup Warning: using default value of 0.05 * the "
832     "electrostaticCutoffRadius for the "
833     "electrostaticSkinThickness\n"
834     );
835     painCave.isFatal = 0;
836     simError();
837     theEst = 0.05 * theEcr;
838 mmeineke 614 } else {
839 mmeineke 626 theEst= globals->getEST();
840 mmeineke 614 }
841 mmeineke 626
842     info->setEcr( theEcr, theEst );
843 mmeineke 614 }
844     }
845    
846     #ifdef IS_MPI
847     strcpy( checkPointMsg, "post processing checks out" );
848     MPIcheckPoint();
849     #endif // is_mpi
850    
851     }
852    
853     void SimSetup::initSystemCoords( void ){
854    
855 mmeineke 616 if( globals->haveInitialConfig() ){
856 mmeineke 614
857     InitializeFromFile* fileInit;
858     #ifdef IS_MPI // is_mpi
859     if( worldRank == 0 ){
860     #endif //is_mpi
861 mmeineke 616 fileInit = new InitializeFromFile( globals->getInitialConfig() );
862 mmeineke 614 #ifdef IS_MPI
863     }else fileInit = new InitializeFromFile( NULL );
864     #endif
865 mmeineke 644 fileInit->readInit( info ); // default velocities on
866 mmeineke 614
867     delete fileInit;
868     }
869     else{
870    
871     #ifdef IS_MPI
872    
873     // no init from bass
874    
875     sprintf( painCave.errMsg,
876     "Cannot intialize a parallel simulation without an initial configuration file.\n" );
877     painCave.isFatal;
878     simError();
879    
880     #else
881    
882     initFromBass();
883    
884    
885     #endif
886     }
887    
888     #ifdef IS_MPI
889     strcpy( checkPointMsg, "Successfully read in the initial configuration" );
890     MPIcheckPoint();
891     #endif // is_mpi
892    
893     }
894    
895    
896     void SimSetup::makeOutNames( void ){
897    
898     #ifdef IS_MPI
899     if( worldRank == 0 ){
900     #endif // is_mpi
901    
902 mmeineke 616 if( globals->haveFinalConfig() ){
903     strcpy( info->finalName, globals->getFinalConfig() );
904 mmeineke 614 }
905     else{
906     strcpy( info->finalName, inFileName );
907     char* endTest;
908     int nameLength = strlen( info->finalName );
909     endTest = &(info->finalName[nameLength - 5]);
910     if( !strcmp( endTest, ".bass" ) ){
911     strcpy( endTest, ".eor" );
912     }
913     else if( !strcmp( endTest, ".BASS" ) ){
914     strcpy( endTest, ".eor" );
915     }
916     else{
917     endTest = &(info->finalName[nameLength - 4]);
918     if( !strcmp( endTest, ".bss" ) ){
919     strcpy( endTest, ".eor" );
920     }
921     else if( !strcmp( endTest, ".mdl" ) ){
922     strcpy( endTest, ".eor" );
923     }
924     else{
925     strcat( info->finalName, ".eor" );
926     }
927     }
928     }
929    
930     // make the sample and status out names
931    
932     strcpy( info->sampleName, inFileName );
933     char* endTest;
934     int nameLength = strlen( info->sampleName );
935     endTest = &(info->sampleName[nameLength - 5]);
936     if( !strcmp( endTest, ".bass" ) ){
937     strcpy( endTest, ".dump" );
938     }
939     else if( !strcmp( endTest, ".BASS" ) ){
940     strcpy( endTest, ".dump" );
941     }
942     else{
943     endTest = &(info->sampleName[nameLength - 4]);
944     if( !strcmp( endTest, ".bss" ) ){
945     strcpy( endTest, ".dump" );
946     }
947     else if( !strcmp( endTest, ".mdl" ) ){
948     strcpy( endTest, ".dump" );
949     }
950     else{
951     strcat( info->sampleName, ".dump" );
952     }
953     }
954    
955     strcpy( info->statusName, inFileName );
956     nameLength = strlen( info->statusName );
957     endTest = &(info->statusName[nameLength - 5]);
958     if( !strcmp( endTest, ".bass" ) ){
959     strcpy( endTest, ".stat" );
960     }
961     else if( !strcmp( endTest, ".BASS" ) ){
962     strcpy( endTest, ".stat" );
963     }
964     else{
965     endTest = &(info->statusName[nameLength - 4]);
966     if( !strcmp( endTest, ".bss" ) ){
967     strcpy( endTest, ".stat" );
968     }
969     else if( !strcmp( endTest, ".mdl" ) ){
970     strcpy( endTest, ".stat" );
971     }
972     else{
973     strcat( info->statusName, ".stat" );
974     }
975     }
976    
977     #ifdef IS_MPI
978     }
979     #endif // is_mpi
980    
981     }
982    
983    
984     void SimSetup::sysObjectsCreation( void ){
985    
986 mmeineke 616 int i;
987    
988 mmeineke 614 // create the forceField
989    
990     createFF();
991    
992     // extract componentList
993    
994     compList();
995    
996     // calc the number of atoms, bond, bends, and torsions
997    
998     calcSysValues();
999    
1000     #ifdef IS_MPI
1001     // divide the molecules among the processors
1002    
1003     mpiMolDivide();
1004     #endif //is_mpi
1005    
1006     // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1007    
1008     makeSysArrays();
1009    
1010 mmeineke 616 // make and initialize the molecules (all but atomic coordinates)
1011 mmeineke 614
1012 mmeineke 616 makeMolecules();
1013     info->identArray = new int[info->n_atoms];
1014     for(i=0; i<info->n_atoms; i++){
1015     info->identArray[i] = the_atoms[i]->getIdent();
1016     }
1017    
1018 mmeineke 614
1019    
1020     }
1021    
1022    
1023     void SimSetup::createFF( void ){
1024    
1025     switch( ffCase ){
1026    
1027     case FF_DUFF:
1028     the_ff = new DUFF();
1029     break;
1030    
1031     case FF_LJ:
1032     the_ff = new LJFF();
1033     break;
1034    
1035     default:
1036     sprintf( painCave.errMsg,
1037     "SimSetup Error. Unrecognized force field in case statement.\n");
1038     painCave.isFatal = 1;
1039     simError();
1040     }
1041    
1042     #ifdef IS_MPI
1043     strcpy( checkPointMsg, "ForceField creation successful" );
1044     MPIcheckPoint();
1045     #endif // is_mpi
1046    
1047     }
1048    
1049    
1050     void SimSetup::compList( void ){
1051    
1052 mmeineke 616 int i;
1053    
1054 mmeineke 614 comp_stamps = new MoleculeStamp*[n_components];
1055    
1056     // make an array of molecule stamps that match the components used.
1057     // also extract the used stamps out into a separate linked list
1058    
1059     info->nComponents = n_components;
1060     info->componentsNmol = components_nmol;
1061     info->compStamps = comp_stamps;
1062     info->headStamp = new LinkedMolStamp();
1063    
1064     char* id;
1065     LinkedMolStamp* headStamp = info->headStamp;
1066     LinkedMolStamp* currentStamp = NULL;
1067     for( i=0; i<n_components; i++ ){
1068    
1069     id = the_components[i]->getType();
1070     comp_stamps[i] = NULL;
1071    
1072     // check to make sure the component isn't already in the list
1073    
1074     comp_stamps[i] = headStamp->match( id );
1075     if( comp_stamps[i] == NULL ){
1076    
1077     // extract the component from the list;
1078    
1079 mmeineke 616 currentStamp = stamps->extractMolStamp( id );
1080 mmeineke 614 if( currentStamp == NULL ){
1081     sprintf( painCave.errMsg,
1082     "SimSetup error: Component \"%s\" was not found in the "
1083     "list of declared molecules\n",
1084     id );
1085     painCave.isFatal = 1;
1086     simError();
1087     }
1088    
1089     headStamp->add( currentStamp );
1090     comp_stamps[i] = headStamp->match( id );
1091     }
1092     }
1093    
1094     #ifdef IS_MPI
1095     strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
1096     MPIcheckPoint();
1097     #endif // is_mpi
1098    
1099    
1100     }
1101    
1102     void SimSetup::calcSysValues( void ){
1103 mmeineke 616 int i, j, k;
1104 mmeineke 614
1105 mmeineke 616
1106 mmeineke 614 tot_atoms = 0;
1107     tot_bonds = 0;
1108     tot_bends = 0;
1109     tot_torsions = 0;
1110     for( i=0; i<n_components; i++ ){
1111    
1112     tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms();
1113     tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds();
1114     tot_bends += components_nmol[i] * comp_stamps[i]->getNBends();
1115     tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
1116     }
1117    
1118     tot_SRI = tot_bonds + tot_bends + tot_torsions;
1119    
1120     info->n_atoms = tot_atoms;
1121     info->n_bonds = tot_bonds;
1122     info->n_bends = tot_bends;
1123     info->n_torsions = tot_torsions;
1124     info->n_SRI = tot_SRI;
1125     info->n_mol = tot_nmol;
1126    
1127     info->molMembershipArray = new int[tot_atoms];
1128     }
1129    
1130    
1131     #ifdef IS_MPI
1132    
1133     void SimSetup::mpiMolDivide( void ){
1134    
1135 mmeineke 616 int i, j, k;
1136 mmeineke 614 int localMol, allMol;
1137     int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
1138    
1139     mpiSim = new mpiSimulation( info );
1140    
1141     globalIndex = mpiSim->divideLabor();
1142    
1143     // set up the local variables
1144    
1145     mol2proc = mpiSim->getMolToProcMap();
1146     molCompType = mpiSim->getMolComponentType();
1147    
1148     allMol = 0;
1149     localMol = 0;
1150     local_atoms = 0;
1151     local_bonds = 0;
1152     local_bends = 0;
1153     local_torsions = 0;
1154     globalAtomIndex = 0;
1155    
1156    
1157     for( i=0; i<n_components; i++ ){
1158    
1159     for( j=0; j<components_nmol[i]; j++ ){
1160    
1161     if( mol2proc[allMol] == worldRank ){
1162    
1163     local_atoms += comp_stamps[i]->getNAtoms();
1164     local_bonds += comp_stamps[i]->getNBonds();
1165     local_bends += comp_stamps[i]->getNBends();
1166     local_torsions += comp_stamps[i]->getNTorsions();
1167     localMol++;
1168     }
1169     for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1170     info->molMembershipArray[globalAtomIndex] = allMol;
1171     globalAtomIndex++;
1172     }
1173    
1174     allMol++;
1175     }
1176     }
1177     local_SRI = local_bonds + local_bends + local_torsions;
1178    
1179     info->n_atoms = mpiSim->getMyNlocal();
1180    
1181     if( local_atoms != info->n_atoms ){
1182     sprintf( painCave.errMsg,
1183     "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
1184     " localAtom (%d) are not equal.\n",
1185     info->n_atoms,
1186     local_atoms );
1187     painCave.isFatal = 1;
1188     simError();
1189     }
1190    
1191     info->n_bonds = local_bonds;
1192     info->n_bends = local_bends;
1193     info->n_torsions = local_torsions;
1194     info->n_SRI = local_SRI;
1195     info->n_mol = localMol;
1196    
1197     strcpy( checkPointMsg, "Passed nlocal consistency check." );
1198     MPIcheckPoint();
1199     }
1200    
1201     #endif // is_mpi
1202    
1203    
1204     void SimSetup::makeSysArrays( void ){
1205 mmeineke 616 int i, j, k;
1206 mmeineke 614
1207 mmeineke 616
1208 mmeineke 614 // create the atom and short range interaction arrays
1209    
1210     Atom::createArrays(info->n_atoms);
1211     the_atoms = new Atom*[info->n_atoms];
1212     the_molecules = new Molecule[info->n_mol];
1213     int molIndex;
1214    
1215     // initialize the molecule's stampID's
1216    
1217     #ifdef IS_MPI
1218    
1219    
1220     molIndex = 0;
1221     for(i=0; i<mpiSim->getTotNmol(); i++){
1222    
1223     if(mol2proc[i] == worldRank ){
1224     the_molecules[molIndex].setStampID( molCompType[i] );
1225     the_molecules[molIndex].setMyIndex( molIndex );
1226     the_molecules[molIndex].setGlobalIndex( i );
1227     molIndex++;
1228     }
1229     }
1230    
1231     #else // is_mpi
1232    
1233     molIndex = 0;
1234     globalAtomIndex = 0;
1235     for(i=0; i<n_components; i++){
1236     for(j=0; j<components_nmol[i]; j++ ){
1237     the_molecules[molIndex].setStampID( i );
1238     the_molecules[molIndex].setMyIndex( molIndex );
1239     the_molecules[molIndex].setGlobalIndex( molIndex );
1240     for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1241     info->molMembershipArray[globalAtomIndex] = molIndex;
1242     globalAtomIndex++;
1243     }
1244     molIndex++;
1245     }
1246     }
1247    
1248    
1249     #endif // is_mpi
1250    
1251    
1252     if( info->n_SRI ){
1253    
1254     Exclude::createArray(info->n_SRI);
1255     the_excludes = new Exclude*[info->n_SRI];
1256     for( int ex=0; ex<info->n_SRI; ex++) the_excludes[ex] = new Exclude(ex);
1257     info->globalExcludes = new int;
1258     info->n_exclude = info->n_SRI;
1259     }
1260     else{
1261    
1262     Exclude::createArray( 1 );
1263     the_excludes = new Exclude*;
1264     the_excludes[0] = new Exclude(0);
1265     the_excludes[0]->setPair( 0,0 );
1266     info->globalExcludes = new int;
1267     info->globalExcludes[0] = 0;
1268     info->n_exclude = 0;
1269     }
1270    
1271     // set the arrays into the SimInfo object
1272    
1273     info->atoms = the_atoms;
1274     info->molecules = the_molecules;
1275     info->nGlobalExcludes = 0;
1276     info->excludes = the_excludes;
1277    
1278     the_ff->setSimInfo( info );
1279    
1280     }
1281 mmeineke 616
1282     void SimSetup::makeIntegrator( void ){
1283    
1284     NVT* myNVT = NULL;
1285     NPTi* myNPTi = NULL;
1286     NPTf* myNPTf = NULL;
1287     NPTim* myNPTim = NULL;
1288     NPTfm* myNPTfm = NULL;
1289    
1290     switch( ensembleCase ){
1291    
1292     case NVE_ENS:
1293     new NVE( info, the_ff );
1294     break;
1295    
1296     case NVT_ENS:
1297     myNVT = new NVT( info, the_ff );
1298     myNVT->setTargetTemp(globals->getTargetTemp());
1299    
1300     if (globals->haveTauThermostat())
1301     myNVT->setTauThermostat(globals->getTauThermostat());
1302    
1303     else {
1304     sprintf( painCave.errMsg,
1305     "SimSetup error: If you use the NVT\n"
1306     " ensemble, you must set tauThermostat.\n");
1307     painCave.isFatal = 1;
1308     simError();
1309     }
1310     break;
1311    
1312     case NPTi_ENS:
1313     myNPTi = new NPTi( info, the_ff );
1314     myNPTi->setTargetTemp( globals->getTargetTemp() );
1315    
1316     if (globals->haveTargetPressure())
1317     myNPTi->setTargetPressure(globals->getTargetPressure());
1318     else {
1319     sprintf( painCave.errMsg,
1320     "SimSetup error: If you use a constant pressure\n"
1321     " ensemble, you must set targetPressure in the BASS file.\n");
1322     painCave.isFatal = 1;
1323     simError();
1324     }
1325    
1326     if( globals->haveTauThermostat() )
1327     myNPTi->setTauThermostat( globals->getTauThermostat() );
1328     else{
1329     sprintf( painCave.errMsg,
1330     "SimSetup error: If you use an NPT\n"
1331     " ensemble, you must set tauThermostat.\n");
1332     painCave.isFatal = 1;
1333     simError();
1334     }
1335    
1336     if( globals->haveTauBarostat() )
1337     myNPTi->setTauBarostat( globals->getTauBarostat() );
1338     else{
1339     sprintf( painCave.errMsg,
1340     "SimSetup error: If you use an NPT\n"
1341     " ensemble, you must set tauBarostat.\n");
1342     painCave.isFatal = 1;
1343     simError();
1344     }
1345     break;
1346    
1347     case NPTf_ENS:
1348     myNPTf = new NPTf( info, the_ff );
1349     myNPTf->setTargetTemp( globals->getTargetTemp());
1350    
1351     if (globals->haveTargetPressure())
1352     myNPTf->setTargetPressure(globals->getTargetPressure());
1353     else {
1354     sprintf( painCave.errMsg,
1355     "SimSetup error: If you use a constant pressure\n"
1356     " ensemble, you must set targetPressure in the BASS file.\n");
1357     painCave.isFatal = 1;
1358     simError();
1359     }
1360    
1361     if( globals->haveTauThermostat() )
1362     myNPTf->setTauThermostat( globals->getTauThermostat() );
1363     else{
1364     sprintf( painCave.errMsg,
1365     "SimSetup error: If you use an NPT\n"
1366     " ensemble, you must set tauThermostat.\n");
1367     painCave.isFatal = 1;
1368     simError();
1369     }
1370    
1371     if( globals->haveTauBarostat() )
1372     myNPTf->setTauBarostat( globals->getTauBarostat() );
1373     else{
1374     sprintf( painCave.errMsg,
1375     "SimSetup error: If you use an NPT\n"
1376     " ensemble, you must set tauBarostat.\n");
1377     painCave.isFatal = 1;
1378     simError();
1379     }
1380     break;
1381    
1382     case NPTim_ENS:
1383     myNPTim = new NPTim( info, the_ff );
1384     myNPTim->setTargetTemp( globals->getTargetTemp());
1385    
1386     if (globals->haveTargetPressure())
1387     myNPTim->setTargetPressure(globals->getTargetPressure());
1388     else {
1389     sprintf( painCave.errMsg,
1390     "SimSetup error: If you use a constant pressure\n"
1391     " ensemble, you must set targetPressure in the BASS file.\n");
1392     painCave.isFatal = 1;
1393     simError();
1394     }
1395    
1396     if( globals->haveTauThermostat() )
1397     myNPTim->setTauThermostat( globals->getTauThermostat() );
1398     else{
1399     sprintf( painCave.errMsg,
1400     "SimSetup error: If you use an NPT\n"
1401     " ensemble, you must set tauThermostat.\n");
1402     painCave.isFatal = 1;
1403     simError();
1404     }
1405    
1406     if( globals->haveTauBarostat() )
1407     myNPTim->setTauBarostat( globals->getTauBarostat() );
1408     else{
1409     sprintf( painCave.errMsg,
1410     "SimSetup error: If you use an NPT\n"
1411     " ensemble, you must set tauBarostat.\n");
1412     painCave.isFatal = 1;
1413     simError();
1414     }
1415     break;
1416    
1417     case NPTfm_ENS:
1418     myNPTfm = new NPTfm( info, the_ff );
1419     myNPTfm->setTargetTemp( globals->getTargetTemp());
1420    
1421     if (globals->haveTargetPressure())
1422     myNPTfm->setTargetPressure(globals->getTargetPressure());
1423     else {
1424     sprintf( painCave.errMsg,
1425     "SimSetup error: If you use a constant pressure\n"
1426     " ensemble, you must set targetPressure in the BASS file.\n");
1427     painCave.isFatal = 1;
1428     simError();
1429     }
1430    
1431     if( globals->haveTauThermostat() )
1432     myNPTfm->setTauThermostat( globals->getTauThermostat() );
1433     else{
1434     sprintf( painCave.errMsg,
1435     "SimSetup error: If you use an NPT\n"
1436     " ensemble, you must set tauThermostat.\n");
1437     painCave.isFatal = 1;
1438     simError();
1439     }
1440    
1441     if( globals->haveTauBarostat() )
1442     myNPTfm->setTauBarostat( globals->getTauBarostat() );
1443     else{
1444     sprintf( painCave.errMsg,
1445     "SimSetup error: If you use an NPT\n"
1446     " ensemble, you must set tauBarostat.\n");
1447     painCave.isFatal = 1;
1448     simError();
1449     }
1450     break;
1451    
1452     default:
1453     sprintf( painCave.errMsg,
1454     "SimSetup Error. Unrecognized ensemble in case statement.\n");
1455     painCave.isFatal = 1;
1456     simError();
1457     }
1458    
1459     }
1460    
1461     void SimSetup::initFortran( void ){
1462    
1463     info->refreshSim();
1464    
1465     if( !strcmp( info->mixingRule, "standard") ){
1466     the_ff->initForceField( LB_MIXING_RULE );
1467     }
1468     else if( !strcmp( info->mixingRule, "explicit") ){
1469     the_ff->initForceField( EXPLICIT_MIXING_RULE );
1470     }
1471     else{
1472     sprintf( painCave.errMsg,
1473     "SimSetup Error: unknown mixing rule -> \"%s\"\n",
1474     info->mixingRule );
1475     painCave.isFatal = 1;
1476     simError();
1477     }
1478    
1479    
1480     #ifdef IS_MPI
1481     strcpy( checkPointMsg,
1482     "Successfully intialized the mixingRule for Fortran." );
1483     MPIcheckPoint();
1484     #endif // is_mpi
1485    
1486     }