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 417 by chrisfen, Thu Mar 10 15:10:24 2005 UTC vs.
Revision 1360 by cli2, Mon Sep 7 16:31:51 2009 UTC

# Line 1 | Line 1
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. 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
19 < *    notice, this list of conditions and the following disclaimer.
20 < *
21 < * 3. Redistributions in binary form must reproduce the above copyright
22 < *    notice, this list of conditions and the following disclaimer in the
23 < *    documentation and/or other materials provided with the
24 < *    distribution.
25 < *
26 < * This software is provided "AS IS," without a warranty of any
27 < * kind. All express or implied conditions, representations and
28 < * warranties, including any implied warranty of merchantability,
29 < * fitness for a particular purpose or non-infringement, are hereby
30 < * excluded.  The University of Notre Dame and its licensors shall not
31 < * be liable for any damages suffered by licensee as a result of
32 < * using, modifying or distributing the software or its
33 < * derivatives. In no event will the University of Notre Dame or its
34 < * licensors be liable for any lost revenue, profit or data, or for
35 < * direct, indirect, special, consequential, incidental or punitive
36 < * damages, however caused and regardless of the theory of liability,
37 < * arising out of the use of or inability to use software, even if the
38 < * University of Notre Dame has been advised of the possibility of
39 < * such damages.
40 < */
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. 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
19 > *    notice, this list of conditions and the following disclaimer.
20 > *
21 > * 3. Redistributions in binary form must reproduce the above copyright
22 > *    notice, this list of conditions and the following disclaimer in the
23 > *    documentation and/or other materials provided with the
24 > *    distribution.
25 > *
26 > * This software is provided "AS IS," without a warranty of any
27 > * kind. All express or implied conditions, representations and
28 > * warranties, including any implied warranty of merchantability,
29 > * fitness for a particular purpose or non-infringement, are hereby
30 > * excluded.  The University of Notre Dame and its licensors shall not
31 > * be liable for any damages suffered by licensee as a result of
32 > * using, modifying or distributing the software or its
33 > * derivatives. In no event will the University of Notre Dame or its
34 > * licensors be liable for any lost revenue, profit or data, or for
35 > * direct, indirect, special, consequential, incidental or punitive
36 > * damages, however caused and regardless of the theory of liability,
37 > * arising out of the use of or inability to use software, even if the
38 > * University of Notre Dame has been advised of the possibility of
39 > * such damages.
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 < #define _LARGEFILE_SOURCE64
49 < #define _FILE_OFFSET_BITS 64
48 > namespace oopse {
49 >      
50 >  void RestReader::readReferenceStructure() {
51  
52 < #include <sys/types.h>
46 < #include <sys/stat.h>
52 >    // some of this comes directly from DumpReader.
53  
54 < #include <iostream>
55 < #include <math.h>
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 < #include <stdio.h>
52 < #include <stdlib.h>
53 < #include <string.h>
73 >    needAngMom_ = false;
74  
75 < #include "primitives/Molecule.hpp"
76 < #include "utils/MemoryUtils.hpp"
77 < #include "utils/StringTokenizer.hpp"
58 < #include "io/RestReader.hpp"
59 < #include "utils/simError.h"
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 < #ifdef IS_MPI
80 < #include <mpi.h>
63 < #include "brains/mpiSimulation.hpp"
64 < #define TAKE_THIS_TAG_CHAR 0
65 < #define TAKE_THIS_TAG_INT 1
66 < #define TAKE_THIS_TAG_DOUBLE 2
67 < #endif // is_mpi
79 >    all_pos_.clear();
80 >    all_pos_.resize(info_->getNGlobalIntegrableObjects() );
81  
82 < namespace oopse {
83 <  
84 <  RestReader::RestReader( SimInfo* info ) : info_(info){
85 <        
86 <    idealName = "idealCrystal.in";
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 <    isScanned = false;
91 <    
92 < #ifdef IS_MPI
93 <    if (worldRank == 0) {
94 < #endif
80 <      
81 <      inIdealFile = fopen(idealName, "r");
82 <      if(inIdealFile == NULL){
83 <        sprintf(painCave.errMsg,
84 <                "RestReader: Cannot open file: %s\n", idealName);
85 <        painCave.isFatal = 1;
86 <        simError();
87 <      }
88 <      
89 <      inIdealFileName = idealName;
90 < #ifdef IS_MPI
91 <    }
92 <    strcpy( checkPointMsg,
93 <            "File \"idealCrystal.in\" opened successfully for reading." );
94 <    MPIcheckPoint();
95 < #endif
96 <    return;  
97 <  }
98 <  
99 <  RestReader :: ~RestReader( ){
100 < #ifdef IS_MPI
101 <    if (worldRank == 0) {
102 < #endif
103 <      int error;
104 <      error = fclose( inIdealFile );
105 <      
106 <      if( error ){
107 <        sprintf( painCave.errMsg,
108 <                 "Error closing %s\n", inIdealFileName.c_str());
109 <        simError();
110 <      }
111 <      
112 <      MemoryUtils::deletePointers(framePos);
113 <      
114 < #ifdef IS_MPI
115 <    }
116 <    strcpy( checkPointMsg, "Restraint file closed successfully." );
117 <    MPIcheckPoint();
118 < #endif
119 <    
120 <    return;
121 <  }
122 <  
123 <  
124 <  void RestReader :: readIdealCrystal(){
125 <    
126 <    int i;
127 <    unsigned int j;
128 <    
129 < #ifdef IS_MPI
130 <    int done, which_node, which_atom; // loop counter
131 < #endif //is_mpi
132 <    
133 <    const int BUFFERSIZE = 2000; // size of the read buffer
134 <    int nTotObjs; // the number of atoms
135 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
136 <    
137 <    char *eof_test; // ptr to see when we reach the end of the file
138 <    char *parseErr;
139 <    
140 <    std::vector<StuntDouble*> integrableObjects;
141 <    
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* integrableObject;
97 <    SimInfo::MoleculeIterator mi;
98 <    Molecule::IntegrableObjectIterator ii;
99 <    
100 < #ifndef IS_MPI
101 <    
102 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
103 <    if( eof_test == NULL ){
104 <      sprintf( painCave.errMsg,
105 <               "RestraintReader error: error reading 1st line of \"%s\"\n",
106 <               inIdealFileName.c_str() );
154 <      painCave.isFatal = 1;
155 <      simError();
156 <    }
157 <    
158 <    nTotObjs = atoi( read_buffer );
159 <    
160 <    if( nTotObjs != info_->getNGlobalIntegrableObjects() ){
161 <      sprintf( painCave.errMsg,
162 <               "RestraintReader error. %s nIntegrable, %d, "
163 <               "does not match the meta-data file's nIntegrable, %d.\n",
164 <               inIdealFileName.c_str(), nTotObjs,
165 <               info_->getNGlobalIntegrableObjects());
166 <      painCave.isFatal = 1;
167 <      simError();
168 <    }
169 <    
170 <    // skip over the comment line
171 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
172 <    if(eof_test == NULL){
173 <      sprintf( painCave.errMsg,
174 <               "error in reading commment in %s\n", inIdealFileName.c_str());
175 <      painCave.isFatal = 1;
176 <      simError();
177 <    }
178 <    
179 <    // parse the ideal crystal lines
180 <    /*
181 <     * Note: we assume that there is a one-to-one correspondence between
182 <     * integrable objects and lines in the idealCrystal.in file.  Thermodynamic
183 <     * integration is only supported for simple rigid bodies.
184 <     */
185 <    for (mol = info_->beginMolecule(mi); mol != NULL;
186 <         mol = info_->nextMolecule(mi)) {
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 <      for (integrableObject = mol->beginIntegrableObject(ii);
109 <           integrableObject != NULL;
110 <           integrableObject = mol->nextIntegrableObject(ii)) {    
111 <        
112 <        eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
113 <        if(eof_test == NULL){
114 <          sprintf(painCave.errMsg,
115 <                  "RestReader Error: error in reading file %s\n"
116 <                  "natoms  = %d; index = %d\n"
117 <                  "error reading the line from the file.\n",
118 <                  inIdealFileName.c_str(), nTotObjs,
119 <                  integrableObject->getGlobalIndex() );
120 <          painCave.isFatal = 1;
121 <          simError();
122 <        }
123 <        
124 <        parseErr = parseIdealLine( read_buffer, integrableObject);
125 <        if( parseErr != NULL ){
126 <          strcpy( painCave.errMsg, parseErr );
127 <          painCave.isFatal = 1;
128 <          simError();
129 <        }
210 <      }
211 <    }
212 <    
213 <    // MPI Section of code..........
214 < #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 localIndex;
224 <    int nCurObj;
225 <    int nitems;
226 <    
227 <    nTotObjs = info_->getTotIntegrableObjects();
228 <    haveError = 0;
229 <    
230 <    if (worldRank == masterNode) {
231 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
232 <      if( eof_test == NULL ){
233 <        sprintf( painCave.errMsg,
234 <                 "Error reading 1st line of %s \n ",inIdealFileName.c_str());
235 <        painCave.isFatal = 1;
236 <        simError();
237 <      }
238 <      
239 <      nitems = atoi( read_buffer );
240 <      
241 <      // Check to see that the number of integrable objects in the
242 <      // intial configuration file is the same as derived from the
243 <      // 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();
252 <      }
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 <      }
262 <      
263 <      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
264 <        int which_node = info_->getMolToProc(i);
265 <        
266 <        if(which_node == masterNode){
267 <          //molecules belong to master node
268 <          
269 <          localIndex = info_->getMoleculeByGlobalIndex(i);
270 <          
271 <          if(localIndex == NULL) {
272 <            strcpy(painCave.errMsg,
273 <                   "RestReader Error: Molecule not found on node %d!",
274 <                   worldRank);
275 <            painCave.isFatal = 1;
276 <            simError();
277 <          }
278 <          
279 <          for (integrableObject = mol->beginIntegrableObject(ii);
280 <               integrableObject != NULL;
281 <               integrableObject = mol->nextIntegrableObject(ii)){
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 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
131 >            mTot = 0.0;
132              
133 <            if(eof_test == NULL){
134 <              sprintf(painCave.errMsg,
287 <                      "RestReader Error: error in reading file %s\n"
288 <                      "natoms  = %d; index = %d\n"
289 <                      "error reading the line from the file.\n",
290 <                      inIdealFileName.c_str(), nTotObjs, i );
291 <              painCave.isFatal = 1;
292 <              simError();
293 <            }
133 >            // loop over the stunt doubles in this molecule in the order we
134 >            // will be looping them in the restraint code:
135              
136 <            parseIdealLine(read_buffer, integrableObjects[j]);
137 <          }
138 <        } else {
139 <          //molecule belongs to slave nodes
140 <          
141 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
142 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
143 <          
144 <          for(j=0; j < nCurObj; j++){
145 <            
146 <            eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
147 <            if(eof_test == NULL){
148 <              sprintf(painCave.errMsg,
149 <                      "RestReader Error: error in reading file %s\n"
309 <                      "natoms  = %d; index = %d\n"
310 <                      "error reading the line from the file.\n",
311 <                      inIdealFileName.c_str(), nTotObjs, i );
312 <              painCave.isFatal = 1;
313 <              simError();
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 <            if(haveError) nodeZeroError();
153 <            
154 <            MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
155 <                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
152 >            COM /= mTot;
153 >
154 >            mRest->setReferenceStructure(ref, COM);        
155 >
156            }
157          }
158        }
323    } else {
324      //actions taken at slave nodes
325      for (i=0 ; i < info_->getNGlobalMolecules(); i++) {
326        int which_node = info_->getMolToProc(i);
327        
328        if(which_node == worldRank){
329          //molecule with global index i belongs to this processor
330          
331          localIndex = info_->getMoleculeByGlobalIndex(i);
332          
333          if(localIndex == NULL) {
334            sprintf(painCave.errMsg,
335                    "RestReader Error: molecule not found on node %d\n",
336                    worldRank);
337            painCave.isFatal = 1;
338            simError();
339          }
340          
341          nCurObj = localIndex->getNIntegrableObjects();
342          
343          MPI_Send(&nCurObj, 1, MPI_INT, masterNode,
344                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
345          
346          for (integrableObject = mol->beginIntegrableObject(ii);
347               integrableObject != NULL;
348               integrableObject = mol->nextIntegrableObject(ii)){
349            
350            MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, masterNode,
351                     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
352            
353            parseErr = parseIdealLine(read_buffer, integrableObject);
354            
355            if( parseErr != NULL ){
356              strcpy( painCave.errMsg, parseErr );
357              simError();
358            }
359          }
360        }
361      }
159      }
363 #endif
160    }
161 <  
162 <  char* RestReader::parseIdealLine(char* readLine, StuntDouble* sd){
163 <    
164 <    char *foo; // the pointer to the current string token
165 <    
166 <    double pos[3];        // position place holders
167 <    double q[4];          // the quaternions
168 <    double RfromQ[3][3];  // the rotation matrix
169 <    double normalize;     // to normalize the reference unit vector
170 <    double uX, uY, uZ;    // reference unit vector place holders
171 <    double uselessToken;
172 <    StringTokenizer tokenizer(readLine);
173 <    int nTokens;
174 <    
175 <    nTokens = tokenizer.countTokens();
176 <    
177 <    if (nTokens < 14) {
178 <      sprintf(painCave.errMsg,
179 <              "RestReader Error: Not enough Tokens.\n");
180 <      painCave.isFatal = 1;
181 <      simError();
182 <    }
183 <    
184 <    std::string name = tokenizer.nextToken();
185 <    
186 <    if (name != sd->getType()) {
187 <      
188 <      sprintf(painCave.errMsg,
189 <              "RestReader Error: Atom type [%s] in %s does not "
190 <              "match Atom Type [%s] in .md file.\n",
191 <              name.c_str(), inIdealFileName.c_str(),
192 <              sd->getType().c_str());
193 <      painCave.isFatal = 1;
194 <      simError();        
195 <    }
196 <    
197 <    pos[0] = tokenizer.nextTokenAsDouble();
198 <    pos[1] = tokenizer.nextTokenAsDouble();
199 <    pos[2] = tokenizer.nextTokenAsDouble();
200 <    
201 <    // store the positions in the stuntdouble as generic data doubles
202 <    DoubleGenericData* refPosX = new DoubleGenericData();
203 <    refPosX->setID("refPosX");
204 <    refPosX->setData(pos[0]);
205 <    sd->addProperty(refPosX);
206 <    
207 <    DoubleGenericData* refPosY = new DoubleGenericData();
208 <    refPosY->setID("refPosY");
209 <    refPosY->setData(pos[1]);
210 <    sd->addProperty(refPosY);
211 <    
212 <    DoubleGenericData* refPosZ = new DoubleGenericData();
213 <    refPosZ->setID("refPosZ");
214 <    refPosZ->setData(pos[2]);
215 <    sd->addProperty(refPosZ);
216 <    
217 <    // we don't need the velocities
218 <    uselessToken = tokenizer.nextTokenAsDouble();
219 <    uselessToken = tokenizer.nextTokenAsDouble();
220 <    uselessToken = tokenizer.nextTokenAsDouble();
221 <    
222 <    if (sd->isDirectional()) {
223 <      
224 <      q[0] = tokenizer.nextTokenAsDouble();
225 <      q[1] = tokenizer.nextTokenAsDouble();
226 <      q[2] = tokenizer.nextTokenAsDouble();
227 <      q[3] = tokenizer.nextTokenAsDouble();
228 <      
229 <      // now build the rotation matrix and find the unit vectors
230 <      RfromQ[0][0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
231 <      RfromQ[0][1] = 2*(q[1]*q[2] + q[0]*q[3]);
232 <      RfromQ[0][2] = 2*(q[1]*q[3] - q[0]*q[2]);
233 <      RfromQ[1][0] = 2*(q[1]*q[2] - q[0]*q[3]);
234 <      RfromQ[1][1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
235 <      RfromQ[1][2] = 2*(q[2]*q[3] + q[0]*q[1]);
236 <      RfromQ[2][0] = 2*(q[1]*q[3] + q[0]*q[2]);
237 <      RfromQ[2][1] = 2*(q[2]*q[3] - q[0]*q[1]);
238 <      RfromQ[2][2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
239 <      
240 <      normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
241 <                       + RfromQ[2][2]*RfromQ[2][2]);
242 <      uX = RfromQ[2][0]/normalize;
243 <      uY = RfromQ[2][1]/normalize;
244 <      uZ = RfromQ[2][2]/normalize;
245 <      
246 <      // store reference unit vectors as generic data in the stuntdouble
247 <      DoubleGenericData* refVectorX = new DoubleGenericData();
248 <      refVectorX->setID("refVectorX");
249 <      refVectorX->setData(uX);
250 <      sd->addProperty(refVectorX);
251 <      
252 <      DoubleGenericData* refVectorY = new DoubleGenericData();
253 <      refVectorY->setID("refVectorY");
254 <      refVectorY->setData(uY);
255 <      sd->addProperty(refVectorY);
256 <      
257 <      DoubleGenericData* refVectorZ = new DoubleGenericData();
258 <      refVectorZ->setID("refVectorZ");
259 <      refVectorZ->setData(uZ);
260 <      sd->addProperty(refVectorZ);
261 <    }
466 <    
467 <    // we don't need the angular velocities, so let's exit the line
468 <    return NULL;
469 <  }
470 <  
471 <  void RestReader::readZangle(){
472 <    
473 <    int i;
474 <    unsigned int j;
475 <    int isPresent;
476 <    
477 <    Molecule* mol;
478 <    StuntDouble* integrableObject;
479 <    SimInfo::MoleculeIterator mi;
480 <    Molecule::IntegrableObjectIterator ii;
481 <    
482 < #ifdef IS_MPI
483 <    int done, which_node, which_atom; // loop counter
484 <    int nProc;
485 <    MPI_Status istatus;
486 < #endif //is_mpi
487 <    
488 <    const int BUFFERSIZE = 2000; // size of the read buffer
489 <    int nTotObjs; // the number of atoms
490 <    char read_buffer[BUFFERSIZE]; //the line buffer for reading
491 <    
492 <    char *eof_test; // ptr to see when we reach the end of the file
493 <    char *parseErr;
494 <    
495 <    std::vector<StuntDouble*> vecParticles;
496 <    std::vector<double> tempZangs;
497 <      
498 <    inAngFileName = info_->getRestFileName();
499 <    
500 <    inAngFileName += "0";
501 <    
502 <    // open the omega value file for reading
503 < #ifdef IS_MPI
504 <    if (worldRank == 0) {
505 < #endif
506 <      isPresent = 1;
507 <      inAngFile = fopen(inAngFileName.c_str(), "r");
508 <      if(!inAngFile){
509 <        sprintf(painCave.errMsg,
510 <                "Restraints Warning: %s file is not present\n"
511 <                "\tAll omega values will be initialized to zero. If the\n"
512 <                "\tsimulation is starting from the idealCrystal.in reference\n"
513 <                "\tconfiguration, this is the desired action. If this is not\n"
514 <                "\tthe case, the energy calculations will be incorrect.\n",
515 <                inAngFileName.c_str());
516 <        painCave.severity = OOPSE_WARNING;
517 <        painCave.isFatal = 0;
518 <        simError();  
519 <        isPresent = 0;
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 < oopse::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        }
521      
522 #ifdef IS_MPI
523      // let the other nodes know the status of the file search
524      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
525 #endif // is_mpi
526      
527      if (!isPresent) {
528        zeroZangle();
529        return;
530      }
531      
532 #ifdef IS_MPI
263      }
264 +    
265 +    // keep the position in case we need it for a molecular restraint:
266      
267 <    // listen to node 0 to see if we should exit this function
268 <    if (worldRank != 0) {
269 <      MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
270 <      if (!isPresent) {
271 <        zeroZangle();
272 <        return;
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 <    strcpy( checkPointMsg, "zAngle file opened successfully for reading." );
291 <    MPIcheckPoint();
292 < #endif
293 <    
294 < #ifndef IS_MPI
295 <    
296 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
297 <    if( eof_test == NULL ){
298 <      sprintf( painCave.errMsg,
299 <               "RestraintReader error: error reading 1st line of \"%s\"\n",
300 <               inAngFileName.c_str() );
301 <      painCave.isFatal = 1;
302 <      simError();
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 <    eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
306 <    while ( eof_test != NULL ) {
307 <      // check for and ignore blank lines
308 <      if ( read_buffer != NULL )
309 <        tempZangs.push_back( atof(read_buffer) );
310 <      eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
565 <    }
566 <    
567 <    nTotObjs = info_->getNGlobalIntegrableObjects();
568 <    
569 <    if( nTotObjs != tempZangs.size() ){
570 <      sprintf( painCave.errMsg,
571 <               "RestraintReader zAngle reading error. %s nIntegrable, %d, "
572 <               "does not match the meta-data file's nIntegrable, %d.\n",
573 <               inAngFileName.c_str(), tempZangs.size(), nTotObjs );
574 <      painCave.isFatal = 1;
575 <      simError();
576 <    }
577 <    
578 <    // load the zAngles into the integrable objects
579 <    i = 0;
580 <    for (mol = info_->beginMolecule(mi); mol != NULL;
581 <         mol = info_->nextMolecule(mi)) {
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 <      for (integrableObject = mol->beginIntegrableObject(ii);
313 <           integrableObject != NULL;
585 <           integrableObject = mol->nextIntegrableObject(ii)) {    
586 <        
587 <        integrableObject->setZangle(tempZangs[i]);
588 <        i++;
312 >      if(line.find("</FrameData>") != std::string::npos) {
313 >        break;
314        }
590    }
591    
592    // MPI Section of code..........
593 #else //IS_MPI
594    
595    // first thing first, suspend fatalities.
596    painCave.isEventLoop = 1;
597    
598    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
599    int haveError, index;
600    
601    int *MolToProcMap = mpiSim->getMolToProcMap();
602    int localIndex;
603    int nCurObj;
604    double angleTranfer;
605    
606    nTotObjs = info_->getTotIntegrableObjects();
607    haveError = 0;
608    if (worldRank == 0) {
315        
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      
316      }
317 <    // At this point, node 0 has a tempZangs vector completed, and
641 <    // everyone else has nada
642 <    index = 0;
643 <    
644 <    for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
645 <      // Get the Node number which has this atom
646 <      which_node = MolToProcMap[i];
647 <      
648 <      if (worldRank == 0) {
649 <        if (which_node == 0) {
650 <          localIndex = mpiSim->getGlobalToLocalMol(i);
651 <          
652 <          if(localIndex == -1) {
653 <            strcpy(painCave.errMsg, "Molecule not found on node 0!");
654 <            haveError = 1;
655 <            simError();
656 <          }
657 <          
658 <          vecParticles = (info_->molecules[localIndex]).getIntegrableObjects();
659 <          for(j = 0; j < vecParticles.size(); j++){      
660 <            vecParticles[j]->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 <        
682 <        if (which_node == worldRank) {
683 <          
684 <          // BUT I OWN THIS MOLECULE!!!
685 <          
686 <          localIndex = mpiSim->getGlobalToLocalMol(i);
687 <          vecParticles = (info_->molecules[localIndex]).getIntegrableObjects();
688 <          nCurObj = vecParticles.size();
689 <          
690 <          MPI_Send(&nCurObj, 1, MPI_INT, 0,
691 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
692 <          
693 <          for(j = 0; j < vecParticles.size(); j++){
694 <            
695 <            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
696 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
697 <            vecParticles[j]->setZangle(angleTransfer);
698 <          }    
699 <        }
700 <      }
701 <    }
702 < #endif
317 >
318    }
319 <  
320 <  void RestReader :: zeroZangle(){
321 <    
707 <    int i;
708 <    unsigned int j;
709 <    int nTotObjs; // the number of atoms
710 <    
711 <    Molecule* mol;
712 <    StuntDouble* integrableObject;
713 <    SimInfo::MoleculeIterator mi;
714 <    Molecule::IntegrableObjectIterator ii;
715 <    
716 <    std::vector<StuntDouble*> vecParticles;
717 <    
718 < #ifndef IS_MPI
719 <    // set all zAngles to 0.0
720 <    for (mol = info_->beginMolecule(mi); mol != NULL;
721 <         mol = info_->nextMolecule(mi))
722 <      
723 <      for (integrableObject = mol->beginIntegrableObject(ii);
724 <           integrableObject != NULL;
725 <           integrableObject = mol->nextIntegrableObject(ii))    
726 <        integrableObject->setZangle( 0.0 );
727 <    
728 <    
729 <    // MPI Section of code..........
730 < #else //IS_MPI
731 <    
732 <    // first thing first, suspend fatalities.
733 <    painCave.isEventLoop = 1;
734 <    
735 <    int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
736 <    int haveError, index;
737 <    int which_node;
738 <    
739 <    MPI_Status istatus;
740 <    int *MolToProcMap = mpiSim->getMolToProcMap();
741 <    int localIndex;
742 <    int nCurObj;
743 <    double angleTranfer;
744 <    
745 <    nTotObjs = info_->getTotIntegrableObjects();
746 <    haveError = 0;
747 <    
748 <    for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
749 <      // Get the Node number which has this atom
750 <      which_node = MolToProcMap[i];
751 <      
752 <      // let's let node 0 pass out constant values to all the processors
753 <      if (worldRank == 0) {
754 <        if (which_node == 0) {
755 <          localIndex = mpiSim->getGlobalToLocalMol(i);
756 <          
757 <          if(localIndex == -1) {
758 <            strcpy(painCave.errMsg, "Molecule not found on node 0!");
759 <            haveError = 1;
760 <            simError();
761 <          }
762 <          
763 <          vecParticles = (info_->molecules[localIndex]).getIntegrableObjects();
764 <          for(j = 0; j < vecParticles.size(); j++){      
765 <            vecParticles[j]->setZangle( 0.0 );
766 <          }    
767 <          
768 <        } else {
769 <          // I am MASTER OF THE UNIVERSE, but I don't own this molecule
770 <          
771 <          MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
772 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
773 <          
774 <          for(j=0; j < nCurObj; j++){            
775 <            angleTransfer = 0.0;
776 <            MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
777 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);              
778 <            index++;
779 <          }
780 <        }
781 <      } else {
782 <        // I am SLAVE TO THE MASTER
783 <        
784 <        if (which_node == worldRank) {
785 <          
786 <          // BUT I OWN THIS MOLECULE!!!
787 <          
788 <          localIndex = mpiSim->getGlobalToLocalMol(i);
789 <          vecParticles = (info_->molecules[localIndex]).getIntegrableObjects();
790 <          nCurObj = vecParticles.size();
791 <          
792 <          MPI_Send(&nCurObj, 1, MPI_INT, 0,
793 <                   TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
794 <          
795 <          for(j = 0; j < vecParticles.size(); j++){
796 <            
797 <            MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
798 <                     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
799 <            vecParticles[j]->setZangle(angleTransfer);
800 <          }    
801 <        }
802 <      }
803 <    }
804 < #endif
805 <  }
806 <  
807 < } // end namespace oopse
319 >
320 >  
321 > }//end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines