ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 661
Committed: Fri Aug 1 16:18:13 2003 UTC (20 years, 11 months ago) by tim
File size: 44488 byte(s)
Log Message:
stable version of Z-Constraint

File Contents

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