ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 814
Committed: Thu Oct 23 19:57:25 2003 UTC (20 years, 8 months ago) by mmeineke
File size: 43815 byte(s)
Log Message:
added eam ForceField files to the init

fixed an eam mpi parmeter setup bug

File Contents

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