ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/DumpReader.cpp
Revision: 1465
Committed: Fri Jul 9 23:08:25 2010 UTC (14 years, 9 months ago) by chuckv
File size: 17167 byte(s)
Log Message:
Creating busticated version of OpenMD

File Contents

# Content
1 /*
2 * Copyright (c) 2009 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. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * This software is provided "AS IS," without a warranty of any
18 * kind. All express or implied conditions, representations and
19 * warranties, including any implied warranty of merchantability,
20 * fitness for a particular purpose or non-infringement, are hereby
21 * excluded. The University of Notre Dame and its licensors shall not
22 * be liable for any damages suffered by licensee as a result of
23 * using, modifying or distributing the software or its
24 * derivatives. In no event will the University of Notre Dame or its
25 * licensors be liable for any lost revenue, profit or data, or for
26 * direct, indirect, special, consequential, incidental or punitive
27 * damages, however caused and regardless of the theory of liability,
28 * arising out of the use of or inability to use software, even if the
29 * University of Notre Dame has been advised of the possibility of
30 * such damages.
31 *
32 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33 * research, please cite the appropriate papers when you publish your
34 * work. Good starting points are:
35 *
36 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39 * [4] Vardeman & Gezelter, in progress (2009).
40 */
41
42 #define _LARGEFILE_SOURCE64
43 #define _FILE_OFFSET_BITS 64
44
45 #include <sys/types.h>
46 #include <sys/stat.h>
47
48 #include <iostream>
49 #include <math.h>
50
51 #include <stdio.h>
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
61 #ifdef IS_MPI
62
63 #include <mpi.h>
64 #define TAKE_THIS_TAG_CHAR 0
65 #define TAKE_THIS_TAG_INT 1
66
67 #endif // is_mpi
68
69
70 namespace OpenMD {
71
72 DumpReader::DumpReader(SimInfo* info, const std::string& filename)
73 : info_(info), filename_(filename), isScanned_(false), nframes_(0), needCOMprops_(false) {
74
75 #ifdef IS_MPI
76
77 if (worldRank == 0) {
78 #endif
79
80 inFile_ = new std::ifstream(filename_.c_str());
81
82 if (inFile_->fail()) {
83 sprintf(painCave.errMsg,
84 "DumpReader: Cannot open file: %s\n",
85 filename_.c_str());
86 painCave.isFatal = 1;
87 simError();
88 }
89
90 #ifdef IS_MPI
91
92 }
93
94 strcpy(checkPointMsg, "Dump file opened for reading successfully.");
95 errorCheckPoint();
96
97 #endif
98
99 return;
100 }
101
102 DumpReader::~DumpReader() {
103
104 #ifdef IS_MPI
105
106 if (worldRank == 0) {
107 #endif
108
109 delete inFile_;
110
111 #ifdef IS_MPI
112
113 }
114
115 strcpy(checkPointMsg, "Dump file closed successfully.");
116 errorCheckPoint();
117
118 #endif
119
120 return;
121 }
122
123 int DumpReader::getNFrames(void) {
124
125 if (!isScanned_)
126 scanFile();
127
128 return nframes_;
129 }
130
131 void DumpReader::scanFile(void) {
132 int lineNo = 0;
133 std::streampos prevPos;
134 std::streampos currPos;
135
136 #ifdef IS_MPI
137
138 if (worldRank == 0) {
139 #endif // is_mpi
140
141 currPos = inFile_->tellg();
142 prevPos = currPos;
143 bool foundOpenSnapshotTag = false;
144 bool foundClosedSnapshotTag = false;
145 while(inFile_->getline(buffer, bufferSize)) {
146 ++lineNo;
147
148 std::string line = buffer;
149 currPos = inFile_->tellg();
150 if (line.find("<Snapshot>")!= std::string::npos) {
151 if (foundOpenSnapshotTag) {
152 sprintf(painCave.errMsg,
153 "DumpReader:<Snapshot> is multiply nested at line %d in %s \n", lineNo,
154 filename_.c_str());
155 painCave.isFatal = 1;
156 simError();
157 }
158 foundOpenSnapshotTag = true;
159 foundClosedSnapshotTag = false;
160 framePos_.push_back(prevPos);
161
162 } else if (line.find("</Snapshot>") != std::string::npos){
163 if (!foundOpenSnapshotTag) {
164 sprintf(painCave.errMsg,
165 "DumpReader:</Snapshot> appears before <Snapshot> at line %d in %s \n", lineNo,
166 filename_.c_str());
167 painCave.isFatal = 1;
168 simError();
169 }
170
171 if (foundClosedSnapshotTag) {
172 sprintf(painCave.errMsg,
173 "DumpReader:</Snapshot> appears multiply nested at line %d in %s \n", lineNo,
174 filename_.c_str());
175 painCave.isFatal = 1;
176 simError();
177 }
178 foundClosedSnapshotTag = true;
179 foundOpenSnapshotTag = false;
180 }
181 prevPos = currPos;
182 }
183
184 // only found <Snapshot> for the last frame means the file is corrupted, we should discard
185 // it and give a warning message
186 if (foundOpenSnapshotTag) {
187 sprintf(painCave.errMsg,
188 "DumpReader: last frame in %s is invalid\n", filename_.c_str());
189 painCave.isFatal = 0;
190 simError();
191 framePos_.pop_back();
192 }
193
194 nframes_ = framePos_.size();
195
196 if (nframes_ == 0) {
197 sprintf(painCave.errMsg,
198 "DumpReader: %s does not contain a valid frame\n", filename_.c_str());
199 painCave.isFatal = 1;
200 simError();
201 }
202 #ifdef IS_MPI
203 }
204
205 MPI_Bcast(&nframes_, 1, MPI_INT, 0, MPI_COMM_WORLD);
206
207 #endif // is_mpi
208
209 isScanned_ = true;
210 }
211
212 void DumpReader::readFrame(int whichFrame) {
213 if (!isScanned_)
214 scanFile();
215
216 int storageLayout = info_->getSnapshotManager()->getStorageLayout();
217
218 if (storageLayout & DataStorage::dslPosition) {
219 needPos_ = true;
220 } else {
221 needPos_ = false;
222 }
223
224 if (storageLayout & DataStorage::dslVelocity) {
225 needVel_ = true;
226 } else {
227 needVel_ = false;
228 }
229
230 if (storageLayout & DataStorage::dslAmat || storageLayout & DataStorage::dslElectroFrame) {
231 needQuaternion_ = true;
232 } else {
233 needQuaternion_ = false;
234 }
235
236 if (storageLayout & DataStorage::dslAngularMomentum) {
237 needAngMom_ = true;
238 } else {
239 needAngMom_ = false;
240 }
241
242 readSet(whichFrame);
243
244 if (needCOMprops_) {
245 Snapshot* s = info_->getSnapshotManager()->getCurrentSnapshot();
246 Vector3d com;
247 Vector3d comvel;
248 Vector3d comw;
249 if (needPos_ && needVel_){
250 info_->getComAll(com, comvel);
251 comw = info_->getAngularMomentum();
252 }else{
253 com = info_->getCom();
254 comvel = 0.0;
255 comw = 0.0;
256 }
257 s->setCOMprops(com, comvel, comw);
258 }
259
260 }
261
262 void DumpReader::readSet(int whichFrame) {
263 std::string line;
264
265 #ifndef IS_MPI
266 inFile_->clear();
267 inFile_->seekg(framePos_[whichFrame]);
268
269 std::istream& inputStream = *inFile_;
270
271 #else
272 int masterNode = 0;
273 std::stringstream sstream;
274 if (worldRank == masterNode) {
275 std::string sendBuffer;
276
277 inFile_->clear();
278 inFile_->seekg(framePos_[whichFrame]);
279
280 while (inFile_->getline(buffer, bufferSize)) {
281
282 line = buffer;
283 sendBuffer += line;
284 sendBuffer += '\n';
285 if (line.find("</Snapshot>") != std::string::npos) {
286 break;
287 }
288 }
289
290 int sendBufferSize = sendBuffer.size();
291 MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
292 MPI_Bcast((void *)sendBuffer.c_str(), sendBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
293
294 sstream.str(sendBuffer);
295 } else {
296 int sendBufferSize;
297 MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
298 char * recvBuffer = new char[sendBufferSize+1];
299 assert(recvBuffer);
300 recvBuffer[sendBufferSize] = '\0';
301 MPI_Bcast(recvBuffer, sendBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
302 sstream.str(recvBuffer);
303 delete [] recvBuffer;
304 }
305
306 std::istream& inputStream = sstream;
307 #endif
308
309 inputStream.getline(buffer, bufferSize);
310
311 line = buffer;
312 if (line.find("<Snapshot>") == std::string::npos) {
313 sprintf(painCave.errMsg,
314 "DumpReader Error: can not find <Snapshot>\n");
315 painCave.isFatal = 1;
316 simError();
317 }
318
319 //read frameData
320 readFrameProperties(inputStream);
321
322 //read StuntDoubles
323 readStuntDoubles(inputStream);
324
325 inputStream.getline(buffer, bufferSize);
326 line = buffer;
327 if (line.find("</Snapshot>") == std::string::npos) {
328 sprintf(painCave.errMsg,
329 "DumpReader Error: can not find </Snapshot>\n");
330 painCave.isFatal = 1;
331 simError();
332 }
333
334 }
335
336 void DumpReader::parseDumpLine(const std::string& line) {
337
338
339 StringTokenizer tokenizer(line);
340 int nTokens;
341
342 nTokens = tokenizer.countTokens();
343
344 if (nTokens < 2) {
345 sprintf(painCave.errMsg,
346 "DumpReader Error: Not enough Tokens.\n%s\n", line.c_str());
347 painCave.isFatal = 1;
348 simError();
349 }
350
351 int index = tokenizer.nextTokenAsInt();
352
353 StuntDouble* integrableObject = info_->getIOIndexToIntegrableObject(index);
354
355 if (integrableObject == NULL) {
356 return;
357 }
358 std::string type = tokenizer.nextToken();
359 int size = type.size();
360
361 size_t found;
362
363 if (needPos_) {
364 found = type.find("p");
365 if (found == std::string::npos) {
366 sprintf(painCave.errMsg,
367 "DumpReader Error: StuntDouble %d has no Position\n"
368 "\tField (\"p\") specified.\n%s\n", index,
369 line.c_str());
370 painCave.isFatal = 1;
371 simError();
372 }
373 }
374
375 if (integrableObject->isDirectional()) {
376 if (needQuaternion_) {
377 found = type.find("q");
378 if (found == std::string::npos) {
379 sprintf(painCave.errMsg,
380 "DumpReader Error: Directional StuntDouble %d has no\n"
381 "\tQuaternion Field (\"q\") specified.\n%s\n", index,
382 line.c_str());
383 painCave.isFatal = 1;
384 simError();
385 }
386 }
387 }
388
389 for(int i = 0; i < size; ++i) {
390 switch(type[i]) {
391
392 case 'p': {
393 Vector3d pos;
394 pos[0] = tokenizer.nextTokenAsDouble();
395 pos[1] = tokenizer.nextTokenAsDouble();
396 pos[2] = tokenizer.nextTokenAsDouble();
397 if (needPos_) {
398 integrableObject->setPos(pos);
399 }
400 break;
401 }
402 case 'v' : {
403 Vector3d vel;
404 vel[0] = tokenizer.nextTokenAsDouble();
405 vel[1] = tokenizer.nextTokenAsDouble();
406 vel[2] = tokenizer.nextTokenAsDouble();
407 if (needVel_) {
408 integrableObject->setVel(vel);
409 }
410 break;
411 }
412
413 case 'q' : {
414 Quat4d q;
415 if (integrableObject->isDirectional()) {
416
417 q[0] = tokenizer.nextTokenAsDouble();
418 q[1] = tokenizer.nextTokenAsDouble();
419 q[2] = tokenizer.nextTokenAsDouble();
420 q[3] = tokenizer.nextTokenAsDouble();
421
422 RealType qlen = q.length();
423 if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
424
425 sprintf(painCave.errMsg,
426 "DumpReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2) ~ 0\n");
427 painCave.isFatal = 1;
428 simError();
429
430 }
431
432 q.normalize();
433 if (needQuaternion_) {
434 integrableObject->setQ(q);
435 }
436 }
437 break;
438 }
439 case 'j' : {
440 Vector3d ji;
441 if (integrableObject->isDirectional()) {
442 ji[0] = tokenizer.nextTokenAsDouble();
443 ji[1] = tokenizer.nextTokenAsDouble();
444 ji[2] = tokenizer.nextTokenAsDouble();
445 if (needAngMom_) {
446 integrableObject->setJ(ji);
447 }
448 }
449 break;
450 }
451 case 'f': {
452
453 Vector3d force;
454 force[0] = tokenizer.nextTokenAsDouble();
455 force[1] = tokenizer.nextTokenAsDouble();
456 force[2] = tokenizer.nextTokenAsDouble();
457 integrableObject->setFrc(force);
458 break;
459 }
460 case 't' : {
461
462 Vector3d torque;
463 torque[0] = tokenizer.nextTokenAsDouble();
464 torque[1] = tokenizer.nextTokenAsDouble();
465 torque[2] = tokenizer.nextTokenAsDouble();
466 integrableObject->setTrq(torque);
467 break;
468 }
469 default: {
470 sprintf(painCave.errMsg,
471 "DumpReader Error: %s is an unrecognized type\n", type.c_str());
472 painCave.isFatal = 1;
473 simError();
474 break;
475 }
476
477 }
478 }
479
480 }
481
482
483 void DumpReader::readStuntDoubles(std::istream& inputStream) {
484
485 inputStream.getline(buffer, bufferSize);
486 std::string line(buffer);
487
488 if (line.find("<StuntDoubles>") == std::string::npos) {
489 sprintf(painCave.errMsg,
490 "DumpReader Error: Missing <StuntDoubles>\n");
491 painCave.isFatal = 1;
492 simError();
493 }
494
495 while(inputStream.getline(buffer, bufferSize)) {
496 line = buffer;
497
498 if(line.find("</StuntDoubles>") != std::string::npos) {
499 break;
500 }
501
502 parseDumpLine(line);
503 }
504
505 }
506
507 void DumpReader::readFrameProperties(std::istream& inputStream) {
508
509 Snapshot* s = info_->getSnapshotManager()->getCurrentSnapshot();
510 inputStream.getline(buffer, bufferSize);
511 std::string line(buffer);
512
513 if (line.find("<FrameData>") == std::string::npos) {
514 sprintf(painCave.errMsg,
515 "DumpReader Error: Missing <FrameData>\n");
516 painCave.isFatal = 1;
517 simError();
518 }
519
520 while(inputStream.getline(buffer, bufferSize)) {
521 line = buffer;
522
523 if(line.find("</FrameData>") != std::string::npos) {
524 break;
525 }
526
527 StringTokenizer tokenizer(line, " ;\t\n\r{}:,");
528 if (!tokenizer.hasMoreTokens()) {
529 sprintf(painCave.errMsg,
530 "DumpReader Error: Not enough Tokens.\n%s\n", line.c_str());
531 painCave.isFatal = 1;
532 simError();
533 }
534
535 std::string propertyName = tokenizer.nextToken();
536 if (propertyName == "Time") {
537 RealType currTime = tokenizer.nextTokenAsDouble();
538 s->setTime(currTime);
539 } else if (propertyName == "Hmat"){
540 Mat3x3d hmat;
541 hmat(0, 0) = tokenizer.nextTokenAsDouble();
542 hmat(0, 1) = tokenizer.nextTokenAsDouble();
543 hmat(0, 2) = tokenizer.nextTokenAsDouble();
544 hmat(1, 0) = tokenizer.nextTokenAsDouble();
545 hmat(1, 1) = tokenizer.nextTokenAsDouble();
546 hmat(1, 2) = tokenizer.nextTokenAsDouble();
547 hmat(2, 0) = tokenizer.nextTokenAsDouble();
548 hmat(2, 1) = tokenizer.nextTokenAsDouble();
549 hmat(2, 2) = tokenizer.nextTokenAsDouble();
550 s->setHmat(hmat);
551 } else if (propertyName == "Thermostat") {
552 RealType chi = tokenizer.nextTokenAsDouble();
553 RealType integralOfChiDt = tokenizer.nextTokenAsDouble();
554 s->setChi(chi);
555 s->setIntegralOfChiDt(integralOfChiDt);
556 } else if (propertyName == "Barostat") {
557 Mat3x3d eta;
558 eta(0, 0) = tokenizer.nextTokenAsDouble();
559 eta(0, 1) = tokenizer.nextTokenAsDouble();
560 eta(0, 2) = tokenizer.nextTokenAsDouble();
561 eta(1, 0) = tokenizer.nextTokenAsDouble();
562 eta(1, 1) = tokenizer.nextTokenAsDouble();
563 eta(1, 2) = tokenizer.nextTokenAsDouble();
564 eta(2, 0) = tokenizer.nextTokenAsDouble();
565 eta(2, 1) = tokenizer.nextTokenAsDouble();
566 eta(2, 2) = tokenizer.nextTokenAsDouble();
567 s->setEta(eta);
568 } else {
569 sprintf(painCave.errMsg,
570 "DumpReader Error: %s is an invalid property in <FrameData>\n", propertyName.c_str());
571 painCave.isFatal = 0;
572 simError();
573 }
574
575 }
576
577 }
578
579
580 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date