--- trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/12/04 21:19:38 194 +++ trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/12/05 18:53:40 195 @@ -1,4 +1,4 @@ -#include +i#include #include #include @@ -9,20 +9,136 @@ mpiSimulation::mpiSimulation(SimInfo* the_entryPlug) mpiSimulation::mpiSimulation(SimInfo* the_entryPlug) { - entryPlug = the_entryPlug - + entryPlug = the_entryPlug; + numberProcessors = MPI::COMM_WORLD.Get_size(); myNode = worldRank; - - // let the simulkation know were there. + + // let the simulation know were there. entryPlug->mpiSim = this; } mpiSimulation::~mpiSimulation(){ - + // empty for now - + } +void mpiSimulation::divideLabor(int nComponents, MoleculeStamp** compStamps, int* componentsNmol ){ + + double numerator; + double denominator; + double precast; + + int nTarget; + int molIndex, atomIndex, compIndex, compStart; + int done; + int nLocal; + int i; + int smallDiff, bigDiff; + + int testSum; + + numerator = (double) entryPlug->n_atoms; + denominator = (double) numberProcessors; + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + + molIndex = 0; + atomIndex = 0; + compIndex = 0; + compStart = 0; + for( i=0; i<(numberProcessors-1); i++){ + + done = 0; + nLocal = 0; + + if( i == myNode ){ + myMolStart = molIndex; + myAtomStart = atomIndex; + } + + while( !done ){ + + if( (molIndex-compStart) >= componentsNmol[compIndex] ){ + compStart = molIndex; + compIndex++; + continue; + } + + nLocal += compStamps[compIndex]->getNAtoms(); + atomIndex += compStamps[compIndex]->getNAtoms(); + molIndex++; + + if ( nLocal == nTarget ) done = 1; + + else if( nLocal < nTarget ){ + smallDiff = nTarget - nLocal; + } + else if( nLocal > nTarget ){ + bigDiff = nLocal - nTarget; + + if( bigDiff < smallDiff ) done = 1; + else{ + molIndex--; + atomIndex -= compStamps[compIndex]->getNAtoms(); + nLocal -= compStamps[compIndex]->getNAtoms(); + done = 1; + } + } + } + + if( i == myNode ){ + myMolEnd = (molIndex - 1); + myAtomEnd = (atomIndex - 1); + myNlocal = nLocal; + } + + numerator = (double)( entryPlug->n_atoms - atomIndex ); + denominator = (double)( numberProcessors - (i+1) ); + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + } + + if( myNode == numberProcessors-1 ){ + myMolStart = molIndex; + myAtomStart = atomIndex; + + nLocal = 0; + while( compIndex < nComponents ){ + + if( (molIndex-compStart) >= componentsNmol[compIndex] ){ + compStart = molIndex; + compIndex++; + continue; + } + + nLocal += compStamps[compIndex]->getNAtoms(); + atomIndex += compStamps[compIndex]->getNAtoms(); + molIndex++; + } + + myMolEnd = (molIndex - 1); + myAtomEnd = (atomIndex - 1); + myNlocal = nLocal; + } + + + MPI_Allreduce( &Nlocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); + + if( myNode == 0 ){ + if( testSum != entryPlug->n_atoms ){ + sprintf( painCave.errMsg, + "The summ of all nLocals, %d, did not equal the total number of atoms, %d.\n", + testSum, entryPlug->n_atoms ); + painCave.isFatal = 1; + simError(); + } + } + + sprintf( checkPointMsg, + "Successfully divided the molecules among the processors.\n" ); + MPIcheckPoint(); +}