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

Comparing:
trunk/src/io/RestReader.cpp (file contents), Revision 431 by chrisfen, Fri Mar 11 00:43:19 2005 UTC vs.
branches/development/src/io/RestReader.cpp (file contents), Revision 1665 by gezelter, Tue Nov 22 20:38:56 2011 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){
70 >  void RestReader::scanFile(){
71 >    int lineNo = 0;
72 >    std::streampos prevPos;
73 >    std::streampos  currPos;
74      
75 <    idealName = "idealCrystal.in";
75 > #ifdef IS_MPI
76      
77 <    isScanned = false;
78 <    
79 < #ifdef IS_MPI
80 <    if (worldRank == 0) {
81 < #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();
94 < #endif
100 >    MPI_Bcast(&framePos_, 1, MPI_INT, 0, MPI_COMM_WORLD);
101 > #endif // is_mpi
102 >  }
103  
104 <    return;  
105 <  }
106 <  
107 <  RestReader :: ~RestReader( ){
108 < #ifdef IS_MPI
109 <    if (worldRank == 0) {
110 < #endif
111 <      int error;
112 <      error = fclose( inIdealFile );
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_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 < #ifdef IS_MPI
139 <    }
140 <    strcpy( checkPointMsg, "Restraint file closed successfully." );
141 <    MPIcheckPoint();
138 >      sstream.str(sendBuffer);
139 >    } else {
140 >      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 <    return;
154 <  }
155 <  
156 <  
157 <  void RestReader :: readIdealCrystal(){
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 >    }
162      
163 <    int i;
164 <    unsigned int j;
163 >    //read frameData
164 >    readFrameProperties(inputStream);
165      
166 < #ifdef IS_MPI
167 <    int done, which_node, which_atom; // loop counter
131 < #endif //is_mpi
166 >    //read StuntDoubles
167 >    readStuntDoubles(inputStream);
168      
169 <    const int BUFFERSIZE = 2000; // size of the read buffer
170 <    int nTotObjs; // the number of atoms
171 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
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 <    char *eof_test; // ptr to see when we reach the end of the file
180 <    char *parseErr;
179 >  void RestReader::readReferenceStructure() {
180 >
181 >    // 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 >
185 >    all_pos_.clear();
186 >    all_pos_.resize(info_->getNGlobalIntegrableObjects()) ;
187      
188 <    std::vector<StuntDouble*> integrableObjects;
189 <    
188 >    // 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 >
193 >    scanFile();
194 >
195 >    readSet();
196 >
197 >
198 >    // all ObjectRestraints have been handled, now we have to worry about
199 >    // molecular restraints:
200 >
201 >    SimInfo::MoleculeIterator i;
202 >    Molecule::IntegrableObjectIterator j;
203      Molecule* mol;
204 <    StuntDouble* integrableObject;
144 <    SimInfo::MoleculeIterator mi;
145 <    Molecule::IntegrableObjectIterator ii;
204 >    StuntDouble* sd;
205      
206 < #ifndef IS_MPI
206 >    // 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      
210 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
211 <    if( eof_test == NULL ){
212 <      sprintf( painCave.errMsg,
213 <               "RestraintReader error: error reading 1st line of \"%s\"\n",
214 <               inIdealFileName.c_str() );
215 <      painCave.isFatal = 1;
216 <      simError();
217 <    }
218 <    
219 <    nTotObjs = atoi( read_buffer );
220 <    
221 <    if( nTotObjs != info_->getNGlobalIntegrableObjects() ){
222 <      sprintf( painCave.errMsg,
223 <               "RestraintReader error. %s nIntegrable, %d, "
224 <               "does not match the meta-data file's nIntegrable, %d.\n",
225 <               inIdealFileName.c_str(), nTotObjs,
226 <               info_->getNGlobalIntegrableObjects());
227 <      painCave.isFatal = 1;
228 <      simError();
229 <    }
230 <    
231 <    // skip over the comment line
232 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
233 <    if(eof_test == NULL){
234 <      sprintf( painCave.errMsg,
235 <               "error in reading commment in %s\n", inIdealFileName.c_str());
236 <      painCave.isFatal = 1;
237 <      simError();
238 <    }
239 <    
240 <    // parse the ideal crystal lines
241 <    /*
242 <     * Note: we assume that there is a one-to-one correspondence between
243 <     * integrable objects and lines in the idealCrystal.in file.  Thermodynamic
244 <     * integration is only supported for simple rigid bodies.
245 <     */
246 <    for (mol = info_->beginMolecule(mi); mol != NULL;
247 <         mol = info_->nextMolecule(mi)) {
248 <      
249 <      for (integrableObject = mol->beginIntegrableObject(ii);
250 <           integrableObject != NULL;
251 <           integrableObject = mol->nextIntegrableObject(ii)) {    
252 <        
253 <        eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
254 <        if(eof_test == NULL){
255 <          sprintf(painCave.errMsg,
256 <                  "RestReader Error: error in reading file %s\n"
257 <                  "natoms  = %d; index = %d\n"
258 <                  "error reading the line from the file.\n",
259 <                  inIdealFileName.c_str(), nTotObjs,
199 <                  integrableObject->getGlobalIndex() );
200 <          painCave.isFatal = 1;
201 <          simError();
210 >    for (mol = info_->beginMolecule(i); mol != NULL;
211 >         mol = info_->nextMolecule(i)) {          
212 >      
213 >      // is this molecule restrained?    
214 >      GenericData* data = mol->getPropertyByName("Restraint");
215 >      
216 >      if (data != NULL) {
217 >        
218 >        // make sure we can reinterpret the generic data as restraint data:
219 >        
220 >        RestraintData* restData= dynamic_cast<RestraintData*>(data);        
221 >        
222 >        if (restData != NULL) {
223 >          
224 >          // make sure we can reinterpet the restraint data as a
225 >          // pointer to a MolecularRestraint:
226 >          
227 >          MolecularRestraint* mRest = dynamic_cast<MolecularRestraint*>(restData->getData());
228 >          
229 >          if (mRest != NULL) {          
230 >            
231 >            // now we need to pack the stunt doubles for the reference
232 >            // structure:
233 >            
234 >            std::vector<Vector3d> ref;
235 >            int count = 0;
236 >            RealType mass, mTot;
237 >            Vector3d COM(0.0);
238 >            
239 >            mTot = 0.0;
240 >            
241 >            // 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 >              ref.push_back( all_pos_[sd->getGlobalIntegrableObjectIndex()] );
252 >              mass = sd->getMass();              
253 >              COM = COM + mass * ref[count];
254 >              mTot = mTot + mass;
255 >              count = count + 1;
256 >            }
257 >            COM /= mTot;
258 >            mRest->setReferenceStructure(ref, COM);        
259 >          }
260          }
203        
204        parseErr = parseIdealLine( read_buffer, integrableObject);
205        if( parseErr != NULL ){
206          strcpy( painCave.errMsg, parseErr );
207          painCave.isFatal = 1;
208          simError();
209        }
261        }
262      }
263 +  }
264 +
265 +  
266 +  
267 +  void RestReader::parseDumpLine(const std::string& line) {        
268 +
269 +    StringTokenizer tokenizer(line);
270 +    int nTokens;
271 +    
272 +    nTokens = tokenizer.countTokens();
273 +    
274 +    if (nTokens < 2) {
275 +      sprintf(painCave.errMsg,
276 +              "RestReader Error: Not enough Tokens.\n%s\n", line.c_str());
277 +      painCave.isFatal = 1;
278 +      simError();
279 +    }
280 +
281 +    int index = tokenizer.nextTokenAsInt();
282 +
283 +    StuntDouble* integrableObject = info_->getIOIndexToIntegrableObject(index);
284 +
285 +    if (integrableObject == NULL) {
286 +      return;
287 +    }
288 +  
289 +    std::string type = tokenizer.nextToken();
290 +    int size = type.size();
291      
292 <    // MPI Section of code..........
293 < #else //IS_MPI
215 <    
216 <    // first thing first, suspend fatalities.
217 <    painCave.isEventLoop = 1;
218 <    
219 <    int masterNode = 0;
220 <    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
221 <    
222 <    MPI_Status istatus;
223 <    int nCurObj;
224 <    int nitems;
225 <    int haveError;
292 >    Vector3d pos;
293 >    Quat4d q;
294  
295 <    nTotObjs = info_->getNGlobalIntegrableObjects();
296 <    haveError = 0;
295 >    for(int i = 0; i < size; ++i) {
296 >      switch(type[i]) {
297  
298 <    if (worldRank == masterNode) {
299 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
300 <      if( eof_test == NULL ){
301 <        sprintf( painCave.errMsg,
302 <                 "Error reading 1st line of %s \n ",inIdealFileName.c_str());
235 <        painCave.isFatal = 1;
236 <        simError();
298 >      case 'p': {
299 >        pos[0] = tokenizer.nextTokenAsDouble();
300 >        pos[1] = tokenizer.nextTokenAsDouble();
301 >        pos[2] = tokenizer.nextTokenAsDouble();
302 >        break;
303        }
304 <      
305 <      nitems = atoi( read_buffer );
306 <      
307 <      // Check to see that the number of integrable objects in the
308 <      // intial configuration file is the same as derived from the
309 <      // meta-data file.
244 <      if( nTotObjs != nitems){
245 <        sprintf( painCave.errMsg,
246 <                 "RestraintReader Error. %s nIntegrable, %d, "
247 <                 "does not match the meta-data file's nIntegrable, %d.\n",
248 <                 inIdealFileName.c_str(), nTotObjs,
249 <                 info_->getNGlobalIntegrableObjects());
250 <        painCave.isFatal = 1;
251 <        simError();
304 >      case 'v' : {
305 >        Vector3d vel;
306 >        vel[0] = tokenizer.nextTokenAsDouble();
307 >        vel[1] = tokenizer.nextTokenAsDouble();
308 >        vel[2] = tokenizer.nextTokenAsDouble();
309 >        break;
310        }
253      
254      // skip over the comment line
255      eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
256      if(eof_test == NULL){
257        sprintf( painCave.errMsg,
258                 "error in reading commment in %s\n", inIdealFileName.c_str());
259        painCave.isFatal = 1;
260        simError();
261      }
311  
312 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
313 <        int which_node = info_->getMolToProc(i);
265 <        
266 <        if(which_node == masterNode){
267 <          //molecules belong to master node
312 >      case 'q' : {
313 >        if (integrableObject->isDirectional()) {
314            
315 <          mol = info_->getMoleculeByGlobalIndex(i);
315 >          q[0] = tokenizer.nextTokenAsDouble();
316 >          q[1] = tokenizer.nextTokenAsDouble();
317 >          q[2] = tokenizer.nextTokenAsDouble();
318 >          q[3] = tokenizer.nextTokenAsDouble();
319            
320 <          if(mol == NULL) {
321 <            sprintf(painCave.errMsg,
273 <                   "RestReader Error: Molecule not found on node %d!\n",
274 <                   worldRank);
275 <            painCave.isFatal = 1;
276 <            simError();
277 <          }
278 <          
279 <          for (integrableObject = mol->beginIntegrableObject(ii);
280 <               integrableObject != NULL;
281 <               integrableObject = mol->nextIntegrableObject(ii)){
320 >          RealType qlen = q.length();
321 >          if (qlen < OpenMD::epsilon) { //check quaternion is not equal to 0
322              
323 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
324 <            
325 <            if(eof_test == NULL){
326 <              sprintf(painCave.errMsg,
327 <                      "RestReader Error: error in reading file %s\n"
328 <                      "natoms  = %d; index = %d\n"
329 <                      "error reading the line from the file.\n",
330 <                      inIdealFileName.c_str(), nTotObjs, i );
331 <              painCave.isFatal = 1;
332 <              simError();
333 <            }
334 <        
335 <            parseIdealLine(read_buffer, integrableObject);
336 <        
337 <          }
338 <        } else {
299 <          //molecule belongs to slave nodes
300 <          
301 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
302 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
303 <          
304 <          for(j=0; j < nCurObj; j++){
305 <            
306 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
307 <            if(eof_test == NULL){
308 <              sprintf(painCave.errMsg,
309 <                      "RestReader Error: error in reading file %s\n"
310 <                      "natoms  = %d; index = %d\n"
311 <                      "error reading the line from the file.\n",
312 <                      inIdealFileName.c_str(), nTotObjs, i );
313 <              painCave.isFatal = 1;
314 <              simError();
315 <            }
316 <            
317 <            MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
318 <                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
319 <          }
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 <    } else {
350 <      //actions taken at slave nodes
351 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
352 <        int which_node = info_->getMolToProc(i);
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          
368 <        if(which_node == worldRank){
369 <          //molecule with global index i belongs to this processor
370 <          
371 <          mol = info_->getMoleculeByGlobalIndex(i);
372 <          
373 <          if(mol == NULL) {
374 <            sprintf(painCave.errMsg,
375 <                    "RestReader Error: molecule not found on node %d\n",
376 <                    worldRank);
377 <            painCave.isFatal = 1;
378 <            simError();
379 <          }
380 <          
381 <          nCurObj = mol->getNIntegrableObjects();
382 <          
383 <          MPI_Send(&nCurObj, 1, MPI_INT, masterNode,
343 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
344 <          
345 <          for (integrableObject = mol->beginIntegrableObject(ii);
346 <               integrableObject != NULL;
347 <               integrableObject = mol->nextIntegrableObject(ii)){
348 <            
349 <            MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, masterNode,
350 <                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
351 <            
352 <            parseErr = parseIdealLine(read_buffer, integrableObject);
353 <            
354 <            if( parseErr != NULL ){
355 <              strcpy( painCave.errMsg, parseErr );
356 <              simError();
368 >      // 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 >            // an ObjectRestraint:
378 >          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              }
385            }
386          }
387        }
388      }
362 #endif
389    }
390    
391 <  char* RestReader::parseIdealLine(char* readLine, StuntDouble* sd){
391 >  void  RestReader::readStuntDoubles(std::istream& inputStream) {
392      
393 <    char *foo; // the pointer to the current string token
393 >    inputStream.getline(buffer, bufferSize);
394 >    std::string line(buffer);
395      
396 <    double pos[3];        // position place holders
397 <    double q[4];          // the quaternions
398 <    double RfromQ[3][3];  // the rotation matrix
399 <    double normalize;     // to normalize the reference unit vector
400 <    double uX, uY, uZ;    // reference unit vector place holders
374 <    double uselessToken;
375 <    StringTokenizer tokenizer(readLine);
376 <    int nTokens;
377 <    
378 <    nTokens = tokenizer.countTokens();
379 <
380 <    if (nTokens < 14) {
381 <      sprintf(painCave.errMsg,
382 <              "RestReader Error: Not enough Tokens.\n");
383 <      painCave.isFatal = 1;
384 <      simError();
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 <    std::string name = tokenizer.nextToken();
404 <
389 <    if (name != sd->getType()) {
403 >    while(inputStream.getline(buffer, bufferSize)) {
404 >      line = buffer;
405        
406 <      sprintf(painCave.errMsg,
407 <              "RestReader Error: Atom type [%s] in %s does not "
408 <              "match Atom Type [%s] in .md file.\n",
409 <              name.c_str(), inIdealFileName.c_str(),
410 <              sd->getType().c_str());
396 <      painCave.isFatal = 1;
397 <      simError();        
406 >      if(line.find("</StuntDoubles>") != std::string::npos) {
407 >        break;
408 >      }
409 >      
410 >      parseDumpLine(line);
411      }
412      
413 <    pos[0] = tokenizer.nextTokenAsDouble();
401 <    pos[1] = tokenizer.nextTokenAsDouble();
402 <    pos[2] = tokenizer.nextTokenAsDouble();
413 >  }
414  
415 <    // store the positions in the stuntdouble as generic data doubles
416 <    DoubleGenericData* refPosX = new DoubleGenericData();
417 <    refPosX->setID("refPosX");
418 <    refPosX->setData(pos[0]);
408 <    sd->addProperty(refPosX);
415 >  
416 >  void RestReader::readFrameProperties(std::istream& inputStream) {
417 >    inputStream.getline(buffer, bufferSize);
418 >    std::string line(buffer);
419  
420 <    DoubleGenericData* refPosY = new DoubleGenericData();
421 <    refPosY->setID("refPosY");
422 <    refPosY->setData(pos[1]);
423 <    sd->addProperty(refPosY);
424 <    
425 <    DoubleGenericData* refPosZ = new DoubleGenericData();
416 <    refPosZ->setID("refPosZ");
417 <    refPosZ->setData(pos[2]);
418 <    sd->addProperty(refPosZ);
420 >    if (line.find("<FrameData>") == std::string::npos) {
421 >      sprintf(painCave.errMsg,
422 >              "RestReader Error: Missing <FrameData>\n");
423 >      painCave.isFatal = 1;
424 >      simError();
425 >    }
426  
427 <    // we don't need the velocities
428 <    uselessToken = tokenizer.nextTokenAsDouble();
429 <    uselessToken = tokenizer.nextTokenAsDouble();
430 <    uselessToken = tokenizer.nextTokenAsDouble();
431 <    
432 <    if (sd->isDirectional()) {
427 >    // 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        
434 <      q[0] = tokenizer.nextTokenAsDouble();
435 <      q[1] = tokenizer.nextTokenAsDouble();
429 <      q[2] = tokenizer.nextTokenAsDouble();
430 <      q[3] = tokenizer.nextTokenAsDouble();
431 <      
432 <      // now build the rotation matrix and find the unit vectors
433 <      RfromQ[0][0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
434 <      RfromQ[0][1] = 2*(q[1]*q[2] + q[0]*q[3]);
435 <      RfromQ[0][2] = 2*(q[1]*q[3] - q[0]*q[2]);
436 <      RfromQ[1][0] = 2*(q[1]*q[2] - q[0]*q[3]);
437 <      RfromQ[1][1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
438 <      RfromQ[1][2] = 2*(q[2]*q[3] + q[0]*q[1]);
439 <      RfromQ[2][0] = 2*(q[1]*q[3] + q[0]*q[2]);
440 <      RfromQ[2][1] = 2*(q[2]*q[3] - q[0]*q[1]);
441 <      RfromQ[2][2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
442 <      
443 <      normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
444 <                       + RfromQ[2][2]*RfromQ[2][2]);
445 <      uX = RfromQ[2][0]/normalize;
446 <      uY = RfromQ[2][1]/normalize;
447 <      uZ = RfromQ[2][2]/normalize;
448 <      
449 <      // store reference unit vectors as generic data in the stuntdouble
450 <      DoubleGenericData* refVectorX = new DoubleGenericData();
451 <      refVectorX->setID("refVectorX");
452 <      refVectorX->setData(uX);
453 <      sd->addProperty(refVectorX);
454 <      
455 <      DoubleGenericData* refVectorY = new DoubleGenericData();
456 <      refVectorY->setID("refVectorY");
457 <      refVectorY->setData(uY);
458 <      sd->addProperty(refVectorY);
459 <      
460 <      DoubleGenericData* refVectorZ = new DoubleGenericData();
461 <      refVectorZ->setID("refVectorZ");
462 <      refVectorZ->setData(uZ);
463 <      sd->addProperty(refVectorZ);
464 <    }
465 <    
466 <    // we don't need the angular velocities, so let's exit the line
467 <    return NULL;
468 <  }
469 <  
470 <  void RestReader::readZangle(){
471 <    
472 <    int i;
473 <    unsigned int j;
474 <    int isPresent;
475 <    
476 <    Molecule* mol;
477 <    StuntDouble* integrableObject;
478 <    SimInfo::MoleculeIterator mi;
479 <    Molecule::IntegrableObjectIterator ii;
480 <    
481 < #ifdef IS_MPI
482 <    int done, which_node, which_atom; // loop counter
483 <    int nProc;
484 <    MPI_Status istatus;
485 < #endif //is_mpi
486 <    
487 <    const int BUFFERSIZE = 2000; // size of the read buffer
488 <    int nTotObjs; // the number of atoms
489 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
490 <    
491 <    char *eof_test; // ptr to see when we reach the end of the file
492 <    char *parseErr;
493 <    
494 <    std::vector<StuntDouble*> vecParticles;
495 <    std::vector<double> tempZangs;
496 <      
497 <    inAngFileName = info_->getRestFileName();
498 <    
499 <    inAngFileName += "0";
500 <    
501 <    // open the omega value file for reading
502 < #ifdef IS_MPI
503 <    if (worldRank == 0) {
504 < #endif
505 <      isPresent = 1;
506 <      inAngFile = fopen(inAngFileName.c_str(), "r");
507 <      if(!inAngFile){
508 <        sprintf(painCave.errMsg,
509 <                "Restraints Warning: %s file is not present\n"
510 <                "\tAll omega values will be initialized to zero. If the\n"
511 <                "\tsimulation is starting from the idealCrystal.in reference\n"
512 <                "\tconfiguration, this is the desired action. If this is not\n"
513 <                "\tthe case, the energy calculations will be incorrect.\n",
514 <                inAngFileName.c_str());
515 <        painCave.severity = OOPSE_WARNING;
516 <        painCave.isFatal = 0;
517 <        simError();  
518 <        isPresent = 0;
434 >      if(line.find("</FrameData>") != std::string::npos) {
435 >        break;
436        }
437        
521 #ifdef IS_MPI
522      // let the other nodes know the status of the file search
523      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
524 #endif // is_mpi
525      
526      if (!isPresent) {
527        zeroZangle();
528        return;
529      }
530      
531 #ifdef IS_MPI
438      }
439      
534    // listen to node 0 to see if we should exit this function
535    if (worldRank != 0) {
536      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
537      if (!isPresent) {
538        zeroZangle();
539        return;
540      }
541    }
542    
543    strcpy( checkPointMsg, "zAngle file opened successfully for reading." );
544    MPIcheckPoint();
545 #endif
546    
547 #ifndef IS_MPI
548    
549    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
550    if( eof_test == NULL ){
551      sprintf( painCave.errMsg,
552               "RestraintReader error: error reading 1st line of \"%s\"\n",
553               inAngFileName.c_str() );
554      painCave.isFatal = 1;
555      simError();
556    }
557    
558    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
559    while ( eof_test != NULL ) {
560      // check for and ignore blank lines
561      if ( read_buffer != NULL )
562        tempZangs.push_back( atof(read_buffer) );
563      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
564    }
565    
566    nTotObjs = info_->getNGlobalIntegrableObjects();
567    
568    if( nTotObjs != tempZangs.size() ){
569      sprintf( painCave.errMsg,
570               "RestraintReader zAngle reading error. %s nIntegrable, %d, "
571               "does not match the meta-data file's nIntegrable, %d.\n",
572               inAngFileName.c_str(), tempZangs.size(), nTotObjs );
573      painCave.isFatal = 1;
574      simError();
575    }
576    
577    // load the zAngles into the integrable objects
578    i = 0;
579    for (mol = info_->beginMolecule(mi); mol != NULL;
580         mol = info_->nextMolecule(mi)) {
581      
582      for (integrableObject = mol->beginIntegrableObject(ii);
583           integrableObject != NULL;
584           integrableObject = mol->nextIntegrableObject(ii)) {    
585        
586        integrableObject->setZangle(tempZangs[i]);
587        i++;
588      }
589    }
590    
591    // MPI Section of code..........
592 #else //IS_MPI
593    
594    // first thing first, suspend fatalities.
595    painCave.isEventLoop = 1;
596
597    int masterNode = 0;
598    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
599    int haveError;
600    int index;    
601
602    int nCurObj;
603    double angleTranfer;
604    
605    nTotObjs = info_->getNGlobalIntegrableObjects();
606    haveError = 0;
607
608    if (worldRank == masterNode) {
609      
610      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
611      if( eof_test == NULL ){
612        sprintf( painCave.errMsg,
613                 "Error reading 1st line of %s \n ",inAngFileName.c_str());
614        haveError = 1;
615        simError();
616      }
617      
618      // let node 0 load the temporary angle vector
619      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
620      while ( eof_test != NULL ) {
621        // check for and ignore blank lines
622        if ( read_buffer != NULL )
623          tempZangs.push_back( atof(read_buffer) );
624        eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
625      }
626      
627      // Check to see that the number of integrable objects in the
628      // intial configuration file is the same as derived from the
629      // meta-data file.
630      if( nTotObjs != tempZangs.size() ){
631        sprintf( painCave.errMsg,
632                 "RestraintReader zAngle reading Error. %s nIntegrable, %d, "
633                 "does not match the meta-data file's nIntegrable, %d.\n",
634                 inAngFileName.c_str(), tempZangs.size(), nTotObjs);
635        haveError= 1;
636        simError();
637      }
638      
639      // At this point, node 0 has a tempZangs vector completed, and
640      // everyone else has nada
641      index = 0;
642      
643      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
644        // Get the Node number which has this atom
645        which_node = info_->getMolToProc(i);
646        
647        if (worldRank == masterNode) {
648          mol = info_->getMoleculeByGlobalIndex(i);
649          
650          if(mol == NULL) {
651            strcpy(painCave.errMsg, "Molecule not found on node 0!");
652            haveError = 1;
653            simError();
654          }
655          
656          for (integrableObject = mol->beginIntegrableObject(ii);
657               integrableObject != NULL;
658               integrableObject = mol->nextIntegrableObject(ii)){
659            
660            integrableObject->setZangle(tempZangs[index]);
661            index++;
662          }    
663          
664        } else {
665          // I am MASTER OF THE UNIVERSE, but I don't own this molecule
666          
667          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
668                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
669          
670          for(j=0; j < nCurObj; j++){            
671            angleTransfer = tempZangs[index];
672            MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
673                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);              
674            index++;
675          }
676          
677        }
678      }
679    } else {
680      // I am SLAVE TO THE MASTER
681      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
682        int which_node = info_->getMolToProc(i);
683
684        if (which_node == worldRank) {
685          
686          // BUT I OWN THIS MOLECULE!!!
687          
688          mol = info_->getMoleculeByGlobalIndex(i);
689
690          if(mol == NULL) {
691            sprintf(painCave.errMsg,
692                    "RestReader Error: molecule not found on node %d\n",
693                    worldRank);
694            painCave.isFatal = 1;
695            simError();
696          }
697
698          nCurObj = mol->getNIntegrableObjects();
699        
700          MPI_Send(&nCurObj, 1, MPI_INT, 0,
701                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
702          
703          for (integrableObject = mol->beginIntegrableObject(ii);
704               integrableObject != NULL;
705               integrableObject = mol->nextIntegrableObject(ii)){
706            
707            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
708                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
709
710            integrableObject->setZangle(angleTransfer);
711          }    
712        }
713      }
714    }
715 #endif
440    }
717  
718  void RestReader :: zeroZangle(){
719    
720    int i;
721    unsigned int j;
722    int nTotObjs; // the number of atoms
723    
724    Molecule* mol;
725    StuntDouble* integrableObject;
726    SimInfo::MoleculeIterator mi;
727    Molecule::IntegrableObjectIterator ii;
728    
729    std::vector<StuntDouble*> vecParticles;
730    
731 #ifndef IS_MPI
732    // set all zAngles to 0.0
733    for (mol = info_->beginMolecule(mi); mol != NULL;
734         mol = info_->nextMolecule(mi))
735      
736      for (integrableObject = mol->beginIntegrableObject(ii);
737           integrableObject != NULL;
738           integrableObject = mol->nextIntegrableObject(ii))    
739        integrableObject->setZangle( 0.0 );
740    
741    
742    // MPI Section of code..........
743 #else //IS_MPI
744    
745    // first thing first, suspend fatalities.
746    painCave.isEventLoop = 1;
747    
748    int masterNode = 0;
749    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
750    int haveError;
751    int which_node;
752    
753    MPI_Status istatus;
754    
755    int nCurObj;
756    double angleTranfer;
757    
758    nTotObjs = info_->getNGlobalIntegrableObjects();
759    haveError = 0;
760    if (worldRank == masterNode) {
441  
442 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
443 <        // Get the Node number which has this atom
764 <        which_node = info_->getMolToProc(i);
765 <        
766 <        // let's let node 0 pass out constant values to all the processors
767 <        if (worldRank == masterNode) {
768 <          mol = info_->getMoleculeByGlobalIndex(i);
769 <          
770 <          if(mol == NULL) {
771 <            strcpy(painCave.errMsg, "Molecule not found on node 0!");
772 <            haveError = 1;
773 <            simError();
774 <          }
775 <          
776 <          for (integrableObject = mol->beginIntegrableObject(ii);
777 <               integrableObject != NULL;
778 <               integrableObject = mol->nextIntegrableObject(ii)){
779 <            
780 <            integrableObject->setZangle( 0.0 );
781 <            
782 <          }
783 <          
784 <        } else {
785 <          // I am MASTER OF THE UNIVERSE, but I don't own this molecule
786 <          
787 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
788 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
789 <          
790 <          for(j=0; j < nCurObj; j++){            
791 <            angleTransfer = 0.0;
792 <            MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
793 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);              
794 <            
795 <          }
796 <        }
797 <      }
798 <    } else {
799 <      // I am SLAVE TO THE MASTER
800 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
801 <        int which_node = info_->getMolToProc(i);
802 <        
803 <        if (which_node == worldRank) {
804 <          
805 <          // BUT I OWN THIS MOLECULE!!!
806 <          mol = info_->getMoleculeByGlobalIndex(i);
807 <          
808 <          if(mol == NULL) {
809 <            sprintf(painCave.errMsg,
810 <                    "RestReader Error: molecule not found on node %d\n",
811 <                    worldRank);
812 <            painCave.isFatal = 1;
813 <            simError();
814 <          }
815 <          
816 <          nCurObj = mol->getNIntegrableObjects();
817 <          
818 <          MPI_Send(&nCurObj, 1, MPI_INT, 0,
819 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
820 <          
821 <          for (integrableObject = mol->beginIntegrableObject(ii);
822 <               integrableObject != NULL;
823 <               integrableObject = mol->nextIntegrableObject(ii)){
824 <            
825 <            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
826 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
827 <            vecParticles[j]->setZangle(angleTransfer);
828 <          }    
829 <        }
830 <      }
831 <    }
832 < #endif
833 <  }
834 <  
835 < } // end namespace oopse
442 >  
443 > }//end namespace OpenMD

Comparing:
trunk/src/io/RestReader.cpp (property svn:keywords), Revision 431 by chrisfen, Fri Mar 11 00:43:19 2005 UTC vs.
branches/development/src/io/RestReader.cpp (property svn:keywords), Revision 1665 by gezelter, Tue Nov 22 20:38:56 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines