--- trunk/OOPSE/libmdtools/SimSetup.cpp 2004/04/12 20:32:20 1097 +++ trunk/OOPSE/libmdtools/SimSetup.cpp 2004/06/01 15:57:30 1211 @@ -10,8 +10,9 @@ #include "Integrator.hpp" #include "simError.h" #include "RigidBody.hpp" -//#include "ConjugateMinimizer.hpp" #include "OOPSEMinimizer.hpp" +//#include "ConstraintElement.hpp" +//#include "ConstraintPair.hpp" #ifdef IS_MPI #include "mpiBASS.h" @@ -147,13 +148,6 @@ void SimSetup::createSim(void){ // make the output filenames makeOutNames(); - - if (globals->haveMinimizer()) - // make minimizer - makeMinimizer(); - else - // make the integrator - makeIntegrator(); #ifdef IS_MPI mpiSim->mpiRefresh(); @@ -162,12 +156,20 @@ void SimSetup::createSim(void){ // initialize the Fortran initFortran(); + + if (globals->haveMinimizer()) + // make minimizer + makeMinimizer(); + else + // make the integrator + makeIntegrator(); + } void SimSetup::makeMolecules(void){ int i, j, k; - int exI, exJ, exK, exL, slI; + int exI, exJ, exK, exL, slI, slJ; int tempI, tempJ, tempK, tempL; int molI; int stampID, atomOffset, rbOffset; @@ -182,6 +184,10 @@ void SimSetup::makeMolecules(void){ BendStamp* currentBend; TorsionStamp* currentTorsion; RigidBodyStamp* currentRigidBody; + CutoffGroupStamp* currentCutoffGroup; + CutoffGroup* myCutoffGroup; + int nCutoffGroups;// number of cutoff group of a molecule defined in mdl file + set cutoffAtomSet; //atoms belong to cutoffgroup defined at mdl file bond_pair* theBonds; bend_set* theBends; @@ -190,7 +196,15 @@ void SimSetup::makeMolecules(void){ set skipList; double phi, theta, psi; + char* molName; + char rbName[100]; + //ConstraintPair* consPair; //constraint pair + //ConstraintElement* consElement1; //first element of constraint pair + //ConstraintElement* consElement2; //second element of constraint pair + //int whichRigidBody; + //int consAtomIndex; //index of constraint atom in rigid body's atom array + //vector > jointAtoms; //init the forceField paramters the_ff->readParams(); @@ -203,30 +217,34 @@ void SimSetup::makeMolecules(void){ the_ff->setSimInfo(&(info[k])); atomOffset = 0; + groupOffset = 0; for (i = 0; i < info[k].n_mol; i++){ stampID = info[k].molecules[i].getStampID(); + molName = comp_stamps[stampID]->getID(); molInfo.nAtoms = comp_stamps[stampID]->getNAtoms(); molInfo.nBonds = comp_stamps[stampID]->getNBonds(); molInfo.nBends = comp_stamps[stampID]->getNBends(); molInfo.nTorsions = comp_stamps[stampID]->getNTorsions(); molInfo.nRigidBodies = comp_stamps[stampID]->getNRigidBodies(); + + nCutoffGroups = comp_stamps[stampID]->getNCutoffGroups(); molInfo.myAtoms = &(info[k].atoms[atomOffset]); if (molInfo.nBonds > 0) - molInfo.myBonds = new (Bond *) [molInfo.nBonds]; + molInfo.myBonds = new Bond*[molInfo.nBonds]; else molInfo.myBonds = NULL; if (molInfo.nBends > 0) - molInfo.myBends = new (Bend *) [molInfo.nBends]; + molInfo.myBends = new Bend*[molInfo.nBends]; else molInfo.myBends = NULL; if (molInfo.nTorsions > 0) - molInfo.myTorsions = new (Torsion *) [molInfo.nTorsions]; + molInfo.myTorsions = new Torsion *[molInfo.nTorsions]; else molInfo.myTorsions = NULL; @@ -259,13 +277,13 @@ void SimSetup::makeMolecules(void){ else{ molInfo.myAtoms[j] = new Atom((j + atomOffset), info[k].getConfiguration()); + } molInfo.myAtoms[j]->setType(currentAtom->getType()); - #ifdef IS_MPI - molInfo.myAtoms[j]->setGlobalIndex(globalIndex[j + atomOffset]); + molInfo.myAtoms[j]->setGlobalIndex(globalAtomIndex[j + atomOffset]); #endif // is_mpi } @@ -406,6 +424,9 @@ void SimSetup::makeMolecules(void){ info[k].excludes->addPair(exK, exL); } + + molInfo.myRigidBodies.clear(); + for (j = 0; j < molInfo.nRigidBodies; j++){ currentRigidBody = comp_stamps[stampID]->getRigidBody(j); @@ -414,6 +435,9 @@ void SimSetup::makeMolecules(void){ // Create the Rigid Body: myRB = new RigidBody(); + + sprintf(rbName,"%s_RB_%d", molName, j); + myRB->setType(rbName); for (rb1 = 0; rb1 < nMembers; rb1++) { @@ -454,19 +478,160 @@ void SimSetup::makeMolecules(void){ // used for the exclude list: #ifdef IS_MPI - exI = info[k].atoms[tempI]->getGlobalIndex() + 1; - exJ = info[k].atoms[tempJ]->getGlobalIndex() + 1; + exI = molInfo.myAtoms[tempI]->getGlobalIndex() + 1; + exJ = molInfo.myAtoms[tempJ]->getGlobalIndex() + 1; #else - exI = tempI + 1; - exJ = tempJ + 1; + exI = molInfo.myAtoms[tempI]->getIndex() + 1; + exJ = molInfo.myAtoms[tempJ]->getIndex() + 1; #endif info[k].excludes->addPair(exI, exJ); } } + + molInfo.myRigidBodies.push_back(myRB); + info[k].rigidBodies.push_back(myRB); } + + //create cutoff group for molecule + + cutoffAtomSet.clear(); + molInfo.myCutoffGroups.clear(); + + for (j = 0; j < nCutoffGroups; j++){ + + currentCutoffGroup = comp_stamps[stampID]->getCutoffGroup(j); + nMembers = currentCutoffGroup->getNMembers(); + + myCutoffGroup = new CutoffGroup(); + myCutoffGroup->setGlobalIndex(globalGroupIndex[j + groupOffset]); + + for (int cg = 0; cg < nMembers; cg++) { + + // molI is atom numbering inside this molecule + molI = currentCutoffGroup->getMember(cg); + + // tempI is atom numbering on local processor + tempI = molI + atomOffset; + +#ifdef IS_MPI + globalID = info[k].atoms[tempI]->getGlobalIndex() +#else + globalID = info[k].atoms[tempI]->getIndex(); +#endif + + globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; + + 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 + + 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 + globalID = info[k].atoms[atomOffset + j]->getIndex(); +#endif + globalGroupMembership[globalID] = globalGroupIndex[j+groupOffset]; + molInfo.myCutoffGroups.push_back(myCutoffGroup); + groupOffset++; + } + + } + + // After this is all set up, scan through the atoms to + // see if they can be added to the integrableObjects: + + molInfo.myIntegrableObjects.clear(); + + + for (j = 0; j < molInfo.nAtoms; j++){ + +#ifdef IS_MPI + slJ = molInfo.myAtoms[j]->getGlobalIndex(); +#else + slJ = j+atomOffset; +#endif + + // if they aren't on the skip list, then they can be integrated + + if (skipList.find(slJ) == skipList.end()) { + mySD = (StuntDouble *) molInfo.myAtoms[j]; + info[k].integrableObjects.push_back(mySD); + molInfo.myIntegrableObjects.push_back(mySD); + } + } + + // all rigid bodies are integrated: + + for (j = 0; j < molInfo.nRigidBodies; j++) { + mySD = (StuntDouble *) molInfo.myRigidBodies[j]; + info[k].integrableObjects.push_back(mySD); + molInfo.myIntegrableObjects.push_back(mySD); + } + + + /* + + //creat ConstraintPair. + molInfo.myConstraintPair.clear(); + + for (j = 0; j < molInfo.nBonds; j++){ + + //if both atoms are in the same rigid body, just skip it + currentBond = comp_stamps[stampID]->getBond(j); + if(!comp_stamps[stampID]->isBondInSameRigidBody(currentBond)){ + + tempI = currentBond->getA() + atomOffset; + if( comp_stamps[stampID]->isAtomInRigidBody(currentBond->getA(), whichRigidBody, consAtomIndex)) + consElement1 = new ConstraintRigidBody(molInfo.myRigidBodies[whichRigidBody], consAtomIndex); + else + consElement1 = new ConstraintAtom(info[k].atoms[tempI]); + + tempJ = currentBond->getB() + atomOffset; + if(comp_stamps[stampID]->isAtomInRigidBody(currentBond->getB(), whichRigidBody, consAtomIndex)) + consElement2 = new ConstraintRigidBody(molInfo.myRigidBodies[whichRigidBody], consAtomIndex); + else + consElement2 = new ConstraintAtom(info[k].atoms[tempJ]); + + consPair = new DistanceConstraintPair(consElement1, consElement2); + molInfo.myConstraintPairs.push_back(consPair); + } + } + + //loop over rigid bodies, if two rigid bodies share same joint, creat a HingeConstraintPair + for (int rb1 = 0; rb1 < molInfo.nRigidBodies -1 ; rb1++){ + for (int rb2 = rb1 + 1; rb2 < molInfo.nRigidBodies ; rb2++){ + + jointAtoms = comp_stamps[stampID]->getJointAtoms(rb1, rb2); + + for(size_t m = 0; m < jointAtoms.size(); m++){ + consElement1 = new ConstraintRigidBody(molInfo.myRigidBodies[rb1], jointAtoms[m].first); + consElement2 = new ConstraintRigidBody(molInfo.myRigidBodies[rb2], jointAtoms[m].second); + + consPair = new JointConstraintPair(consElement1, consElement2); + molInfo.myConstraintPairs.push_back(consPair); + } + + } + } + +*/ // send the arrays off to the forceField for init. the_ff->initializeAtoms(molInfo.nAtoms, molInfo.myAtoms); @@ -482,47 +647,14 @@ void SimSetup::makeMolecules(void){ delete[] theBonds; delete[] theBends; delete[] theTorsions; - } - - // build up the integrableObjects vector: - - for (i = 0; i < info[k].n_atoms; i++) { - -#ifdef IS_MPI - slI = info[k].atoms[i]->getGlobalIndex(); -#else - slI = i; -#endif - - if (skipList.find(slI) == skipList.end()) { - mySD = (StuntDouble *) info[k].atoms[i]; - info[k].integrableObjects.push_back(mySD); - } - } - for (i = 0; i < info[k].rigidBodies.size(); i++) { - mySD = (StuntDouble *) info[k].rigidBodies[i]; - info[k].integrableObjects.push_back(mySD); - } - + } } #ifdef IS_MPI sprintf(checkPointMsg, "all molecules initialized succesfully"); MPIcheckPoint(); #endif // is_mpi - - // clean up the forcefield - - if (!globals->haveLJrcut()){ - - the_ff->calcRcut(); - - } else { - - the_ff->setRcut( globals->getLJrcut() ); - } - the_ff->cleanMe(); } void SimSetup::initFromBass(void){ @@ -809,7 +941,7 @@ void SimSetup::gatherInfo(void){ } //check whether sample time, status time, thermal time and reset time are divisble by dt - if (!isDivisible(globals->getSampleTime(), globals->getDt())){ + if (globals->haveSampleTime() && !isDivisible(globals->getSampleTime(), globals->getDt())){ sprintf(painCave.errMsg, "Sample time is not divisible by dt.\n" "\tThis will result in samples that are not uniformly\n" @@ -819,7 +951,7 @@ void SimSetup::gatherInfo(void){ simError(); } - if (globals->haveStatusTime() && !isDivisible(globals->getSampleTime(), globals->getDt())){ + if (globals->haveStatusTime() && !isDivisible(globals->getStatusTime(), globals->getDt())){ sprintf(painCave.errMsg, "Status time is not divisible by dt.\n" "\tThis will result in status reports that are not uniformly\n" @@ -855,12 +987,10 @@ void SimSetup::gatherInfo(void){ if (globals->haveSampleTime()){ info[i].sampleTime = globals->getSampleTime(); info[i].statusTime = info[i].sampleTime; - info[i].thermalTime = info[i].sampleTime; } else{ info[i].sampleTime = globals->getRunTime(); info[i].statusTime = info[i].sampleTime; - info[i].thermalTime = info[i].sampleTime; } if (globals->haveStatusTime()){ @@ -869,6 +999,8 @@ void SimSetup::gatherInfo(void){ if (globals->haveThermalTime()){ info[i].thermalTime = globals->getThermalTime(); + } else { + info[i].thermalTime = globals->getRunTime(); } info[i].resetIntegrator = 0; @@ -886,7 +1018,37 @@ void SimSetup::gatherInfo(void){ info[i].useInitXSstate = globals->getUseInitXSstate(); info[i].orthoTolerance = globals->getOrthoBoxTolerance(); - + + // check for thermodynamic integration + if (globals->getUseThermInt()) { + if (globals->haveThermIntLambda() && globals->haveThermIntK()) { + info[i].useThermInt = globals->getUseThermInt(); + info[i].thermIntLambda = globals->getThermIntLambda(); + info[i].thermIntK = globals->getThermIntK(); + + Restraints *myRestraint = new Restraints(tot_nmol, info[i].thermIntLambda, info[i].thermIntK); + info[i].restraint = myRestraint; + } + else { + sprintf(painCave.errMsg, + "SimSetup Error:\n" + "\tKeyword useThermInt 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->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"); + painCave.isFatal = 0; + simError(); + } } //setup seed for random number generator @@ -939,6 +1101,7 @@ void SimSetup::finalInfoCheck(void){ void SimSetup::finalInfoCheck(void){ int index; int usesDipoles; + int usesCharges; int i; for (i = 0; i < nInfo; i++){ @@ -950,45 +1113,72 @@ void SimSetup::finalInfoCheck(void){ usesDipoles = (info[i].atoms[index])->hasDipole(); index++; } - + index = 0; + usesCharges = 0; + while ((index < info[i].n_atoms) && !usesCharges){ + usesCharges= (info[i].atoms[index])->hasCharge(); + index++; + } #ifdef IS_MPI int myUse = usesDipoles; MPI_Allreduce(&myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); #endif //is_mpi - double theEcr, theEst; + double theRcut, theRsw; + if (globals->haveRcut()) { + theRcut = globals->getRcut(); + + if (globals->haveRsw()) + theRsw = globals->getRsw(); + else + theRsw = theRcut; + + info[i].setDefaultRcut(theRcut, theRsw); + + } else { + + the_ff->calcRcut(); + theRcut = info[i].getRcut(); + + if (globals->haveRsw()) + theRsw = globals->getRsw(); + else + theRsw = theRcut; + + info[i].setDefaultRcut(theRcut, theRsw); + } + if (globals->getUseRF()){ info[i].useReactionField = 1; - - if (!globals->haveECR()){ + + if (!globals->haveRcut()){ sprintf(painCave.errMsg, - "SimSetup Warning: No value was set for electrostaticCutoffRadius.\n" + "SimSetup Warning: No value was set for the cutoffRadius.\n" "\tOOPSE will use a default value of 15.0 angstroms" - "\tfor the electrostaticCutoffRadius.\n"); + "\tfor the cutoffRadius.\n"); painCave.isFatal = 0; simError(); - theEcr = 15.0; + theRcut = 15.0; } else{ - theEcr = globals->getECR(); + theRcut = globals->getRcut(); } - if (!globals->haveEST()){ + if (!globals->haveRsw()){ sprintf(painCave.errMsg, - "SimSetup Warning: No value was set for electrostaticSkinThickness.\n" + "SimSetup Warning: No value was set for switchingRadius.\n" "\tOOPSE will use a default value of\n" - "\t0.05 * electrostaticCutoffRadius\n" - "\tfor the electrostaticSkinThickness\n"); + "\t0.95 * cutoffRadius for the switchingRadius\n"); painCave.isFatal = 0; simError(); - theEst = 0.05 * theEcr; + theRsw = 0.95 * theRcut; } else{ - theEst = globals->getEST(); + theRsw = globals->getRsw(); } - info[i].setDefaultEcr(theEcr, theEst); + info[i].setDefaultRcut(theRcut, theRsw); if (!globals->haveDielectric()){ sprintf(painCave.errMsg, @@ -1001,35 +1191,36 @@ void SimSetup::finalInfoCheck(void){ info[i].dielectric = globals->getDielectric(); } else{ - if (usesDipoles){ - if (!globals->haveECR()){ + if (usesDipoles || usesCharges){ + + if (!globals->haveRcut()){ sprintf(painCave.errMsg, - "SimSetup Warning: No value was set for electrostaticCutoffRadius.\n" + "SimSetup Warning: No value was set for the cutoffRadius.\n" "\tOOPSE will use a default value of 15.0 angstroms" - "\tfor the electrostaticCutoffRadius.\n"); - painCave.isFatal = 0; - simError(); - theEcr = 15.0; - } + "\tfor the cutoffRadius.\n"); + painCave.isFatal = 0; + simError(); + theRcut = 15.0; + } else{ - theEcr = globals->getECR(); + theRcut = globals->getRcut(); } - - if (!globals->haveEST()){ + + if (!globals->haveRsw()){ sprintf(painCave.errMsg, - "SimSetup Warning: No value was set for electrostaticSkinThickness.\n" + "SimSetup Warning: No value was set for switchingRadius.\n" "\tOOPSE will use a default value of\n" - "\t0.05 * electrostaticCutoffRadius\n" - "\tfor the electrostaticSkinThickness\n"); + "\t0.95 * cutoffRadius for the switchingRadius\n"); painCave.isFatal = 0; simError(); - theEst = 0.05 * theEcr; + theRsw = 0.95 * theRcut; } else{ - theEst = globals->getEST(); + theRsw = globals->getRsw(); } + + info[i].setDefaultRcut(theRcut, theRsw); - info[i].setDefaultEcr(theEcr, theEst); } } } @@ -1037,6 +1228,9 @@ void SimSetup::finalInfoCheck(void){ strcpy(checkPointMsg, "post processing checks out"); MPIcheckPoint(); #endif // is_mpi + + // clean up the forcefield + the_ff->cleanMe(); } void SimSetup::initSystemCoords(void){ @@ -1167,6 +1361,28 @@ void SimSetup::makeOutNames(void){ } } + strcpy(info[k].rawPotName, inFileName); + nameLength = strlen(info[k].rawPotName); + endTest = &(info[k].rawPotName[nameLength - 5]); + if (!strcmp(endTest, ".bass")){ + strcpy(endTest, ".raw"); + } + else if (!strcmp(endTest, ".BASS")){ + strcpy(endTest, ".raw"); + } + else{ + endTest = &(info[k].rawPotName[nameLength - 4]); + if (!strcmp(endTest, ".bss")){ + strcpy(endTest, ".raw"); + } + else if (!strcmp(endTest, ".mdl")){ + strcpy(endTest, ".raw"); + } + else{ + strcat(info[k].rawPotName, ".raw"); + } + } + #ifdef IS_MPI } @@ -1251,7 +1467,10 @@ void SimSetup::compList(void){ LinkedMolStamp* headStamp = new LinkedMolStamp(); LinkedMolStamp* currentStamp = NULL; comp_stamps = new MoleculeStamp * [n_components]; + bool haveCutoffGroups; + haveCutoffGroups = false; + // make an array of molecule stamps that match the components used. // also extract the used stamps out into a separate linked list @@ -1286,7 +1505,13 @@ void SimSetup::compList(void){ headStamp->add(currentStamp); comp_stamps[i] = headStamp->match(id); } + + if(comp_stamps[i]->getNCutoffGroups() > 0) + haveCutoffGroups = true; } + + for (i = 0; i < nInfo; i++) + info[i].haveCutoffGroups = haveCutoffGroups; #ifdef IS_MPI strcpy(checkPointMsg, "Component stamps successfully extracted\n"); @@ -1295,21 +1520,33 @@ void SimSetup::calcSysValues(void){ } void SimSetup::calcSysValues(void){ - int i; + int i, j; + int ncutgroups, atomsingroups, ngroupsinstamp; int* molMembershipArray; + CutoffGroupStamp* cg; tot_atoms = 0; tot_bonds = 0; tot_bends = 0; tot_torsions = 0; tot_rigid = 0; + tot_groups = 0; for (i = 0; i < n_components; i++){ tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms(); tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds(); tot_bends += components_nmol[i] * comp_stamps[i]->getNBends(); tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions(); tot_rigid += components_nmol[i] * comp_stamps[i]->getNRigidBodies(); + + ncutgroups = comp_stamps[i]->getNCutoffGroups(); + atomsingroups = 0; + for (j=0; j < ncutgroups; j++) { + cg = comp_stamps[i]->getCutoffGroup(j); + atomsingroups += cg->getNMembers(); + } + ngroupsinstamp = comp_stamps[i]->getNAtoms() - atomsingroups + ncutgroups; + tot_groups += components_nmol[i] * ngroupsinstamp; } tot_SRI = tot_bonds + tot_bends + tot_torsions; @@ -1322,7 +1559,7 @@ void SimSetup::calcSysValues(void){ info[i].n_torsions = tot_torsions; info[i].n_SRI = tot_SRI; info[i].n_mol = tot_nmol; - + info[i].ngroup = tot_groups; info[i].molMembershipArray = molMembershipArray; } } @@ -1333,11 +1570,16 @@ void SimSetup::mpiMolDivide(void){ int i, j, k; int localMol, allMol; int local_atoms, local_bonds, local_bends, local_torsions, local_SRI; - int local_rigid; + int local_rigid, local_groups; + vector globalMolIndex; + int ncutgroups, atomsingroups, ngroupsinstamp; + CutoffGroupStamp* cg; mpiSim = new mpiSimulation(info); - globalIndex = mpiSim->divideLabor(); + mpiSim->divideLabor(); + globalAtomIndex = mpiSim->getGlobalAtomIndex(); + //globalMolIndex = mpiSim->getGlobalMolIndex(); // set up the local variables @@ -1351,7 +1593,8 @@ void SimSetup::mpiMolDivide(void){ local_bends = 0; local_torsions = 0; local_rigid = 0; - globalAtomIndex = 0; + local_groups = 0; + globalAtomCounter = 0; for (i = 0; i < n_components; i++){ for (j = 0; j < components_nmol[i]; j++){ @@ -1361,11 +1604,22 @@ void SimSetup::mpiMolDivide(void){ local_bends += comp_stamps[i]->getNBends(); local_torsions += comp_stamps[i]->getNTorsions(); local_rigid += comp_stamps[i]->getNRigidBodies(); + + ncutgroups = comp_stamps[i]->getNCutoffGroups(); + atomsingroups = 0; + for (k=0; k < ncutgroups; k++) { + cg = comp_stamps[i]->getCutoffGroup(k); + atomsingroups += cg->getNMembers(); + } + ngroupsinstamp = comp_stamps[i]->getNAtoms() - atomsingroups + + ncutgroups; + local_groups += ngroupsinstamp; + localMol++; } for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){ - info[0].molMembershipArray[globalAtomIndex] = allMol; - globalAtomIndex++; + info[0].molMembershipArray[globalAtomCounter] = allMol; + globalAtomCounter++; } allMol++; @@ -1373,9 +1627,8 @@ void SimSetup::mpiMolDivide(void){ } local_SRI = local_bonds + local_bends + local_torsions; - info[0].n_atoms = mpiSim->getMyNlocal(); + info[0].n_atoms = mpiSim->getNAtomsLocal(); - if (local_atoms != info[0].n_atoms){ sprintf(painCave.errMsg, "SimSetup error: mpiSim's localAtom (%d) and SimSetup's\n" @@ -1385,6 +1638,16 @@ void SimSetup::mpiMolDivide(void){ simError(); } + info[0].ngroup = mpiSim->getNGroupsLocal(); + if (local_groups != info[0].ngroup){ + sprintf(painCave.errMsg, + "SimSetup error: mpiSim's localGroups (%d) and SimSetup's\n" + "\tlocalGroups (%d) are not equal.\n", + info[0].ngroup, local_groups); + painCave.isFatal = 1; + simError(); + } + info[0].n_bonds = local_bonds; info[0].n_bends = local_bends; info[0].n_torsions = local_torsions; @@ -1421,7 +1684,7 @@ void SimSetup::makeSysArrays(void){ molIndex = 0; - for (i = 0; i < mpiSim->getTotNmol(); i++){ + for (i = 0; i < mpiSim->getNMolGlobal(); i++){ if (mol2proc[i] == worldRank){ the_molecules[molIndex].setStampID(molCompType[i]); the_molecules[molIndex].setMyIndex(molIndex); @@ -1433,15 +1696,15 @@ void SimSetup::makeSysArrays(void){ #else // is_mpi molIndex = 0; - globalAtomIndex = 0; + globalAtomCounter = 0; for (i = 0; i < n_components; i++){ for (j = 0; j < components_nmol[i]; j++){ the_molecules[molIndex].setStampID(i); the_molecules[molIndex].setMyIndex(molIndex); the_molecules[molIndex].setGlobalIndex(molIndex); for (k = 0; k < comp_stamps[i]->getNAtoms(); k++){ - info[l].molMembershipArray[globalAtomIndex] = molIndex; - globalAtomIndex++; + info[l].molMembershipArray[globalAtomCounter] = molIndex; + globalAtomCounter++; } molIndex++; } @@ -1458,7 +1721,7 @@ void SimSetup::makeSysArrays(void){ info[l].atoms = the_atoms; info[l].molecules = the_molecules; info[l].nGlobalExcludes = 0; - + the_ff->setSimInfo(info); } }