--- trunk/OOPSE/libmdtools/SimSetup.cpp 2004/06/01 15:57:30 1211 +++ trunk/OOPSE/libmdtools/SimSetup.cpp 2004/06/03 20:02:25 1229 @@ -171,8 +171,8 @@ void SimSetup::makeMolecules(void){ int i, j, k; int exI, exJ, exK, exL, slI, slJ; int tempI, tempJ, tempK, tempL; - int molI; - int stampID, atomOffset, rbOffset; + int molI, globalID; + int stampID, atomOffset, rbOffset, groupOffset; molInit molInfo; DirectionalAtom* dAtom; RigidBody* myRB; @@ -215,6 +215,16 @@ void SimSetup::makeMolecules(void){ for (k = 0; k < nInfo; k++){ the_ff->setSimInfo(&(info[k])); + +#ifdef IS_MPI + info[k].globalGroupMembership = new int[mpiSim->getNAtomsGlobal()]; + for (i = 0; i < mpiSim->getNAtomsGlobal(); i++) + info[k].globalGroupMembership[i] = 0; +#else + info[k].globalGroupMembership = new int[info[k].n_atoms]; + for (i = 0; i < info[k].n_atoms; i++) + info[k].globalGroupMembership[i] = 0; +#endif atomOffset = 0; groupOffset = 0; @@ -282,9 +292,7 @@ void SimSetup::makeMolecules(void){ molInfo.myAtoms[j]->setType(currentAtom->getType()); #ifdef IS_MPI - molInfo.myAtoms[j]->setGlobalIndex(globalAtomIndex[j + atomOffset]); - #endif // is_mpi } @@ -506,8 +514,13 @@ void SimSetup::makeMolecules(void){ nMembers = currentCutoffGroup->getNMembers(); myCutoffGroup = new CutoffGroup(); - myCutoffGroup->setGlobalIndex(globalGroupIndex[j + groupOffset]); +#ifdef IS_MPI + myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]); +#else + myCutoffGroup->setGlobalIndex(groupOffset); +#endif + for (int cg = 0; cg < nMembers; cg++) { // molI is atom numbering inside this molecule @@ -517,41 +530,43 @@ void SimSetup::makeMolecules(void){ tempI = molI + atomOffset; #ifdef IS_MPI - globalID = info[k].atoms[tempI]->getGlobalIndex() + globalID = info[k].atoms[tempI]->getGlobalIndex(); + info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset]; #else globalID = info[k].atoms[tempI]->getIndex(); -#endif - - globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; - - myCutoffGroup->addAtom(info[k].atoms[tempI]); - + info[k].globalGroupMembership[globalID] = groupOffset; +#endif + myCutoffGroup->addAtom(info[k].atoms[tempI]); cutoffAtomSet.insert(tempI); } - + molInfo.myCutoffGroups.push_back(myCutoffGroup); groupOffset++; }//end for (j = 0; j < molInfo.nCutoffGroups; j++) - - //creat a cutoff group for every atom in current molecule which does not belong to cutoffgroup defined at mdl file - + + + // create a cutoff group for every atom in current molecule which + // does not belong to cutoffgroup defined at mdl file + for(j = 0; j < molInfo.nAtoms; j++){ - + if(cutoffAtomSet.find(molInfo.myAtoms[j]->getIndex()) == cutoffAtomSet.end()){ myCutoffGroup = new CutoffGroup(); myCutoffGroup->addAtom(molInfo.myAtoms[j]); - myCutoffGroup->setGlobalIndex(globalGroupIndex[j + groupOffset]); + #ifdef IS_MPI - globalID = info[k].atoms[atomOffset + j]->getGlobalIndex() -#else + myCutoffGroup->setGlobalIndex(globalGroupIndex[groupOffset]); + globalID = info[k].atoms[atomOffset + j]->getGlobalIndex(); + info[k].globalGroupMembership[globalID] = globalGroupIndex[groupOffset]; +#else + myCutoffGroup->setGlobalIndex(groupOffset); globalID = info[k].atoms[atomOffset + j]->getIndex(); + info[k].globalGroupMembership[globalID] = groupOffset; #endif - globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; molInfo.myCutoffGroups.push_back(myCutoffGroup); groupOffset++; - } - + } } // After this is all set up, scan through the atoms to @@ -641,13 +656,39 @@ void SimSetup::makeMolecules(void){ theTorsions); info[k].molecules[i].initialize(molInfo); - - + + atomOffset += molInfo.nAtoms; delete[] theBonds; delete[] theBends; delete[] theTorsions; - } + } + + + +#ifdef IS_MPI + // Since the globalGroupMembership has been zero filled and we've only + // poked values into the atoms we know, we can do an Allreduce + // to get the full globalGroupMembership array (We think). + // This would be prettier if we could use MPI_IN_PLACE like the MPI-2 + // docs said we could. + + int* ggMjunk = new int[mpiSim->getNAtomsGlobal()]; + + MPI_Allreduce(info[k].globalGroupMembership, + ggMjunk, + mpiSim->getNAtomsGlobal(), + MPI_INT, MPI_SUM, MPI_COMM_WORLD); + + for (i = 0; i < mpiSim->getNAtomsGlobal(); i++) + info[k].globalGroupMembership[i] = ggMjunk[i]; + + delete[] ggMjunk; + +#endif + + + } #ifdef IS_MPI @@ -1020,9 +1061,9 @@ void SimSetup::gatherInfo(void){ info[i].orthoTolerance = globals->getOrthoBoxTolerance(); // check for thermodynamic integration - if (globals->getUseThermInt()) { + if (globals->getUseSolidThermInt() && !globals->getUseLiquidThermInt()) { if (globals->haveThermIntLambda() && globals->haveThermIntK()) { - info[i].useThermInt = globals->getUseThermInt(); + info[i].useSolidThermInt = globals->getUseSolidThermInt(); info[i].thermIntLambda = globals->getThermIntLambda(); info[i].thermIntK = globals->getThermIntK(); @@ -1032,7 +1073,36 @@ void SimSetup::gatherInfo(void){ else { sprintf(painCave.errMsg, "SimSetup Error:\n" - "\tKeyword useThermInt was set to 'true' but\n" + "\tKeyword useSolidThermInt was set to 'true' but\n" + "\tthermodynamicIntegrationLambda (and/or\n" + "\tthermodynamicIntegrationK) was not specified.\n" + "\tPlease provide a lambda value and k value in your .bass file.\n"); + painCave.isFatal = 1; + simError(); + } + } + else if(globals->getUseLiquidThermInt()) { + if (globals->getUseSolidThermInt()) { + sprintf( painCave.errMsg, + "SimSetup Warning: It appears that you have both solid and\n" + "\tliquid thermodynamic integration activated in your .bass\n" + "\tfile. To avoid confusion, specify only one technique in\n" + "\tyour .bass file. Liquid-state thermodynamic integration\n" + "\twill be assumed for the current simulation. If this is not\n" + "\twhat you desire, set useSolidThermInt to 'true' and\n" + "\tuseLiquidThermInt to 'false' in your .bass file.\n"); + painCave.isFatal = 0; + simError(); + } + if (globals->haveThermIntLambda() && globals->haveThermIntK()) { + info[i].useLiquidThermInt = globals->getUseLiquidThermInt(); + info[i].thermIntLambda = globals->getThermIntLambda(); + info[i].thermIntK = globals->getThermIntK(); + } + else { + sprintf(painCave.errMsg, + "SimSetup Error:\n" + "\tKeyword useLiquidThermInt was set to 'true' but\n" "\tthermodynamicIntegrationLambda (and/or\n" "\tthermodynamicIntegrationK) was not specified.\n" "\tPlease provide a lambda value and k value in your .bass file.\n"); @@ -1043,9 +1113,10 @@ void SimSetup::gatherInfo(void){ else if(globals->haveThermIntLambda() || globals->haveThermIntK()){ sprintf(painCave.errMsg, "SimSetup Warning: If you want to use Thermodynamic\n" - "\tIntegration, set useThermInt to 'true' in your .bass file.\n" - "\tThe useThermInt keyword is 'false' by default, so your\n" - "\tlambda and/or k values are being ignored.\n"); + "\tIntegration, set useSolidThermInt or useLiquidThermInt to\n" + "\t'true' in your .bass file. These keywords are set to\n" + "\t'false' by default, so your lambda and/or k values are\n" + "\tbeing ignored.\n"); painCave.isFatal = 0; simError(); } @@ -1579,6 +1650,7 @@ void SimSetup::mpiMolDivide(void){ mpiSim->divideLabor(); globalAtomIndex = mpiSim->getGlobalAtomIndex(); + globalGroupIndex = mpiSim->getGlobalGroupIndex(); //globalMolIndex = mpiSim->getGlobalMolIndex(); // set up the local variables