171 |
|
int i, j, k; |
172 |
|
int exI, exJ, exK, exL, slI, slJ; |
173 |
|
int tempI, tempJ, tempK, tempL; |
174 |
< |
int molI; |
175 |
< |
int stampID, atomOffset, rbOffset; |
174 |
> |
int molI, globalID; |
175 |
> |
int stampID, atomOffset, rbOffset, groupOffset; |
176 |
|
molInit molInfo; |
177 |
|
DirectionalAtom* dAtom; |
178 |
|
RigidBody* myRB; |
215 |
|
|
216 |
|
for (k = 0; k < nInfo; k++){ |
217 |
|
the_ff->setSimInfo(&(info[k])); |
218 |
+ |
|
219 |
+ |
#ifdef IS_MPI |
220 |
+ |
info[k].globalGroupMembership = new int[mpiSim->getNAtomsGlobal()]; |
221 |
+ |
for (i = 0; i < mpiSim->getNAtomsGlobal(); i++) |
222 |
+ |
info[k].globalGroupMembership[i] = 0; |
223 |
+ |
#else |
224 |
+ |
info[k].globalGroupMembership = new int[info[k].n_atoms]; |
225 |
+ |
for (i = 0; i < info[k].n_atoms; i++) |
226 |
+ |
info[k].globalGroupMembership[i] = 0; |
227 |
+ |
#endif |
228 |
|
|
229 |
|
atomOffset = 0; |
230 |
|
groupOffset = 0; |
292 |
|
|
293 |
|
molInfo.myAtoms[j]->setType(currentAtom->getType()); |
294 |
|
#ifdef IS_MPI |
285 |
– |
|
295 |
|
molInfo.myAtoms[j]->setGlobalIndex(globalAtomIndex[j + atomOffset]); |
287 |
– |
|
296 |
|
#endif // is_mpi |
297 |
|
} |
298 |
|
|
514 |
|
nMembers = currentCutoffGroup->getNMembers(); |
515 |
|
|
516 |
|
myCutoffGroup = new CutoffGroup(); |
509 |
– |
myCutoffGroup->setGlobalIndex(globalGroupIndex[j + groupOffset]); |
517 |
|
|
518 |
+ |
#ifdef IS_MPI |
519 |
+ |
myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]); |
520 |
+ |
#else |
521 |
+ |
myCutoffGroup->setGlobalIndex(groupOffset); |
522 |
+ |
#endif |
523 |
+ |
|
524 |
|
for (int cg = 0; cg < nMembers; cg++) { |
525 |
|
|
526 |
|
// molI is atom numbering inside this molecule |
530 |
|
tempI = molI + atomOffset; |
531 |
|
|
532 |
|
#ifdef IS_MPI |
533 |
< |
globalID = info[k].atoms[tempI]->getGlobalIndex() |
533 |
> |
globalID = info[k].atoms[tempI]->getGlobalIndex(); |
534 |
> |
info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset]; |
535 |
|
#else |
536 |
|
globalID = info[k].atoms[tempI]->getIndex(); |
537 |
< |
#endif |
538 |
< |
|
539 |
< |
globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; |
526 |
< |
|
527 |
< |
myCutoffGroup->addAtom(info[k].atoms[tempI]); |
528 |
< |
|
537 |
> |
info[k].globalGroupMembership[globalID] = groupOffset; |
538 |
> |
#endif |
539 |
> |
myCutoffGroup->addAtom(info[k].atoms[tempI]); |
540 |
|
cutoffAtomSet.insert(tempI); |
541 |
|
} |
542 |
< |
|
542 |
> |
|
543 |
|
molInfo.myCutoffGroups.push_back(myCutoffGroup); |
544 |
|
groupOffset++; |
545 |
|
|
546 |
|
}//end for (j = 0; j < molInfo.nCutoffGroups; j++) |
547 |
< |
|
548 |
< |
//creat a cutoff group for every atom in current molecule which does not belong to cutoffgroup defined at mdl file |
549 |
< |
|
547 |
> |
|
548 |
> |
|
549 |
> |
// create a cutoff group for every atom in current molecule which |
550 |
> |
// does not belong to cutoffgroup defined at mdl file |
551 |
> |
|
552 |
|
for(j = 0; j < molInfo.nAtoms; j++){ |
553 |
< |
|
553 |
> |
|
554 |
|
if(cutoffAtomSet.find(molInfo.myAtoms[j]->getIndex()) == cutoffAtomSet.end()){ |
555 |
|
myCutoffGroup = new CutoffGroup(); |
556 |
|
myCutoffGroup->addAtom(molInfo.myAtoms[j]); |
557 |
< |
myCutoffGroup->setGlobalIndex(globalGroupIndex[j + groupOffset]); |
557 |
> |
|
558 |
|
#ifdef IS_MPI |
559 |
< |
globalID = info[k].atoms[atomOffset + j]->getGlobalIndex() |
560 |
< |
#else |
559 |
> |
myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]); |
560 |
> |
globalID = info[k].atoms[atomOffset + j]->getGlobalIndex(); |
561 |
> |
info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset]; |
562 |
> |
#else |
563 |
> |
myCutoffGroup->setGlobalIndex(groupOffset); |
564 |
|
globalID = info[k].atoms[atomOffset + j]->getIndex(); |
565 |
+ |
info[k].globalGroupMembership[globalID] = groupOffset; |
566 |
|
#endif |
550 |
– |
globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; |
567 |
|
molInfo.myCutoffGroups.push_back(myCutoffGroup); |
568 |
|
groupOffset++; |
569 |
< |
} |
554 |
< |
|
569 |
> |
} |
570 |
|
} |
571 |
|
|
572 |
|
// After this is all set up, scan through the atoms to |
656 |
|
theTorsions); |
657 |
|
|
658 |
|
info[k].molecules[i].initialize(molInfo); |
659 |
< |
|
660 |
< |
|
659 |
> |
|
660 |
> |
|
661 |
|
atomOffset += molInfo.nAtoms; |
662 |
|
delete[] theBonds; |
663 |
|
delete[] theBends; |
664 |
|
delete[] theTorsions; |
665 |
< |
} |
665 |
> |
} |
666 |
> |
|
667 |
> |
|
668 |
> |
|
669 |
> |
#ifdef IS_MPI |
670 |
> |
// Since the globalGroupMembership has been zero filled and we've only |
671 |
> |
// poked values into the atoms we know, we can do an Allreduce |
672 |
> |
// to get the full globalGroupMembership array (We think). |
673 |
> |
// This would be prettier if we could use MPI_IN_PLACE like the MPI-2 |
674 |
> |
// docs said we could. |
675 |
> |
|
676 |
> |
int* ggMjunk = new int[mpiSim->getNAtomsGlobal()]; |
677 |
> |
|
678 |
> |
MPI_Allreduce(info[k].globalGroupMembership, |
679 |
> |
ggMjunk, |
680 |
> |
mpiSim->getNAtomsGlobal(), |
681 |
> |
MPI_INT, MPI_SUM, MPI_COMM_WORLD); |
682 |
> |
|
683 |
> |
for (i = 0; i < mpiSim->getNAtomsGlobal(); i++) |
684 |
> |
info[k].globalGroupMembership[i] = ggMjunk[i]; |
685 |
> |
|
686 |
> |
delete[] ggMjunk; |
687 |
> |
|
688 |
> |
#endif |
689 |
> |
|
690 |
> |
|
691 |
> |
|
692 |
|
} |
693 |
|
|
694 |
|
#ifdef IS_MPI |
1061 |
|
info[i].orthoTolerance = globals->getOrthoBoxTolerance(); |
1062 |
|
|
1063 |
|
// check for thermodynamic integration |
1064 |
< |
if (globals->getUseThermInt()) { |
1064 |
> |
if (globals->getUseSolidThermInt() && !globals->getUseLiquidThermInt()) { |
1065 |
|
if (globals->haveThermIntLambda() && globals->haveThermIntK()) { |
1066 |
< |
info[i].useThermInt = globals->getUseThermInt(); |
1066 |
> |
info[i].useSolidThermInt = globals->getUseSolidThermInt(); |
1067 |
|
info[i].thermIntLambda = globals->getThermIntLambda(); |
1068 |
|
info[i].thermIntK = globals->getThermIntK(); |
1069 |
|
|
1073 |
|
else { |
1074 |
|
sprintf(painCave.errMsg, |
1075 |
|
"SimSetup Error:\n" |
1076 |
< |
"\tKeyword useThermInt was set to 'true' but\n" |
1076 |
> |
"\tKeyword useSolidThermInt was set to 'true' but\n" |
1077 |
> |
"\tthermodynamicIntegrationLambda (and/or\n" |
1078 |
> |
"\tthermodynamicIntegrationK) was not specified.\n" |
1079 |
> |
"\tPlease provide a lambda value and k value in your .bass file.\n"); |
1080 |
> |
painCave.isFatal = 1; |
1081 |
> |
simError(); |
1082 |
> |
} |
1083 |
> |
} |
1084 |
> |
else if(globals->getUseLiquidThermInt()) { |
1085 |
> |
if (globals->getUseSolidThermInt()) { |
1086 |
> |
sprintf( painCave.errMsg, |
1087 |
> |
"SimSetup Warning: It appears that you have both solid and\n" |
1088 |
> |
"\tliquid thermodynamic integration activated in your .bass\n" |
1089 |
> |
"\tfile. To avoid confusion, specify only one technique in\n" |
1090 |
> |
"\tyour .bass file. Liquid-state thermodynamic integration\n" |
1091 |
> |
"\twill be assumed for the current simulation. If this is not\n" |
1092 |
> |
"\twhat you desire, set useSolidThermInt to 'true' and\n" |
1093 |
> |
"\tuseLiquidThermInt to 'false' in your .bass file.\n"); |
1094 |
> |
painCave.isFatal = 0; |
1095 |
> |
simError(); |
1096 |
> |
} |
1097 |
> |
if (globals->haveThermIntLambda() && globals->haveThermIntK()) { |
1098 |
> |
info[i].useLiquidThermInt = globals->getUseLiquidThermInt(); |
1099 |
> |
info[i].thermIntLambda = globals->getThermIntLambda(); |
1100 |
> |
info[i].thermIntK = globals->getThermIntK(); |
1101 |
> |
} |
1102 |
> |
else { |
1103 |
> |
sprintf(painCave.errMsg, |
1104 |
> |
"SimSetup Error:\n" |
1105 |
> |
"\tKeyword useLiquidThermInt was set to 'true' but\n" |
1106 |
|
"\tthermodynamicIntegrationLambda (and/or\n" |
1107 |
|
"\tthermodynamicIntegrationK) was not specified.\n" |
1108 |
|
"\tPlease provide a lambda value and k value in your .bass file.\n"); |
1113 |
|
else if(globals->haveThermIntLambda() || globals->haveThermIntK()){ |
1114 |
|
sprintf(painCave.errMsg, |
1115 |
|
"SimSetup Warning: If you want to use Thermodynamic\n" |
1116 |
< |
"\tIntegration, set useThermInt to 'true' in your .bass file.\n" |
1117 |
< |
"\tThe useThermInt keyword is 'false' by default, so your\n" |
1118 |
< |
"\tlambda and/or k values are being ignored.\n"); |
1116 |
> |
"\tIntegration, set useSolidThermInt or useLiquidThermInt to\n" |
1117 |
> |
"\t'true' in your .bass file. These keywords are set to\n" |
1118 |
> |
"\t'false' by default, so your lambda and/or k values are\n" |
1119 |
> |
"\tbeing ignored.\n"); |
1120 |
|
painCave.isFatal = 0; |
1121 |
|
simError(); |
1122 |
|
} |
1650 |
|
|
1651 |
|
mpiSim->divideLabor(); |
1652 |
|
globalAtomIndex = mpiSim->getGlobalAtomIndex(); |
1653 |
+ |
globalGroupIndex = mpiSim->getGlobalGroupIndex(); |
1654 |
|
//globalMolIndex = mpiSim->getGlobalMolIndex(); |
1655 |
|
|
1656 |
|
// set up the local variables |