ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new-templateless/OOPSE/libmdtools/SimSetup.cpp
Revision: 850
Committed: Mon Nov 3 22:07:17 2003 UTC (20 years, 9 months ago) by mmeineke
File size: 42314 byte(s)
Log Message:
begun work on removing templates and most of standard template library from OOPSE.

File Contents

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