ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/RestReader.cpp
Revision: 1973
Committed: Thu Mar 6 19:34:22 2014 UTC (11 years, 1 month ago) by gezelter
File size: 13520 byte(s)
Log Message:
Some updates for restraints and fluctuating charges in Ewald

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 gezelter 1971 std::streampos currPos;
72 cli2 1407
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 gezelter 1973 framePos_ = (long long) prevPos;
92 cli2 1407 }
93     prevPos = currPos;
94     }
95    
96     #ifdef IS_MPI
97     }
98 gezelter 1973 MPI_Bcast(&framePos_, 1, MPI_LONG_LONG, 0, MPI_COMM_WORLD);
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 1969 MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
134     MPI_Bcast((void *)sendBuffer.c_str(), sendBufferSize,
135     MPI_CHAR, masterNode, MPI_COMM_WORLD);
136 cli2 1407
137     sstream.str(sendBuffer);
138 cli2 1360 } else {
139 cli2 1407 int sendBufferSize;
140 gezelter 1969 MPI_Bcast(&sendBufferSize, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
141 cli2 1407 char * recvBuffer = new char[sendBufferSize+1];
142     assert(recvBuffer);
143     recvBuffer[sendBufferSize] = '\0';
144 gezelter 1969 MPI_Bcast(recvBuffer, sendBufferSize, MPI_CHAR, masterNode,
145     MPI_COMM_WORLD);
146 cli2 1407 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 1782 StuntDouble* sd = info_->getIOIndexToIntegrableObject(index);
284 gezelter 1408
285 gezelter 1782 if (sd == NULL) {
286 gezelter 1408 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 gezelter 1782 if (sd->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 gezelter 1782 if (sd->isDirectional()) {
336 gezelter 1408 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 gezelter 1782 GenericData* data = sd->getPropertyByName("Restraint");
370 gezelter 1408
371     if (data != NULL) {
372     // make sure we can reinterpret the generic data as restraint data:
373     RestraintData* restData= dynamic_cast<RestraintData*>(data);
374     if (restData != NULL) {
375     // make sure we can reinterpet the restraint data as a pointer to
376 cli2 1407 // an ObjectRestraint:
377 gezelter 1879 ObjectRestraint* oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
378 gezelter 1408 if (oRest != NULL) {
379 gezelter 1782 if (sd->isDirectional()) {
380 gezelter 1408 oRest->setReferenceStructure(pos, q.toRotationMatrix3());
381     } else {
382     oRest->setReferenceStructure(pos);
383 cli2 1407 }
384 cli2 1360 }
385     }
386 chrisfen 417 }
387     }
388 cli2 1407 }
389    
390     void RestReader::readStuntDoubles(std::istream& inputStream) {
391 chrisfen 417
392 cli2 1407 inputStream.getline(buffer, bufferSize);
393     std::string line(buffer);
394    
395     if (line.find("<StuntDoubles>") == std::string::npos) {
396     sprintf(painCave.errMsg,
397     "RestReader Error: Missing <StuntDoubles>\n");
398     painCave.isFatal = 1;
399     simError();
400     }
401    
402     while(inputStream.getline(buffer, bufferSize)) {
403     line = buffer;
404    
405     if(line.find("</StuntDoubles>") != std::string::npos) {
406     break;
407 chrisfen 417 }
408 cli2 1407
409     parseDumpLine(line);
410 chrisfen 417 }
411 cli2 1407
412 cli2 1360 }
413 chrisfen 996
414 cli2 1407
415 cli2 1360 void RestReader::readFrameProperties(std::istream& inputStream) {
416     inputStream.getline(buffer, bufferSize);
417     std::string line(buffer);
418 chrisfen 423
419 cli2 1360 if (line.find("<FrameData>") == std::string::npos) {
420     sprintf(painCave.errMsg,
421 cli2 1407 "RestReader Error: Missing <FrameData>\n");
422 cli2 1360 painCave.isFatal = 1;
423     simError();
424     }
425 chrisfen 996
426 cli2 1360 // restraints don't care about frame data (unless we need to wrap
427     // coordinates, but we'll worry about that later), so
428     // we'll just scan ahead until the end of the frame data:
429    
430     while(inputStream.getline(buffer, bufferSize)) {
431     line = buffer;
432 chrisfen 417
433 cli2 1360 if(line.find("</FrameData>") != std::string::npos) {
434     break;
435 chrisfen 417 }
436    
437 cli2 1360 }
438 cli2 1407
439 chrisfen 417 }
440 chrisfen 1030
441 cli2 1360
442 gezelter 1390 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date