ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/io/DumpReader.cpp
(Generate patch)

Comparing trunk/OOPSE-2.0/src/io/DumpReader.cpp (file contents):
Revision 1492 by tim, Fri Sep 24 16:27:58 2004 UTC vs.
Revision 1958 by tim, Tue Jan 25 21:59:18 2005 UTC

# Line 1 | Line 1
1 + /*
2 + * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 + *
4 + * The University of Notre Dame grants you ("Licensee") a
5 + * non-exclusive, royalty free, license to use, modify and
6 + * redistribute this software in source and binary code form, provided
7 + * that the following conditions are met:
8 + *
9 + * 1. Acknowledgement of the program authors must be made in any
10 + *    publication of scientific results based in part on use of the
11 + *    program.  An acceptable form of acknowledgement is citation of
12 + *    the article in which the program was described (Matthew
13 + *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 + *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 + *    Parallel Simulation Engine for Molecular Dynamics,"
16 + *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 + *
18 + * 2. Redistributions of source code must retain the above copyright
19 + *    notice, this list of conditions and the following disclaimer.
20 + *
21 + * 3. Redistributions in binary form must reproduce the above copyright
22 + *    notice, this list of conditions and the following disclaimer in the
23 + *    documentation and/or other materials provided with the
24 + *    distribution.
25 + *
26 + * This software is provided "AS IS," without a warranty of any
27 + * kind. All express or implied conditions, representations and
28 + * warranties, including any implied warranty of merchantability,
29 + * fitness for a particular purpose or non-infringement, are hereby
30 + * excluded.  The University of Notre Dame and its licensors shall not
31 + * be liable for any damages suffered by licensee as a result of
32 + * using, modifying or distributing the software or its
33 + * derivatives. In no event will the University of Notre Dame or its
34 + * licensors be liable for any lost revenue, profit or data, or for
35 + * direct, indirect, special, consequential, incidental or punitive
36 + * damages, however caused and regardless of the theory of liability,
37 + * arising out of the use of or inability to use software, even if the
38 + * University of Notre Dame has been advised of the possibility of
39 + * such damages.
40 + */
41 +
42   #define _LARGEFILE_SOURCE64
43   #define _FILE_OFFSET_BITS 64
44  
# Line 11 | Line 52
52   #include <stdlib.h>
53   #include <string.h>
54  
55 <
56 < #include "io/ReadWrite.hpp"
55 > #include "io/DumpReader.hpp"
56 > #include "primitives/Molecule.hpp"
57   #include "utils/simError.h"
58 + #include "utils/MemoryUtils.hpp"
59 + #include "utils/StringTokenizer.hpp"
60  
61   #ifdef IS_MPI
62 +
63   #include <mpi.h>
20 #include "brains/mpiSimulation.hpp"
64   #define TAKE_THIS_TAG_CHAR 0
65   #define TAKE_THIS_TAG_INT 1
66 +
67   #endif // is_mpi
68  
69  
70 < DumpReader :: DumpReader(const char *in_name ){
70 > namespace oopse {
71  
72 <  isScanned = false;
72 > DumpReader::DumpReader(SimInfo* info, const std::string& filename)
73 >                     : info_(info), filename_(filename), isScanned_(false), nframes_(0) {
74  
75   #ifdef IS_MPI
76 <  if (worldRank == 0) {
76 >
77 >    if (worldRank == 0) {
78   #endif
79  
80 <  inFile = fopen(in_name, "r");
81 <  if(inFile == NULL){
82 <    sprintf(painCave.errMsg,
83 <            "Cannot open file: %s\n", in_name);
84 <    painCave.isFatal = 1;
85 <    simError();
86 <  }
87 <  
42 <  inFileName = in_name;
80 >        inFile_ = fopen(filename_.c_str(), "r");
81 >
82 >        if (inFile_ == NULL) {
83 >            sprintf(painCave.errMsg, "DumpReader: Cannot open file: %s\n", filename_.c_str());
84 >            painCave.isFatal = 1;
85 >            simError();
86 >        }
87 >
88   #ifdef IS_MPI
89 <  }
90 <  strcpy( checkPointMsg, "Dump file opened for reading successfully." );
91 <  MPIcheckPoint();
89 >
90 >    }
91 >
92 >    strcpy(checkPointMsg, "Dump file opened for reading successfully.");
93 >    MPIcheckPoint();
94 >
95   #endif
96 <  return;  
96 >
97 >    return;
98   }
99  
100 < DumpReader :: ~DumpReader( ){
100 > DumpReader::~DumpReader() {
101 >
102   #ifdef IS_MPI
103 <  if (worldRank == 0) {
103 >
104 >    if (worldRank == 0) {
105   #endif
55  vector<fpos_t*>::iterator i;
106  
107 <  int error;
108 <  error = fclose( inFile );
59 <  if( error ){
60 <    sprintf( painCave.errMsg,
61 <             "Error closing %s\n", inFileName.c_str());
62 <    simError();
63 <  }
107 >        int error;
108 >        error = fclose(inFile_);
109  
110 <  for(i = framePos.begin(); i != framePos.end(); ++i)
111 <    delete *i;
112 <  framePos.clear();
113 <  
110 >        if (error) {
111 >            sprintf(painCave.errMsg, "DumpReader Error: Error closing %s\n", filename_.c_str());
112 >            painCave.isFatal = 1;            
113 >            simError();
114 >        }
115 >
116 >        MemoryUtils::deleteVectorOfPointer(framePos_);
117 >
118   #ifdef IS_MPI
119 <  }
120 <  strcpy( checkPointMsg, "Dump file closed successfully." );
121 <  MPIcheckPoint();
119 >
120 >    }
121 >
122 >    strcpy(checkPointMsg, "Dump file closed successfully.");
123 >    MPIcheckPoint();
124 >
125   #endif
126  
127 <  return;
127 >    return;
128   }
129  
130 < int DumpReader::getNframes( void ){
130 > int DumpReader::getNFrames(void) {
131  
132 <  if( !isScanned )
133 <    scanFile();
134 <  return framePos.size();
132 >    if (!isScanned_)
133 >        scanFile();
134 >
135 >    return nframes_;
136   }
137  
138 < void DumpReader::scanFile( void ){
86 <
138 > void DumpReader::scanFile(void) {
139    int i, j;
140    int lineNum = 0;
141 <  char readBuffer[2000];
142 <  fpos_t *currPos;
141 >  char readBuffer[maxBufferSize];
142 >  fpos_t * currPos;
143  
144   #ifdef IS_MPI
145 <  if( worldRank == 0 ){
145 >
146 >    if (worldRank == 0) {
147   #endif // is_mpi
95    
96    rewind( inFile );
97    
98    currPos = new fpos_t;
99    fgetpos( inFile, currPos );
100    fgets( readBuffer, sizeof( readBuffer ), inFile );
101    lineNum++;
102    if( feof( inFile ) ){
103      sprintf( painCave.errMsg,
104               "File \"%s\" ended unexpectedly at line %d\n",
105               inFileName.c_str(),
106               lineNum );
107      painCave.isFatal = 1;
108      simError();
109    }
148  
149 <    while( !feof( inFile ) ){
112 <      
113 <      framePos.push_back(currPos);
149 >        rewind(inFile_);
150  
151 <      i = atoi(readBuffer);
152 <      
153 <      fgets( readBuffer, sizeof( readBuffer ), inFile );
154 <      lineNum++;    
119 <      if( feof( inFile ) ){
120 <        sprintf( painCave.errMsg,
121 <                 "File \"%s\" ended unexpectedly at line %d\n",
122 <                 inFileName.c_str(),
123 <                 lineNum );
124 <        painCave.isFatal = 1;
125 <        simError();
126 <      }
127 <            
128 <      for(j=0; j<i; j++){
129 <        
130 <        fgets( readBuffer, sizeof( readBuffer ), inFile );
131 <        lineNum++;    
132 <        if( feof( inFile ) ){
133 <          sprintf( painCave.errMsg,
134 <                   "File \"%s\" ended unexpectedly at line %d,"
135 <                   " with atom %d\n",
136 <                   inFileName.c_str(),
137 <                   lineNum,
138 <                   j );
139 <          painCave.isFatal = 1;
140 <          simError();
141 <        }
142 <        
143 <      }
144 <      
145 <      currPos = new fpos_t;
146 <      fgetpos( inFile, currPos );
147 <      fgets( readBuffer, sizeof( readBuffer ), inFile );
148 <      lineNum++;
149 <    }
150 <    
151 <    delete currPos;
152 <    rewind( inFile );
153 <    
154 <    isScanned = true;
151 >        currPos = new fpos_t;
152 >        fgetpos(inFile_, currPos);
153 >        fgets(readBuffer, sizeof(readBuffer), inFile_);
154 >        lineNum++;
155  
156 < #ifdef IS_MPI
157 <  }
158 <  strcpy( checkPointMsg, "Successfully scanned DumpFile\n" );
159 <  MPIcheckPoint();
160 < #endif // is_mpi
161 < }
156 >        if (feof(inFile_)) {
157 >            sprintf(painCave.errMsg,
158 >                    "DumpReader Error: File \"%s\" ended unexpectedly at line %d\n",
159 >                    filename_.c_str(),
160 >                    lineNum);
161 >            painCave.isFatal = 1;
162 >            simError();
163 >        }
164  
165 < void DumpReader :: readFrame( SimInfo* the_simnfo, int whichFrame){
165 >        while (!feof(inFile_)) {
166 >            framePos_.push_back(currPos);
167  
168 <  simnfo = the_simnfo;
168 >            i = atoi(readBuffer);
169  
170 <  this->readSet( whichFrame );
171 < }
170 >            fgets(readBuffer, sizeof(readBuffer), inFile_);
171 >            lineNum++;
172  
173 +            if (feof(inFile_)) {
174 +                sprintf(painCave.errMsg,
175 +                        "DumpReader Error: File \"%s\" ended unexpectedly at line %d\n",
176 +                        filename_.c_str(),
177 +                        lineNum);
178 +                painCave.isFatal = 1;
179 +                simError();
180 +            }
181  
182 +            for(j = 0; j < i; j++) {
183 +                fgets(readBuffer, sizeof(readBuffer), inFile_);
184 +                lineNum++;
185  
186 < void DumpReader :: readSet( int whichFrame ){
186 >                if (feof(inFile_)) {
187 >                    sprintf(painCave.errMsg,
188 >                            "DumpReader Error: File \"%s\" ended unexpectedly at line %d,"
189 >                                " with atom %d\n", filename_.c_str(),
190 >                            lineNum,
191 >                            j);
192  
193 <  int i;
194 <  unsigned int j;
193 >                    painCave.isFatal = 1;
194 >                    simError();
195 >                }
196 >            }
197  
198 +            currPos = new fpos_t;
199 +            fgetpos(inFile_, currPos);
200 +            fgets(readBuffer, sizeof(readBuffer), inFile_);
201 +            lineNum++;
202 +        }
203 +
204 +        delete currPos;
205 +        rewind(inFile_);
206 +        
207 +        nframes_ = framePos_.size();
208   #ifdef IS_MPI
209 <  int done, which_node, which_atom; // loop counter
179 < #endif //is_mpi
209 >    }
210  
211 <  const int BUFFERSIZE = 2000; // size of the read buffer
182 <  int nTotObjs; // the number of atoms
183 <  char read_buffer[BUFFERSIZE]; //the line buffer for reading
211 >    MPI_Bcast(&nframes_, 1, MPI_INT, 0, MPI_COMM_WORLD);
212  
213 <  char *eof_test; // ptr to see when we reach the end of the file
214 <  char *parseErr;
213 >    strcpy(checkPointMsg, "Successfully scanned DumpFile\n");
214 >    MPIcheckPoint();
215  
216 <  vector<StuntDouble*> integrableObjects;
216 > #endif // is_mpi
217  
218 +    isScanned_ = true;
219 + }
220  
221 < #ifndef IS_MPI
221 > void DumpReader::readFrame(int whichFrame) {
222 >    readSet(whichFrame);
223 > }
224  
225 <  fsetpos(inFile, framePos[whichFrame]);
226 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
227 <  if( eof_test == NULL ){
228 <    sprintf( painCave.errMsg,
229 <             "DumpReader error: error reading 1st line of \"%s\"\n",
198 <             inFileName.c_str() );
199 <    painCave.isFatal = 1;
200 <    simError();
201 <  }
225 > void DumpReader::readSet(int whichFrame) {
226 >  int i;
227 >  int nTotObjs;                  // the number of atoms
228 >  char read_buffer[maxBufferSize];  //the line buffer for reading
229 >  char * eof_test;               // ptr to see when we reach the end of the file
230  
231 <  nTotObjs = atoi( read_buffer );
231 >  Molecule* mol;
232 >  StuntDouble* integrableObject;
233 >  SimInfo::MoleculeIterator mi;
234 >  Molecule::IntegrableObjectIterator ii;
235  
236 <  if( nTotObjs != simnfo->getTotIntegrableObjects() ){
206 <    sprintf( painCave.errMsg,
207 <             "DumpReader error. %s nIntegrable, %d, "
208 <             "does not match the meta-data file's nIntegrable, %d.\n",
209 <             inFileName.c_str(), nTotObjs, simnfo->getTotIntegrableObjects());
210 <    painCave.isFatal = 1;
211 <    simError();
212 <  }
213 <
214 <  //read the box mat from the comment line
236 > #ifndef IS_MPI
237  
238 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
239 <  if(eof_test == NULL){
218 <    sprintf( painCave.errMsg,
219 <             "error in reading commment in %s\n", inFileName.c_str());
220 <    painCave.isFatal = 1;
221 <    simError();
222 <  }
238 >    fsetpos(inFile_, framePos_[whichFrame]);
239 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
240  
241 <  parseErr = parseCommentLine( read_buffer, simnfo);
225 <  if( parseErr != NULL ){
226 <    strcpy( painCave.errMsg, parseErr );
227 <    painCave.isFatal = 1;
228 <    simError();
229 <  }
230 <
231 <  //parse dump lines
232 <
233 <  for( i=0; i < simnfo->n_mol; i++){
234 <
235 <    integrableObjects = (simnfo->molecules[i]).getIntegrableObjects();
236 <
237 <    for(j = 0; j < integrableObjects.size(); j++){
238 <
239 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
240 <      if(eof_test == NULL){
241 >    if (eof_test == NULL) {
242          sprintf(painCave.errMsg,
243 <              "error in reading file %s\n"
244 <              "natoms  = %d; index = %d\n"
244 <              "error reading the line from the file.\n",
245 <              inFileName.c_str(), nTotObjs, i );
243 >                "DumpReader error: error reading 1st line of \"%s\"\n",
244 >                filename_.c_str());
245          painCave.isFatal = 1;
246          simError();
248      }
249      
250      parseErr = parseDumpLine( read_buffer, integrableObjects[j]);
251      if( parseErr != NULL ){
252        strcpy( painCave.errMsg, parseErr );
253        painCave.isFatal = 1;
254        simError();
255      }
247      }
257  }
248  
249 <  // MPI Section of code..........
260 < #else //IS_MPI
249 >    nTotObjs = atoi(read_buffer);
250  
251 <  // first thing first, suspend fatalities.
252 <  painCave.isEventLoop = 1;
251 >    if (nTotObjs != info_->getNGlobalIntegrableObjects()) {
252 >        sprintf(painCave.errMsg,
253 >                "DumpReader error. %s nIntegrable, %d, "
254 >                    "does not match the meta-data file's nIntegrable, %d.\n",
255 >                filename_.c_str(),
256 >                nTotObjs,
257 >                info_->getNGlobalIntegrableObjects());
258  
259 <  int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
260 <  int haveError;
259 >        painCave.isFatal = 1;
260 >        simError();
261 >    }
262  
263 <  MPI_Status istatus;
269 <  int *MolToProcMap = mpiSim->getMolToProcMap();
270 <  int localIndex;
271 <  int nCurObj;
272 <  int nitems;
263 >    //read the box mat from the comment line
264  
265 <  nTotObjs = simnfo->getTotIntegrableObjects();
275 <  haveError = 0;
276 <  if (worldRank == 0) {
277 <     fsetpos(inFile,  framePos[whichFrame]);
265 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
266  
267 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
268 <    if( eof_test == NULL ){
269 <      sprintf( painCave.errMsg,
270 <               "Error reading 1st line of %s \n ",inFileName.c_str());
271 <      haveError = 1;
284 <      simError();
267 >    if (eof_test == NULL) {
268 >        sprintf(painCave.errMsg, "DumpReader Error: error in reading commment in %s\n",
269 >                filename_.c_str());
270 >        painCave.isFatal = 1;
271 >        simError();
272      }
273  
274 <    nitems = atoi( read_buffer );
274 >    parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
275  
276 <    // Check to see that the number of integrable objects in the
290 <    // intial configuration file is the same as derived from the
291 <    // meta-data file.
276 >    //parse dump lines
277  
278 <    if( nTotObjs != nitems){
294 <      sprintf( painCave.errMsg,
295 <               "DumpReader Error. %s nIntegrable, %d, "
296 <               "does not match the meta-data file's nIntegrable, %d.\n",
297 <               inFileName.c_str(), nTotObjs, simnfo->getTotIntegrableObjects());
298 <      haveError= 1;
299 <      simError();
300 <    }
278 >    for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
279  
280 <    //read the boxMat from the comment line
280 >        for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
281 >            integrableObject = mol->nextIntegrableObject(ii)) {          
282  
283 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
305 <    if(eof_test == NULL){
306 <      sprintf( painCave.errMsg,
307 <               "error in reading commment in %s\n", inFileName.c_str());
308 <      haveError = 1;
309 <      simError();
310 <    }
283 >            eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
284  
285 <    //Every single processor will parse the comment line by itself
286 <    //By using this way, we might lose some efficiency, but if we want to add
287 <    //more parameters into comment line, we only need to modify function
288 <    //parseCommentLine
285 >            if (eof_test == NULL) {
286 >                sprintf(painCave.errMsg,
287 >                        "DumpReader Error: error in reading file %s\n"
288 >                            "natoms  = %d; index = %d\n"
289 >                            "error reading the line from the file.\n",
290 >                        filename_.c_str(),
291 >                        nTotObjs,
292 >                        i);
293  
294 <    MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
294 >                painCave.isFatal = 1;
295 >                simError();
296 >            }
297  
298 <    parseErr = parseCommentLine( read_buffer, simnfo);
299 <
300 <    if( parseErr != NULL ){
322 <      strcpy( painCave.errMsg, parseErr );
323 <      haveError = 1;
324 <      simError();
298 >            parseDumpLine(read_buffer, integrableObject);
299 >            
300 >            }
301      }
302  
303 <    for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
328 <      which_node = MolToProcMap[i];
329 <      if(which_node == 0){
330 <       //molecules belong to master node
303 >    // MPI Section of code..........
304  
305 <      localIndex = mpiSim->getGlobalToLocalMol(i);
305 > #else //IS_MPI
306  
307 <      if(localIndex == -1) {
308 <        strcpy(painCave.errMsg, "Molecule not found on node 0!");
309 <        haveError = 1;
310 <        simError();
338 <      }
307 >    // first thing first, suspend fatalities.
308 >    int masterNode = 0;
309 >    int nCurObj;
310 >    painCave.isEventLoop = 1;
311  
312 <       integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
313 <       for(j=0; j < integrableObjects.size(); j++){
342 <        
343 <          eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
344 <          if(eof_test == NULL){
345 <                sprintf(painCave.errMsg,
346 <                    "error in reading file %s\n"
347 <                    "natoms  = %d; index = %d\n"
348 <                    "error reading the line from the file.\n",
349 <                    inFileName.c_str(), nTotObjs, i );
350 <                haveError= 1;
351 <                simError();
352 <          }
353 <          
354 <          if(haveError) nodeZeroError();
312 >    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
313 >    int haveError;
314  
315 <          parseDumpLine(read_buffer, integrableObjects[j]);
316 <          
358 <       }
315 >    MPI_Status istatus;
316 >    int nitems;
317  
318 +    nTotObjs = info_->getNGlobalIntegrableObjects();
319 +    haveError = 0;
320  
321 <      }
322 <      else{
363 <      //molecule belongs to slave nodes
321 >    if (worldRank == masterNode) {
322 >        fsetpos(inFile_, framePos_[whichFrame]);
323  
324 <        MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
366 <               TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
367 <      
368 <       for(j=0; j < nCurObj; j++){
369 <        
370 <          eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
371 <          if(eof_test == NULL){
372 <                sprintf(painCave.errMsg,
373 <                    "error in reading file %s\n"
374 <                    "natoms  = %d; index = %d\n"
375 <                    "error reading the line from the file.\n",
376 <                    inFileName.c_str(), nTotObjs, i );
377 <                haveError= 1;
378 <                simError();
379 <          }
380 <          
381 <          if(haveError) nodeZeroError();
324 >        eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
325  
326 <            MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
327 <                      TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
328 <          
329 <       }
330 <
388 <      }
389 <      
390 <    }
391 <    
392 <  }
393 <  else{
394 <  //actions taken at slave nodes
395 <    MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
396 <
397 <    parseErr = parseCommentLine( read_buffer, simnfo);
398 <
399 <    if( parseErr != NULL ){
400 <      strcpy( painCave.errMsg, parseErr );
401 <      haveError = 1;
402 <      simError();
403 <    }
404 <  
405 <    for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
406 <      which_node = MolToProcMap[i];
407 <      
408 <      if(which_node == worldRank){
409 <      //molecule with global index i belongs to this processor
410 <      
411 <        localIndex = mpiSim->getGlobalToLocalMol(i);
412 <
413 <        if(localIndex == -1) {
414 <          sprintf(painCave.errMsg, "Molecule not found on node %d\n", worldRank);
415 <          haveError = 1;
416 <          simError();
326 >        if (eof_test == NULL) {
327 >            sprintf(painCave.errMsg, "DumpReader Error: Error reading 1st line of %s \n ",
328 >                    filename_.c_str());
329 >            painCave.isFatal = 1;
330 >            simError();
331          }
332  
333 <        integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();        
333 >        nitems = atoi(read_buffer);
334  
335 <        nCurObj = integrableObjects.size();
336 <        
337 <        MPI_Send(&nCurObj, 1, MPI_INT, 0,
424 <                        TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
335 >        // Check to see that the number of integrable objects in the
336 >        // intial configuration file is the same as derived from the
337 >        // meta-data file.
338  
339 <        for(j = 0; j < integrableObjects.size(); j++){
340 <
341 <          MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
342 <                              TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
343 <
344 <          parseErr = parseDumpLine(read_buffer, integrableObjects[j]);
345 <
433 <          if( parseErr != NULL ){
434 <                strcpy( painCave.errMsg, parseErr );
435 <                simError();
436 <          }
339 >        if (nTotObjs != nitems) {
340 >            sprintf(painCave.errMsg,
341 >                    "DumpReader Error. %s nIntegrable, %d, "
342 >                        "does not match the meta-data file's nIntegrable, %d.\n",
343 >                    filename_.c_str(),
344 >                    nTotObjs,
345 >                    info_->getNGlobalIntegrableObjects());
346  
347 +            painCave.isFatal = 1;
348 +            simError();
349          }
439          
440      }
441      
442    }
350  
351 <  }
351 >        //read the boxMat from the comment line
352  
353 < #endif
447 < }
353 >        eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
354  
355 < char* DumpReader::parseDumpLine(char* readLine, StuntDouble* sd){
355 >        if (eof_test == NULL) {
356 >            sprintf(painCave.errMsg, "DumpReader Error: error in reading commment in %s\n",
357 >                    filename_.c_str());
358 >            painCave.isFatal = 1;
359 >            simError();
360 >        }
361  
362 <  char *foo; // the pointer to the current string token
362 >        //Every single processor will parse the comment line by itself
363 >        //By using this way, we might lose some efficiency, but if we want to add
364 >        //more parameters into comment line, we only need to modify function
365 >        //parseCommentLine
366  
367 <  double pos[3]; // position place holders
368 <  double vel[3]; // velocity placeholders
455 <  double q[4]; // the quaternions
456 <  double ji[3]; // angular velocity placeholders;
457 <  double qSqr, qLength; // needed to normalize the quaternion vector.
367 >        MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
368 >        parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
369  
370 +        for(i = 0; i < info_->getNGlobalMolecules(); i++) {
371 +            int which_node = info_->getMolToProc(i);
372  
373 <  // set the string tokenizer
373 >            if (which_node == masterNode) {
374 >                //molecules belong to master node
375  
376 <  foo = strtok(readLine, " ,;\t");
376 >                mol = info_->getMoleculeByGlobalIndex(i);
377  
378 <  // check the atom name to the current atom
378 >                if (mol == NULL) {
379 >                    sprintf(painCave.errMsg, "DumpReader Error: Molecule not found on node %d!", worldRank);
380 >                        painCave.isFatal = 1;
381 >                    simError();
382 >                }
383  
384 <  if( strcmp( foo, sd->getType() ) ){
385 <    sprintf( painCave.errMsg,
386 <             "DumpReader error.  Does not"
387 <             " match the meta-data atom %s.\n",
470 <             sd->getType() );
471 <    return strdup( painCave.errMsg );
472 <  }
384 >                for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
385 >                       integrableObject = mol->nextIntegrableObject(ii)){
386 >                        
387 >                    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
388  
389 <  // get the positions
389 >                    if (eof_test == NULL) {
390 >                        sprintf(painCave.errMsg,
391 >                                "DumpReader Error: error in reading file %s\n"
392 >                                    "natoms  = %d; index = %d\n"
393 >                                    "error reading the line from the file.\n",
394 >                                filename_.c_str(),
395 >                                nTotObjs,
396 >                                i);
397  
398 <  foo = strtok(NULL, " ,;\t");
399 <  if(foo == NULL){
400 <    sprintf( painCave.errMsg,
479 <             "error in reading postition x from %s\n",
480 <             inFileName.c_str());
481 <    return strdup( painCave.errMsg );
482 <  }
483 <  pos[0] = atof( foo );
398 >                        painCave.isFatal = 1;
399 >                        simError();
400 >                    }
401  
402 <  foo = strtok(NULL, " ,;\t");
403 <  if(foo == NULL){
404 <    sprintf( painCave.errMsg,
405 <             "error in reading postition y from %s\n",
489 <             inFileName.c_str());
490 <    return strdup( painCave.errMsg );
491 <  }
492 <  pos[1] = atof( foo );
402 >                    parseDumpLine(read_buffer, integrableObject);
403 >                }
404 >            } else {
405 >                //molecule belongs to slave nodes
406  
407 <  foo = strtok(NULL, " ,;\t");
408 <  if(foo == NULL){
496 <    sprintf( painCave.errMsg,
497 <             "error in reading postition z from %s\n",
498 <             inFileName.c_str());
499 <    return strdup( painCave.errMsg );
500 <  }
501 <  pos[2] = atof( foo );
407 >                MPI_Recv(&nCurObj, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT,
408 >                         MPI_COMM_WORLD, &istatus);
409  
410 +                for(int j = 0; j < nCurObj; j++) {
411 +                    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
412  
413 <  // get the velocities
413 >                    if (eof_test == NULL) {
414 >                        sprintf(painCave.errMsg,
415 >                                "DumpReader Error: error in reading file %s\n"
416 >                                    "natoms  = %d; index = %d\n"
417 >                                    "error reading the line from the file.\n",
418 >                                filename_.c_str(),
419 >                                nTotObjs,
420 >                                i);
421  
422 <  foo = strtok(NULL, " ,;\t");
423 <  if(foo == NULL){
424 <    sprintf( painCave.errMsg,
425 <             "error in reading velocity x from %s\n",
426 <             inFileName.c_str() );
427 <    return strdup( painCave.errMsg );
428 <  }
429 <  vel[0] = atof( foo );
422 >                        painCave.isFatal = 1;
423 >                        simError();
424 >                    }
425 >                    
426 >                    MPI_Send(read_buffer, maxBufferSize, MPI_CHAR, which_node,
427 >                             TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
428 >                }
429 >            }
430 >        }
431 >    } else {
432 >        //actions taken at slave nodes
433 >        MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
434  
435 <  foo = strtok(NULL, " ,;\t");
436 <  if(foo == NULL){
517 <    sprintf( painCave.errMsg,
518 <             "error in reading velocity x from %s\n",
519 <             inFileName.c_str() );
520 <    return strdup( painCave.errMsg );
521 <  }
522 <  vel[1] = atof( foo );
435 >        /**@todo*/
436 >        parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
437  
438 <  foo = strtok(NULL, " ,;\t");
439 <  if(foo == NULL){
526 <    sprintf( painCave.errMsg,
527 <             "error in reading velocity x from %s\n",
528 <             inFileName.c_str() );
529 <    return strdup( painCave.errMsg );
530 <  }
531 <  vel[2] = atof( foo );
438 >        for(i = 0; i < info_->getNGlobalMolecules(); i++) {
439 >            int which_node = info_->getMolToProc(i);
440  
441 +            if (which_node == worldRank) {
442 +                //molecule with global index i belongs to this processor
443 +                
444 +                mol = info_->getMoleculeByGlobalIndex(i);
445 +                if (mol == NULL) {
446 +                    sprintf(painCave.errMsg, "DumpReader Error: Molecule not found on node %d!", worldRank);
447 +                    painCave.isFatal = 1;
448 +                    simError();
449 +                }
450 +                
451 +                nCurObj = mol->getNIntegrableObjects();
452  
453 <  // add the positions and velocities to the atom
453 >                MPI_Send(&nCurObj, 1, MPI_INT, masterNode, TAKE_THIS_TAG_INT,
454 >                         MPI_COMM_WORLD);
455  
456 <  sd->setPos( pos );
457 <  sd->setVel( vel );
456 >                for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
457 >                       integrableObject = mol->nextIntegrableObject(ii)){
458 >                        
459 >                    MPI_Recv(read_buffer, maxBufferSize, MPI_CHAR, masterNode,
460 >                             TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
461  
462 <  if (!sd->isDirectional())
463 <    return NULL;
462 >                    parseDumpLine(read_buffer, integrableObject);
463 >                }
464 >                      
465 >            }
466 >            
467 >        }
468 >        
469 >    }
470  
471 <  // get the quaternions
471 > #endif
472  
473 <  if( sd->isDirectional() ){
473 > }
474  
475 <    foo = strtok(NULL, " ,;\t");
547 <    if(foo == NULL){
548 <      sprintf( painCave.errMsg,
549 <                     "error in reading velocity x from %s\n",
550 <                      inFileName.c_str() );
551 <      return strdup( painCave.errMsg );
552 <    }
553 <    q[0] = atof( foo );
475 > void DumpReader::parseDumpLine(char *line, StuntDouble *integrableObject) {
476  
477 <    foo = strtok(NULL, " ,;\t");
478 <    if(foo == NULL){
479 <      sprintf( painCave.errMsg,
480 <                     "error in reading velocity x from %s\n",
481 <                      inFileName.c_str() );
482 <      return strdup( painCave.errMsg );
483 <    }
484 <    q[1] = atof( foo );
477 >    Vector3d pos;  // position place holders
478 >    Vector3d vel;  // velocity placeholders
479 >    Quat4d q;    // the quaternions
480 >    Vector3d ji;   // angular velocity placeholders;
481 >    StringTokenizer tokenizer(line);
482 >    int nTokens;
483 >    
484 >    nTokens = tokenizer.countTokens();
485  
486 <    foo = strtok(NULL, " ,;\t");
487 <    if(foo == NULL){
488 <      sprintf( painCave.errMsg,
489 <                     "error in reading velocity x from %s\n",
490 <                      inFileName.c_str() );
569 <      return strdup( painCave.errMsg );
486 >    if (nTokens < 14) {
487 >            sprintf(painCave.errMsg,
488 >                    "DumpReader Error: Not enough Tokens.\n");
489 >            painCave.isFatal = 1;
490 >            simError();
491      }
571    q[2] = atof( foo );
492  
493 <    foo = strtok(NULL, " ,;\t");
574 <    if(foo == NULL){
575 <      sprintf( painCave.errMsg,
576 <                     "error in reading velocity x from %s\n",
577 <                      inFileName.c_str() );
578 <      return strdup( painCave.errMsg );
579 <    }
580 <    q[3] = atof( foo );
493 >    std::string name = tokenizer.nextToken();
494  
495 <    // get the angular velocities
495 >    if (name != integrableObject->getType()) {
496  
497 <    foo = strtok(NULL, " ,;\t");
498 <    if(foo == NULL){
499 <      sprintf( painCave.errMsg,
500 <                     "error in reading velocity x from %s\n",
501 <                      inFileName.c_str() );
589 <      return strdup( painCave.errMsg );
497 >            sprintf(painCave.errMsg,
498 >                    "DumpReader Error: Atom type [%s] in %s does not match Atom Type [%s] in .md file.\n",
499 >                    name.c_str(), filename_.c_str(), integrableObject->getType().c_str());
500 >            painCave.isFatal = 1;
501 >            simError();        
502      }
591    ji[0] = atof( foo );
503  
504 <    foo = strtok(NULL, " ,;\t");
505 <    if(foo == NULL){
506 <      sprintf( painCave.errMsg,
507 <                     "error in reading velocity x from %s\n",
508 <                      inFileName.c_str() );
509 <      return strdup( painCave.errMsg );
510 <    }
511 <    ji[1] = atof(foo );
504 >    pos[0] = tokenizer.nextTokenAsDouble();
505 >    pos[1] = tokenizer.nextTokenAsDouble();
506 >    pos[2] = tokenizer.nextTokenAsDouble();
507 >    integrableObject->setPos(pos);
508 >    
509 >    vel[0] = tokenizer.nextTokenAsDouble();
510 >    vel[1] = tokenizer.nextTokenAsDouble();
511 >    vel[2] = tokenizer.nextTokenAsDouble();
512 >    integrableObject->setVel(vel);
513  
514 <    foo = strtok(NULL, " ,;\t");
515 <    if(foo == NULL){
516 <      sprintf( painCave.errMsg,
517 <                     "error in reading velocity x from %s\n",
518 <                      inFileName.c_str() );
519 <      return strdup( painCave.errMsg );
608 <    }
609 <    ji[2] = atof( foo );
514 >    if (integrableObject->isDirectional()) {
515 >        
516 >        q[0] = tokenizer.nextTokenAsDouble();
517 >        q[1] = tokenizer.nextTokenAsDouble();
518 >        q[2] = tokenizer.nextTokenAsDouble();
519 >        q[3] = tokenizer.nextTokenAsDouble();
520  
521 +        double qlen = q.length();
522 +        if (qlen < oopse::epsilon) { //check quaternion is not equal to 0
523 +            
524 +            sprintf(painCave.errMsg,
525 +                    "DumpReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2 ~ 0).\n");
526 +            painCave.isFatal = 1;
527 +            simError();
528 +            
529 +        }
530  
531 <    // check that the quaternion vector is normalized
532 <
533 <    qSqr = (q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]);
534 <
535 <    if (fabs(qSqr) < 1e-6) {
536 <      sprintf(painCave.errMsg,
537 <          "initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2 ~ 0).\n");
538 <       return strdup(painCave.errMsg);
531 >        q.normalize();
532 >              
533 >        integrableObject->setQ(q);
534 >        
535 >        ji[0] = tokenizer.nextTokenAsDouble();
536 >        ji[1] = tokenizer.nextTokenAsDouble();
537 >        ji[2] = tokenizer.nextTokenAsDouble();
538 >        integrableObject->setJ(ji);
539      }
540  
622    qLength = sqrt( qSqr );
623    q[0] = q[0] / qLength;
624    q[1] = q[1] / qLength;
625    q[2] = q[2] / qLength;
626    q[3] = q[3] / qLength;
627
628    // add quaternion and angular velocities
629
630    sd->setQ( q );
631    sd->setJ( ji );
632  }
633
634
635
636  return NULL;
541   }
542  
543  
544 < char* DumpReader::parseCommentLine(char* readLine, SimInfo* entry_plug){
544 > void DumpReader::parseCommentLine(char* line, Snapshot* s) {
545 >    double currTime;
546 >    Mat3x3d hmat;
547 >    double chi;
548 >    double integralOfChiDt;
549 >    Mat3x3d eta;
550  
551 <  double currTime;
552 <  double boxMat[9];
644 <  double theBoxMat3[3][3];
645 <  double chi;
646 <  double integralOfChidt;
647 <  double eta[9];
551 >    StringTokenizer tokenizer(line);
552 >    int nTokens;
553  
554 <  char *foo; // the pointer to the current string token
554 >    nTokens = tokenizer.countTokens();
555  
556 <  // set the string tokenizer
557 <
558 <  foo = strtok(readLine, " ,;\t");
559 <  // set the timeToken.
560 <
561 <  if(foo == NULL){
657 <    sprintf( painCave.errMsg,
658 <             "error in reading Time from %s\n",
659 <             inFileName.c_str() );
660 <    return strdup( painCave.errMsg );
661 <  }
662 <
663 <  currTime = atof( foo );
664 <  entry_plug->setTime( currTime );
665 <
666 <  //get H-Matrix
667 <
668 <  for(int i = 0 ; i < 9; i++){
669 <    foo = strtok(NULL, " ,;\t");
670 <    if(foo == NULL){
671 <      sprintf( painCave.errMsg,
672 <               "error in reading H[%d] from %s\n", i, inFileName.c_str() );
673 <      return strdup( painCave.errMsg );
556 >    //comment line should at least contain 10 tokens: current time(1 token) and  h-matrix(9 tokens)
557 >    if (nTokens < 10) {
558 >            sprintf(painCave.errMsg,
559 >                    "DumpReader Error: Not enough tokens in comment line: %s", line);
560 >            painCave.isFatal = 1;
561 >            simError();  
562      }
675    boxMat[i] = atof( foo );
676  }
563  
564 <  for(int i=0;i<3;i++)
565 <    for(int j=0;j<3;j++) theBoxMat3[i][j] = boxMat[3*j+i];
564 >    //read current time
565 >    currTime = tokenizer.nextTokenAsDouble();
566 >    s->setTime(currTime);
567 >    
568 >    //read h-matrix
569 >    hmat(0, 0) = tokenizer.nextTokenAsDouble();
570 >    hmat(0, 1) = tokenizer.nextTokenAsDouble();
571 >    hmat(0, 2) = tokenizer.nextTokenAsDouble();
572 >    hmat(1, 0) = tokenizer.nextTokenAsDouble();
573 >    hmat(1, 1) = tokenizer.nextTokenAsDouble();
574 >    hmat(1, 2) = tokenizer.nextTokenAsDouble();
575 >    hmat(2, 0) = tokenizer.nextTokenAsDouble();
576 >    hmat(2, 1) = tokenizer.nextTokenAsDouble();
577 >    hmat(2, 2) = tokenizer.nextTokenAsDouble();
578 >    s->setHmat(hmat);
579 >    
580 >    //read chi and integrablOfChidt, they should apprear in pair
581 >    if (tokenizer.countTokens() >= 2) {
582 >        chi = tokenizer.nextTokenAsDouble();
583 >        integralOfChiDt = tokenizer.nextTokenAsDouble();            
584  
585 <  //set H-Matrix
586 <  entry_plug->setBoxM( theBoxMat3 );
683 <
684 <  //get chi and integralOfChidt, they should appear by pair
685 <
686 <  if( entry_plug->useInitXSstate ){
687 <    foo = strtok(NULL, " ,;\t\n");
688 <    if(foo != NULL){
689 <      chi = atof(foo);
690 <      
691 <      foo = strtok(NULL, " ,;\t\n");
692 <      if(foo == NULL){
693 <        sprintf( painCave.errMsg,
694 <                 "chi and integralOfChidt should appear by pair in %s\n", inFileName.c_str() );
695 <        return strdup( painCave.errMsg );
696 <      }
697 <      integralOfChidt = atof( foo );
698 <      
699 <      //push chi and integralOfChidt into SimInfo::properties which can be
700 <      //retrieved by integrator later
701 <      DoubleData* chiValue = new DoubleData();
702 <      chiValue->setID(CHIVALUE_ID);
703 <      chiValue->setData(chi);
704 <      entry_plug->addProperty(chiValue);
705 <      
706 <      DoubleData* integralOfChidtValue = new DoubleData();
707 <      integralOfChidtValue->setID(INTEGRALOFCHIDT_ID);
708 <      integralOfChidtValue->setData(integralOfChidt);
709 <      entry_plug->addProperty(integralOfChidtValue);
710 <      
585 >        s->setChi(chi);
586 >        s->setIntegralOfChiDt(integralOfChiDt);
587      }
712    else
713      return NULL;
588      
589 <    //get eta
590 <    foo = strtok(NULL, " ,;\t\n");
591 <    if(foo != NULL ){
592 <  
593 <      for(int i = 0 ; i < 9; i++){
594 <        
595 <        if(foo == NULL){
596 <          sprintf( painCave.errMsg,
597 <                   "error in reading eta[%d] from %s\n", i, inFileName.c_str() );
598 <          return strdup( painCave.errMsg );
599 <        }
600 <        eta[i] = atof( foo );
601 <        foo = strtok(NULL, " ,;\t\n");
728 <      }
589 >    //read eta (eta is 3x3 matrix)
590 >    if (tokenizer.countTokens() >= 9) {
591 >        eta(0, 0) = tokenizer.nextTokenAsDouble();
592 >        eta(0, 1) = tokenizer.nextTokenAsDouble();
593 >        eta(0, 2) = tokenizer.nextTokenAsDouble();
594 >        eta(1, 0) = tokenizer.nextTokenAsDouble();
595 >        eta(1, 1) = tokenizer.nextTokenAsDouble();
596 >        eta(1, 2) = tokenizer.nextTokenAsDouble();
597 >        eta(2, 0) = tokenizer.nextTokenAsDouble();
598 >        eta(2, 1) = tokenizer.nextTokenAsDouble();
599 >        eta(2, 2) = tokenizer.nextTokenAsDouble();      
600 >
601 >        s->setEta(eta);
602      }
730    else
731      return NULL;
732    
733    //push eta into SimInfo::properties which can be
734    //retrieved by integrator later
735    //entry_plug->setBoxM( theBoxMat3 );
736    DoubleArrayData* etaValue = new DoubleArrayData();
737    etaValue->setID(ETAVALUE_ID);
738    etaValue->setData(eta, 9);
739    entry_plug->addProperty(etaValue);
740  }
603  
604 <  return NULL;
604 >    
605   }
606  
607 < #ifdef IS_MPI
746 < void DumpReader::nodeZeroError( void ){
747 <  int j, myStatus;
748 <
749 <  myStatus = 0;
750 <  for (j = 0; j < mpiSim->getNProcessors(); j++) {
751 <    MPI_Send( &myStatus, 1, MPI_INT, j,
752 <              TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
753 <  }
754 <
755 <
756 <  MPI_Finalize();
757 <  exit (0);
758 <
759 < }
760 <
761 < void DumpReader::anonymousNodeDie( void ){
762 <
763 <  MPI_Finalize();
764 <  exit (0);
765 < }
766 < #endif
607 > }//end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines