ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/io/DumpReader.cpp
Revision: 1864
Committed: Tue Dec 7 05:00:31 2004 UTC (19 years, 7 months ago) by tim
File size: 16083 byte(s)
Log Message:
no message

File Contents

# Content
1 #define _LARGEFILE_SOURCE64
2 #define _FILE_OFFSET_BITS 64
3
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 #include <iostream>
8 #include <math.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "io/DumpReader.hpp"
15 #include "primitives/Molecule.hpp"
16 #include "utils/simError.h"
17 #include "utils/MemoryUtils.hpp"
18 #include "utils/StringTokenizer.hpp"
19
20 #ifdef IS_MPI
21
22 #include <mpi.h>
23 #define TAKE_THIS_TAG_CHAR 0
24 #define TAKE_THIS_TAG_INT 1
25
26 #endif // is_mpi
27
28
29 namespace oopse {
30
31 DumpReader::DumpReader(SimInfo* info, const std::string& filename)
32 : info_(info), filename_(filename), isScanned_(false){
33
34 #ifdef IS_MPI
35
36 if (worldRank == 0) {
37 #endif
38
39 inFile_ = fopen(filename_.c_str(), "r");
40
41 if (inFile_ == NULL) {
42 sprintf(painCave.errMsg, "Cannot open file: %s\n", filename_.c_str());
43 painCave.isFatal = 1;
44 simError();
45 }
46
47 #ifdef IS_MPI
48
49 }
50
51 strcpy(checkPointMsg, "Dump file opened for reading successfully.");
52 MPIcheckPoint();
53
54 #endif
55
56 return;
57 }
58
59 DumpReader::~DumpReader() {
60
61 #ifdef IS_MPI
62
63 if (worldRank == 0) {
64 #endif
65
66 int error;
67 error = fclose(inFile_);
68
69 if (error) {
70 sprintf(painCave.errMsg, "Error closing %s\n", filename_.c_str());
71 painCave.isFatal = 1;
72 simError();
73 }
74
75 MemoryUtils::deleteVectorOfPointer(framePos_);
76
77 #ifdef IS_MPI
78
79 }
80
81 strcpy(checkPointMsg, "Dump file closed successfully.");
82 MPIcheckPoint();
83
84 #endif
85
86 return;
87 }
88
89 int DumpReader::getNFrames(void) {
90 if (!isScanned_)
91 scanFile();
92
93 return framePos_.size();
94 }
95
96 void DumpReader::scanFile(void) {
97 int i, j;
98 int lineNum = 0;
99 char readBuffer[maxBufferSize];
100 fpos_t * currPos;
101
102 #ifdef IS_MPI
103
104 if (worldRank == 0) {
105 #endif // is_mpi
106
107 rewind(inFile_);
108
109 currPos = new fpos_t;
110 fgetpos(inFile_, currPos);
111 fgets(readBuffer, sizeof(readBuffer), inFile_);
112 lineNum++;
113
114 if (feof(inFile_)) {
115 sprintf(painCave.errMsg,
116 "File \"%s\" ended unexpectedly at line %d\n",
117 filename_.c_str(),
118 lineNum);
119 painCave.isFatal = 1;
120 simError();
121 }
122
123 while (!feof(inFile_)) {
124 framePos_.push_back(currPos);
125
126 i = atoi(readBuffer);
127
128 fgets(readBuffer, sizeof(readBuffer), inFile_);
129 lineNum++;
130
131 if (feof(inFile_)) {
132 sprintf(painCave.errMsg,
133 "File \"%s\" ended unexpectedly at line %d\n",
134 filename_.c_str(),
135 lineNum);
136 painCave.isFatal = 1;
137 simError();
138 }
139
140 for(j = 0; j < i; j++) {
141 fgets(readBuffer, sizeof(readBuffer), inFile_);
142 lineNum++;
143
144 if (feof(inFile_)) {
145 sprintf(painCave.errMsg,
146 "File \"%s\" ended unexpectedly at line %d,"
147 " with atom %d\n", filename_.c_str(),
148 lineNum,
149 j);
150
151 painCave.isFatal = 1;
152 simError();
153 }
154 }
155
156 currPos = new fpos_t;
157 fgetpos(inFile_, currPos);
158 fgets(readBuffer, sizeof(readBuffer), inFile_);
159 lineNum++;
160 }
161
162 delete currPos;
163 rewind(inFile_);
164
165 isScanned_ = true;
166
167 #ifdef IS_MPI
168
169 }
170
171 strcpy(checkPointMsg, "Successfully scanned DumpFile\n");
172 MPIcheckPoint();
173
174 #endif // is_mpi
175
176 }
177
178 void DumpReader::readFrame(int whichFrame) {
179 readSet(whichFrame);
180 }
181
182 void DumpReader::readSet(int whichFrame) {
183 int i;
184 int nTotObjs; // the number of atoms
185 char read_buffer[maxBufferSize]; //the line buffer for reading
186 char * eof_test; // ptr to see when we reach the end of the file
187
188 Molecule* mol;
189 StuntDouble* integrableObject;
190 SimInfo::MoleculeIterator mi;
191 Molecule::IntegrableObjectIterator ii;
192
193 #ifndef IS_MPI
194
195 fsetpos(inFile_, framePos_[whichFrame]);
196 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
197
198 if (eof_test == NULL) {
199 sprintf(painCave.errMsg,
200 "DumpReader error: error reading 1st line of \"%s\"\n",
201 filename_.c_str());
202 painCave.isFatal = 1;
203 simError();
204 }
205
206 nTotObjs = atoi(read_buffer);
207
208 if (nTotObjs != info_->getNGlobalIntegrableObjects()) {
209 sprintf(painCave.errMsg,
210 "DumpReader error. %s nIntegrable, %d, "
211 "does not match the meta-data file's nIntegrable, %d.\n",
212 filename_.c_str(),
213 nTotObjs,
214 info_->getNIntegrableObjects());
215
216 painCave.isFatal = 1;
217 simError();
218 }
219
220 //read the box mat from the comment line
221
222 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
223
224 if (eof_test == NULL) {
225 sprintf(painCave.errMsg, "error in reading commment in %s\n",
226 filename_.c_str());
227 painCave.isFatal = 1;
228 simError();
229 }
230
231 parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
232
233 //parse dump lines
234
235 for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
236
237 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
238 integrableObject = mol->nextIntegrableObject(ii)) {
239
240 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
241
242 if (eof_test == NULL) {
243 sprintf(painCave.errMsg,
244 "error in reading file %s\n"
245 "natoms = %d; index = %d\n"
246 "error reading the line from the file.\n",
247 filename_.c_str(),
248 nTotObjs,
249 i);
250
251 painCave.isFatal = 1;
252 simError();
253 }
254
255 parseDumpLine(read_buffer, integrableObject);
256
257 }
258 }
259
260 // MPI Section of code..........
261
262 #else //IS_MPI
263
264 // first thing first, suspend fatalities.
265 int masterNode = 0;
266 int nCurObj;
267 painCave.isEventLoop = 1;
268
269 int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
270 int haveError;
271
272 MPI_Status istatus;
273 int nitems;
274
275 nTotObjs = info_->getNGlobalIntegrableObjects();
276 haveError = 0;
277
278 if (worldRank == masterNode) {
279 fsetpos(inFile_, framePos_[whichFrame]);
280
281 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
282
283 if (eof_test == NULL) {
284 sprintf(painCave.errMsg, "Error reading 1st line of %s \n ",
285 filename_.c_str());
286 painCave.isFatal = 1;
287 simError();
288 }
289
290 nitems = atoi(read_buffer);
291
292 // Check to see that the number of integrable objects in the
293 // intial configuration file is the same as derived from the
294 // meta-data file.
295
296 if (nTotObjs != nitems) {
297 sprintf(painCave.errMsg,
298 "DumpReader Error. %s nIntegrable, %d, "
299 "does not match the meta-data file's nIntegrable, %d.\n",
300 filename_.c_str(),
301 nTotObjs,
302 info_->getTotIntegrableObjects());
303
304 painCave.isFatal = 1;
305 simError();
306 }
307
308 //read the boxMat from the comment line
309
310 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
311
312 if (eof_test == NULL) {
313 sprintf(painCave.errMsg, "error in reading commment in %s\n",
314 filename_.c_str());
315 painCave.isFatal = 1;
316 simError();
317 }
318
319 //Every single processor will parse the comment line by itself
320 //By using this way, we might lose some efficiency, but if we want to add
321 //more parameters into comment line, we only need to modify function
322 //parseCommentLine
323
324 MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
325 parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
326
327 for(i = 0; i < info_->getNGlobalMolecules(); i++) {
328 which_node = info_->getMolToProc(i);
329
330 if (which_node == masterNode) {
331 //molecules belong to master node
332
333 mol = info_->getMoleculeByGlobalIndex(i);
334
335 if (mol == NULL) {
336 strcpy(painCave.errMsg, "Molecule not found on node %d!", worldRank);
337 painCave.isFatal = 1;
338 simError();
339 }
340
341 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
342 integrableObject = mol->nextIntegrableObject(ii)){
343
344 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
345
346 if (eof_test == NULL) {
347 sprintf(painCave.errMsg,
348 "error in reading file %s\n"
349 "natoms = %d; index = %d\n"
350 "error reading the line from the file.\n",
351 filename_.c_str(),
352 nTotObjs,
353 i);
354
355 painCave.isFatal = 1;
356 simError();
357 }
358
359 parseDumpLine(read_buffer, integrableObject);
360 }
361 } else {
362 //molecule belongs to slave nodes
363
364 MPI_Recv(&nCurObj, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT,
365 MPI_COMM_WORLD, &istatus);
366
367 for(int j = 0; j < nCurObj; j++) {
368 eof_test = fgets(read_buffer, sizeof(read_buffer), inFile_);
369
370 if (eof_test == NULL) {
371 sprintf(painCave.errMsg,
372 "error in reading file %s\n"
373 "natoms = %d; index = %d\n"
374 "error reading the line from the file.\n",
375 filename_.c_str(),
376 nTotObjs,
377 i);
378
379 painCave.isFatal = 1;
380 simError();
381 }
382
383 MPI_Send(read_buffer, maxBufferSize, MPI_CHAR, which_node,
384 TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
385 }
386 }
387 }
388 } else {
389 //actions taken at slave nodes
390 MPI_Bcast(read_buffer, maxBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
391
392 /**@todo*/
393 parseCommentLine(read_buffer, info_->getSnapshotManager()->getCurrentSnapshot());
394
395 for(i = 0; i < info_->getNGlobalMolecules(); i++) {
396 which_node = info_->getMolToProc(i);
397
398 if (which_node == worldRank) {
399 //molecule with global index i belongs to this processor
400
401 mol = info_->getMoleculeByGlobalIndex(i);
402 if (mol == NULL) {
403 strcpy(painCave.errMsg, "Molecule not found on node %d!", worldRank);
404 painCave.isFatal = 1;
405 simError();
406 }
407
408 nCurObj = mol->getNIntegrableObjects();
409
410 MPI_Send(&nCurObj, 1, MPI_INT, masterNode, TAKE_THIS_TAG_INT,
411 MPI_COMM_WORLD);
412
413 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
414 integrableObject = mol->nextIntegrableObject(ii)){
415
416 MPI_Recv(read_buffer, maxBufferSize, MPI_CHAR, masterNode,
417 TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
418
419 parseDumpLine(read_buffer, integrableObject);
420 }
421
422 }
423
424 }
425
426 }
427
428 #endif
429
430 }
431
432 void DumpReader::parseDumpLine(char *line, StuntDouble *integrableObject) {
433
434 Vector3d pos; // position place holders
435 Vector3d vel; // velocity placeholders
436 Quat4d q; // the quaternions
437 Vector3d ji; // angular velocity placeholders;
438 StringTokenizer tokenizer(line);
439 int nTokens;
440
441 nTokens = tokenizer.countTokens();
442
443 if (nTokens < 14) {
444 sprintf(painCave.errMsg,
445 "Not enough Tokens.\n");
446 painCave.isFatal = 1;
447 simError();
448 }
449
450 std::string name = tokenizer.nextToken();
451
452 if (name != integrableObject->getType()) {
453
454 }
455
456 pos[0] = tokenizer.nextTokenAsFloat();
457 pos[1] = tokenizer.nextTokenAsFloat();
458 pos[2] = tokenizer.nextTokenAsFloat();
459 integrableObject->setPos(pos);
460
461 vel[0] = tokenizer.nextTokenAsFloat();
462 vel[1] = tokenizer.nextTokenAsFloat();
463 vel[2] = tokenizer.nextTokenAsFloat();
464 integrableObject->setVel(vel);
465
466 if (integrableObject->isDirectional()) {
467
468 q[0] = tokenizer.nextTokenAsFloat();
469 q[1] = tokenizer.nextTokenAsFloat();
470 q[2] = tokenizer.nextTokenAsFloat();
471 q[3] = tokenizer.nextTokenAsFloat();
472
473 double qlen = q.length();
474 if (qlen < oopse::epsilon) { //check quaternion is not equal to 0
475
476 sprintf(painCave.errMsg,
477 "initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2 ~ 0).\n");
478 painCave.isFatal = 1;
479 simError();
480
481 }
482
483 q.normalize();
484
485 integrableObject->setQ(q);
486
487 ji[0] = tokenizer.nextTokenAsFloat();
488 ji[1] = tokenizer.nextTokenAsFloat();
489 ji[2] = tokenizer.nextTokenAsFloat();
490 integrableObject->setJ(ji);
491 }
492
493 }
494
495
496 void DumpReader::parseCommentLine(char* line, Snapshot* s) {
497 double currTime;
498 Mat3x3d hmat;
499 double chi;
500 double integralOfChiDt;
501 Mat3x3d eta;
502
503 StringTokenizer tokenizer(line);
504 int nTokens;
505
506 nTokens = tokenizer.countTokens();
507
508 //comment line should at least contain 10 tokens: current time(1 token) and h-matrix(9 tokens)
509 if (nTokens < 10) {
510 sprintf(painCave.errMsg,
511 "Not enough tokens in comment line: %s", line);
512 painCave.isFatal = 1;
513 simError();
514 }
515
516 //read current time
517 currTime = tokenizer.nextTokenAsFloat();
518 s->setTime(currTime);
519
520 //read h-matrix
521 hmat(0, 0) = tokenizer.nextTokenAsFloat();
522 hmat(0, 1) = tokenizer.nextTokenAsFloat();
523 hmat(0, 2) = tokenizer.nextTokenAsFloat();
524 hmat(1, 0) = tokenizer.nextTokenAsFloat();
525 hmat(1, 1) = tokenizer.nextTokenAsFloat();
526 hmat(1, 2) = tokenizer.nextTokenAsFloat();
527 hmat(2, 0) = tokenizer.nextTokenAsFloat();
528 hmat(2, 1) = tokenizer.nextTokenAsFloat();
529 hmat(2, 2) = tokenizer.nextTokenAsFloat();
530 s->setHmat(hmat);
531
532 //read chi and integrablOfChidt, they should apprear in pair
533 if (tokenizer.countTokens() >= 2) {
534 chi = tokenizer.nextTokenAsFloat();
535 integralOfChiDt = tokenizer.nextTokenAsFloat();
536
537 s->setChi(chi);
538 s->setIntegralOfChiDt(integralOfChiDt);
539 }
540
541 //read eta (eta is 3x3 matrix)
542 if (tokenizer.countTokens() >= 9) {
543 eta(0, 0) = tokenizer.nextTokenAsFloat();
544 eta(0, 1) = tokenizer.nextTokenAsFloat();
545 eta(0, 2) = tokenizer.nextTokenAsFloat();
546 eta(1, 0) = tokenizer.nextTokenAsFloat();
547 eta(1, 1) = tokenizer.nextTokenAsFloat();
548 eta(1, 2) = tokenizer.nextTokenAsFloat();
549 eta(2, 0) = tokenizer.nextTokenAsFloat();
550 eta(2, 1) = tokenizer.nextTokenAsFloat();
551 eta(2, 2) = tokenizer.nextTokenAsFloat();
552
553 s->setEta(eta);
554 }
555
556
557 }
558
559 }//end namespace oopse