ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/RestReader.cpp
Revision: 1665
Committed: Tue Nov 22 20:38:56 2011 UTC (13 years, 5 months ago) by gezelter
File size: 13588 byte(s)
Log Message:
updated copyright notices

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     MPI_Bcast(&framePos_, 1, MPI_INT, 0, MPI_COMM_WORLD);
101     #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     MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
136     MPI_Bcast((void *)sendBuffer.c_str(), sendBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
137    
138     sstream.str(sendBuffer);
139 cli2 1360 } else {
140 cli2 1407 int sendBufferSize;
141     MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
142     char * recvBuffer = new char[sendBufferSize+1];
143     assert(recvBuffer);
144     recvBuffer[sendBufferSize] = '\0';
145     MPI_Bcast(recvBuffer, sendBufferSize, MPI_CHAR, masterNode, MPI_COMM_WORLD);
146     sstream.str(recvBuffer);
147     delete [] recvBuffer;
148     }
149    
150     std::istream& inputStream = sstream;
151     #endif
152    
153     inputStream.getline(buffer, bufferSize);
154    
155     line = buffer;
156     if (line.find("<Snapshot>") == std::string::npos) {
157     sprintf(painCave.errMsg,
158     "RestReader Error: can not find <Snapshot>\n");
159     painCave.isFatal = 1;
160     simError();
161 cli2 1360 }
162 cli2 1407
163     //read frameData
164     readFrameProperties(inputStream);
165    
166     //read StuntDoubles
167     readStuntDoubles(inputStream);
168    
169     inputStream.getline(buffer, bufferSize);
170     line = buffer;
171     if (line.find("</Snapshot>") == std::string::npos) {
172     sprintf(painCave.errMsg,
173     "RestReader Error: can not find </Snapshot>\n");
174     painCave.isFatal = 1;
175     simError();
176     }
177     }
178    
179     void RestReader::readReferenceStructure() {
180 chrisfen 417
181 cli2 1360 // We need temporary storage to keep track of all StuntDouble positions
182     // in case some of the restraints are molecular (i.e. if they use
183     // multiple SD positions to determine restrained orientations or positions:
184 chrisfen 417
185 cli2 1360 all_pos_.clear();
186 cli2 1407 all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
187    
188 cli2 1360 // Restraint files are just standard dump files, but with the reference
189     // structure stored in the first frame (frame 0).
190     // RestReader overloads readSet and explicitly handles all of the
191     // ObjectRestraints in that method:
192 chrisfen 996
193 cli2 1407 scanFile();
194    
195     readSet();
196    
197    
198 cli2 1360 // all ObjectRestraints have been handled, now we have to worry about
199     // molecular restraints:
200 chrisfen 431
201 cli2 1360 SimInfo::MoleculeIterator i;
202     Molecule::IntegrableObjectIterator j;
203     Molecule* mol;
204     StuntDouble* sd;
205 cli2 1407
206 cli2 1360 // no need to worry about parallel molecules, as molecules are not
207     // split across processor boundaries. Just loop over all molecules
208     // we know about:
209 cli2 1407
210 cli2 1360 for (mol = info_->beginMolecule(i); mol != NULL;
211     mol = info_->nextMolecule(i)) {
212 cli2 1407
213 cli2 1360 // is this molecule restrained?
214     GenericData* data = mol->getPropertyByName("Restraint");
215 chrisfen 417
216 cli2 1360 if (data != NULL) {
217 cli2 1407
218 cli2 1360 // make sure we can reinterpret the generic data as restraint data:
219 cli2 1407
220 cli2 1360 RestraintData* restData= dynamic_cast<RestraintData*>(data);
221 cli2 1407
222 cli2 1360 if (restData != NULL) {
223 cli2 1407
224 cli2 1360 // make sure we can reinterpet the restraint data as a
225     // pointer to a MolecularRestraint:
226 cli2 1407
227 cli2 1360 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
228 cli2 1407
229 cli2 1360 if (mRest != NULL) {
230 cli2 1407
231 cli2 1360 // now we need to pack the stunt doubles for the reference
232     // structure:
233 cli2 1407
234 cli2 1360 std::vector<Vector3d> ref;
235     int count = 0;
236     RealType mass, mTot;
237     Vector3d COM(0.0);
238 chrisfen 417
239 cli2 1360 mTot = 0.0;
240 chrisfen 417
241 cli2 1360 // loop over the stunt doubles in this molecule in the order we
242     // will be looping them in the restraint code:
243    
244     for (sd = mol->beginIntegrableObject(j); sd != NULL;
245     sd = mol->nextIntegrableObject(j)) {
246    
247     // push back the reference positions of the stunt
248     // doubles from the *globally* sorted array of
249     // positions:
250    
251 cli2 1407 ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
252     mass = sd->getMass();
253 cli2 1360 COM = COM + mass * ref[count];
254     mTot = mTot + mass;
255     count = count + 1;
256 chrisfen 417 }
257 cli2 1360 COM /= mTot;
258     mRest->setReferenceStructure(ref, COM);
259 chrisfen 417 }
260     }
261     }
262     }
263     }
264 chrisfen 431
265 cli2 1360
266    
267     void RestReader::parseDumpLine(const std::string& line) {
268 cli2 1407
269 cli2 1360 StringTokenizer tokenizer(line);
270     int nTokens;
271    
272     nTokens = tokenizer.countTokens();
273    
274     if (nTokens < 2) {
275     sprintf(painCave.errMsg,
276 cli2 1407 "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
277 cli2 1360 painCave.isFatal = 1;
278     simError();
279     }
280 chrisfen 431
281 cli2 1360 int index = tokenizer.nextTokenAsInt();
282 chrisfen 431
283 gezelter 1408 StuntDouble* integrableObject = info_->getIOIndexToIntegrableObject(index);
284    
285     if (integrableObject == NULL) {
286     return;
287     }
288 cli2 1407
289 gezelter 1408 std::string type = tokenizer.nextToken();
290     int size = type.size();
291    
292     Vector3d pos;
293     Quat4d q;
294    
295     for(int i = 0; i < size; ++i) {
296     switch(type[i]) {
297    
298     case 'p': {
299 cli2 1407 pos[0] = tokenizer.nextTokenAsDouble();
300     pos[1] = tokenizer.nextTokenAsDouble();
301     pos[2] = tokenizer.nextTokenAsDouble();
302 gezelter 1408 break;
303     }
304     case 'v' : {
305 cli2 1407 Vector3d vel;
306     vel[0] = tokenizer.nextTokenAsDouble();
307     vel[1] = tokenizer.nextTokenAsDouble();
308     vel[2] = tokenizer.nextTokenAsDouble();
309 gezelter 1408 break;
310     }
311    
312     case 'q' : {
313 cli2 1407 if (integrableObject->isDirectional()) {
314 cli2 1360
315 cli2 1407 q[0] = tokenizer.nextTokenAsDouble();
316     q[1] = tokenizer.nextTokenAsDouble();
317     q[2] = tokenizer.nextTokenAsDouble();
318     q[3] = tokenizer.nextTokenAsDouble();
319 gezelter 1408
320     RealType qlen = q.length();
321     if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
322    
323     sprintf(painCave.errMsg,
324     "RestReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2) ~ 0\n");
325     painCave.isFatal = 1;
326     simError();
327     }
328    
329     q.normalize();
330     }
331     break;
332     }
333     case 'j' : {
334     Vector3d ji;
335     if (integrableObject->isDirectional()) {
336     ji[0] = tokenizer.nextTokenAsDouble();
337     ji[1] = tokenizer.nextTokenAsDouble();
338     ji[2] = tokenizer.nextTokenAsDouble();
339     }
340     break;
341     }
342     case 'f': {
343     Vector3d force;
344     force[0] = tokenizer.nextTokenAsDouble();
345     force[1] = tokenizer.nextTokenAsDouble();
346     force[2] = tokenizer.nextTokenAsDouble();
347     break;
348     }
349     case 't' : {
350     Vector3d torque;
351     torque[0] = tokenizer.nextTokenAsDouble();
352     torque[1] = tokenizer.nextTokenAsDouble();
353     torque[2] = tokenizer.nextTokenAsDouble();
354     break;
355     }
356     default: {
357     sprintf(painCave.errMsg,
358     "RestReader Error: %s is an unrecognized type\n", type.c_str());
359     painCave.isFatal = 1;
360     simError();
361     break;
362     }
363     }
364     // keep the position in case we need it for a molecular restraint:
365    
366     all_pos_[index] = pos;
367 cli2 1360
368 gezelter 1408 // is this io restrained?
369     GenericData* data = integrableObject->getPropertyByName("Restraint");
370     ObjectRestraint* oRest;
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 cli2 1407 // an ObjectRestraint:
378 gezelter 1408 oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
379     if (oRest != NULL) {
380     if (integrableObject->isDirectional()) {
381     oRest->setReferenceStructure(pos, q.toRotationMatrix3());
382     } else {
383     oRest->setReferenceStructure(pos);
384 cli2 1407 }
385 cli2 1360 }
386     }
387 chrisfen 417 }
388     }
389 cli2 1407 }
390    
391     void RestReader::readStuntDoubles(std::istream& inputStream) {
392 chrisfen 417
393 cli2 1407 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 chrisfen 417 }
409 cli2 1407
410     parseDumpLine(line);
411 chrisfen 417 }
412 cli2 1407
413 cli2 1360 }
414 chrisfen 996
415 cli2 1407
416 cli2 1360 void RestReader::readFrameProperties(std::istream& inputStream) {
417     inputStream.getline(buffer, bufferSize);
418     std::string line(buffer);
419 chrisfen 423
420 cli2 1360 if (line.find("<FrameData>") == std::string::npos) {
421     sprintf(painCave.errMsg,
422 cli2 1407 "RestReader Error: Missing <FrameData>\n");
423 cli2 1360 painCave.isFatal = 1;
424     simError();
425     }
426 chrisfen 996
427 cli2 1360 // 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 chrisfen 417
434 cli2 1360 if(line.find("</FrameData>") != std::string::npos) {
435     break;
436 chrisfen 417 }
437    
438 cli2 1360 }
439 cli2 1407
440 chrisfen 417 }
441 chrisfen 1030
442 cli2 1360
443 gezelter 1390 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date