ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/RestReader.cpp
Revision: 1798
Committed: Thu Sep 13 14:10:11 2012 UTC (12 years, 7 months ago) by gezelter
File size: 13497 byte(s)
Log Message:
Merged trunk changes into the development branch

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     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39 gezelter 1665 * [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    
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 gezelter 1409 #include "utils/StringTokenizer.hpp"
60 cli2 1360 #include "restraints/ObjectRestraint.hpp"
61 cli2 1407 #include "restraints/MolecularRestraint.hpp"
62    
63     #ifdef IS_MPI
64    
65     #include <mpi.h>
66     #endif
67 chrisfen 417
68 gezelter 1390 namespace OpenMD {
69 cli2 1407
70     void RestReader::scanFile(){
71     int lineNo = 0;
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 cli2 1360
84 cli2 1407 bool foundOpenSnapshotTag = false;
85    
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 gezelter 1798 MPI::COMM_WORLD.Bcast(&framePos_, 1, MPI::INT, 0);
101 cli2 1407 #endif // is_mpi
102     }
103 chrisfen 417
104    
105 cli2 1407 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 gezelter 1798 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
136     MPI::COMM_WORLD.Bcast((void *)sendBuffer.c_str(), sendBufferSize,
137     MPI::CHAR, masterNode);
138 cli2 1407
139     sstream.str(sendBuffer);
140 cli2 1360 } else {
141 cli2 1407 int sendBufferSize;
142 gezelter 1798 MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
143 cli2 1407 char * recvBuffer = new char[sendBufferSize+1];
144     assert(recvBuffer);
145     recvBuffer[sendBufferSize] = '\0';
146 gezelter 1798 MPI::COMM_WORLD.Bcast(recvBuffer, sendBufferSize, MPI::CHAR, masterNode);
147 cli2 1407 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 cli2 1360 }
163 cli2 1407
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 chrisfen 417
182 cli2 1360 // 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 chrisfen 417
186 cli2 1360 all_pos_.clear();
187 cli2 1407 all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
188    
189 cli2 1360 // 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 chrisfen 996
194 cli2 1407 scanFile();
195    
196     readSet();
197    
198    
199 cli2 1360 // all ObjectRestraints have been handled, now we have to worry about
200     // molecular restraints:
201 chrisfen 431
202 cli2 1360 SimInfo::MoleculeIterator i;
203     Molecule::IntegrableObjectIterator j;
204     Molecule* mol;
205     StuntDouble* sd;
206 cli2 1407
207 cli2 1360 // 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 cli2 1407
211 cli2 1360 for (mol = info_->beginMolecule(i); mol != NULL;
212     mol = info_->nextMolecule(i)) {
213 cli2 1407
214 cli2 1360 // is this molecule restrained?
215     GenericData* data = mol->getPropertyByName("Restraint");
216 chrisfen 417
217 cli2 1360 if (data != NULL) {
218 cli2 1407
219 cli2 1360 // make sure we can reinterpret the generic data as restraint data:
220 cli2 1407
221 cli2 1360 RestraintData* restData= dynamic_cast<RestraintData*>(data);
222 cli2 1407
223 cli2 1360 if (restData != NULL) {
224 cli2 1407
225 cli2 1360 // make sure we can reinterpet the restraint data as a
226     // pointer to a MolecularRestraint:
227 cli2 1407
228 cli2 1360 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
229 cli2 1407
230 cli2 1360 if (mRest != NULL) {
231 cli2 1407
232 cli2 1360 // now we need to pack the stunt doubles for the reference
233     // structure:
234 cli2 1407
235 cli2 1360 std::vector<Vector3d> ref;
236     int count = 0;
237     RealType mass, mTot;
238     Vector3d COM(0.0);
239 chrisfen 417
240 cli2 1360 mTot = 0.0;
241 chrisfen 417
242 cli2 1360 // 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 cli2 1407 ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
253     mass = sd->getMass();
254 cli2 1360 COM = COM + mass * ref[count];
255     mTot = mTot + mass;
256     count = count + 1;
257 chrisfen 417 }
258 cli2 1360 COM /= mTot;
259     mRest->setReferenceStructure(ref, COM);
260 chrisfen 417 }
261     }
262     }
263     }
264     }
265 chrisfen 431
266 cli2 1360
267    
268     void RestReader::parseDumpLine(const std::string& line) {
269 cli2 1407
270 cli2 1360 StringTokenizer tokenizer(line);
271     int nTokens;
272    
273     nTokens = tokenizer.countTokens();
274    
275     if (nTokens < 2) {
276     sprintf(painCave.errMsg,
277 cli2 1407 "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
278 cli2 1360 painCave.isFatal = 1;
279     simError();
280     }
281 chrisfen 431
282 cli2 1360 int index = tokenizer.nextTokenAsInt();
283 chrisfen 431
284 gezelter 1769 StuntDouble* sd = info_->getIOIndexToIntegrableObject(index);
285 gezelter 1408
286 gezelter 1769 if (sd == NULL) {
287 gezelter 1408 return;
288     }
289 cli2 1407
290 gezelter 1408 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 cli2 1407 pos[0] = tokenizer.nextTokenAsDouble();
301     pos[1] = tokenizer.nextTokenAsDouble();
302     pos[2] = tokenizer.nextTokenAsDouble();
303 gezelter 1408 break;
304     }
305     case 'v' : {
306 cli2 1407 Vector3d vel;
307     vel[0] = tokenizer.nextTokenAsDouble();
308     vel[1] = tokenizer.nextTokenAsDouble();
309     vel[2] = tokenizer.nextTokenAsDouble();
310 gezelter 1408 break;
311     }
312    
313     case 'q' : {
314 gezelter 1769 if (sd->isDirectional()) {
315 cli2 1360
316 cli2 1407 q[0] = tokenizer.nextTokenAsDouble();
317     q[1] = tokenizer.nextTokenAsDouble();
318     q[2] = tokenizer.nextTokenAsDouble();
319     q[3] = tokenizer.nextTokenAsDouble();
320 gezelter 1408
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 gezelter 1769 if (sd->isDirectional()) {
337 gezelter 1408 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 cli2 1360
369 gezelter 1408 // is this io restrained?
370 gezelter 1769 GenericData* data = sd->getPropertyByName("Restraint");
371 gezelter 1408 ObjectRestraint* oRest;
372    
373     if (data != NULL) {
374     // make sure we can reinterpret the generic data as restraint data:
375     RestraintData* restData= dynamic_cast<RestraintData*>(data);
376     if (restData != NULL) {
377     // make sure we can reinterpet the restraint data as a pointer to
378 cli2 1407 // an ObjectRestraint:
379 gezelter 1408 oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
380     if (oRest != NULL) {
381 gezelter 1769 if (sd->isDirectional()) {
382 gezelter 1408 oRest->setReferenceStructure(pos, q.toRotationMatrix3());
383     } else {
384     oRest->setReferenceStructure(pos);
385 cli2 1407 }
386 cli2 1360 }
387     }
388 chrisfen 417 }
389     }
390 cli2 1407 }
391    
392     void RestReader::readStuntDoubles(std::istream& inputStream) {
393 chrisfen 417
394 cli2 1407 inputStream.getline(buffer, bufferSize);
395     std::string line(buffer);
396    
397     if (line.find("<StuntDoubles>") == std::string::npos) {
398     sprintf(painCave.errMsg,
399     "RestReader Error: Missing <StuntDoubles>\n");
400     painCave.isFatal = 1;
401     simError();
402     }
403    
404     while(inputStream.getline(buffer, bufferSize)) {
405     line = buffer;
406    
407     if(line.find("</StuntDoubles>") != std::string::npos) {
408     break;
409 chrisfen 417 }
410 cli2 1407
411     parseDumpLine(line);
412 chrisfen 417 }
413 cli2 1407
414 cli2 1360 }
415 chrisfen 996
416 cli2 1407
417 cli2 1360 void RestReader::readFrameProperties(std::istream& inputStream) {
418     inputStream.getline(buffer, bufferSize);
419     std::string line(buffer);
420 chrisfen 423
421 cli2 1360 if (line.find("<FrameData>") == std::string::npos) {
422     sprintf(painCave.errMsg,
423 cli2 1407 "RestReader Error: Missing <FrameData>\n");
424 cli2 1360 painCave.isFatal = 1;
425     simError();
426     }
427 chrisfen 996
428 cli2 1360 // restraints don't care about frame data (unless we need to wrap
429     // coordinates, but we'll worry about that later), so
430     // we'll just scan ahead until the end of the frame data:
431    
432     while(inputStream.getline(buffer, bufferSize)) {
433     line = buffer;
434 chrisfen 417
435 cli2 1360 if(line.find("</FrameData>") != std::string::npos) {
436     break;
437 chrisfen 417 }
438    
439 cli2 1360 }
440 cli2 1407
441 chrisfen 417 }
442 chrisfen 1030
443 cli2 1360
444 gezelter 1390 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date