ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/RestReader.cpp
(Generate patch)

Comparing trunk/src/io/RestReader.cpp (file contents):
Revision 423 by chrisfen, Thu Mar 10 19:11:02 2005 UTC vs.
Revision 1796 by gezelter, Mon Sep 10 18:38:44 2012 UTC

# Line 1 | Line 1
1 < /*
2 < * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 < *
1 > /*
2 > * Copyright (c) 2009 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. Acknowledgement of the program authors must be made in any
10 < *    publication of scientific results based in part on use of the
11 < *    program.  An acceptable form of acknowledgement is citation of
12 < *    the article in which the program was described (Matthew
13 < *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 < *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 < *    Parallel Simulation Engine for Molecular Dynamics,"
16 < *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 < *
18 < * 2. Redistributions of source code must retain the above copyright
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
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.
# Line 37 | Line 28
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 < */
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]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40 > * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 > */
42  
43 < #define _LARGEFILE_SOURCE64
44 < #define _FILE_OFFSET_BITS 64
45 <
46 < #include <sys/types.h>
47 < #include <sys/stat.h>
48 <
49 < #include <iostream>
50 < #include <math.h>
51 <
52 < #include <stdio.h>
53 < #include <stdlib.h>
54 < #include <string.h>
55 <
56 < #include "primitives/Molecule.hpp"
57 < #include "utils/MemoryUtils.hpp"
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   #include "utils/StringTokenizer.hpp"
60 < #include "io/RestReader.hpp"
61 < #include "utils/simError.h"
60 > #include "restraints/ObjectRestraint.hpp"
61 > #include "restraints/MolecularRestraint.hpp"
62 >
63 > #ifdef IS_MPI
64 >
65 > #include <mpi.h>
66 > #endif
67  
68 < #ifdef IS_MPI
62 < #include <mpi.h>
63 < #define TAKE_THIS_TAG_CHAR 0
64 < #define TAKE_THIS_TAG_INT 1
65 < #define TAKE_THIS_TAG_DOUBLE 2
66 < #endif // is_mpi
68 > namespace OpenMD {
69  
70 < namespace oopse {
71 <  
72 <  RestReader::RestReader( SimInfo* info ) : info_(info){
73 <        
72 <    idealName = "idealCrystal.in";
70 >  void RestReader::scanFile(){
71 >    int lineNo = 0;
72 >    std::streampos prevPos;
73 >    std::streampos  currPos;
74      
75 <    isScanned = false;
75 > #ifdef IS_MPI
76      
77 < #ifdef IS_MPI
78 <    if (worldRank == 0) {
79 < #endif
77 >    if (worldRank == 0) {
78 > #endif // is_mpi
79 >
80 >      inFile_->clear();
81 >      currPos = inFile_->tellg();
82 >      prevPos = currPos;
83        
84 <      inIdealFile = fopen(idealName, "r");
85 <      if(inIdealFile == NULL){
86 <        sprintf(painCave.errMsg,
87 <                "RestReader: Cannot open file: %s\n", idealName);
88 <        painCave.isFatal = 1;
89 <        simError();
84 >      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 <      inIdealFileName = idealName;
89 < #ifdef IS_MPI
98 > #ifdef IS_MPI
99      }
100 <    strcpy( checkPointMsg,
101 <            "File \"idealCrystal.in\" opened successfully for reading." );
102 <    MPIcheckPoint();
103 < #endif
104 <    return;  
105 <  }
106 <  
107 <  RestReader :: ~RestReader( ){
108 < #ifdef IS_MPI
109 <    if (worldRank == 0) {
110 < #endif
111 <      int error;
112 <      error = fclose( inIdealFile );
100 >    MPI::COMM_WORLD.Bcast(&framePos_, 1, MPI::INT, 0);
101 > #endif // is_mpi
102 >  }
103 >
104 >
105 >  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 <      if( error ){
122 <        sprintf( painCave.errMsg,
123 <                 "Error closing %s\n", inIdealFileName.c_str());
124 <        simError();
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 <      MemoryUtils::deletePointers(framePos);
134 >      int sendBufferSize = sendBuffer.size();
135 >      MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
136 >      MPI::COMM_WORLD.Bcast((void *)sendBuffer.c_str(), sendBufferSize,
137 >                            MPI::CHAR, masterNode);
138        
139 < #ifdef IS_MPI
140 <    }
141 <    strcpy( checkPointMsg, "Restraint file closed successfully." );
142 <    MPIcheckPoint();
139 >      sstream.str(sendBuffer);
140 >    } else {
141 >      int sendBufferSize;
142 >      MPI::COMM_WORLD.Bcast(&sendBufferSize, 1, MPI::INT, masterNode);
143 >      char * recvBuffer = new char[sendBufferSize+1];
144 >      assert(recvBuffer);
145 >      recvBuffer[sendBufferSize] = '\0';
146 >      MPI::COMM_WORLD.Bcast(recvBuffer, sendBufferSize, MPI::CHAR, masterNode);
147 >      sstream.str(recvBuffer);
148 >      delete [] recvBuffer;
149 >    }      
150 >    
151 >    std::istream& inputStream = sstream;  
152   #endif
153      
154 <    return;
155 <  }
156 <  
157 <  
158 <  void RestReader :: readIdealCrystal(){
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 >    }
163      
164 <    int i;
165 <    unsigned int j;
164 >    //read frameData
165 >    readFrameProperties(inputStream);
166      
167 < #ifdef IS_MPI
168 <    int done, which_node, which_atom; // loop counter
130 < #endif //is_mpi
167 >    //read StuntDoubles
168 >    readStuntDoubles(inputStream);
169      
170 <    const int BUFFERSIZE = 2000; // size of the read buffer
171 <    int nTotObjs; // the number of atoms
172 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
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 <    char *eof_test; // ptr to see when we reach the end of the file
181 <    char *parseErr;
180 >  void RestReader::readReferenceStructure() {
181 >
182 >    // 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 >
186 >    all_pos_.clear();
187 >    all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
188      
189 <    std::vector<StuntDouble*> integrableObjects;
190 <    
189 >    // 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 >
194 >    scanFile();
195 >
196 >    readSet();
197 >
198 >
199 >    // all ObjectRestraints have been handled, now we have to worry about
200 >    // molecular restraints:
201 >
202 >    SimInfo::MoleculeIterator i;
203 >    Molecule::IntegrableObjectIterator j;
204      Molecule* mol;
205 <    StuntDouble* integrableObject;
143 <    SimInfo::MoleculeIterator mi;
144 <    Molecule::IntegrableObjectIterator ii;
205 >    StuntDouble* sd;
206      
207 < #ifndef IS_MPI
207 >    // 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      
211 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
212 <    if( eof_test == NULL ){
150 <      sprintf( painCave.errMsg,
151 <               "RestraintReader error: error reading 1st line of \"%s\"\n",
152 <               inIdealFileName.c_str() );
153 <      painCave.isFatal = 1;
154 <      simError();
155 <    }
156 <    
157 <    nTotObjs = atoi( read_buffer );
158 <    
159 <    if( nTotObjs != info_->getNGlobalIntegrableObjects() ){
160 <      sprintf( painCave.errMsg,
161 <               "RestraintReader error. %s nIntegrable, %d, "
162 <               "does not match the meta-data file's nIntegrable, %d.\n",
163 <               inIdealFileName.c_str(), nTotObjs,
164 <               info_->getNGlobalIntegrableObjects());
165 <      painCave.isFatal = 1;
166 <      simError();
167 <    }
168 <    
169 <    // skip over the comment line
170 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
171 <    if(eof_test == NULL){
172 <      sprintf( painCave.errMsg,
173 <               "error in reading commment in %s\n", inIdealFileName.c_str());
174 <      painCave.isFatal = 1;
175 <      simError();
176 <    }
177 <    
178 <    // parse the ideal crystal lines
179 <    /*
180 <     * Note: we assume that there is a one-to-one correspondence between
181 <     * integrable objects and lines in the idealCrystal.in file.  Thermodynamic
182 <     * integration is only supported for simple rigid bodies.
183 <     */
184 <    for (mol = info_->beginMolecule(mi); mol != NULL;
185 <         mol = info_->nextMolecule(mi)) {
211 >    for (mol = info_->beginMolecule(i); mol != NULL;
212 >         mol = info_->nextMolecule(i)) {          
213        
214 <      for (integrableObject = mol->beginIntegrableObject(ii);
215 <           integrableObject != NULL;
216 <           integrableObject = mol->nextIntegrableObject(ii)) {    
214 >      // is this molecule restrained?    
215 >      GenericData* data = mol->getPropertyByName("Restraint");
216 >      
217 >      if (data != NULL) {
218          
219 <        eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
192 <        if(eof_test == NULL){
193 <          sprintf(painCave.errMsg,
194 <                  "RestReader Error: error in reading file %s\n"
195 <                  "natoms  = %d; index = %d\n"
196 <                  "error reading the line from the file.\n",
197 <                  inIdealFileName.c_str(), nTotObjs,
198 <                  integrableObject->getGlobalIndex() );
199 <          painCave.isFatal = 1;
200 <          simError();
201 <        }
219 >        // make sure we can reinterpret the generic data as restraint data:
220          
221 <        parseErr = parseIdealLine( read_buffer, integrableObject);
204 <        if( parseErr != NULL ){
205 <          strcpy( painCave.errMsg, parseErr );
206 <          painCave.isFatal = 1;
207 <          simError();
208 <        }
209 <      }
210 <    }
211 <    
212 <    // MPI Section of code..........
213 < #else //IS_MPI
214 <    
215 <    // first thing first, suspend fatalities.
216 <    painCave.isEventLoop = 1;
217 <    
218 <    int masterNode = 0;
219 <    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
220 <    
221 <    MPI_Status istatus;
222 <    int nCurObj;
223 <    int nitems;
224 <    int haveError;
225 <
226 <    nTotObjs = info_->getNGlobalIntegrableObjects();
227 <    haveError = 0;
228 <    
229 <    if (worldRank == masterNode) {
230 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
231 <      if( eof_test == NULL ){
232 <        sprintf( painCave.errMsg,
233 <                 "Error reading 1st line of %s \n ",inIdealFileName.c_str());
234 <        painCave.isFatal = 1;
235 <        simError();
236 <      }
237 <      
238 <      nitems = atoi( read_buffer );
239 <      
240 <      // Check to see that the number of integrable objects in the
241 <      // intial configuration file is the same as derived from the
242 <      // meta-data file.
243 <      if( nTotObjs != nitems){
244 <        sprintf( painCave.errMsg,
245 <                 "RestraintReader Error. %s nIntegrable, %d, "
246 <                 "does not match the meta-data file's nIntegrable, %d.\n",
247 <                 inIdealFileName.c_str(), nTotObjs,
248 <                 info_->getNGlobalIntegrableObjects());
249 <        painCave.isFatal = 1;
250 <        simError();
251 <      }
252 <      
253 <      // skip over the comment line
254 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
255 <      if(eof_test == NULL){
256 <        sprintf( painCave.errMsg,
257 <                 "error in reading commment in %s\n", inIdealFileName.c_str());
258 <        painCave.isFatal = 1;
259 <        simError();
260 <      }
261 <      
262 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
263 <        int which_node = info_->getMolToProc(i);
221 >        RestraintData* restData= dynamic_cast<RestraintData*>(data);        
222          
223 <        if(which_node == masterNode){
266 <          //molecules belong to master node
223 >        if (restData != NULL) {
224            
225 <          mol = info_->getMoleculeByGlobalIndex(i);
225 >          // make sure we can reinterpet the restraint data as a
226 >          // pointer to a MolecularRestraint:
227            
228 <          if(mol == NULL) {
271 <            sprintf(painCave.errMsg,
272 <                   "RestReader Error: Molecule not found on node %d!\n",
273 <                   worldRank);
274 <            painCave.isFatal = 1;
275 <            simError();
276 <          }
228 >          MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
229            
230 <          for (integrableObject = mol->beginIntegrableObject(ii);
279 <               integrableObject != NULL;
280 <               integrableObject = mol->nextIntegrableObject(ii)){
230 >          if (mRest != NULL) {          
231              
232 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
232 >            // now we need to pack the stunt doubles for the reference
233 >            // structure:
234              
235 <            if(eof_test == NULL){
236 <              sprintf(painCave.errMsg,
237 <                      "RestReader Error: error in reading file %s\n"
238 <                      "natoms  = %d; index = %d\n"
288 <                      "error reading the line from the file.\n",
289 <                      inIdealFileName.c_str(), nTotObjs, i );
290 <              painCave.isFatal = 1;
291 <              simError();
292 <            }
235 >            std::vector<Vector3d> ref;
236 >            int count = 0;
237 >            RealType mass, mTot;
238 >            Vector3d COM(0.0);
239              
240 <            parseIdealLine(read_buffer, integrableObjects[j]);
295 <          }
296 <        } else {
297 <          //molecule belongs to slave nodes
298 <          
299 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
300 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
301 <          
302 <          for(j=0; j < nCurObj; j++){
240 >            mTot = 0.0;
241              
242 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
243 <            if(eof_test == NULL){
306 <              sprintf(painCave.errMsg,
307 <                      "RestReader Error: error in reading file %s\n"
308 <                      "natoms  = %d; index = %d\n"
309 <                      "error reading the line from the file.\n",
310 <                      inIdealFileName.c_str(), nTotObjs, i );
311 <              painCave.isFatal = 1;
312 <              simError();
313 <            }
242 >            // loop over the stunt doubles in this molecule in the order we
243 >            // will be looping them in the restraint code:
244              
245 <            MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
246 <                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
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 >              ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
253 >              mass = sd->getMass();              
254 >              COM = COM + mass * ref[count];
255 >              mTot = mTot + mass;
256 >              count = count + 1;
257 >            }
258 >            COM /= mTot;
259 >            mRest->setReferenceStructure(ref, COM);        
260            }
261          }
262        }
263 <    } else {
264 <      //actions taken at slave nodes
265 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
266 <        int which_node = info_->getMolToProc(i);
267 <        
268 <        if(which_node == worldRank){
269 <          //molecule with global index i belongs to this processor
263 >    }
264 >  }
265 >
266 >  
267 >  
268 >  void RestReader::parseDumpLine(const std::string& line) {        
269 >
270 >    StringTokenizer tokenizer(line);
271 >    int nTokens;
272 >    
273 >    nTokens = tokenizer.countTokens();
274 >    
275 >    if (nTokens < 2) {
276 >      sprintf(painCave.errMsg,
277 >              "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
278 >      painCave.isFatal = 1;
279 >      simError();
280 >    }
281 >
282 >    int index = tokenizer.nextTokenAsInt();
283 >
284 >    StuntDouble* sd = info_->getIOIndexToIntegrableObject(index);
285 >
286 >    if (sd == NULL) {
287 >      return;
288 >    }
289 >  
290 >    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 >        pos[0] = tokenizer.nextTokenAsDouble();
301 >        pos[1] = tokenizer.nextTokenAsDouble();
302 >        pos[2] = tokenizer.nextTokenAsDouble();
303 >        break;
304 >      }
305 >      case 'v' : {
306 >        Vector3d vel;
307 >        vel[0] = tokenizer.nextTokenAsDouble();
308 >        vel[1] = tokenizer.nextTokenAsDouble();
309 >        vel[2] = tokenizer.nextTokenAsDouble();
310 >        break;
311 >      }
312 >
313 >      case 'q' : {
314 >        if (sd->isDirectional()) {
315            
316 <          mol = info_->getMoleculeByGlobalIndex(i);
316 >          q[0] = tokenizer.nextTokenAsDouble();
317 >          q[1] = tokenizer.nextTokenAsDouble();
318 >          q[2] = tokenizer.nextTokenAsDouble();
319 >          q[3] = tokenizer.nextTokenAsDouble();
320            
321 <          if(mol == NULL) {
322 <            sprintf(painCave.errMsg,
332 <                    "RestReader Error: molecule not found on node %d\n",
333 <                    worldRank);
334 <            painCave.isFatal = 1;
335 <            simError();
336 <          }
337 <          
338 <          nCurObj = mol->getNIntegrableObjects();
339 <          
340 <          MPI_Send(&nCurObj, 1, MPI_INT, masterNode,
341 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
342 <          
343 <          for (integrableObject = mol->beginIntegrableObject(ii);
344 <               integrableObject != NULL;
345 <               integrableObject = mol->nextIntegrableObject(ii)){
321 >          RealType qlen = q.length();
322 >          if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
323              
324 <            MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, masterNode,
325 <                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
326 <            
327 <            parseErr = parseIdealLine(read_buffer, integrableObject);
328 <            
329 <            if( parseErr != NULL ){
330 <              strcpy( painCave.errMsg, parseErr );
331 <              simError();
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 >        if (sd->isDirectional()) {
337 >          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 >        
369 >      // is this io restrained?
370 >      GenericData* data = sd->getPropertyByName("Restraint");
371 >      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 >            // an ObjectRestraint:
379 >          oRest = dynamic_cast<ObjectRestraint*>(restData->getData());
380 >          if (oRest != NULL) {          
381 >            if (sd->isDirectional()) {
382 >              oRest->setReferenceStructure(pos, q.toRotationMatrix3());
383 >            } else {                          
384 >              oRest->setReferenceStructure(pos);
385              }
386            }
387          }
388        }
389      }
360 #endif
390    }
391    
392 <  char* RestReader::parseIdealLine(char* readLine, StuntDouble* sd){
392 >  void  RestReader::readStuntDoubles(std::istream& inputStream) {
393      
394 <    char *foo; // the pointer to the current string token
394 >    inputStream.getline(buffer, bufferSize);
395 >    std::string line(buffer);
396      
397 <    double pos[3];        // position place holders
398 <    double q[4];          // the quaternions
399 <    double RfromQ[3][3];  // the rotation matrix
400 <    double normalize;     // to normalize the reference unit vector
401 <    double uX, uY, uZ;    // reference unit vector place holders
372 <    double uselessToken;
373 <    StringTokenizer tokenizer(readLine);
374 <    int nTokens;
375 <    
376 <    nTokens = tokenizer.countTokens();
377 <    
378 <    if (nTokens < 14) {
379 <      sprintf(painCave.errMsg,
380 <              "RestReader Error: Not enough Tokens.\n");
381 <      painCave.isFatal = 1;
382 <      simError();
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 <    std::string name = tokenizer.nextToken();
405 <    
387 <    if (name != sd->getType()) {
404 >    while(inputStream.getline(buffer, bufferSize)) {
405 >      line = buffer;
406        
407 <      sprintf(painCave.errMsg,
408 <              "RestReader Error: Atom type [%s] in %s does not "
409 <              "match Atom Type [%s] in .md file.\n",
392 <              name.c_str(), inIdealFileName.c_str(),
393 <              sd->getType().c_str());
394 <      painCave.isFatal = 1;
395 <      simError();        
396 <    }
397 <    
398 <    pos[0] = tokenizer.nextTokenAsDouble();
399 <    pos[1] = tokenizer.nextTokenAsDouble();
400 <    pos[2] = tokenizer.nextTokenAsDouble();
401 <    
402 <    // store the positions in the stuntdouble as generic data doubles
403 <    DoubleGenericData* refPosX = new DoubleGenericData();
404 <    refPosX->setID("refPosX");
405 <    refPosX->setData(pos[0]);
406 <    sd->addProperty(refPosX);
407 <    
408 <    DoubleGenericData* refPosY = new DoubleGenericData();
409 <    refPosY->setID("refPosY");
410 <    refPosY->setData(pos[1]);
411 <    sd->addProperty(refPosY);
412 <    
413 <    DoubleGenericData* refPosZ = new DoubleGenericData();
414 <    refPosZ->setID("refPosZ");
415 <    refPosZ->setData(pos[2]);
416 <    sd->addProperty(refPosZ);
417 <    
418 <    // we don't need the velocities
419 <    uselessToken = tokenizer.nextTokenAsDouble();
420 <    uselessToken = tokenizer.nextTokenAsDouble();
421 <    uselessToken = tokenizer.nextTokenAsDouble();
422 <    
423 <    if (sd->isDirectional()) {
407 >      if(line.find("</StuntDoubles>") != std::string::npos) {
408 >        break;
409 >      }
410        
411 <      q[0] = tokenizer.nextTokenAsDouble();
426 <      q[1] = tokenizer.nextTokenAsDouble();
427 <      q[2] = tokenizer.nextTokenAsDouble();
428 <      q[3] = tokenizer.nextTokenAsDouble();
429 <      
430 <      // now build the rotation matrix and find the unit vectors
431 <      RfromQ[0][0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
432 <      RfromQ[0][1] = 2*(q[1]*q[2] + q[0]*q[3]);
433 <      RfromQ[0][2] = 2*(q[1]*q[3] - q[0]*q[2]);
434 <      RfromQ[1][0] = 2*(q[1]*q[2] - q[0]*q[3]);
435 <      RfromQ[1][1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
436 <      RfromQ[1][2] = 2*(q[2]*q[3] + q[0]*q[1]);
437 <      RfromQ[2][0] = 2*(q[1]*q[3] + q[0]*q[2]);
438 <      RfromQ[2][1] = 2*(q[2]*q[3] - q[0]*q[1]);
439 <      RfromQ[2][2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
440 <      
441 <      normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
442 <                       + RfromQ[2][2]*RfromQ[2][2]);
443 <      uX = RfromQ[2][0]/normalize;
444 <      uY = RfromQ[2][1]/normalize;
445 <      uZ = RfromQ[2][2]/normalize;
446 <      
447 <      // store reference unit vectors as generic data in the stuntdouble
448 <      DoubleGenericData* refVectorX = new DoubleGenericData();
449 <      refVectorX->setID("refVectorX");
450 <      refVectorX->setData(uX);
451 <      sd->addProperty(refVectorX);
452 <      
453 <      DoubleGenericData* refVectorY = new DoubleGenericData();
454 <      refVectorY->setID("refVectorY");
455 <      refVectorY->setData(uY);
456 <      sd->addProperty(refVectorY);
457 <      
458 <      DoubleGenericData* refVectorZ = new DoubleGenericData();
459 <      refVectorZ->setID("refVectorZ");
460 <      refVectorZ->setData(uZ);
461 <      sd->addProperty(refVectorZ);
411 >      parseDumpLine(line);
412      }
413      
464    // we don't need the angular velocities, so let's exit the line
465    return NULL;
414    }
415 +
416    
417 <  void RestReader::readZangle(){
418 <    
419 <    int i;
420 <    unsigned int j;
421 <    int isPresent;
422 <    
423 <    Molecule* mol;
424 <    StuntDouble* integrableObject;
425 <    SimInfo::MoleculeIterator mi;
426 <    Molecule::IntegrableObjectIterator ii;
427 <    
428 < #ifdef IS_MPI
429 <    int done, which_node, which_atom; // loop counter
430 <    int nProc;
431 <    MPI_Status istatus;
432 < #endif //is_mpi
433 <    
485 <    const int BUFFERSIZE = 2000; // size of the read buffer
486 <    int nTotObjs; // the number of atoms
487 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
488 <    
489 <    char *eof_test; // ptr to see when we reach the end of the file
490 <    char *parseErr;
491 <    
492 <    std::vector<StuntDouble*> vecParticles;
493 <    std::vector<double> tempZangs;
417 >  void RestReader::readFrameProperties(std::istream& inputStream) {
418 >    inputStream.getline(buffer, bufferSize);
419 >    std::string line(buffer);
420 >
421 >    if (line.find("<FrameData>") == std::string::npos) {
422 >      sprintf(painCave.errMsg,
423 >              "RestReader Error: Missing <FrameData>\n");
424 >      painCave.isFatal = 1;
425 >      simError();
426 >    }
427 >
428 >    // 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        
435 <    inAngFileName = info_->getRestFileName();
436 <    
497 <    inAngFileName += "0";
498 <    
499 <    // open the omega value file for reading
500 < #ifdef IS_MPI
501 <    if (worldRank == 0) {
502 < #endif
503 <      isPresent = 1;
504 <      inAngFile = fopen(inAngFileName.c_str(), "r");
505 <      if(!inAngFile){
506 <        sprintf(painCave.errMsg,
507 <                "Restraints Warning: %s file is not present\n"
508 <                "\tAll omega values will be initialized to zero. If the\n"
509 <                "\tsimulation is starting from the idealCrystal.in reference\n"
510 <                "\tconfiguration, this is the desired action. If this is not\n"
511 <                "\tthe case, the energy calculations will be incorrect.\n",
512 <                inAngFileName.c_str());
513 <        painCave.severity = OOPSE_WARNING;
514 <        painCave.isFatal = 0;
515 <        simError();  
516 <        isPresent = 0;
435 >      if(line.find("</FrameData>") != std::string::npos) {
436 >        break;
437        }
518      
519 #ifdef IS_MPI
520      // let the other nodes know the status of the file search
521      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
522 #endif // is_mpi
523      
524      if (!isPresent) {
525        zeroZangle();
526        return;
527      }
528      
529 #ifdef IS_MPI
530    }
531    
532    // listen to node 0 to see if we should exit this function
533    if (worldRank != 0) {
534      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
535      if (!isPresent) {
536        zeroZangle();
537        return;
538      }
539    }
540    
541    strcpy( checkPointMsg, "zAngle file opened successfully for reading." );
542    MPIcheckPoint();
543 #endif
544    
545 #ifndef IS_MPI
546    
547    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
548    if( eof_test == NULL ){
549      sprintf( painCave.errMsg,
550               "RestraintReader error: error reading 1st line of \"%s\"\n",
551               inAngFileName.c_str() );
552      painCave.isFatal = 1;
553      simError();
554    }
555    
556    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
557    while ( eof_test != NULL ) {
558      // check for and ignore blank lines
559      if ( read_buffer != NULL )
560        tempZangs.push_back( atof(read_buffer) );
561      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
562    }
563    
564    nTotObjs = info_->getNGlobalIntegrableObjects();
565    
566    if( nTotObjs != tempZangs.size() ){
567      sprintf( painCave.errMsg,
568               "RestraintReader zAngle reading error. %s nIntegrable, %d, "
569               "does not match the meta-data file's nIntegrable, %d.\n",
570               inAngFileName.c_str(), tempZangs.size(), nTotObjs );
571      painCave.isFatal = 1;
572      simError();
573    }
574    
575    // load the zAngles into the integrable objects
576    i = 0;
577    for (mol = info_->beginMolecule(mi); mol != NULL;
578         mol = info_->nextMolecule(mi)) {
438        
580      for (integrableObject = mol->beginIntegrableObject(ii);
581           integrableObject != NULL;
582           integrableObject = mol->nextIntegrableObject(ii)) {    
583        
584        integrableObject->setZangle(tempZangs[i]);
585        i++;
586      }
439      }
440      
589    // MPI Section of code..........
590 #else //IS_MPI
591    
592    // first thing first, suspend fatalities.
593    painCave.isEventLoop = 1;
594
595    int masterNode = 0;
596    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
597    int haveError;
598    int index;    
599
600    int nCurObj;
601    double angleTranfer;
602    
603    nTotObjs = info_->getNGlobalIntegrableObjects();
604    haveError = 0;
605
606    if (worldRank == masterNode) {
607      
608      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
609      if( eof_test == NULL ){
610        sprintf( painCave.errMsg,
611                 "Error reading 1st line of %s \n ",inAngFileName.c_str());
612        haveError = 1;
613        simError();
614      }
615      
616      // let node 0 load the temporary angle vector
617      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
618      while ( eof_test != NULL ) {
619        // check for and ignore blank lines
620        if ( read_buffer != NULL )
621          tempZangs.push_back( atof(read_buffer) );
622        eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
623      }
624      
625      // Check to see that the number of integrable objects in the
626      // intial configuration file is the same as derived from the
627      // meta-data file.
628      if( nTotObjs != tempZangs.size() ){
629        sprintf( painCave.errMsg,
630                 "RestraintReader zAngle reading Error. %s nIntegrable, %d, "
631                 "does not match the meta-data file's nIntegrable, %d.\n",
632                 inAngFileName.c_str(), tempZangs.size(), nTotObjs);
633        haveError= 1;
634        simError();
635      }
636      
637      // At this point, node 0 has a tempZangs vector completed, and
638      // everyone else has nada
639      index = 0;
640      
641      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
642        // Get the Node number which has this atom
643        which_node = info_->getMolToProc(i);
644        
645        if (worldRank == masterNode) {
646          mol = info_->getMoleculeByGlobalIndex(i);
647          
648          if(mol == NULL) {
649            strcpy(painCave.errMsg, "Molecule not found on node 0!");
650            haveError = 1;
651            simError();
652          }
653          
654          for (integrableObject = mol->beginIntegrableObject(ii);
655               integrableObject != NULL;
656               integrableObject = mol->nextIntegrableObject(ii)){
657            
658            integrableObject->setZangle(tempZangs[index]);
659            index++;
660          }    
661          
662        } else {
663          // I am MASTER OF THE UNIVERSE, but I don't own this molecule
664          
665          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
666                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
667          
668          for(j=0; j < nCurObj; j++){            
669            angleTransfer = tempZangs[index];
670            MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
671                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);              
672            index++;
673          }
674          
675        }
676      }
677    } else {
678      // I am SLAVE TO THE MASTER
679      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
680        int which_node = info_->getMolToProc(i);
681
682        if (which_node == worldRank) {
683          
684          // BUT I OWN THIS MOLECULE!!!
685          
686          mol = info_->getMoleculeByGlobalIndex(i);
687
688          if(mol == NULL) {
689            sprintf(painCave.errMsg,
690                    "RestReader Error: molecule not found on node %d\n",
691                    worldRank);
692            painCave.isFatal = 1;
693            simError();
694          }
695
696          nCurObj = mol->getNIntegrableObjects();
697        
698          MPI_Send(&nCurObj, 1, MPI_INT, 0,
699                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
700          
701          for (integrableObject = mol->beginIntegrableObject(ii);
702               integrableObject != NULL;
703               integrableObject = mol->nextIntegrableObject(ii)){
704            
705            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
706                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
707
708            integrableObject->setZangle(angleTransfer);
709          }    
710        }
711      }
712    }
713 #endif
441    }
715  
716  void RestReader :: zeroZangle(){
717    
718    int i;
719    unsigned int j;
720    int nTotObjs; // the number of atoms
721    
722    Molecule* mol;
723    StuntDouble* integrableObject;
724    SimInfo::MoleculeIterator mi;
725    Molecule::IntegrableObjectIterator ii;
726    
727    std::vector<StuntDouble*> vecParticles;
728    
729 #ifndef IS_MPI
730    // set all zAngles to 0.0
731    for (mol = info_->beginMolecule(mi); mol != NULL;
732         mol = info_->nextMolecule(mi))
733      
734      for (integrableObject = mol->beginIntegrableObject(ii);
735           integrableObject != NULL;
736           integrableObject = mol->nextIntegrableObject(ii))    
737        integrableObject->setZangle( 0.0 );
738    
739    
740    // MPI Section of code..........
741 #else //IS_MPI
742    
743    // first thing first, suspend fatalities.
744    painCave.isEventLoop = 1;
745    
746    int masterNode = 0;
747    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
748    int haveError;
749    int which_node;
750    
751    MPI_Status istatus;
752    
753    int nCurObj;
754    double angleTranfer;
755    
756    nTotObjs = info_->getNGlobalIntegrableObjects();
757    haveError = 0;
758    if (worldRank == masterNode) {
442  
443 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
444 <        // Get the Node number which has this atom
762 <        which_node = info_->getMolToProc(i);
763 <        
764 <        // let's let node 0 pass out constant values to all the processors
765 <        if (worldRank == masterNode) {
766 <          mol = info_->getMoleculeByGlobalIndex(i);
767 <          
768 <          if(mol == NULL) {
769 <            strcpy(painCave.errMsg, "Molecule not found on node 0!");
770 <            haveError = 1;
771 <            simError();
772 <          }
773 <          
774 <          for (integrableObject = mol->beginIntegrableObject(ii);
775 <               integrableObject != NULL;
776 <               integrableObject = mol->nextIntegrableObject(ii)){
777 <            
778 <            integrableObject->setZangle( 0.0 );
779 <            
780 <          }
781 <          
782 <        } else {
783 <          // I am MASTER OF THE UNIVERSE, but I don't own this molecule
784 <          
785 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
786 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
787 <          
788 <          for(j=0; j < nCurObj; j++){            
789 <            angleTransfer = 0.0;
790 <            MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
791 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);              
792 <            
793 <          }
794 <        }
795 <      }
796 <    } else {
797 <      // I am SLAVE TO THE MASTER
798 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
799 <        int which_node = info_->getMolToProc(i);
800 <        
801 <        if (which_node == worldRank) {
802 <          
803 <          // BUT I OWN THIS MOLECULE!!!
804 <          mol = info_->getMoleculeByGlobalIndex(i);
805 <          
806 <          if(mol == NULL) {
807 <            sprintf(painCave.errMsg,
808 <                    "RestReader Error: molecule not found on node %d\n",
809 <                    worldRank);
810 <            painCave.isFatal = 1;
811 <            simError();
812 <          }
813 <          
814 <          nCurObj = mol->getNIntegrableObjects();
815 <          
816 <          MPI_Send(&nCurObj, 1, MPI_INT, 0,
817 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
818 <          
819 <          for (integrableObject = mol->beginIntegrableObject(ii);
820 <               integrableObject != NULL;
821 <               integrableObject = mol->nextIntegrableObject(ii)){
822 <            
823 <            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
824 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
825 <            vecParticles[j]->setZangle(angleTransfer);
826 <          }    
827 <        }
828 <      }
829 <    }
830 < #endif
831 <  }
832 <  
833 < } // end namespace oopse
443 >  
444 > }//end namespace OpenMD

Comparing trunk/src/io/RestReader.cpp (property svn:keywords):
Revision 423 by chrisfen, Thu Mar 10 19:11:02 2005 UTC vs.
Revision 1796 by gezelter, Mon Sep 10 18:38:44 2012 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines