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

# Content
1 /*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * 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 */
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
48 namespace OpenMD {
49
50 void RestReader::readReferenceStructure() {
51
52 // some of this comes directly from DumpReader.
53
54 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
73 needAngMom_ = false;
74
75 // 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
79 all_pos_.clear();
80 all_pos_.resize(info_->getNGlobalIntegrableObjects() );
81
82
83 // 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
88 readSet(0);
89
90 // all ObjectRestraints have been handled, now we have to worry about
91 // molecular restraints:
92
93 SimInfo::MoleculeIterator i;
94 Molecule::IntegrableObjectIterator j;
95 Molecule* mol;
96 StuntDouble* sd;
97
98 // 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
102 for (mol = info_->beginMolecule(i); mol != NULL;
103 mol = info_->nextMolecule(i)) {
104
105 // is this molecule restrained?
106 GenericData* data = mol->getPropertyByName("Restraint");
107
108 if (data != NULL) {
109
110 // make sure we can reinterpret the generic data as restraint data:
111
112 RestraintData* restData= dynamic_cast<RestraintData*>(data);
113
114 if (restData != NULL) {
115
116 // make sure we can reinterpet the restraint data as a
117 // pointer to a MolecularRestraint:
118
119 MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
120
121 if (mRest != NULL) {
122
123 // now we need to pack the stunt doubles for the reference
124 // structure:
125
126 std::vector<Vector3d> ref;
127 int count = 0;
128 RealType mass, mTot;
129 Vector3d COM(0.0);
130
131 mTot = 0.0;
132
133 // 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 }
151
152 COM /= mTot;
153
154 mRest->setReferenceStructure(ref, COM);
155
156 }
157 }
158 }
159 }
160 }
161
162
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
177 int index = tokenizer.nextTokenAsInt();
178
179 StuntDouble* integrableObject = info_->getIOIndexToIntegrableObject(index);
180
181 if (integrableObject == NULL) {
182 return;
183 }
184
185 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
210 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 if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
220
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
245 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 }
263 }
264
265 // keep the position in case we need it for a molecular restraint:
266
267 all_pos_[index] = pos;
268
269 // is this io restrained?
270 GenericData* data = integrableObject->getPropertyByName("Restraint");
271 ObjectRestraint* oRest;
272
273 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 }
288 }
289
290 }
291
292
293
294 void RestReader::readFrameProperties(std::istream& inputStream) {
295 inputStream.getline(buffer, bufferSize);
296 std::string line(buffer);
297
298 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
305 // 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
312 if(line.find("</FrameData>") != std::string::npos) {
313 break;
314 }
315
316 }
317
318 }
319
320
321 }//end namespace OpenMD