ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/RestReader.cpp
Revision: 1875
Committed: Fri May 17 14:41:42 2013 UTC (11 years, 11 months ago) by gezelter
File size: 13487 byte(s)
Log Message:
Fixed a bunch of stylistic and performance issues discovered via cppcheck.

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, 234107 (2008).
39 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43
44 #include <sys/types.h>
45 #include <sys/stat.h>
46
47 #include <math.h>
48 #include <string>
49 #include <sstream>
50 #include <iostream>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #include "io/RestReader.hpp"
56 #include "primitives/Molecule.hpp"
57 #include "utils/simError.h"
58 #include "utils/MemoryUtils.hpp"
59 #include "utils/StringTokenizer.hpp"
60 #include "restraints/ObjectRestraint.hpp"
61 #include "restraints/MolecularRestraint.hpp"
62
63 #ifdef IS_MPI
64
65 #include <mpi.h>
66 #endif
67
68 namespace OpenMD {
69
70 void RestReader::scanFile(){
71
72 std::streampos prevPos;
73 std::streampos currPos;
74
75 #ifdef IS_MPI
76
77 if (worldRank == 0) {
78 #endif // is_mpi
79
80 inFile_->clear();
81 currPos = inFile_->tellg();
82 prevPos = currPos;
83
84 bool foundOpenSnapshotTag = false;
85 int lineNo = 0;
86 while(!foundOpenSnapshotTag && inFile_->getline(buffer, bufferSize)) {
87 ++lineNo;
88
89 std::string line = buffer;
90 currPos = inFile_->tellg();
91 if (line.find("<Snapshot>")!= std::string::npos) {
92 foundOpenSnapshotTag = true;
93 framePos_ = prevPos;
94 }
95 prevPos = currPos;
96 }
97
98 #ifdef IS_MPI
99 }
100 MPI::COMM_WORLD.Bcast(&framePos_, 1, MPI::INT, 0);
101 #endif // is_mpi
102 }
103
104
105 void RestReader::readSet(){
106 std::string line;
107
108 #ifndef IS_MPI
109
110 inFile_->clear();
111 inFile_->seekg(framePos_);
112
113 std::istream& inputStream = *inFile_;
114 #else
115
116 int masterNode = 0;
117 std::stringstream sstream;
118 if (worldRank == masterNode) {
119 std::string sendBuffer;
120
121 inFile_->clear();
122 inFile_->seekg(framePos_);
123
124 while (inFile_->getline(buffer, bufferSize)) {
125
126 line = buffer;
127 sendBuffer += line;
128 sendBuffer += '\n';
129 if (line.find("</Snapshot>") != std::string::npos) {
130 break;
131 }
132 }
133
134 int sendBufferSize = sendBuffer.size();
135 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
136 MPI::COMM_WORLD.Bcast((void *)sendBuffer.c_str(), sendBufferSize,
137 MPI::CHAR, masterNode);
138
139 sstream.str(sendBuffer);
140 } else {
141 int sendBufferSize;
142 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
143 char * recvBuffer = new char[sendBufferSize+1];
144 assert(recvBuffer);
145 recvBuffer[sendBufferSize] = '\0';
146 MPI::COMM_WORLD.Bcast(recvBuffer, sendBufferSize, MPI::CHAR, masterNode);
147 sstream.str(recvBuffer);
148 delete [] recvBuffer;
149 }
150
151 std::istream& inputStream = sstream;
152 #endif
153
154 inputStream.getline(buffer, bufferSize);
155
156 line = buffer;
157 if (line.find("<Snapshot>") == std::string::npos) {
158 sprintf(painCave.errMsg,
159 "RestReader Error: can not find <Snapshot>\n");
160 painCave.isFatal = 1;
161 simError();
162 }
163
164 //read frameData
165 readFrameProperties(inputStream);
166
167 //read StuntDoubles
168 readStuntDoubles(inputStream);
169
170 inputStream.getline(buffer, bufferSize);
171 line = buffer;
172 if (line.find("</Snapshot>") == std::string::npos) {
173 sprintf(painCave.errMsg,
174 "RestReader Error: can not find </Snapshot>\n");
175 painCave.isFatal = 1;
176 simError();
177 }
178 }
179
180 void RestReader::readReferenceStructure() {
181
182 // We need temporary storage to keep track of all StuntDouble positions
183 // in case some of the restraints are molecular (i.e. if they use
184 // multiple SD positions to determine restrained orientations or positions:
185
186 all_pos_.clear();
187 all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
188
189 // Restraint files are just standard dump files, but with the reference
190 // structure stored in the first frame (frame 0).
191 // RestReader overloads readSet and explicitly handles all of the
192 // ObjectRestraints in that method:
193
194 scanFile();
195
196 readSet();
197
198
199 // all ObjectRestraints have been handled, now we have to worry about
200 // molecular restraints:
201
202 SimInfo::MoleculeIterator i;
203 Molecule::IntegrableObjectIterator j;
204 Molecule* mol;
205 StuntDouble* sd;
206
207 // no need to worry about parallel molecules, as molecules are not
208 // split across processor boundaries. Just loop over all molecules
209 // we know about:
210
211 for (mol = info_->beginMolecule(i); mol != NULL;
212 mol = info_->nextMolecule(i)) {
213
214 // is this molecule restrained?
215 GenericData* data = mol->getPropertyByName("Restraint");
216
217 if (data != NULL) {
218
219 // make sure we can reinterpret the generic data as restraint data:
220
221 RestraintData* restData= dynamic_cast<RestraintData*>(data);
222
223 if (restData != NULL) {
224
225 // make sure we can reinterpet the restraint data as a
226 // pointer to a MolecularRestraint:
227
228 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
229
230 if (mRest != NULL) {
231
232 // now we need to pack the stunt doubles for the reference
233 // structure:
234
235 std::vector<Vector3d> ref;
236 int count = 0;
237 RealType mass, mTot;
238 Vector3d COM(0.0);
239
240 mTot = 0.0;
241
242 // loop over the stunt doubles in this molecule in the order we
243 // will be looping them in the restraint code:
244
245 for (sd = mol->beginIntegrableObject(j); sd != NULL;
246 sd = mol->nextIntegrableObject(j)) {
247
248 // push back the reference positions of the stunt
249 // doubles from the *globally* sorted array of
250 // positions:
251
252 ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
253 mass = sd->getMass();
254 COM = COM + mass * ref[count];
255 mTot = mTot + mass;
256 count = count + 1;
257 }
258 COM /= mTot;
259 mRest->setReferenceStructure(ref, COM);
260 }
261 }
262 }
263 }
264 }
265
266
267
268 void RestReader::parseDumpLine(const std::string& line) {
269
270 StringTokenizer tokenizer(line);
271 int nTokens;
272
273 nTokens = tokenizer.countTokens();
274
275 if (nTokens < 2) {
276 sprintf(painCave.errMsg,
277 "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
278 painCave.isFatal = 1;
279 simError();
280 }
281
282 int index = tokenizer.nextTokenAsInt();
283
284 StuntDouble* sd = info_->getIOIndexToIntegrableObject(index);
285
286 if (sd == NULL) {
287 return;
288 }
289
290 std::string type = tokenizer.nextToken();
291 int size = type.size();
292
293 Vector3d pos;
294 Quat4d q;
295
296 for(int i = 0; i < size; ++i) {
297 switch(type[i]) {
298
299 case 'p': {
300 pos[0] = tokenizer.nextTokenAsDouble();
301 pos[1] = tokenizer.nextTokenAsDouble();
302 pos[2] = tokenizer.nextTokenAsDouble();
303 break;
304 }
305 case 'v' : {
306 Vector3d vel;
307 vel[0] = tokenizer.nextTokenAsDouble();
308 vel[1] = tokenizer.nextTokenAsDouble();
309 vel[2] = tokenizer.nextTokenAsDouble();
310 break;
311 }
312
313 case 'q' : {
314 if (sd->isDirectional()) {
315
316 q[0] = tokenizer.nextTokenAsDouble();
317 q[1] = tokenizer.nextTokenAsDouble();
318 q[2] = tokenizer.nextTokenAsDouble();
319 q[3] = tokenizer.nextTokenAsDouble();
320
321 RealType qlen = q.length();
322 if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
323
324 sprintf(painCave.errMsg,
325 "RestReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2) ~ 0\n");
326 painCave.isFatal = 1;
327 simError();
328 }
329
330 q.normalize();
331 }
332 break;
333 }
334 case 'j' : {
335 Vector3d ji;
336 if (sd->isDirectional()) {
337 ji[0] = tokenizer.nextTokenAsDouble();
338 ji[1] = tokenizer.nextTokenAsDouble();
339 ji[2] = tokenizer.nextTokenAsDouble();
340 }
341 break;
342 }
343 case 'f': {
344 Vector3d force;
345 force[0] = tokenizer.nextTokenAsDouble();
346 force[1] = tokenizer.nextTokenAsDouble();
347 force[2] = tokenizer.nextTokenAsDouble();
348 break;
349 }
350 case 't' : {
351 Vector3d torque;
352 torque[0] = tokenizer.nextTokenAsDouble();
353 torque[1] = tokenizer.nextTokenAsDouble();
354 torque[2] = tokenizer.nextTokenAsDouble();
355 break;
356 }
357 default: {
358 sprintf(painCave.errMsg,
359 "RestReader Error: %s is an unrecognized type\n", type.c_str());
360 painCave.isFatal = 1;
361 simError();
362 break;
363 }
364 }
365 // keep the position in case we need it for a molecular restraint:
366
367 all_pos_[index] = pos;
368
369 // is this io restrained?
370 GenericData* data = sd->getPropertyByName("Restraint");
371
372 if (data != NULL) {
373 // make sure we can reinterpret the generic data as restraint data:
374 RestraintData* restData= dynamic_cast<RestraintData*>(data);
375 if (restData != NULL) {
376 // make sure we can reinterpet the restraint data as a pointer to
377 // an ObjectRestraint:
378 ObjectRestraint* oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
379 if (oRest != NULL) {
380 if (sd->isDirectional()) {
381 oRest->setReferenceStructure(pos, q.toRotationMatrix3());
382 } else {
383 oRest->setReferenceStructure(pos);
384 }
385 }
386 }
387 }
388 }
389 }
390
391 void RestReader::readStuntDoubles(std::istream& inputStream) {
392
393 inputStream.getline(buffer, bufferSize);
394 std::string line(buffer);
395
396 if (line.find("<StuntDoubles>") == std::string::npos) {
397 sprintf(painCave.errMsg,
398 "RestReader Error: Missing <StuntDoubles>\n");
399 painCave.isFatal = 1;
400 simError();
401 }
402
403 while(inputStream.getline(buffer, bufferSize)) {
404 line = buffer;
405
406 if(line.find("</StuntDoubles>") != std::string::npos) {
407 break;
408 }
409
410 parseDumpLine(line);
411 }
412
413 }
414
415
416 void RestReader::readFrameProperties(std::istream& inputStream) {
417 inputStream.getline(buffer, bufferSize);
418 std::string line(buffer);
419
420 if (line.find("<FrameData>") == std::string::npos) {
421 sprintf(painCave.errMsg,
422 "RestReader Error: Missing <FrameData>\n");
423 painCave.isFatal = 1;
424 simError();
425 }
426
427 // restraints don't care about frame data (unless we need to wrap
428 // coordinates, but we'll worry about that later), so
429 // we'll just scan ahead until the end of the frame data:
430
431 while(inputStream.getline(buffer, bufferSize)) {
432 line = buffer;
433
434 if(line.find("</FrameData>") != std::string::npos) {
435 break;
436 }
437
438 }
439
440 }
441
442
443 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date