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

# User Rev Content
1 cli2 1360 /*
2 cli2 1407 * Copyright (c) 2009 The University of Notre Dame. All Rights Reserved.
3 cli2 1360 *
4 gezelter 1390 * 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 gezelter 1879 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 gezelter 1782 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 cli2 1360 */
42 cli2 1407
43 gezelter 1938 #ifdef IS_MPI
44     #include <mpi.h>
45     #endif
46    
47 cli2 1407 #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 gezelter 1409 #include "utils/StringTokenizer.hpp"
63 cli2 1360 #include "restraints/ObjectRestraint.hpp"
64 cli2 1407 #include "restraints/MolecularRestraint.hpp"
65 chrisfen 417
66 gezelter 1390 namespace OpenMD {
67 cli2 1407
68     void RestReader::scanFile(){
69 gezelter 1879
70 cli2 1407 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 cli2 1360
82 cli2 1407 bool foundOpenSnapshotTag = false;
83 gezelter 1879 int lineNo = 0;
84 cli2 1407 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 gezelter 1796 MPI::COMM_WORLD.Bcast(&framePos_, 1, MPI::INT, 0);
99 cli2 1407 #endif // is_mpi
100     }
101 chrisfen 417
102    
103 cli2 1407 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 gezelter 1796 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
134     MPI::COMM_WORLD.Bcast((void *)sendBuffer.c_str(), sendBufferSize,
135     MPI::CHAR, masterNode);
136 cli2 1407
137     sstream.str(sendBuffer);
138 cli2 1360 } else {
139 cli2 1407 int sendBufferSize;
140 gezelter 1796 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
141 cli2 1407 char * recvBuffer = new char[sendBufferSize+1];
142     assert(recvBuffer);
143     recvBuffer[sendBufferSize] = '\0';
144 gezelter 1796 MPI::COMM_WORLD.Bcast(recvBuffer, sendBufferSize, MPI::CHAR, masterNode);
145 cli2 1407 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 cli2 1360 }
161 cli2 1407
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 chrisfen 417
180 cli2 1360 // 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 chrisfen 417
184 cli2 1360 all_pos_.clear();
185 cli2 1407 all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
186    
187 cli2 1360 // 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 chrisfen 996
192 cli2 1407 scanFile();
193    
194     readSet();
195    
196    
197 cli2 1360 // all ObjectRestraints have been handled, now we have to worry about
198     // molecular restraints:
199 chrisfen 431
200 cli2 1360 SimInfo::MoleculeIterator i;
201     Molecule::IntegrableObjectIterator j;
202     Molecule* mol;
203     StuntDouble* sd;
204 cli2 1407
205 cli2 1360 // 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 cli2 1407
209 cli2 1360 for (mol = info_->beginMolecule(i); mol != NULL;
210     mol = info_->nextMolecule(i)) {
211 cli2 1407
212 cli2 1360 // is this molecule restrained?
213     GenericData* data = mol->getPropertyByName("Restraint");
214 chrisfen 417
215 cli2 1360 if (data != NULL) {
216 cli2 1407
217 cli2 1360 // make sure we can reinterpret the generic data as restraint data:
218 cli2 1407
219 cli2 1360 RestraintData* restData= dynamic_cast<RestraintData*>(data);
220 cli2 1407
221 cli2 1360 if (restData != NULL) {
222 cli2 1407
223 cli2 1360 // make sure we can reinterpet the restraint data as a
224     // pointer to a MolecularRestraint:
225 cli2 1407
226 cli2 1360 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
227 cli2 1407
228 cli2 1360 if (mRest != NULL) {
229 cli2 1407
230 cli2 1360 // now we need to pack the stunt doubles for the reference
231     // structure:
232 cli2 1407
233 cli2 1360 std::vector<Vector3d> ref;
234     int count = 0;
235     RealType mass, mTot;
236     Vector3d COM(0.0);
237 chrisfen 417
238 cli2 1360 mTot = 0.0;
239 chrisfen 417
240 cli2 1360 // 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 cli2 1407 ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
251     mass = sd->getMass();
252 cli2 1360 COM = COM + mass * ref[count];
253     mTot = mTot + mass;
254     count = count + 1;
255 chrisfen 417 }
256 cli2 1360 COM /= mTot;
257     mRest->setReferenceStructure(ref, COM);
258 chrisfen 417 }
259     }
260     }
261     }
262     }
263 chrisfen 431
264 cli2 1360
265    
266     void RestReader::parseDumpLine(const std::string& line) {
267 cli2 1407
268 cli2 1360 StringTokenizer tokenizer(line);
269     int nTokens;
270    
271     nTokens = tokenizer.countTokens();
272    
273     if (nTokens < 2) {
274     sprintf(painCave.errMsg,
275 cli2 1407 "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
276 cli2 1360 painCave.isFatal = 1;
277     simError();
278     }
279 chrisfen 431
280 cli2 1360 int index = tokenizer.nextTokenAsInt();
281 chrisfen 431
282 gezelter 1782 StuntDouble* sd = info_->getIOIndexToIntegrableObject(index);
283 gezelter 1408
284 gezelter 1782 if (sd == NULL) {
285 gezelter 1408 return;
286     }
287 cli2 1407
288 gezelter 1408 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 cli2 1407 pos[0] = tokenizer.nextTokenAsDouble();
299     pos[1] = tokenizer.nextTokenAsDouble();
300     pos[2] = tokenizer.nextTokenAsDouble();
301 gezelter 1408 break;
302     }
303     case 'v' : {
304 cli2 1407 Vector3d vel;
305     vel[0] = tokenizer.nextTokenAsDouble();
306     vel[1] = tokenizer.nextTokenAsDouble();
307     vel[2] = tokenizer.nextTokenAsDouble();
308 gezelter 1408 break;
309     }
310    
311     case 'q' : {
312 gezelter 1782 if (sd->isDirectional()) {
313 cli2 1360
314 cli2 1407 q[0] = tokenizer.nextTokenAsDouble();
315     q[1] = tokenizer.nextTokenAsDouble();
316     q[2] = tokenizer.nextTokenAsDouble();
317     q[3] = tokenizer.nextTokenAsDouble();
318 gezelter 1408
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 gezelter 1782 if (sd->isDirectional()) {
335 gezelter 1408 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 cli2 1360
367 gezelter 1408 // is this io restrained?
368 gezelter 1782 GenericData* data = sd->getPropertyByName("Restraint");
369 gezelter 1408
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 cli2 1407 // an ObjectRestraint:
376 gezelter 1879 ObjectRestraint* oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
377 gezelter 1408 if (oRest != NULL) {
378 gezelter 1782 if (sd->isDirectional()) {
379 gezelter 1408 oRest->setReferenceStructure(pos, q.toRotationMatrix3());
380     } else {
381     oRest->setReferenceStructure(pos);
382 cli2 1407 }
383 cli2 1360 }
384     }
385 chrisfen 417 }
386     }
387 cli2 1407 }
388    
389     void RestReader::readStuntDoubles(std::istream& inputStream) {
390 chrisfen 417
391 cli2 1407 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 chrisfen 417 }
407 cli2 1407
408     parseDumpLine(line);
409 chrisfen 417 }
410 cli2 1407
411 cli2 1360 }
412 chrisfen 996
413 cli2 1407
414 cli2 1360 void RestReader::readFrameProperties(std::istream& inputStream) {
415     inputStream.getline(buffer, bufferSize);
416     std::string line(buffer);
417 chrisfen 423
418 cli2 1360 if (line.find("<FrameData>") == std::string::npos) {
419     sprintf(painCave.errMsg,
420 cli2 1407 "RestReader Error: Missing <FrameData>\n");
421 cli2 1360 painCave.isFatal = 1;
422     simError();
423     }
424 chrisfen 996
425 cli2 1360 // 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 chrisfen 417
432 cli2 1360 if(line.find("</FrameData>") != std::string::npos) {
433     break;
434 chrisfen 417 }
435    
436 cli2 1360 }
437 cli2 1407
438 chrisfen 417 }
439 chrisfen 1030
440 cli2 1360
441 gezelter 1390 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date