ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 653
Committed: Fri Jul 25 20:00:17 2003 UTC (20 years, 11 months ago) by chuckv
File size: 35772 byte(s)
Log Message:
Added eam to simSetup and added changecutoffeam.

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 chuckv 653 #define FF_EAM 2
28 mmeineke 557
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 chuckv 653 else if( !strcasecmp( force_field, "EAM" )) ffCase = FF_EAM;
590 mmeineke 614 else{
591     sprintf( painCave.errMsg,
592     "SimSetup Error. Unrecognized force field -> %s\n",
593     force_field );
594     painCave.isFatal = 1;
595     simError();
596     }
597    
598     // get the ensemble
599    
600 mmeineke 616 strcpy( ensemble, globals->getEnsemble() );
601 mmeineke 614
602     if( !strcasecmp( ensemble, "NVE" )) ensembleCase = NVE_ENS;
603     else if( !strcasecmp( ensemble, "NVT" )) ensembleCase = NVT_ENS;
604     else if( !strcasecmp( ensemble, "NPTi" ) || !strcasecmp( ensemble, "NPT") )
605     ensembleCase = NPTi_ENS;
606     else if( !strcasecmp( ensemble, "NPTf" )) ensembleCase = NPTf_ENS;
607     else if( !strcasecmp( ensemble, "NPTim" )) ensembleCase = NPTim_ENS;
608     else if( !strcasecmp( ensemble, "NPTfm" )) ensembleCase = NPTfm_ENS;
609     else{
610     sprintf( painCave.errMsg,
611     "SimSetup Warning. Unrecognized Ensemble -> %s, "
612     "reverting to NVE for this simulation.\n",
613     ensemble );
614     painCave.isFatal = 0;
615     simError();
616     strcpy( ensemble, "NVE" );
617     ensembleCase = NVE_ENS;
618     }
619     strcpy( info->ensemble, ensemble );
620    
621     // get the mixing rule
622    
623 mmeineke 616 strcpy( info->mixingRule, globals->getMixingRule() );
624     info->usePBC = globals->getPBC();
625 mmeineke 614
626    
627     // get the components and calculate the tot_nMol and indvidual n_mol
628    
629 mmeineke 616 the_components = globals->getComponents();
630 mmeineke 614 components_nmol = new int[n_components];
631    
632    
633 mmeineke 616 if( !globals->haveNMol() ){
634 mmeineke 614 // we don't have the total number of molecules, so we assume it is
635     // given in each component
636    
637     tot_nmol = 0;
638     for( i=0; i<n_components; i++ ){
639    
640     if( !the_components[i]->haveNMol() ){
641     // we have a problem
642     sprintf( painCave.errMsg,
643     "SimSetup Error. No global NMol or component NMol"
644     " given. Cannot calculate the number of atoms.\n" );
645     painCave.isFatal = 1;
646     simError();
647     }
648    
649     tot_nmol += the_components[i]->getNMol();
650     components_nmol[i] = the_components[i]->getNMol();
651     }
652     }
653     else{
654     sprintf( painCave.errMsg,
655     "SimSetup error.\n"
656     "\tSorry, the ability to specify total"
657     " nMols and then give molfractions in the components\n"
658     "\tis not currently supported."
659     " Please give nMol in the components.\n" );
660     painCave.isFatal = 1;
661     simError();
662     }
663    
664     // set the status, sample, and thermal kick times
665    
666 mmeineke 616 if( globals->haveSampleTime() ){
667     info->sampleTime = globals->getSampleTime();
668 mmeineke 614 info->statusTime = info->sampleTime;
669     info->thermalTime = info->sampleTime;
670     }
671     else{
672 mmeineke 616 info->sampleTime = globals->getRunTime();
673 mmeineke 614 info->statusTime = info->sampleTime;
674     info->thermalTime = info->sampleTime;
675     }
676    
677 mmeineke 616 if( globals->haveStatusTime() ){
678     info->statusTime = globals->getStatusTime();
679 mmeineke 614 }
680    
681 mmeineke 616 if( globals->haveThermalTime() ){
682     info->thermalTime = globals->getThermalTime();
683 mmeineke 614 }
684    
685     // check for the temperature set flag
686    
687 mmeineke 616 if( globals->haveTempSet() ) info->setTemp = globals->getTempSet();
688 mmeineke 614
689     // get some of the tricky things that may still be in the globals
690    
691     double boxVector[3];
692 mmeineke 616 if( globals->haveBox() ){
693     boxVector[0] = globals->getBox();
694     boxVector[1] = globals->getBox();
695     boxVector[2] = globals->getBox();
696 mmeineke 614
697     info->setBox( boxVector );
698     }
699 mmeineke 616 else if( globals->haveDensity() ){
700 mmeineke 614
701     double vol;
702 mmeineke 616 vol = (double)tot_nmol / globals->getDensity();
703 mmeineke 614 boxVector[0] = pow( vol, ( 1.0 / 3.0 ) );
704     boxVector[1] = boxVector[0];
705     boxVector[2] = boxVector[0];
706    
707     info->setBox( boxVector );
708     }
709     else{
710 mmeineke 616 if( !globals->haveBoxX() ){
711 mmeineke 614 sprintf( painCave.errMsg,
712     "SimSetup error, no periodic BoxX size given.\n" );
713     painCave.isFatal = 1;
714     simError();
715     }
716 mmeineke 616 boxVector[0] = globals->getBoxX();
717 mmeineke 614
718 mmeineke 616 if( !globals->haveBoxY() ){
719 mmeineke 614 sprintf( painCave.errMsg,
720     "SimSetup error, no periodic BoxY size given.\n" );
721     painCave.isFatal = 1;
722     simError();
723     }
724 mmeineke 616 boxVector[1] = globals->getBoxY();
725 mmeineke 614
726 mmeineke 616 if( !globals->haveBoxZ() ){
727 mmeineke 614 sprintf( painCave.errMsg,
728     "SimSetup error, no periodic BoxZ size given.\n" );
729     painCave.isFatal = 1;
730     simError();
731     }
732 mmeineke 616 boxVector[2] = globals->getBoxZ();
733 mmeineke 614
734     info->setBox( boxVector );
735     }
736    
737    
738    
739     #ifdef IS_MPI
740     strcpy( checkPointMsg, "Succesfully gathered all information from Bass\n" );
741     MPIcheckPoint();
742     #endif // is_mpi
743    
744     }
745    
746    
747     void SimSetup::finalInfoCheck( void ){
748     int index;
749     int usesDipoles;
750    
751    
752     // check electrostatic parameters
753    
754     index = 0;
755     usesDipoles = 0;
756     while( (index < info->n_atoms) && !usesDipoles ){
757     usesDipoles = ((info->atoms)[index])->hasDipole();
758     index++;
759     }
760    
761     #ifdef IS_MPI
762 mmeineke 616 int myUse = usesDipoles;
763     MPI_Allreduce( &myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
764 mmeineke 614 #endif //is_mpi
765    
766 mmeineke 626 double theEcr, theEst;
767 mmeineke 614
768 mmeineke 616 if (globals->getUseRF() ) {
769 mmeineke 614 info->useReactionField = 1;
770    
771 mmeineke 616 if( !globals->haveECR() ){
772 mmeineke 614 sprintf( painCave.errMsg,
773     "SimSetup Warning: using default value of 1/2 the smallest "
774     "box length for the electrostaticCutoffRadius.\n"
775     "I hope you have a very fast processor!\n");
776     painCave.isFatal = 0;
777     simError();
778     double smallest;
779 gezelter 621 smallest = info->boxL[0];
780     if (info->boxL[1] <= smallest) smallest = info->boxL[1];
781     if (info->boxL[2] <= smallest) smallest = info->boxL[2];
782 mmeineke 626 theEcr = 0.5 * smallest;
783 mmeineke 614 } else {
784 mmeineke 626 theEcr = globals->getECR();
785 mmeineke 614 }
786    
787 mmeineke 616 if( !globals->haveEST() ){
788 mmeineke 614 sprintf( painCave.errMsg,
789     "SimSetup Warning: using default value of 0.05 * the "
790     "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
791     );
792     painCave.isFatal = 0;
793     simError();
794 mmeineke 626 theEst = 0.05 * theEcr;
795 mmeineke 614 } else {
796 mmeineke 626 theEst= globals->getEST();
797 mmeineke 614 }
798 mmeineke 626
799     info->setEcr( theEcr, theEst );
800 mmeineke 614
801 mmeineke 616 if(!globals->haveDielectric() ){
802 mmeineke 614 sprintf( painCave.errMsg,
803     "SimSetup Error: You are trying to use Reaction Field without"
804     "setting a dielectric constant!\n"
805     );
806     painCave.isFatal = 1;
807     simError();
808     }
809 mmeineke 616 info->dielectric = globals->getDielectric();
810 mmeineke 614 }
811     else {
812     if (usesDipoles) {
813    
814 mmeineke 616 if( !globals->haveECR() ){
815 mmeineke 626 sprintf( painCave.errMsg,
816     "SimSetup Warning: using default value of 1/2 the smallest "
817     "box length for the electrostaticCutoffRadius.\n"
818     "I hope you have a very fast processor!\n");
819     painCave.isFatal = 0;
820     simError();
821     double smallest;
822     smallest = info->boxL[0];
823     if (info->boxL[1] <= smallest) smallest = info->boxL[1];
824     if (info->boxL[2] <= smallest) smallest = info->boxL[2];
825     theEcr = 0.5 * smallest;
826 mmeineke 614 } else {
827 mmeineke 626 theEcr = globals->getECR();
828 mmeineke 614 }
829    
830 mmeineke 616 if( !globals->haveEST() ){
831 mmeineke 626 sprintf( painCave.errMsg,
832     "SimSetup Warning: using default value of 0.05 * the "
833     "electrostaticCutoffRadius for the "
834     "electrostaticSkinThickness\n"
835     );
836     painCave.isFatal = 0;
837     simError();
838     theEst = 0.05 * theEcr;
839 mmeineke 614 } else {
840 mmeineke 626 theEst= globals->getEST();
841 mmeineke 614 }
842 mmeineke 626
843     info->setEcr( theEcr, theEst );
844 mmeineke 614 }
845     }
846    
847     #ifdef IS_MPI
848     strcpy( checkPointMsg, "post processing checks out" );
849     MPIcheckPoint();
850     #endif // is_mpi
851    
852     }
853    
854     void SimSetup::initSystemCoords( void ){
855    
856 mmeineke 616 if( globals->haveInitialConfig() ){
857 mmeineke 614
858     InitializeFromFile* fileInit;
859     #ifdef IS_MPI // is_mpi
860     if( worldRank == 0 ){
861     #endif //is_mpi
862 mmeineke 616 fileInit = new InitializeFromFile( globals->getInitialConfig() );
863 mmeineke 614 #ifdef IS_MPI
864     }else fileInit = new InitializeFromFile( NULL );
865     #endif
866 mmeineke 644 fileInit->readInit( info ); // default velocities on
867 mmeineke 614
868     delete fileInit;
869     }
870     else{
871    
872     #ifdef IS_MPI
873    
874     // no init from bass
875    
876     sprintf( painCave.errMsg,
877     "Cannot intialize a parallel simulation without an initial configuration file.\n" );
878     painCave.isFatal;
879     simError();
880    
881     #else
882    
883     initFromBass();
884    
885    
886     #endif
887     }
888    
889     #ifdef IS_MPI
890     strcpy( checkPointMsg, "Successfully read in the initial configuration" );
891     MPIcheckPoint();
892     #endif // is_mpi
893    
894     }
895    
896    
897     void SimSetup::makeOutNames( void ){
898    
899     #ifdef IS_MPI
900     if( worldRank == 0 ){
901     #endif // is_mpi
902    
903 mmeineke 616 if( globals->haveFinalConfig() ){
904     strcpy( info->finalName, globals->getFinalConfig() );
905 mmeineke 614 }
906     else{
907     strcpy( info->finalName, inFileName );
908     char* endTest;
909     int nameLength = strlen( info->finalName );
910     endTest = &(info->finalName[nameLength - 5]);
911     if( !strcmp( endTest, ".bass" ) ){
912     strcpy( endTest, ".eor" );
913     }
914     else if( !strcmp( endTest, ".BASS" ) ){
915     strcpy( endTest, ".eor" );
916     }
917     else{
918     endTest = &(info->finalName[nameLength - 4]);
919     if( !strcmp( endTest, ".bss" ) ){
920     strcpy( endTest, ".eor" );
921     }
922     else if( !strcmp( endTest, ".mdl" ) ){
923     strcpy( endTest, ".eor" );
924     }
925     else{
926     strcat( info->finalName, ".eor" );
927     }
928     }
929     }
930    
931     // make the sample and status out names
932    
933     strcpy( info->sampleName, inFileName );
934     char* endTest;
935     int nameLength = strlen( info->sampleName );
936     endTest = &(info->sampleName[nameLength - 5]);
937     if( !strcmp( endTest, ".bass" ) ){
938     strcpy( endTest, ".dump" );
939     }
940     else if( !strcmp( endTest, ".BASS" ) ){
941     strcpy( endTest, ".dump" );
942     }
943     else{
944     endTest = &(info->sampleName[nameLength - 4]);
945     if( !strcmp( endTest, ".bss" ) ){
946     strcpy( endTest, ".dump" );
947     }
948     else if( !strcmp( endTest, ".mdl" ) ){
949     strcpy( endTest, ".dump" );
950     }
951     else{
952     strcat( info->sampleName, ".dump" );
953     }
954     }
955    
956     strcpy( info->statusName, inFileName );
957     nameLength = strlen( info->statusName );
958     endTest = &(info->statusName[nameLength - 5]);
959     if( !strcmp( endTest, ".bass" ) ){
960     strcpy( endTest, ".stat" );
961     }
962     else if( !strcmp( endTest, ".BASS" ) ){
963     strcpy( endTest, ".stat" );
964     }
965     else{
966     endTest = &(info->statusName[nameLength - 4]);
967     if( !strcmp( endTest, ".bss" ) ){
968     strcpy( endTest, ".stat" );
969     }
970     else if( !strcmp( endTest, ".mdl" ) ){
971     strcpy( endTest, ".stat" );
972     }
973     else{
974     strcat( info->statusName, ".stat" );
975     }
976     }
977    
978     #ifdef IS_MPI
979     }
980     #endif // is_mpi
981    
982     }
983    
984    
985     void SimSetup::sysObjectsCreation( void ){
986    
987 mmeineke 616 int i;
988    
989 mmeineke 614 // create the forceField
990    
991     createFF();
992    
993     // extract componentList
994    
995     compList();
996    
997     // calc the number of atoms, bond, bends, and torsions
998    
999     calcSysValues();
1000    
1001     #ifdef IS_MPI
1002     // divide the molecules among the processors
1003    
1004     mpiMolDivide();
1005     #endif //is_mpi
1006    
1007     // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1008    
1009     makeSysArrays();
1010    
1011 mmeineke 616 // make and initialize the molecules (all but atomic coordinates)
1012 mmeineke 614
1013 mmeineke 616 makeMolecules();
1014     info->identArray = new int[info->n_atoms];
1015     for(i=0; i<info->n_atoms; i++){
1016     info->identArray[i] = the_atoms[i]->getIdent();
1017     }
1018    
1019 mmeineke 614
1020    
1021     }
1022    
1023    
1024     void SimSetup::createFF( void ){
1025    
1026     switch( ffCase ){
1027    
1028     case FF_DUFF:
1029     the_ff = new DUFF();
1030     break;
1031    
1032     case FF_LJ:
1033     the_ff = new LJFF();
1034     break;
1035    
1036 chuckv 653 case FF_EAM:
1037     the_ff = new EAM_FF();
1038     break;
1039    
1040 mmeineke 614 default:
1041     sprintf( painCave.errMsg,
1042     "SimSetup Error. Unrecognized force field in case statement.\n");
1043     painCave.isFatal = 1;
1044     simError();
1045     }
1046    
1047     #ifdef IS_MPI
1048     strcpy( checkPointMsg, "ForceField creation successful" );
1049     MPIcheckPoint();
1050     #endif // is_mpi
1051    
1052     }
1053    
1054    
1055     void SimSetup::compList( void ){
1056    
1057 mmeineke 616 int i;
1058    
1059 mmeineke 614 comp_stamps = new MoleculeStamp*[n_components];
1060    
1061     // make an array of molecule stamps that match the components used.
1062     // also extract the used stamps out into a separate linked list
1063    
1064     info->nComponents = n_components;
1065     info->componentsNmol = components_nmol;
1066     info->compStamps = comp_stamps;
1067     info->headStamp = new LinkedMolStamp();
1068    
1069     char* id;
1070     LinkedMolStamp* headStamp = info->headStamp;
1071     LinkedMolStamp* currentStamp = NULL;
1072     for( i=0; i<n_components; i++ ){
1073    
1074     id = the_components[i]->getType();
1075     comp_stamps[i] = NULL;
1076    
1077     // check to make sure the component isn't already in the list
1078    
1079     comp_stamps[i] = headStamp->match( id );
1080     if( comp_stamps[i] == NULL ){
1081    
1082     // extract the component from the list;
1083    
1084 mmeineke 616 currentStamp = stamps->extractMolStamp( id );
1085 mmeineke 614 if( currentStamp == NULL ){
1086     sprintf( painCave.errMsg,
1087     "SimSetup error: Component \"%s\" was not found in the "
1088     "list of declared molecules\n",
1089     id );
1090     painCave.isFatal = 1;
1091     simError();
1092     }
1093    
1094     headStamp->add( currentStamp );
1095     comp_stamps[i] = headStamp->match( id );
1096     }
1097     }
1098    
1099     #ifdef IS_MPI
1100     strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
1101     MPIcheckPoint();
1102     #endif // is_mpi
1103    
1104    
1105     }
1106    
1107     void SimSetup::calcSysValues( void ){
1108 mmeineke 616 int i, j, k;
1109 mmeineke 614
1110 mmeineke 616
1111 mmeineke 614 tot_atoms = 0;
1112     tot_bonds = 0;
1113     tot_bends = 0;
1114     tot_torsions = 0;
1115     for( i=0; i<n_components; i++ ){
1116    
1117     tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms();
1118     tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds();
1119     tot_bends += components_nmol[i] * comp_stamps[i]->getNBends();
1120     tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
1121     }
1122    
1123     tot_SRI = tot_bonds + tot_bends + tot_torsions;
1124    
1125     info->n_atoms = tot_atoms;
1126     info->n_bonds = tot_bonds;
1127     info->n_bends = tot_bends;
1128     info->n_torsions = tot_torsions;
1129     info->n_SRI = tot_SRI;
1130     info->n_mol = tot_nmol;
1131    
1132     info->molMembershipArray = new int[tot_atoms];
1133     }
1134    
1135    
1136     #ifdef IS_MPI
1137    
1138     void SimSetup::mpiMolDivide( void ){
1139    
1140 mmeineke 616 int i, j, k;
1141 mmeineke 614 int localMol, allMol;
1142     int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
1143    
1144     mpiSim = new mpiSimulation( info );
1145    
1146     globalIndex = mpiSim->divideLabor();
1147    
1148     // set up the local variables
1149    
1150     mol2proc = mpiSim->getMolToProcMap();
1151     molCompType = mpiSim->getMolComponentType();
1152    
1153     allMol = 0;
1154     localMol = 0;
1155     local_atoms = 0;
1156     local_bonds = 0;
1157     local_bends = 0;
1158     local_torsions = 0;
1159     globalAtomIndex = 0;
1160    
1161    
1162     for( i=0; i<n_components; i++ ){
1163    
1164     for( j=0; j<components_nmol[i]; j++ ){
1165    
1166     if( mol2proc[allMol] == worldRank ){
1167    
1168     local_atoms += comp_stamps[i]->getNAtoms();
1169     local_bonds += comp_stamps[i]->getNBonds();
1170     local_bends += comp_stamps[i]->getNBends();
1171     local_torsions += comp_stamps[i]->getNTorsions();
1172     localMol++;
1173     }
1174     for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1175     info->molMembershipArray[globalAtomIndex] = allMol;
1176     globalAtomIndex++;
1177     }
1178    
1179     allMol++;
1180     }
1181     }
1182     local_SRI = local_bonds + local_bends + local_torsions;
1183    
1184     info->n_atoms = mpiSim->getMyNlocal();
1185    
1186     if( local_atoms != info->n_atoms ){
1187     sprintf( painCave.errMsg,
1188     "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
1189     " localAtom (%d) are not equal.\n",
1190     info->n_atoms,
1191     local_atoms );
1192     painCave.isFatal = 1;
1193     simError();
1194     }
1195    
1196     info->n_bonds = local_bonds;
1197     info->n_bends = local_bends;
1198     info->n_torsions = local_torsions;
1199     info->n_SRI = local_SRI;
1200     info->n_mol = localMol;
1201    
1202     strcpy( checkPointMsg, "Passed nlocal consistency check." );
1203     MPIcheckPoint();
1204     }
1205    
1206     #endif // is_mpi
1207    
1208    
1209     void SimSetup::makeSysArrays( void ){
1210 mmeineke 616 int i, j, k;
1211 mmeineke 614
1212 mmeineke 616
1213 mmeineke 614 // create the atom and short range interaction arrays
1214    
1215     Atom::createArrays(info->n_atoms);
1216     the_atoms = new Atom*[info->n_atoms];
1217     the_molecules = new Molecule[info->n_mol];
1218     int molIndex;
1219    
1220     // initialize the molecule's stampID's
1221    
1222     #ifdef IS_MPI
1223    
1224    
1225     molIndex = 0;
1226     for(i=0; i<mpiSim->getTotNmol(); i++){
1227    
1228     if(mol2proc[i] == worldRank ){
1229     the_molecules[molIndex].setStampID( molCompType[i] );
1230     the_molecules[molIndex].setMyIndex( molIndex );
1231     the_molecules[molIndex].setGlobalIndex( i );
1232     molIndex++;
1233     }
1234     }
1235    
1236     #else // is_mpi
1237    
1238     molIndex = 0;
1239     globalAtomIndex = 0;
1240     for(i=0; i<n_components; i++){
1241     for(j=0; j<components_nmol[i]; j++ ){
1242     the_molecules[molIndex].setStampID( i );
1243     the_molecules[molIndex].setMyIndex( molIndex );
1244     the_molecules[molIndex].setGlobalIndex( molIndex );
1245     for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1246     info->molMembershipArray[globalAtomIndex] = molIndex;
1247     globalAtomIndex++;
1248     }
1249     molIndex++;
1250     }
1251     }
1252    
1253    
1254     #endif // is_mpi
1255    
1256    
1257     if( info->n_SRI ){
1258    
1259     Exclude::createArray(info->n_SRI);
1260     the_excludes = new Exclude*[info->n_SRI];
1261     for( int ex=0; ex<info->n_SRI; ex++) the_excludes[ex] = new Exclude(ex);
1262     info->globalExcludes = new int;
1263     info->n_exclude = info->n_SRI;
1264     }
1265     else{
1266    
1267     Exclude::createArray( 1 );
1268     the_excludes = new Exclude*;
1269     the_excludes[0] = new Exclude(0);
1270     the_excludes[0]->setPair( 0,0 );
1271     info->globalExcludes = new int;
1272     info->globalExcludes[0] = 0;
1273     info->n_exclude = 0;
1274     }
1275    
1276     // set the arrays into the SimInfo object
1277    
1278     info->atoms = the_atoms;
1279     info->molecules = the_molecules;
1280     info->nGlobalExcludes = 0;
1281     info->excludes = the_excludes;
1282    
1283     the_ff->setSimInfo( info );
1284    
1285     }
1286 mmeineke 616
1287     void SimSetup::makeIntegrator( void ){
1288    
1289 tim 645 NVT<RealIntegrator>* myNVT = NULL;
1290     NPTi<RealIntegrator>* myNPTi = NULL;
1291     NPTf<RealIntegrator>* myNPTf = NULL;
1292     NPTim<RealIntegrator>* myNPTim = NULL;
1293     NPTfm<RealIntegrator>* myNPTfm = NULL;
1294 mmeineke 616
1295     switch( ensembleCase ){
1296    
1297     case NVE_ENS:
1298 tim 645 new NVE<RealIntegrator>( info, the_ff );
1299 mmeineke 616 break;
1300    
1301     case NVT_ENS:
1302 tim 645 myNVT = new NVT<RealIntegrator>( info, the_ff );
1303 mmeineke 616 myNVT->setTargetTemp(globals->getTargetTemp());
1304    
1305     if (globals->haveTauThermostat())
1306     myNVT->setTauThermostat(globals->getTauThermostat());
1307    
1308     else {
1309     sprintf( painCave.errMsg,
1310     "SimSetup error: If you use the NVT\n"
1311     " ensemble, you must set tauThermostat.\n");
1312     painCave.isFatal = 1;
1313     simError();
1314     }
1315     break;
1316    
1317     case NPTi_ENS:
1318 tim 645 myNPTi = new NPTi<RealIntegrator>( info, the_ff );
1319 mmeineke 616 myNPTi->setTargetTemp( globals->getTargetTemp() );
1320    
1321     if (globals->haveTargetPressure())
1322     myNPTi->setTargetPressure(globals->getTargetPressure());
1323     else {
1324     sprintf( painCave.errMsg,
1325     "SimSetup error: If you use a constant pressure\n"
1326     " ensemble, you must set targetPressure in the BASS file.\n");
1327     painCave.isFatal = 1;
1328     simError();
1329     }
1330    
1331     if( globals->haveTauThermostat() )
1332     myNPTi->setTauThermostat( globals->getTauThermostat() );
1333     else{
1334     sprintf( painCave.errMsg,
1335     "SimSetup error: If you use an NPT\n"
1336     " ensemble, you must set tauThermostat.\n");
1337     painCave.isFatal = 1;
1338     simError();
1339     }
1340    
1341     if( globals->haveTauBarostat() )
1342     myNPTi->setTauBarostat( globals->getTauBarostat() );
1343     else{
1344     sprintf( painCave.errMsg,
1345     "SimSetup error: If you use an NPT\n"
1346     " ensemble, you must set tauBarostat.\n");
1347     painCave.isFatal = 1;
1348     simError();
1349     }
1350     break;
1351    
1352     case NPTf_ENS:
1353 tim 645 myNPTf = new NPTf<RealIntegrator>( info, the_ff );
1354 mmeineke 616 myNPTf->setTargetTemp( globals->getTargetTemp());
1355    
1356     if (globals->haveTargetPressure())
1357     myNPTf->setTargetPressure(globals->getTargetPressure());
1358     else {
1359     sprintf( painCave.errMsg,
1360     "SimSetup error: If you use a constant pressure\n"
1361     " ensemble, you must set targetPressure in the BASS file.\n");
1362     painCave.isFatal = 1;
1363     simError();
1364     }
1365    
1366     if( globals->haveTauThermostat() )
1367     myNPTf->setTauThermostat( globals->getTauThermostat() );
1368     else{
1369     sprintf( painCave.errMsg,
1370     "SimSetup error: If you use an NPT\n"
1371     " ensemble, you must set tauThermostat.\n");
1372     painCave.isFatal = 1;
1373     simError();
1374     }
1375    
1376     if( globals->haveTauBarostat() )
1377     myNPTf->setTauBarostat( globals->getTauBarostat() );
1378     else{
1379     sprintf( painCave.errMsg,
1380     "SimSetup error: If you use an NPT\n"
1381     " ensemble, you must set tauBarostat.\n");
1382     painCave.isFatal = 1;
1383     simError();
1384     }
1385     break;
1386    
1387     case NPTim_ENS:
1388 tim 645 myNPTim = new NPTim<RealIntegrator>( info, the_ff );
1389 mmeineke 616 myNPTim->setTargetTemp( globals->getTargetTemp());
1390    
1391     if (globals->haveTargetPressure())
1392     myNPTim->setTargetPressure(globals->getTargetPressure());
1393     else {
1394     sprintf( painCave.errMsg,
1395     "SimSetup error: If you use a constant pressure\n"
1396     " ensemble, you must set targetPressure in the BASS file.\n");
1397     painCave.isFatal = 1;
1398     simError();
1399     }
1400    
1401     if( globals->haveTauThermostat() )
1402     myNPTim->setTauThermostat( globals->getTauThermostat() );
1403     else{
1404     sprintf( painCave.errMsg,
1405     "SimSetup error: If you use an NPT\n"
1406     " ensemble, you must set tauThermostat.\n");
1407     painCave.isFatal = 1;
1408     simError();
1409     }
1410    
1411     if( globals->haveTauBarostat() )
1412     myNPTim->setTauBarostat( globals->getTauBarostat() );
1413     else{
1414     sprintf( painCave.errMsg,
1415     "SimSetup error: If you use an NPT\n"
1416     " ensemble, you must set tauBarostat.\n");
1417     painCave.isFatal = 1;
1418     simError();
1419     }
1420     break;
1421    
1422     case NPTfm_ENS:
1423 tim 645 myNPTfm = new NPTfm<RealIntegrator>( info, the_ff );
1424 mmeineke 616 myNPTfm->setTargetTemp( globals->getTargetTemp());
1425    
1426     if (globals->haveTargetPressure())
1427     myNPTfm->setTargetPressure(globals->getTargetPressure());
1428     else {
1429     sprintf( painCave.errMsg,
1430     "SimSetup error: If you use a constant pressure\n"
1431     " ensemble, you must set targetPressure in the BASS file.\n");
1432     painCave.isFatal = 1;
1433     simError();
1434     }
1435    
1436     if( globals->haveTauThermostat() )
1437     myNPTfm->setTauThermostat( globals->getTauThermostat() );
1438     else{
1439     sprintf( painCave.errMsg,
1440     "SimSetup error: If you use an NPT\n"
1441     " ensemble, you must set tauThermostat.\n");
1442     painCave.isFatal = 1;
1443     simError();
1444     }
1445    
1446     if( globals->haveTauBarostat() )
1447     myNPTfm->setTauBarostat( globals->getTauBarostat() );
1448     else{
1449     sprintf( painCave.errMsg,
1450     "SimSetup error: If you use an NPT\n"
1451     " ensemble, you must set tauBarostat.\n");
1452     painCave.isFatal = 1;
1453     simError();
1454     }
1455     break;
1456    
1457     default:
1458     sprintf( painCave.errMsg,
1459     "SimSetup Error. Unrecognized ensemble in case statement.\n");
1460     painCave.isFatal = 1;
1461     simError();
1462     }
1463    
1464     }
1465    
1466     void SimSetup::initFortran( void ){
1467    
1468     info->refreshSim();
1469    
1470     if( !strcmp( info->mixingRule, "standard") ){
1471     the_ff->initForceField( LB_MIXING_RULE );
1472     }
1473     else if( !strcmp( info->mixingRule, "explicit") ){
1474     the_ff->initForceField( EXPLICIT_MIXING_RULE );
1475     }
1476     else{
1477     sprintf( painCave.errMsg,
1478     "SimSetup Error: unknown mixing rule -> \"%s\"\n",
1479     info->mixingRule );
1480     painCave.isFatal = 1;
1481     simError();
1482     }
1483    
1484    
1485     #ifdef IS_MPI
1486     strcpy( checkPointMsg,
1487     "Successfully intialized the mixingRule for Fortran." );
1488     MPIcheckPoint();
1489     #endif // is_mpi
1490    
1491     }