ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 670
Committed: Thu Aug 7 21:47:18 2003 UTC (20 years, 11 months ago) by mmeineke
File size: 45076 byte(s)
Log Message:
switched SimInfo to use a system configuration from SimState rather than arrays from Atom

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