--- trunk/OOPSE/libmdtools/SimSetup.cpp 2004/06/01 17:15:43 1212 +++ trunk/OOPSE/libmdtools/SimSetup.cpp 2004/06/11 14:14:10 1261 @@ -11,8 +11,9 @@ #include "simError.h" #include "RigidBody.hpp" #include "OOPSEMinimizer.hpp" -//#include "ConstraintElement.hpp" -//#include "ConstraintPair.hpp" +#include "ConstraintElement.hpp" +#include "ConstraintPair.hpp" +#include "ConstraintManager.hpp" #ifdef IS_MPI #include "mpiBASS.h" @@ -157,6 +158,10 @@ void SimSetup::createSim(void){ initFortran(); + //creat constraint manager + for(int i = 0; i < nInfo; i++) + info[i].consMan = new ConstraintManager(&info[i]); + if (globals->haveMinimizer()) // make minimizer makeMinimizer(); @@ -171,8 +176,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; @@ -199,12 +204,13 @@ void SimSetup::makeMolecules(void){ 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; + 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; + double bondLength2; //init the forceField paramters the_ff->readParams(); @@ -216,6 +222,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 +298,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,7 +520,12 @@ 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++) { @@ -517,41 +536,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 @@ -584,37 +605,50 @@ void SimSetup::makeMolecules(void){ info[k].integrableObjects.push_back(mySD); molInfo.myIntegrableObjects.push_back(mySD); } + + // send the arrays off to the forceField for init. + + the_ff->initializeAtoms(molInfo.nAtoms, molInfo.myAtoms); + the_ff->initializeBonds(molInfo.nBonds, molInfo.myBonds, theBonds); + the_ff->initializeBends(molInfo.nBends, molInfo.myBends, theBends); + the_ff->initializeTorsions(molInfo.nTorsions, molInfo.myTorsions, + theTorsions); - /* - //creat ConstraintPair. - molInfo.myConstraintPair.clear(); + molInfo.myConstraintPairs.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)){ + //if bond is constrained bond, add it into constraint pair + if(molInfo.myBonds[j]->is_constrained()){ - 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]); + //if both atoms are in the same rigid body, just skip it + currentBond = comp_stamps[stampID]->getBond(j); + + if(!comp_stamps[stampID]->isBondInSameRigidBody(currentBond)){ - 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]); + 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]); - consPair = new DistanceConstraintPair(consElement1, consElement2); - molInfo.myConstraintPairs.push_back(consPair); - } + 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]); + + bondLength2 = molInfo.myBonds[j]->get_constraint()->get_dsqr(); + consPair = new DistanceConstraintPair(consElement1, consElement2, bondLength2); + + molInfo.myConstraintPairs.push_back(consPair); + } + }//end if(molInfo.myBonds[j]->is_constrained()) } - //loop over rigid bodies, if two rigid bodies share same joint, creat a HingeConstraintPair + //loop over rigid bodies, if two rigid bodies share same joint, creat a JointConstraintPair for (int rb1 = 0; rb1 < molInfo.nRigidBodies -1 ; rb1++){ for (int rb2 = rb1 + 1; rb2 < molInfo.nRigidBodies ; rb2++){ @@ -631,23 +665,41 @@ void SimSetup::makeMolecules(void){ } } -*/ - // send the arrays off to the forceField for init. - - the_ff->initializeAtoms(molInfo.nAtoms, molInfo.myAtoms); - the_ff->initializeBonds(molInfo.nBonds, molInfo.myBonds, theBonds); - the_ff->initializeBends(molInfo.nBends, molInfo.myBends, theBends); - the_ff->initializeTorsions(molInfo.nTorsions, molInfo.myTorsions, - 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 @@ -864,8 +916,12 @@ void SimSetup::gatherInfo(void){ painCave.isFatal = 1; simError(); } - - // get the ensemble + if (globals->haveForceFieldVariant()) { + strcpy(forcefield_variant, globals->getForceFieldVariant()); + has_forcefield_variant = 1; + } + + // get the ensemble strcpy(ensemble, globals->getEnsemble()); @@ -1462,7 +1518,7 @@ void SimSetup::createFF(void){ void SimSetup::createFF(void){ switch (ffCase){ case FF_DUFF: - the_ff = new DUFF(); + the_ff = new DUFF(); break; case FF_LJ: @@ -1470,7 +1526,10 @@ void SimSetup::createFF(void){ break; case FF_EAM: - the_ff = new EAM_FF(); + if (has_forcefield_variant) + the_ff = new EAM_FF(forcefield_variant); + else + the_ff = new EAM_FF(); break; case FF_H2O: @@ -1483,6 +1542,7 @@ void SimSetup::createFF(void){ painCave.isFatal = 1; simError(); } + #ifdef IS_MPI strcpy(checkPointMsg, "ForceField creation successful"); @@ -1609,6 +1669,7 @@ void SimSetup::mpiMolDivide(void){ mpiSim->divideLabor(); globalAtomIndex = mpiSim->getGlobalAtomIndex(); + globalGroupIndex = mpiSim->getGlobalGroupIndex(); //globalMolIndex = mpiSim->getGlobalMolIndex(); // set up the local variables