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 1490 by gezelter, Fri Sep 24 04:16:43 2004 UTC vs.
Revision 2065 by tim, Tue Mar 1 14:45:45 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 + #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  
15 #include "ReadWrite.hpp"
16 #include "simError.h"
17
61   #ifdef IS_MPI
62 +
63   #include <mpi.h>
20 #include "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 >    int storageLayout = info_->getSnapshotManager()->getStorageLayout();
223  
224 <  fsetpos(inFile, framePos[whichFrame]);
225 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
226 <  if( eof_test == NULL ){
227 <    sprintf( painCave.errMsg,
228 <             "DumpReader error: error reading 1st line of \"%s\"\n",
198 <             inFileName.c_str() );
199 <    painCave.isFatal = 1;
200 <    simError();
201 <  }
224 >    if (storageLayout & DataStorage::dslPosition) {
225 >        needPos_ = true;
226 >    } else {
227 >        needPos_ = false;
228 >    }
229  
230 <  nTotObjs = atoi( read_buffer );
230 >    if (storageLayout & DataStorage::dslVelocity) {
231 >        needVel_ = true;
232 >    } else {
233 >        needVel_ = false;
234 >    }
235  
236 <  if( nTotObjs != simnfo->getTotIntegrableObjects() ){
237 <    sprintf( painCave.errMsg,
238 <             "DumpReader error. %s nIntegrable, %d, "
239 <             "does not match the meta-data file's nIntegrable, %d.\n",
240 <             inFileName.c_str(), nTotObjs, simnfo->getTotIntegrableObjects());
210 <    painCave.isFatal = 1;
211 <    simError();
212 <  }
236 >    if (storageLayout & DataStorage::dslAmat || storageLayout & DataStorage::dslElectroFrame) {
237 >        needQuaternion_ = true;
238 >    } else {
239 >        needQuaternion_ = false;
240 >    }
241  
242 <  //read the box mat from the comment line
242 >    if (storageLayout & DataStorage::dslAngularMomentum) {
243 >        needAngMom_ = true;
244 >    } else {
245 >        needAngMom_ = false;    
246 >    }
247  
248 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
249 <  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 <  }
248 >    readSet(whichFrame);
249 > }
250  
251 <  parseErr = parseCommentLine( read_buffer, simnfo);
252 <  if( parseErr != NULL ){
253 <    strcpy( painCave.errMsg, parseErr );
254 <    painCave.isFatal = 1;
255 <    simError();
229 <  }
251 > void DumpReader::readSet(int whichFrame) {
252 >  int i;
253 >  int nTotObjs;                  // the number of atoms
254 >  char read_buffer[maxBufferSize];  //the line buffer for reading
255 >  char * eof_test;               // ptr to see when we reach the end of the file
256  
257 <  //parse dump lines
257 >  Molecule* mol;
258 >  StuntDouble* integrableObject;
259 >  SimInfo::MoleculeIterator mi;
260 >  Molecule::IntegrableObjectIterator ii;
261  
262 <  for( i=0; i < simnfo->n_mol; i++){
262 > #ifndef IS_MPI
263  
264 <    integrableObjects = (simnfo->molecules[i]).getIntegrableObjects();
264 >    fsetpos(inFile_, framePos_[whichFrame]);
265 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
266  
267 <    for(j = 0; j < integrableObjects.size(); j++){
238 <
239 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
240 <      if(eof_test == NULL){
267 >    if (eof_test == NULL) {
268          sprintf(painCave.errMsg,
269 <              "error in reading file %s\n"
270 <              "natoms  = %d; index = %d\n"
244 <              "error reading the line from the file.\n",
245 <              inFileName.c_str(), nTotObjs, i );
269 >                "DumpReader error: error reading 1st line of \"%s\"\n",
270 >                filename_.c_str());
271          painCave.isFatal = 1;
272          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      }
273      }
257  }
274  
275 <  // MPI Section of code..........
260 < #else //IS_MPI
275 >    nTotObjs = atoi(read_buffer);
276  
277 <  // first thing first, suspend fatalities.
278 <  painCave.isEventLoop = 1;
277 >    if (nTotObjs != info_->getNGlobalIntegrableObjects()) {
278 >        sprintf(painCave.errMsg,
279 >                "DumpReader error. %s nIntegrable, %d, "
280 >                    "does not match the meta-data file's nIntegrable, %d.\n",
281 >                filename_.c_str(),
282 >                nTotObjs,
283 >                info_->getNGlobalIntegrableObjects());
284  
285 <  int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
286 <  int haveError;
285 >        painCave.isFatal = 1;
286 >        simError();
287 >    }
288  
289 <  MPI_Status istatus;
269 <  int *MolToProcMap = mpiSim->getMolToProcMap();
270 <  int localIndex;
271 <  int nCurObj;
272 <  int nitems;
289 >    //read the box mat from the comment line
290  
291 <  nTotObjs = simnfo->getTotIntegrableObjects();
275 <  haveError = 0;
276 <  if (worldRank == 0) {
277 <     fsetpos(inFile,  framePos[whichFrame]);
291 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
292  
293 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
294 <    if( eof_test == NULL ){
295 <      sprintf( painCave.errMsg,
296 <               "Error reading 1st line of %s \n ",inFileName.c_str());
297 <      haveError = 1;
284 <      simError();
293 >    if (eof_test == NULL) {
294 >        sprintf(painCave.errMsg, "DumpReader Error: error in reading commment in %s\n",
295 >                filename_.c_str());
296 >        painCave.isFatal = 1;
297 >        simError();
298      }
299  
300 <    nitems = atoi( read_buffer );
300 >    parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
301  
302 <    // 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.
302 >    //parse dump lines
303  
304 <    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 <    }
304 >    for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
305  
306 <    //read the boxMat from the comment line
306 >        for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
307 >            integrableObject = mol->nextIntegrableObject(ii)) {          
308  
309 <    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 <    }
309 >            eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
310  
311 <    //Every single processor will parse the comment line by itself
312 <    //By using this way, we might lose some efficiency, but if we want to add
313 <    //more parameters into comment line, we only need to modify function
314 <    //parseCommentLine
311 >            if (eof_test == NULL) {
312 >                sprintf(painCave.errMsg,
313 >                        "DumpReader Error: error in reading file %s\n"
314 >                            "natoms  = %d; index = %d\n"
315 >                            "error reading the line from the file.\n",
316 >                        filename_.c_str(),
317 >                        nTotObjs,
318 >                        i);
319  
320 <    MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
320 >                painCave.isFatal = 1;
321 >                simError();
322 >            }
323  
324 <    parseErr = parseCommentLine( read_buffer, simnfo);
325 <
326 <    if( parseErr != NULL ){
322 <      strcpy( painCave.errMsg, parseErr );
323 <      haveError = 1;
324 <      simError();
324 >            parseDumpLine(read_buffer, integrableObject);
325 >            
326 >            }
327      }
328  
329 <    for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
328 <      which_node = MolToProcMap[i];
329 <      if(which_node == 0){
330 <       //molecules belong to master node
329 >    // MPI Section of code..........
330  
331 <      localIndex = mpiSim->getGlobalToLocalMol(i);
331 > #else //IS_MPI
332  
333 <      if(localIndex == -1) {
334 <        strcpy(painCave.errMsg, "Molecule not found on node 0!");
335 <        haveError = 1;
336 <        simError();
338 <      }
333 >    // first thing first, suspend fatalities.
334 >    int masterNode = 0;
335 >    int nCurObj;
336 >    painCave.isEventLoop = 1;
337  
338 <       integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
339 <       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();
338 >    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
339 >    int haveError;
340  
341 <          parseDumpLine(read_buffer, integrableObjects[j]);
342 <          
358 <       }
341 >    MPI_Status istatus;
342 >    int nitems;
343  
344 +    nTotObjs = info_->getNGlobalIntegrableObjects();
345 +    haveError = 0;
346  
347 <      }
348 <      else{
363 <      //molecule belongs to slave nodes
347 >    if (worldRank == masterNode) {
348 >        fsetpos(inFile_, framePos_[whichFrame]);
349  
350 <        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();
350 >        eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
351  
352 <            MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
353 <                      TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
354 <          
355 <       }
352 >        if (eof_test == NULL) {
353 >            sprintf(painCave.errMsg, "DumpReader Error: Error reading 1st line of %s \n ",
354 >                    filename_.c_str());
355 >            painCave.isFatal = 1;
356 >            simError();
357 >        }
358  
359 <      }
389 <      
390 <    }
391 <    
392 <  }
393 <  else{
394 <  //actions taken at slave nodes
395 <    MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
359 >        nitems = atoi(read_buffer);
360  
361 <    parseErr = parseCommentLine( read_buffer, simnfo);
361 >        // Check to see that the number of integrable objects in the
362 >        // intial configuration file is the same as derived from the
363 >        // meta-data file.
364  
365 <    if( parseErr != NULL ){
366 <      strcpy( painCave.errMsg, parseErr );
367 <      haveError = 1;
368 <      simError();
369 <    }
370 <  
371 <    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);
365 >        if (nTotObjs != nitems) {
366 >            sprintf(painCave.errMsg,
367 >                    "DumpReader Error. %s nIntegrable, %d, "
368 >                        "does not match the meta-data file's nIntegrable, %d.\n",
369 >                    filename_.c_str(),
370 >                    nTotObjs,
371 >                    info_->getNGlobalIntegrableObjects());
372  
373 <        if(localIndex == -1) {
374 <          sprintf(painCave.errMsg, "Molecule not found on node %d\n", worldRank);
415 <          haveError = 1;
416 <          simError();
373 >            painCave.isFatal = 1;
374 >            simError();
375          }
376  
377 <        integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();        
377 >        //read the boxMat from the comment line
378  
379 <        nCurObj = integrableObjects.size();
422 <        
423 <        MPI_Send(&nCurObj, 1, MPI_INT, 0,
424 <                        TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
379 >        eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
380  
381 <        for(j = 0; j < integrableObjects.size(); j++){
382 <
383 <          MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
384 <                              TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
385 <
431 <          parseErr = parseDumpLine(read_buffer, integrableObjects[j]);
432 <
433 <          if( parseErr != NULL ){
434 <                strcpy( painCave.errMsg, parseErr );
435 <                simError();
436 <          }
437 <
381 >        if (eof_test == NULL) {
382 >            sprintf(painCave.errMsg, "DumpReader Error: error in reading commment in %s\n",
383 >                    filename_.c_str());
384 >            painCave.isFatal = 1;
385 >            simError();
386          }
439          
440      }
441      
442    }
387  
388 <  }
388 >        //Every single processor will parse the comment line by itself
389 >        //By using this way, we might lose some efficiency, but if we want to add
390 >        //more parameters into comment line, we only need to modify function
391 >        //parseCommentLine
392  
393 < #endif
394 < }
393 >        MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
394 >        parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
395  
396 < char* DumpReader::parseDumpLine(char* readLine, StuntDouble* sd){
396 >        for(i = 0; i < info_->getNGlobalMolecules(); i++) {
397 >            int which_node = info_->getMolToProc(i);
398  
399 <  char *foo; // the pointer to the current string token
399 >            if (which_node == masterNode) {
400 >                //molecules belong to master node
401  
402 <  double pos[3]; // position place holders
454 <  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.
402 >                mol = info_->getMoleculeByGlobalIndex(i);
403  
404 +                if (mol == NULL) {
405 +                    sprintf(painCave.errMsg, "DumpReader Error: Molecule not found on node %d!", worldRank);
406 +                        painCave.isFatal = 1;
407 +                    simError();
408 +                }
409  
410 <  // set the string tokenizer
410 >                for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
411 >                       integrableObject = mol->nextIntegrableObject(ii)){
412 >                        
413 >                    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
414  
415 <  foo = strtok(readLine, " ,;\t");
415 >                    if (eof_test == NULL) {
416 >                        sprintf(painCave.errMsg,
417 >                                "DumpReader Error: error in reading file %s\n"
418 >                                    "natoms  = %d; index = %d\n"
419 >                                    "error reading the line from the file.\n",
420 >                                filename_.c_str(),
421 >                                nTotObjs,
422 >                                i);
423  
424 <  // check the atom name to the current atom
424 >                        painCave.isFatal = 1;
425 >                        simError();
426 >                    }
427  
428 <  if( strcmp( foo, sd->getType() ) ){
429 <    sprintf( painCave.errMsg,
430 <             "DumpReader error.  Does not"
431 <             " match the meta-data atom %s.\n",
470 <             sd->getType() );
471 <    return strdup( painCave.errMsg );
472 <  }
428 >                    parseDumpLine(read_buffer, integrableObject);
429 >                }
430 >            } else {
431 >                //molecule belongs to slave nodes
432  
433 <  // get the positions
433 >                MPI_Recv(&nCurObj, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT,
434 >                         MPI_COMM_WORLD, &istatus);
435  
436 <  foo = strtok(NULL, " ,;\t");
437 <  if(foo == NULL){
478 <    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 );
436 >                for(int j = 0; j < nCurObj; j++) {
437 >                    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
438  
439 <  foo = strtok(NULL, " ,;\t");
440 <  if(foo == NULL){
441 <    sprintf( painCave.errMsg,
442 <             "error in reading postition y from %s\n",
443 <             inFileName.c_str());
444 <    return strdup( painCave.errMsg );
445 <  }
446 <  pos[1] = atof( foo );
439 >                    if (eof_test == NULL) {
440 >                        sprintf(painCave.errMsg,
441 >                                "DumpReader Error: error in reading file %s\n"
442 >                                    "natoms  = %d; index = %d\n"
443 >                                    "error reading the line from the file.\n",
444 >                                filename_.c_str(),
445 >                                nTotObjs,
446 >                                i);
447  
448 <  foo = strtok(NULL, " ,;\t");
449 <  if(foo == NULL){
450 <    sprintf( painCave.errMsg,
451 <             "error in reading postition z from %s\n",
452 <             inFileName.c_str());
453 <    return strdup( painCave.errMsg );
454 <  }
455 <  pos[2] = atof( foo );
448 >                        painCave.isFatal = 1;
449 >                        simError();
450 >                    }
451 >                    
452 >                    MPI_Send(read_buffer, maxBufferSize, MPI_CHAR, which_node,
453 >                             TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
454 >                }
455 >            }
456 >        }
457 >    } else {
458 >        //actions taken at slave nodes
459 >        MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
460  
461 +        /**@todo*/
462 +        parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
463  
464 <  // get the velocities
464 >        for(i = 0; i < info_->getNGlobalMolecules(); i++) {
465 >            int which_node = info_->getMolToProc(i);
466  
467 <  foo = strtok(NULL, " ,;\t");
468 <  if(foo == NULL){
469 <    sprintf( painCave.errMsg,
470 <             "error in reading velocity x from %s\n",
471 <             inFileName.c_str() );
472 <    return strdup( painCave.errMsg );
473 <  }
474 <  vel[0] = atof( foo );
467 >            if (which_node == worldRank) {
468 >                //molecule with global index i belongs to this processor
469 >                
470 >                mol = info_->getMoleculeByGlobalIndex(i);
471 >                if (mol == NULL) {
472 >                    sprintf(painCave.errMsg, "DumpReader Error: Molecule not found on node %d!", worldRank);
473 >                    painCave.isFatal = 1;
474 >                    simError();
475 >                }
476 >                
477 >                nCurObj = mol->getNIntegrableObjects();
478  
479 <  foo = strtok(NULL, " ,;\t");
480 <  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 );
479 >                MPI_Send(&nCurObj, 1, MPI_INT, masterNode, TAKE_THIS_TAG_INT,
480 >                         MPI_COMM_WORLD);
481  
482 <  foo = strtok(NULL, " ,;\t");
483 <  if(foo == NULL){
484 <    sprintf( painCave.errMsg,
485 <             "error in reading velocity x from %s\n",
486 <             inFileName.c_str() );
529 <    return strdup( painCave.errMsg );
530 <  }
531 <  vel[2] = atof( foo );
482 >                for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
483 >                       integrableObject = mol->nextIntegrableObject(ii)){
484 >                        
485 >                    MPI_Recv(read_buffer, maxBufferSize, MPI_CHAR, masterNode,
486 >                             TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
487  
488 +                    parseDumpLine(read_buffer, integrableObject);
489 +                }
490 +                      
491 +            }
492 +            
493 +        }
494 +        
495 +    }
496  
497 <  // add the positions and velocities to the atom
497 > #endif
498  
499 <  sd->setPos( pos );
537 <  sd->setVel( vel );
499 > }
500  
501 <  if (!sd->isDirectional())
540 <    return NULL;
501 > void DumpReader::parseDumpLine(char *line, StuntDouble *integrableObject) {
502  
503 <  // get the quaternions
503 >    Vector3d pos;  // position place holders
504 >    Vector3d vel;  // velocity placeholders
505 >    Quat4d q;    // the quaternions
506 >    Vector3d ji;   // angular velocity placeholders;
507 >    StringTokenizer tokenizer(line);
508 >    int nTokens;
509 >    
510 >    nTokens = tokenizer.countTokens();
511  
512 <  if( sd->isDirectional() ){
513 <
514 <    foo = strtok(NULL, " ,;\t");
515 <    if(foo == NULL){
516 <      sprintf( painCave.errMsg,
549 <                     "error in reading velocity x from %s\n",
550 <                      inFileName.c_str() );
551 <      return strdup( painCave.errMsg );
512 >    if (nTokens < 14) {
513 >            sprintf(painCave.errMsg,
514 >                    "DumpReader Error: Not enough Tokens.\n%s\n", line);
515 >            painCave.isFatal = 1;
516 >            simError();
517      }
553    q[0] = atof( foo );
518  
519 <    foo = strtok(NULL, " ,;\t");
556 <    if(foo == NULL){
557 <      sprintf( painCave.errMsg,
558 <                     "error in reading velocity x from %s\n",
559 <                      inFileName.c_str() );
560 <      return strdup( painCave.errMsg );
561 <    }
562 <    q[1] = atof( foo );
519 >    std::string name = tokenizer.nextToken();
520  
521 <    foo = strtok(NULL, " ,;\t");
565 <    if(foo == NULL){
566 <      sprintf( painCave.errMsg,
567 <                     "error in reading velocity x from %s\n",
568 <                      inFileName.c_str() );
569 <      return strdup( painCave.errMsg );
570 <    }
571 <    q[2] = atof( foo );
521 >    if (name != integrableObject->getType()) {
522  
523 <    foo = strtok(NULL, " ,;\t");
524 <    if(foo == NULL){
525 <      sprintf( painCave.errMsg,
526 <                     "error in reading velocity x from %s\n",
527 <                      inFileName.c_str() );
578 <      return strdup( painCave.errMsg );
523 >            sprintf(painCave.errMsg,
524 >                    "DumpReader Error: Atom type [%s] in %s does not match Atom Type [%s] in .md file.\n",
525 >                    name.c_str(), filename_.c_str(), integrableObject->getType().c_str());
526 >            painCave.isFatal = 1;
527 >            simError();        
528      }
580    q[3] = atof( foo );
529  
530 <    // get the angular velocities
531 <
532 <    foo = strtok(NULL, " ,;\t");
533 <    if(foo == NULL){
534 <      sprintf( painCave.errMsg,
587 <                     "error in reading velocity x from %s\n",
588 <                      inFileName.c_str() );
589 <      return strdup( painCave.errMsg );
530 >    pos[0] = tokenizer.nextTokenAsDouble();
531 >    pos[1] = tokenizer.nextTokenAsDouble();
532 >    pos[2] = tokenizer.nextTokenAsDouble();
533 >    if (needPos_) {
534 >        integrableObject->setPos(pos);
535      }
536 <    ji[0] = atof( foo );
537 <
538 <    foo = strtok(NULL, " ,;\t");
539 <    if(foo == NULL){
540 <      sprintf( painCave.errMsg,
541 <                     "error in reading velocity x from %s\n",
597 <                      inFileName.c_str() );
598 <      return strdup( painCave.errMsg );
536 >    
537 >    vel[0] = tokenizer.nextTokenAsDouble();
538 >    vel[1] = tokenizer.nextTokenAsDouble();
539 >    vel[2] = tokenizer.nextTokenAsDouble();
540 >    if (needVel_) {
541 >        integrableObject->setVel(vel);
542      }
543 <    ji[1] = atof(foo );
543 >    
544 >    if (integrableObject->isDirectional()) {
545 >        
546 >        q[0] = tokenizer.nextTokenAsDouble();
547 >        q[1] = tokenizer.nextTokenAsDouble();
548 >        q[2] = tokenizer.nextTokenAsDouble();
549 >        q[3] = tokenizer.nextTokenAsDouble();
550  
551 <    foo = strtok(NULL, " ,;\t");
552 <    if(foo == NULL){
553 <      sprintf( painCave.errMsg,
554 <                     "error in reading velocity x from %s\n",
555 <                      inFileName.c_str() );
556 <      return strdup( painCave.errMsg );
557 <    }
558 <    ji[2] = atof( foo );
551 >        double qlen = q.length();
552 >        if (qlen < oopse::epsilon) { //check quaternion is not equal to 0
553 >            
554 >            sprintf(painCave.errMsg,
555 >                    "DumpReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2 ~ 0).\n");
556 >            painCave.isFatal = 1;
557 >            simError();
558 >            
559 >        }
560  
561 +        q.normalize();
562 +        if (needQuaternion_) {          
563 +            integrableObject->setQ(q);
564 +        }
565  
566 <    // check that the quaternion vector is normalized
567 <
568 <    qSqr = (q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]);
569 <
570 <    if (fabs(qSqr) < 1e-6) {
571 <      sprintf(painCave.errMsg,
618 <          "initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2 ~ 0).\n");
619 <       return strdup(painCave.errMsg);
566 >        ji[0] = tokenizer.nextTokenAsDouble();
567 >        ji[1] = tokenizer.nextTokenAsDouble();
568 >        ji[2] = tokenizer.nextTokenAsDouble();
569 >        if (needAngMom_) {
570 >            integrableObject->setJ(ji);
571 >        }
572      }
573  
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;
574   }
575  
576  
577 < char* DumpReader::parseCommentLine(char* readLine, SimInfo* entry_plug){
577 > void DumpReader::parseCommentLine(char* line, Snapshot* s) {
578 >    double currTime;
579 >    Mat3x3d hmat;
580 >    double chi;
581 >    double integralOfChiDt;
582 >    Mat3x3d eta;
583  
584 <  double currTime;
585 <  double boxMat[9];
644 <  double theBoxMat3[3][3];
645 <  double chi;
646 <  double integralOfChidt;
647 <  double eta[9];
584 >    StringTokenizer tokenizer(line);
585 >    int nTokens;
586  
587 <  char *foo; // the pointer to the current string token
587 >    nTokens = tokenizer.countTokens();
588  
589 <  // set the string tokenizer
590 <
591 <  foo = strtok(readLine, " ,;\t");
592 <  // set the timeToken.
593 <
594 <  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 );
589 >    //comment line should at least contain 10 tokens: current time(1 token) and  h-matrix(9 tokens)
590 >    if (nTokens < 10) {
591 >            sprintf(painCave.errMsg,
592 >                    "DumpReader Error: Not enough tokens in comment line: %s", line);
593 >            painCave.isFatal = 1;
594 >            simError();  
595      }
675    boxMat[i] = atof( foo );
676  }
596  
597 <  for(int i=0;i<3;i++)
598 <    for(int j=0;j<3;j++) theBoxMat3[i][j] = boxMat[3*j+i];
597 >    //read current time
598 >    currTime = tokenizer.nextTokenAsDouble();
599 >    s->setTime(currTime);
600 >    
601 >    //read h-matrix
602 >    hmat(0, 0) = tokenizer.nextTokenAsDouble();
603 >    hmat(0, 1) = tokenizer.nextTokenAsDouble();
604 >    hmat(0, 2) = tokenizer.nextTokenAsDouble();
605 >    hmat(1, 0) = tokenizer.nextTokenAsDouble();
606 >    hmat(1, 1) = tokenizer.nextTokenAsDouble();
607 >    hmat(1, 2) = tokenizer.nextTokenAsDouble();
608 >    hmat(2, 0) = tokenizer.nextTokenAsDouble();
609 >    hmat(2, 1) = tokenizer.nextTokenAsDouble();
610 >    hmat(2, 2) = tokenizer.nextTokenAsDouble();
611 >    s->setHmat(hmat);
612 >    
613 >    //read chi and integralOfChidt, they should apprear in pair
614 >    if (tokenizer.countTokens() >= 2) {
615 >        chi = tokenizer.nextTokenAsDouble();
616 >        integralOfChiDt = tokenizer.nextTokenAsDouble();            
617  
618 <  //set H-Matrix
619 <  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 <      
618 >        s->setChi(chi);
619 >        s->setIntegralOfChiDt(integralOfChiDt);
620      }
712    else
713      return NULL;
621      
622 <    //get eta
623 <    foo = strtok(NULL, " ,;\t\n");
624 <    if(foo != NULL ){
625 <  
626 <      for(int i = 0 ; i < 9; i++){
627 <        
628 <        if(foo == NULL){
629 <          sprintf( painCave.errMsg,
630 <                   "error in reading eta[%d] from %s\n", i, inFileName.c_str() );
631 <          return strdup( painCave.errMsg );
632 <        }
633 <        eta[i] = atof( foo );
634 <        foo = strtok(NULL, " ,;\t\n");
728 <      }
622 >    //read eta (eta is 3x3 matrix)
623 >    if (tokenizer.countTokens() >= 9) {
624 >        eta(0, 0) = tokenizer.nextTokenAsDouble();
625 >        eta(0, 1) = tokenizer.nextTokenAsDouble();
626 >        eta(0, 2) = tokenizer.nextTokenAsDouble();
627 >        eta(1, 0) = tokenizer.nextTokenAsDouble();
628 >        eta(1, 1) = tokenizer.nextTokenAsDouble();
629 >        eta(1, 2) = tokenizer.nextTokenAsDouble();
630 >        eta(2, 0) = tokenizer.nextTokenAsDouble();
631 >        eta(2, 1) = tokenizer.nextTokenAsDouble();
632 >        eta(2, 2) = tokenizer.nextTokenAsDouble();      
633 >
634 >        s->setEta(eta);
635      }
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  }
636  
637 <  return NULL;
637 >    
638   }
639  
640 < #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
640 > }//end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines