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

Comparing trunk/OOPSE-3.0/src/io/DumpReader.cpp (file contents):
Revision 1492 by tim, Fri Sep 24 16:27:58 2004 UTC vs.
Revision 2002 by tim, Sun Feb 13 06:57:48 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
31  if (worldRank == 0) {
32 #endif
76  
77 <  inFile = fopen(in_name, "r");
35 <  if(inFile == NULL){
36 <    sprintf(painCave.errMsg,
37 <            "Cannot open file: %s\n", in_name);
38 <    painCave.isFatal = 1;
39 <    simError();
40 <  }
41 <  
42 <  inFileName = in_name;
43 < #ifdef IS_MPI
44 <  }
45 <  strcpy( checkPointMsg, "Dump file opened for reading successfully." );
46 <  MPIcheckPoint();
77 >    if (worldRank == 0) {
78   #endif
48  return;  
49 }
79  
80 < DumpReader :: ~DumpReader( ){
52 < #ifdef IS_MPI
53 <  if (worldRank == 0) {
54 < #endif
55 <  vector<fpos_t*>::iterator i;
80 >        inFile_ = fopen(filename_.c_str(), "r");
81  
82 <  int error;
83 <  error = fclose( inFile );
84 <  if( error ){
85 <    sprintf( painCave.errMsg,
86 <             "Error closing %s\n", inFileName.c_str());
62 <    simError();
63 <  }
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  
65  for(i = framePos.begin(); i != framePos.end(); ++i)
66    delete *i;
67  framePos.clear();
68  
88   #ifdef IS_MPI
89 <  }
90 <  strcpy( checkPointMsg, "Dump file closed successfully." );
91 <  MPIcheckPoint();
89 >
90 >    }
91 >
92 >    strcpy(checkPointMsg, "Dump file opened for reading successfully.");
93 >    MPIcheckPoint();
94 >
95   #endif
96  
97 <  return;
97 >    return;
98   }
99  
100 < int DumpReader::getNframes( void ){
100 > DumpReader::~DumpReader() {
101  
102 <  if( !isScanned )
81 <    scanFile();
82 <  return framePos.size();
83 < }
102 > #ifdef IS_MPI
103  
104 < void DumpReader::scanFile( void ){
104 >    if (worldRank == 0) {
105 > #endif
106  
107 <  int i, j;
108 <  int lineNum = 0;
89 <  char readBuffer[2000];
90 <  fpos_t *currPos;
107 >        int error;
108 >        error = fclose(inFile_);
109  
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 <  if( worldRank == 0 ){
94 < #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();
119 >
120      }
121  
122 <    while( !feof( inFile ) ){
123 <      
113 <      framePos.push_back(currPos);
122 >    strcpy(checkPointMsg, "Dump file closed successfully.");
123 >    MPIcheckPoint();
124  
125 <      i = atoi(readBuffer);
116 <      
117 <      fgets( readBuffer, sizeof( readBuffer ), inFile );
118 <      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;
125 > #endif
126  
127 < #ifdef IS_MPI
157 <  }
158 <  strcpy( checkPointMsg, "Successfully scanned DumpFile\n" );
159 <  MPIcheckPoint();
160 < #endif // is_mpi
127 >    return;
128   }
129  
130 < void DumpReader :: readFrame( SimInfo* the_simnfo, int whichFrame){
130 > int DumpReader::getNFrames(void) {
131  
132 <  simnfo = the_simnfo;
132 >    if (!isScanned_)
133 >        scanFile();
134  
135 <  this->readSet( whichFrame );
135 >    return nframes_;
136   }
137  
138 + void DumpReader::scanFile(void) {
139 +  int i, j;
140 +  int lineNum = 0;
141 +  char readBuffer[maxBufferSize];
142 +  fpos_t * currPos;
143  
144 + #ifdef IS_MPI
145  
146 < void DumpReader :: readSet( int whichFrame ){
146 >    if (worldRank == 0) {
147 > #endif // is_mpi
148  
149 <  int i;
175 <  unsigned int j;
149 >        rewind(inFile_);
150  
151 < #ifdef IS_MPI
152 <  int done, which_node, which_atom; // loop counter
153 < #endif //is_mpi
151 >        currPos = new fpos_t;
152 >        fgetpos(inFile_, currPos);
153 >        fgets(readBuffer, sizeof(readBuffer), inFile_);
154 >        lineNum++;
155  
156 <  const int BUFFERSIZE = 2000; // size of the read buffer
157 <  int nTotObjs; // the number of atoms
158 <  char read_buffer[BUFFERSIZE]; //the line buffer for reading
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 <  char *eof_test; // ptr to see when we reach the end of the file
166 <  char *parseErr;
165 >        while (!feof(inFile_)) {
166 >            framePos_.push_back(currPos);
167  
168 <  vector<StuntDouble*> integrableObjects;
168 >            i = atoi(readBuffer);
169  
170 +            fgets(readBuffer, sizeof(readBuffer), inFile_);
171 +            lineNum++;
172  
173 < #ifndef IS_MPI
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 <  fsetpos(inFile, framePos[whichFrame]);
183 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
184 <  if( eof_test == NULL ){
196 <    sprintf( painCave.errMsg,
197 <             "DumpReader error: error reading 1st line of \"%s\"\n",
198 <             inFileName.c_str() );
199 <    painCave.isFatal = 1;
200 <    simError();
201 <  }
182 >            for(j = 0; j < i; j++) {
183 >                fgets(readBuffer, sizeof(readBuffer), inFile_);
184 >                lineNum++;
185  
186 <  nTotObjs = atoi( read_buffer );
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 <  if( nTotObjs != simnfo->getTotIntegrableObjects() ){
194 <    sprintf( painCave.errMsg,
195 <             "DumpReader error. %s nIntegrable, %d, "
196 <             "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 <  }
193 >                    painCave.isFatal = 1;
194 >                    simError();
195 >                }
196 >            }
197  
198 <  //read the box mat from the comment line
198 >            currPos = new fpos_t;
199 >            fgetpos(inFile_, currPos);
200 >            fgets(readBuffer, sizeof(readBuffer), inFile_);
201 >            lineNum++;
202 >        }
203  
204 <  eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
205 <  if(eof_test == NULL){
206 <    sprintf( painCave.errMsg,
207 <             "error in reading commment in %s\n", inFileName.c_str());
208 <    painCave.isFatal = 1;
209 <    simError();
222 <  }
204 >        delete currPos;
205 >        rewind(inFile_);
206 >        
207 >        nframes_ = framePos_.size();
208 > #ifdef IS_MPI
209 >    }
210  
211 <  parseErr = parseCommentLine( read_buffer, simnfo);
225 <  if( parseErr != NULL ){
226 <    strcpy( painCave.errMsg, parseErr );
227 <    painCave.isFatal = 1;
228 <    simError();
229 <  }
211 >    MPI_Bcast(&nframes_, 1, MPI_INT, 0, MPI_COMM_WORLD);
212  
213 <  //parse dump lines
213 >    strcpy(checkPointMsg, "Successfully scanned DumpFile\n");
214 >    MPIcheckPoint();
215  
216 <  for( i=0; i < simnfo->n_mol; i++){
216 > #endif // is_mpi
217  
218 <    integrableObjects = (simnfo->molecules[i]).getIntegrableObjects();
218 >    isScanned_ = true;
219 > }
220  
221 <    for(j = 0; j < integrableObjects.size(); j++){
221 > void DumpReader::readFrame(int whichFrame) {
222 >    int storageLayout = info_->getSnapshotManager()->getStorageLayout();
223  
224 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
225 <      if(eof_test == NULL){
226 <        sprintf(painCave.errMsg,
227 <              "error in reading file %s\n"
243 <              "natoms  = %d; index = %d\n"
244 <              "error reading the line from the file.\n",
245 <              inFileName.c_str(), nTotObjs, i );
246 <        painCave.isFatal = 1;
247 <        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 <      }
224 >    if (storageLayout & DataStorage::dslPosition) {
225 >        needPos_ = true;
226 >    } else {
227 >        needPos_ = false;
228      }
257  }
229  
230 <  // MPI Section of code..........
231 < #else //IS_MPI
230 >    if (storageLayout & DataStorage::dslVelocity) {
231 >        needVel_ = true;
232 >    } else {
233 >        needVel_ = false;
234 >    }
235  
236 <  // first thing first, suspend fatalities.
237 <  painCave.isEventLoop = 1;
236 >    if (storageLayout & DataStorage::dslAmat || storageLayout & DataStorage::dslElectroFrame) {
237 >        needQuaternion_ = true;
238 >    } else {
239 >        needQuaternion_ = false;
240 >    }
241  
242 <  int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
243 <  int haveError;
242 >    if (storageLayout & DataStorage::dslAngularMomentum) {
243 >        needAngMom_ = true;
244 >    } else {
245 >        needAngMom_ = false;    
246 >    }
247  
248 <  MPI_Status istatus;
249 <  int *MolToProcMap = mpiSim->getMolToProcMap();
270 <  int localIndex;
271 <  int nCurObj;
272 <  int nitems;
248 >    readSet(whichFrame);
249 > }
250  
251 <  nTotObjs = simnfo->getTotIntegrableObjects();
252 <  haveError = 0;
253 <  if (worldRank == 0) {
254 <     fsetpos(inFile,  framePos[whichFrame]);
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 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
258 <    if( eof_test == NULL ){
259 <      sprintf( painCave.errMsg,
260 <               "Error reading 1st line of %s \n ",inFileName.c_str());
261 <      haveError = 1;
262 <      simError();
257 >  Molecule* mol;
258 >  StuntDouble* integrableObject;
259 >  SimInfo::MoleculeIterator mi;
260 >  Molecule::IntegrableObjectIterator ii;
261 >
262 > #ifndef IS_MPI
263 >
264 >    fsetpos(inFile_, framePos_[whichFrame]);
265 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
266 >
267 >    if (eof_test == NULL) {
268 >        sprintf(painCave.errMsg,
269 >                "DumpReader error: error reading 1st line of \"%s\"\n",
270 >                filename_.c_str());
271 >        painCave.isFatal = 1;
272 >        simError();
273      }
274  
275 <    nitems = atoi( read_buffer );
275 >    nTotObjs = atoi(read_buffer);
276  
277 <    // Check to see that the number of integrable objects in the
278 <    // intial configuration file is the same as derived from the
279 <    // meta-data file.
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 <    if( nTotObjs != nitems){
286 <      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();
285 >        painCave.isFatal = 1;
286 >        simError();
287      }
288  
289 <    //read the boxMat from the comment line
289 >    //read the box mat from the comment line
290  
291 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile);
292 <    if(eof_test == NULL){
293 <      sprintf( painCave.errMsg,
294 <               "error in reading commment in %s\n", inFileName.c_str());
295 <      haveError = 1;
296 <      simError();
291 >    eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
292 >
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 <    //Every single processor will parse the comment line by itself
313 <    //By using this way, we might lose some efficiency, but if we want to add
314 <    //more parameters into comment line, we only need to modify function
315 <    //parseCommentLine
300 >    parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
301  
302 <    MPI_Bcast(read_buffer, BUFFERSIZE, MPI_CHAR, 0, MPI_COMM_WORLD);
302 >    //parse dump lines
303  
304 <    parseErr = parseCommentLine( read_buffer, simnfo);
304 >    for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
305  
306 <    if( parseErr != NULL ){
307 <      strcpy( painCave.errMsg, parseErr );
308 <      haveError = 1;
309 <      simError();
306 >        for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
307 >            integrableObject = mol->nextIntegrableObject(ii)) {          
308 >
309 >            eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
310 >
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 >                painCave.isFatal = 1;
321 >                simError();
322 >            }
323 >
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();
380 <        
381 <        MPI_Send(&nCurObj, 1, MPI_INT, 0,
382 <                        TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
383 <
384 <        for(j = 0; j < integrableObjects.size(); j++){
385 <
428 <          MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
429 <                              TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
430 <
431 <          parseErr = parseDumpLine(read_buffer, integrableObjects[j]);
432 <
433 <          if( parseErr != NULL ){
434 <                strcpy( painCave.errMsg, parseErr );
435 <                simError();
436 <          }
437 <
379 >        eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
380 >
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");
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 );
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 >    
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[1] = 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 <    foo = strtok(NULL, " ,;\t");
562 <    if(foo == NULL){
563 <      sprintf( painCave.errMsg,
564 <                     "error in reading velocity x from %s\n",
606 <                      inFileName.c_str() );
607 <      return strdup( painCave.errMsg );
608 <    }
609 <    ji[2] = atof( foo );
561 >        q.normalize();
562 >        if (needQuaternion_) {          
563 >            integrableObject->setQ(q);
564 >        }
565  
566 <
567 <    // check that the quaternion vector is normalized
568 <
569 <    qSqr = (q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]);
570 <
571 <    if (fabs(qSqr) < 1e-6) {
617 <      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