ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/RestReader.cpp
Revision: 1938
Committed: Thu Oct 31 15:32:17 2013 UTC (11 years, 6 months ago) by gezelter
File size: 13484 byte(s)
Log Message:
Some MPI include re-ordering to work with the Intel MPI implementation.

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

Properties

Name Value
svn:keywords Author Id Revision Date