ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/RestReader.cpp
Revision: 1390
Committed: Wed Nov 25 20:02:06 2009 UTC (15 years, 5 months ago) by gezelter
Original Path: trunk/src/io/RestReader.cpp
File size: 10389 byte(s)
Log Message:
Almost all of the changes necessary to create OpenMD out of our old
project (OOPSE-4)

File Contents

# User Rev Content
1 cli2 1360 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
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     * [4] Vardeman & Gezelter, in progress (2009).
40 cli2 1360 */
41    
42     #include "io/DumpReader.hpp"
43     #include "io/RestReader.hpp"
44     #include "primitives/Molecule.hpp"
45     #include "restraints/ObjectRestraint.hpp"
46     #include "restraints/MolecularRestraint.hpp"
47 chrisfen 417
48 gezelter 1390 namespace OpenMD {
49 cli2 1360
50     void RestReader::readReferenceStructure() {
51 chrisfen 417
52 cli2 1360 // some of this comes directly from DumpReader.
53 chrisfen 417
54 cli2 1360 if (!isScanned_)
55     scanFile();
56    
57     int storageLayout = info_->getSnapshotManager()->getStorageLayout();
58    
59     if (storageLayout & DataStorage::dslPosition) {
60     needPos_ = true;
61     } else {
62     needPos_ = false;
63     }
64    
65     needVel_ = false;
66    
67     if (storageLayout & DataStorage::dslAmat || storageLayout & DataStorage::dslElectroFrame) {
68     needQuaternion_ = true;
69     } else {
70     needQuaternion_ = false;
71     }
72 chrisfen 417
73 cli2 1360 needAngMom_ = false;
74 chrisfen 417
75 cli2 1360 // We need temporary storage to keep track of all StuntDouble positions
76     // in case some of the restraints are molecular (i.e. if they use
77     // multiple SD positions to determine restrained orientations or positions:
78 chrisfen 417
79 cli2 1360 all_pos_.clear();
80     all_pos_.resize(info_->getNGlobalIntegrableObjects() );
81 chrisfen 417
82 chrisfen 996
83 cli2 1360 // Restraint files are just standard dump files, but with the reference
84     // structure stored in the first frame (frame 0).
85     // RestReader overloads readSet and explicitly handles all of the
86     // ObjectRestraints in that method:
87 chrisfen 996
88 cli2 1360 readSet(0);
89    
90     // all ObjectRestraints have been handled, now we have to worry about
91     // molecular restraints:
92 chrisfen 431
93 cli2 1360 SimInfo::MoleculeIterator i;
94     Molecule::IntegrableObjectIterator j;
95     Molecule* mol;
96     StuntDouble* sd;
97 chrisfen 996
98 cli2 1360 // no need to worry about parallel molecules, as molecules are not
99     // split across processor boundaries. Just loop over all molecules
100     // we know about:
101 chrisfen 996
102 cli2 1360 for (mol = info_->beginMolecule(i); mol != NULL;
103     mol = info_->nextMolecule(i)) {
104 chrisfen 996
105 cli2 1360 // is this molecule restrained?
106     GenericData* data = mol->getPropertyByName("Restraint");
107 chrisfen 417
108 cli2 1360 if (data != NULL) {
109 chrisfen 996
110 cli2 1360 // make sure we can reinterpret the generic data as restraint data:
111 chrisfen 996
112 cli2 1360 RestraintData* restData= dynamic_cast<RestraintData*>(data);
113 chrisfen 423
114 cli2 1360 if (restData != NULL) {
115 chrisfen 431
116 cli2 1360 // make sure we can reinterpet the restraint data as a
117     // pointer to a MolecularRestraint:
118 chrisfen 996
119 cli2 1360 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
120 chrisfen 996
121 cli2 1360 if (mRest != NULL) {
122 chrisfen 431
123 cli2 1360 // now we need to pack the stunt doubles for the reference
124     // structure:
125 chrisfen 990
126 cli2 1360 std::vector<Vector3d> ref;
127     int count = 0;
128     RealType mass, mTot;
129     Vector3d COM(0.0);
130 chrisfen 417
131 cli2 1360 mTot = 0.0;
132 chrisfen 417
133 cli2 1360 // loop over the stunt doubles in this molecule in the order we
134     // will be looping them in the restraint code:
135    
136     for (sd = mol->beginIntegrableObject(j); sd != NULL;
137     sd = mol->nextIntegrableObject(j)) {
138    
139     // push back the reference positions of the stunt
140     // doubles from the *globally* sorted array of
141     // positions:
142    
143     ref.push_back( all_pos_[sd->getGlobalIndex()] );
144    
145     mass = sd->getMass();
146    
147     COM = COM + mass * ref[count];
148     mTot = mTot + mass;
149     count = count + 1;
150 chrisfen 417 }
151    
152 cli2 1360 COM /= mTot;
153 chrisfen 990
154 cli2 1360 mRest->setReferenceStructure(ref, COM);
155 chrisfen 990
156 chrisfen 417 }
157     }
158     }
159     }
160     }
161 chrisfen 431
162 cli2 1360
163    
164     void RestReader::parseDumpLine(const std::string& line) {
165     StringTokenizer tokenizer(line);
166     int nTokens;
167    
168     nTokens = tokenizer.countTokens();
169    
170     if (nTokens < 2) {
171     sprintf(painCave.errMsg,
172     "DumpReader Error: Not enough Tokens.\n%s\n", line.c_str());
173     painCave.isFatal = 1;
174     simError();
175     }
176 chrisfen 431
177 cli2 1360 int index = tokenizer.nextTokenAsInt();
178    
179     StuntDouble* integrableObject = info_->getIOIndexToIntegrableObject(index);
180 chrisfen 431
181 cli2 1360 if (integrableObject == NULL) {
182     return;
183     }
184 chrisfen 431
185 cli2 1360 std::string type = tokenizer.nextToken();
186     int size = type.size();
187     Vector3d pos;
188     Vector3d vel;
189     Quat4d q;
190     Vector3d ji;
191     Vector3d force;
192     Vector3d torque;
193    
194     for(int i = 0; i < size; ++i) {
195     switch(type[i]) {
196    
197     case 'p': {
198     pos[0] = tokenizer.nextTokenAsDouble();
199     pos[1] = tokenizer.nextTokenAsDouble();
200     pos[2] = tokenizer.nextTokenAsDouble();
201     break;
202     }
203     case 'v' : {
204     vel[0] = tokenizer.nextTokenAsDouble();
205     vel[1] = tokenizer.nextTokenAsDouble();
206     vel[2] = tokenizer.nextTokenAsDouble();
207     break;
208     }
209 chrisfen 431
210 cli2 1360 case 'q' : {
211     if (integrableObject->isDirectional()) {
212    
213     q[0] = tokenizer.nextTokenAsDouble();
214     q[1] = tokenizer.nextTokenAsDouble();
215     q[2] = tokenizer.nextTokenAsDouble();
216     q[3] = tokenizer.nextTokenAsDouble();
217    
218     RealType qlen = q.length();
219 gezelter 1390 if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
220 cli2 1360
221     sprintf(painCave.errMsg,
222     "DumpReader Error: initial quaternion error (q0^2 + q1^2 + q2^2 + q3^2) ~ 0\n");
223     painCave.isFatal = 1;
224     simError();
225    
226     }
227    
228     q.normalize();
229     }
230     break;
231     }
232     case 'j' : {
233     if (integrableObject->isDirectional()) {
234     ji[0] = tokenizer.nextTokenAsDouble();
235     ji[1] = tokenizer.nextTokenAsDouble();
236     ji[2] = tokenizer.nextTokenAsDouble();
237     }
238     break;
239     }
240     case 'f': {
241     force[0] = tokenizer.nextTokenAsDouble();
242     force[1] = tokenizer.nextTokenAsDouble();
243     force[2] = tokenizer.nextTokenAsDouble();
244 chrisfen 996
245 cli2 1360 break;
246     }
247     case 't' : {
248     torque[0] = tokenizer.nextTokenAsDouble();
249     torque[1] = tokenizer.nextTokenAsDouble();
250     torque[2] = tokenizer.nextTokenAsDouble();
251    
252     break;
253     }
254     default: {
255     sprintf(painCave.errMsg,
256     "DumpReader Error: %s is an unrecognized type\n", type.c_str());
257     painCave.isFatal = 1;
258     simError();
259     break;
260     }
261    
262 chrisfen 417 }
263     }
264 cli2 1360
265     // keep the position in case we need it for a molecular restraint:
266 chrisfen 417
267 cli2 1360 all_pos_[index] = pos;
268 chrisfen 996
269 cli2 1360 // is this io restrained?
270     GenericData* data = integrableObject->getPropertyByName("Restraint");
271     ObjectRestraint* oRest;
272 chrisfen 996
273 cli2 1360 if (data != NULL) {
274     // make sure we can reinterpret the generic data as restraint data:
275     RestraintData* restData= dynamic_cast<RestraintData*>(data);
276     if (restData != NULL) {
277     // make sure we can reinterpet the restraint data as a pointer to
278     // an ObjectRestraint:
279     oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
280     if (oRest != NULL) {
281     if (integrableObject->isDirectional()) {
282     oRest->setReferenceStructure(pos, q.toRotationMatrix3());
283     } else {
284     oRest->setReferenceStructure(pos);
285     }
286     }
287 chrisfen 417 }
288     }
289 chrisfen 423
290 cli2 1360 }
291    
292 chrisfen 996
293 chrisfen 423
294 cli2 1360 void RestReader::readFrameProperties(std::istream& inputStream) {
295     inputStream.getline(buffer, bufferSize);
296     std::string line(buffer);
297 chrisfen 423
298 cli2 1360 if (line.find("<FrameData>") == std::string::npos) {
299     sprintf(painCave.errMsg,
300     "DumpReader Error: Missing <FrameData>\n");
301     painCave.isFatal = 1;
302     simError();
303     }
304 chrisfen 996
305 cli2 1360 // restraints don't care about frame data (unless we need to wrap
306     // coordinates, but we'll worry about that later), so
307     // we'll just scan ahead until the end of the frame data:
308    
309     while(inputStream.getline(buffer, bufferSize)) {
310     line = buffer;
311 chrisfen 417
312 cli2 1360 if(line.find("</FrameData>") != std::string::npos) {
313     break;
314 chrisfen 417 }
315    
316 cli2 1360 }
317 chrisfen 985
318 chrisfen 417 }
319 chrisfen 1030
320 cli2 1360
321 gezelter 1390 }//end namespace OpenMD