--- trunk/OOPSE/libmdtools/InitializeFromFile.cpp 2003/03/27 01:49:45 417 +++ trunk/OOPSE/libmdtools/InitializeFromFile.cpp 2003/10/28 16:03:37 829 @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -13,12 +13,21 @@ #ifdef IS_MPI #include -#include #include "mpiSimulation.hpp" -#define TAKE_THIS_TAG 0 +#define TAKE_THIS_TAG_CHAR 0 +#define TAKE_THIS_TAG_INT 1 + +namespace initFile{ + void nodeZeroError( void ); + void anonymousNodeDie( void ); +} + +using namespace initFile; + #endif // is_mpi -InitializeFromFile :: InitializeFromFile( char *in_name ){ +InitializeFromFile::InitializeFromFile( char *in_name ){ + #ifdef IS_MPI if (worldRank == 0) { #endif @@ -40,7 +49,7 @@ InitializeFromFile :: InitializeFromFile( char *in_nam return; } -InitializeFromFile :: ~InitializeFromFile( ){ +InitializeFromFile::~InitializeFromFile( ){ #ifdef IS_MPI if (worldRank == 0) { #endif @@ -61,24 +70,28 @@ InitializeFromFile :: ~InitializeFromFile( ){ } -void InitializeFromFile :: read_xyz( SimInfo* the_entry_plug ){ +void InitializeFromFile :: readInit( SimInfo* the_simnfo ){ - int i, j, done, which_node, which_atom; // loop counter + int i, j; + +#ifdef IS_MPI + int done, which_node, which_atom; // loop counter +#endif //is_mpi const int BUFFERSIZE = 2000; // size of the read buffer int n_atoms; // the number of atoms char read_buffer[BUFFERSIZE]; //the line buffer for reading -#ifdef IS_MPI - char send_buffer[BUFFERSIZE]; -#endif char *eof_test; // ptr to see when we reach the end of the file char *parseErr; - int procIndex; - entry_plug = the_entry_plug; + double currTime; + double boxMat[9]; + double theBoxMat3[3][3]; + simnfo = the_simnfo; + #ifndef IS_MPI eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if( eof_test == NULL ){ @@ -91,19 +104,16 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr n_atoms = atoi( read_buffer ); - Atom **atoms = entry_plug->atoms; - DirectionalAtom* dAtom; - - if( n_atoms != entry_plug->n_atoms ){ + if( n_atoms != simnfo->n_atoms ){ sprintf( painCave.errMsg, "Initialize from File error. %s n_atoms, %d, " "does not match the BASS file's n_atoms, %d.\n", - c_in_name, n_atoms, entry_plug->n_atoms ); + c_in_name, n_atoms, simnfo->n_atoms ); painCave.isFatal = 1; simError(); } - //read and toss the comment line + //read the box mat from the comment line eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if(eof_test == NULL){ @@ -113,6 +123,20 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr simError(); } + parseErr = parseBoxLine( read_buffer, boxMat, currTime ); + if( parseErr != NULL ){ + strcpy( painCave.errMsg, parseErr ); + painCave.isFatal = 1; + simError(); + } + + for(i=0;i<3;i++) + for(j=0;j<3;j++) theBoxMat3[i][j] = boxMat[3*j+i]; + + simnfo->setBoxM( theBoxMat3 ); + simnfo->setTime( currTime ); + + for( i=0; i < n_atoms; i++){ eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); @@ -132,30 +156,36 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr strcpy( painCave.errMsg, parseErr ); painCave.isFatal = 1; simError(); - } + } } // MPI Section of code.......... #else //IS_MPI - MPI::Status istatus; + // first thing first, suspend fatalities. + painCave.isEventLoop = 1; + + int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone + int haveError; + + MPI_Status istatus; int *AtomToProcMap = mpiSim->getAtomToProcMap(); + + haveError = 0; if (worldRank == 0) { + eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if( eof_test == NULL ){ sprintf( painCave.errMsg, - "Error reading 1st line of %d \n ",c_in_name); - painCave.isFatal = 1; + "Error reading 1st line of %s \n ",c_in_name); + haveError = 1; simError(); } n_atoms = atoi( read_buffer ); - Atom **atoms = entry_plug->atoms; - DirectionalAtom* dAtom; - // Check to see that the number of atoms in the intial configuration file is the // same as declared in simBass. @@ -163,21 +193,32 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr sprintf( painCave.errMsg, "Initialize from File error. %s n_atoms, %d, " "does not match the BASS file's n_atoms, %d.\n", - c_in_name, n_atoms, entry_plug->n_atoms ); - painCave.isFatal = 1; + c_in_name, n_atoms, simnfo->n_atoms ); + haveError= 1; simError(); } - //read and toss the comment line + //read the boxMat from the comment line eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if(eof_test == NULL){ sprintf( painCave.errMsg, "error in reading commment in %s\n", c_in_name); - painCave.isFatal = 1; + haveError = 1; simError(); } + + parseErr = parseBoxLine( read_buffer, boxMat, currTime ); + if( parseErr != NULL ){ + strcpy( painCave.errMsg, parseErr ); + haveError = 1; + simError(); + } + + MPI_Bcast(boxMat, 9, MPI_DOUBLE, 0, MPI_COMM_WORLD ); + MPI_Bcast(&currTime, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD ); + if(haveError) nodeZeroError(); for (i=0 ; i < mpiSim->getTotAtoms(); i++) { @@ -188,78 +229,127 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr "natoms = %d; index = %d\n" "error reading the line from the file.\n", c_in_name, n_atoms, i ); - painCave.isFatal = 1; + haveError= 1; simError(); } + if(haveError) nodeZeroError(); + // Get the Node number which wants this atom: which_node = AtomToProcMap[i]; - if (which_node == mpiSim->getMyNode()) { + if (which_node == 0) { parseErr = parseDumpLine( read_buffer, i ); if( parseErr != NULL ){ strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; + haveError = 1; simError(); } - } else { - MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node, - TAKE_THIS_TAG); - MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG); + if(haveError) nodeZeroError(); + } + + else { + + myStatus = 1; + MPI_Send(&myStatus, 1, MPI_INT, which_node, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD); + MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node, + TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD); + MPI_Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT, + MPI_COMM_WORLD); + MPI_Recv(&myStatus, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT, + MPI_COMM_WORLD, &istatus); + + if(!myStatus) nodeZeroError(); } } - sprintf(read_buffer, "GAMEOVER"); + myStatus = -1; for (j = 0; j < mpiSim->getNumberProcessors(); j++) { - MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, j, - TAKE_THIS_TAG); + MPI_Send( &myStatus, 1, MPI_INT, j, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD); } - + } else { + + MPI_Bcast(boxMat, 9, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&currTime, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); done = 0; while (!done) { - MPI::COMM_WORLD.Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0, - TAKE_THIS_TAG, istatus); - if (strcmp(read_buffer, "GAMEOVER")) { - done = 1; - continue; - } else { - MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0, - TAKE_THIS_TAG, istatus); - parseErr = parseDumpLine( read_buffer, which_atom ); - if( parseErr != NULL ){ - strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; - simError(); - } + + MPI_Recv(&myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus); + + if(!myStatus) anonymousNodeDie(); + + if(myStatus < 0) break; + + MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0, + TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus); + MPI_Recv(&which_atom, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus); + + myStatus = 1; + parseErr = parseDumpLine( read_buffer, which_atom ); + if( parseErr != NULL ){ + strcpy( painCave.errMsg, parseErr ); + myStatus = 0;; + simError(); } + + MPI_Send( &myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD); + } } - + + // last thing last, enable fatalities. + painCave.isEventLoop = 0; + + for(i=0;i<3;i++) + for(j=0;j<3;j++) theBoxMat3[i][j] = boxMat[3*j+i]; + + simnfo->setBoxM( theBoxMat3 ); + simnfo->setTime( currTime ); + + #endif } -char* InitializeFromFile::parseDumpLine(char* readLine, int atomIndex){ +char* InitializeFromFile::parseDumpLine(char* readLine, int globalIndex){ char *foo; // the pointer to the current string token - double rx, ry, rz; // position place holders - double vx, vy, vz; // velocity placeholders + double pos[3]; // position place holders + double vel[3]; // velocity placeholders double q[4]; // the quaternions double jx, jy, jz; // angular velocity placeholders; double qSqr, qLength; // needed to normalize the quaternion vector. - Atom **atoms = entry_plug->atoms; + Atom **atoms = simnfo->atoms; DirectionalAtom* dAtom; - int n_atoms; + int n_atoms, atomIndex; #ifdef IS_MPI + int j; + n_atoms = mpiSim->getTotAtoms(); + atomIndex=-1; + for (j=0; j < mpiSim->getMyNlocal(); j++) { + if (atoms[j]->getGlobalIndex() == globalIndex) atomIndex = j; + } + if (atomIndex == -1) { + sprintf( painCave.errMsg, + "Initialize from file error. Atom at index %d " + "in file %s does not exist on processor %d .\n", + globalIndex, c_in_name, mpiSim->getMyNode() ); + return strdup( painCave.errMsg ); + } #else - n_atoms = entry_plug->n_atoms; + n_atoms = simnfo->n_atoms; + atomIndex = globalIndex; #endif // is_mpi - // set the string tokenizer foo = strtok(readLine, " ,;\t"); @@ -285,7 +375,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - rx = atof( foo ); + pos[0] = atof( foo ); foo = strtok(NULL, " ,;\t"); if(foo == NULL){ @@ -295,7 +385,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - ry = atof( foo ); + pos[1] = atof( foo ); foo = strtok(NULL, " ,;\t"); if(foo == NULL){ @@ -305,7 +395,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - rz = atof( foo ); + pos[2] = atof( foo ); // get the velocities @@ -318,7 +408,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - vx = atof( foo ); + vel[0] = atof( foo ); foo = strtok(NULL, " ,;\t"); if(foo == NULL){ @@ -328,7 +418,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - vy = atof( foo ); + vel[1] = atof( foo ); foo = strtok(NULL, " ,;\t"); if(foo == NULL){ @@ -338,7 +428,7 @@ char* InitializeFromFile::parseDumpLine(char* readLine c_in_name, n_atoms, atomIndex ); return strdup( painCave.errMsg ); } - vz = atof( foo ); + vel[2] = atof( foo ); // get the quaternions @@ -440,13 +530,145 @@ char* InitializeFromFile::parseDumpLine(char* readLine // add the positions and velocities to the atom - atoms[atomIndex]->setX( rx ); - atoms[atomIndex]->setY( ry ); - atoms[atomIndex]->setZ( rz ); - - atoms[atomIndex]->set_vx( vx ); - atoms[atomIndex]->set_vy( vy ); - atoms[atomIndex]->set_vz( vz ); + atoms[atomIndex]->setPos( pos ); + atoms[atomIndex]->setVel( vel ); return NULL; } + + +char* InitializeFromFile::parseBoxLine(char* readLine, double boxMat[9], + double &time ){ + + char *foo; // the pointer to the current string token + + // set the string tokenizer + + foo = strtok(readLine, " ,;\t"); + // set the timeToken. + + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Time from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + time = atof( foo ); + + // get the Hx vector + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hx[0] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[0] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hx[1] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[1] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hx[2] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[2] = atof( foo ); + + // get the Hy vector + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hy[0] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[3] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hy[1] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[4] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hy[2] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[5] = atof( foo ); + + // get the Hz vector + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hz[0] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[6] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hz[1] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[7] = atof( foo ); + + foo = strtok(NULL, " ,;\t"); + if(foo == NULL){ + sprintf( painCave.errMsg, + "error in reading Hz[2] from %s\n", + c_in_name ); + return strdup( painCave.errMsg ); + } + boxMat[8] = atof( foo ); + + return NULL; +} + + +#ifdef IS_MPI + +// a couple of functions to let us escape the read loop + +void initFile::nodeZeroError( void ){ + int j, myStatus; + + myStatus = 0; + for (j = 0; j < mpiSim->getNumberProcessors(); j++) { + MPI_Send( &myStatus, 1, MPI_INT, j, + TAKE_THIS_TAG_INT, MPI_COMM_WORLD); + } + + + MPI_Finalize(); + exit (0); + +} + +void initFile::anonymousNodeDie( void ){ + + MPI_Finalize(); + exit (0); +} + +#endif //is_mpi