ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 658
Committed: Thu Jul 31 15:35:07 2003 UTC (20 years, 11 months ago) by tim
File size: 38158 byte(s)
Log Message:
 Added Z constraint.

File Contents

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