ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/io/RestraintReader.cpp
Revision: 1772
Committed: Tue Nov 23 22:48:31 2004 UTC (19 years, 7 months ago) by chrisfen
File size: 19981 byte(s)
Log Message:
Improvements to restraints

File Contents

# User Rev Content
1 chrisfen 1772 #define _LARGEFILE_SOURCE64
2     #define _FILE_OFFSET_BITS 64
3    
4     #include <sys/types.h>
5     #include <sys/stat.h>
6    
7     #include <iostream>
8     #include <math.h>
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13    
14    
15     #include "io/ReadWrite.hpp"
16     #include "utils/simError.h"
17    
18     #ifdef IS_MPI
19     #include <mpi.h>
20     #include "brains/mpiSimulation.hpp"
21     #define TAKE_THIS_TAG_CHAR 0
22     #define TAKE_THIS_TAG_INT 1
23     #define TAKE_THIS_TAG_DOUBLE 2
24     #endif // is_mpi
25    
26    
27     RestraintReader :: RestraintReader( SimInfo* the_simnfo ){
28    
29     simnfo = the_simnfo;
30    
31     idealName = "idealCrystal.in";
32    
33     isScanned = false;
34    
35     #ifdef IS_MPI
36     if (worldRank == 0) {
37     #endif
38    
39     inIdealFile = fopen(idealName, "r");
40     if(inIdealFile == NULL){
41     sprintf(painCave.errMsg,
42     "Cannot open file: %s\n", idealName);
43     painCave.isFatal = 1;
44     simError();
45     }
46    
47     inIdealFileName = idealName;
48     #ifdef IS_MPI
49     }
50     strcpy( checkPointMsg, "Restraint file opened for reading successfully." );
51     MPIcheckPoint();
52     #endif
53     return;
54     }
55    
56     RestraintReader :: ~RestraintReader( ){
57     #ifdef IS_MPI
58     if (worldRank == 0) {
59     #endif
60     vector<fpos_t*>::iterator i;
61    
62     int error;
63     error = fclose( inIdealFile );
64     if( error ){
65     sprintf( painCave.errMsg,
66     "Error closing %s\n", inIdealFileName.c_str());
67     simError();
68     }
69    
70     for(i = framePos.begin(); i != framePos.end(); ++i)
71     delete *i;
72     framePos.clear();
73    
74     #ifdef IS_MPI
75     }
76     strcpy( checkPointMsg, "Restraint file closed successfully." );
77     MPIcheckPoint();
78     #endif
79    
80     return;
81     }
82    
83    
84     void RestraintReader :: readIdealCrystal(){
85    
86     int i;
87     unsigned int j;
88    
89     #ifdef IS_MPI
90     int done, which_node, which_atom; // loop counter
91     #endif //is_mpi
92    
93     const int BUFFERSIZE = 2000; // size of the read buffer
94     int nTotObjs; // the number of atoms
95     char read_buffer[BUFFERSIZE]; //the line buffer for reading
96    
97     char *eof_test; // ptr to see when we reach the end of the file
98     char *parseErr;
99    
100     vector<StuntDouble*> integrableObjects;
101    
102    
103     #ifndef IS_MPI
104    
105     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
106     if( eof_test == NULL ){
107     sprintf( painCave.errMsg,
108     "RestraintReader error: error reading 1st line of \"%s\"\n",
109     inIdealFileName.c_str() );
110     painCave.isFatal = 1;
111     simError();
112     }
113    
114     nTotObjs = atoi( read_buffer );
115    
116     if( nTotObjs != simnfo->getTotIntegrableObjects() ){
117     sprintf( painCave.errMsg,
118     "RestraintReader error. %s nIntegrable, %d, "
119     "does not match the meta-data file's nIntegrable, %d.\n",
120     inIdealFileName.c_str(), nTotObjs, simnfo->getTotIntegrableObjects());
121     painCave.isFatal = 1;
122     simError();
123     }
124    
125     // skip over the comment line
126     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
127     if(eof_test == NULL){
128     sprintf( painCave.errMsg,
129     "error in reading commment in %s\n", inIdealFileName.c_str());
130     painCave.isFatal = 1;
131     simError();
132     }
133    
134     // parse the ideal crystal lines
135     /*
136     Note: we assume that there is a one-to-one correspondence between
137     integrable objects and lines in the idealCrystal.in file. Thermodynamic
138     integration is only supported for simple rigid bodies.
139     */
140     for( i=0; i < simnfo->n_mol; i++){
141    
142     integrableObjects = (simnfo->molecules[i]).getIntegrableObjects();
143    
144     for(j = 0; j < integrableObjects.size(); j++){
145    
146     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
147     if(eof_test == NULL){
148     sprintf(painCave.errMsg,
149     "error in reading file %s\n"
150     "natoms = %d; index = %d\n"
151     "error reading the line from the file.\n",
152     inIdealFileName.c_str(), nTotObjs, i );
153     painCave.isFatal = 1;
154     simError();
155     }
156    
157     parseErr = parseIdealLine( read_buffer, integrableObjects[j]);
158     if( parseErr != NULL ){
159     strcpy( painCave.errMsg, parseErr );
160     painCave.isFatal = 1;
161     simError();
162     }
163     }
164     }
165    
166     // MPI Section of code..........
167     #else //IS_MPI
168    
169     // first thing first, suspend fatalities.
170     painCave.isEventLoop = 1;
171    
172     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
173     int haveError;
174    
175     MPI_Status istatus;
176     int *MolToProcMap = mpiSim->getMolToProcMap();
177     int localIndex;
178     int nCurObj;
179     int nitems;
180    
181     nTotObjs = simnfo->getTotIntegrableObjects();
182     haveError = 0;
183     if (worldRank == 0) {
184     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
185     if( eof_test == NULL ){
186     sprintf( painCave.errMsg,
187     "Error reading 1st line of %s \n ",inIdealFileName.c_str());
188     haveError = 1;
189     simError();
190     }
191    
192     nitems = atoi( read_buffer );
193    
194     // Check to see that the number of integrable objects in the
195     // intial configuration file is the same as derived from the
196     // meta-data file.
197     if( nTotObjs != nitems){
198     sprintf( painCave.errMsg,
199     "RestraintReader Error. %s nIntegrable, %d, "
200     "does not match the meta-data file's nIntegrable, %d.\n",
201     inIdealFileName.c_str(), nTotObjs, simnfo->getTotIntegrableObjects());
202     haveError= 1;
203     simError();
204     }
205    
206     // skip over the comment line
207     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
208     if(eof_test == NULL){
209     sprintf( painCave.errMsg,
210     "error in reading commment in %s\n", inIdealFileName.c_str());
211     haveError = 1;
212     simError();
213     }
214    
215     for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
216     which_node = MolToProcMap[i];
217     if(which_node == 0){
218     //molecules belong to master node
219    
220     localIndex = mpiSim->getGlobalToLocalMol(i);
221    
222     if(localIndex == -1) {
223     strcpy(painCave.errMsg, "Molecule not found on node 0!");
224     haveError = 1;
225     simError();
226     }
227    
228     integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
229     for(j=0; j < integrableObjects.size(); j++){
230    
231     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
232     if(eof_test == NULL){
233     sprintf(painCave.errMsg,
234     "error in reading file %s\n"
235     "natoms = %d; index = %d\n"
236     "error reading the line from the file.\n",
237     inIdealFileName.c_str(), nTotObjs, i );
238     haveError= 1;
239     simError();
240     }
241    
242     if(haveError) nodeZeroError();
243    
244     parseIdealLine(read_buffer, integrableObjects[j]);
245     }
246     }
247     else{
248     //molecule belongs to slave nodes
249    
250     MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
251     TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
252    
253     for(j=0; j < nCurObj; j++){
254    
255     eof_test = fgets(read_buffer, sizeof(read_buffer), inIdealFile);
256     if(eof_test == NULL){
257     sprintf(painCave.errMsg,
258     "error in reading file %s\n"
259     "natoms = %d; index = %d\n"
260     "error reading the line from the file.\n",
261     inIdealFileName.c_str(), nTotObjs, i );
262     haveError= 1;
263     simError();
264     }
265    
266     if(haveError) nodeZeroError();
267    
268     MPI_Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node,
269     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD);
270     }
271     }
272     }
273     }
274     else{
275     //actions taken at slave nodes
276     for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
277     which_node = MolToProcMap[i];
278    
279     if(which_node == worldRank){
280     //molecule with global index i belongs to this processor
281    
282     localIndex = mpiSim->getGlobalToLocalMol(i);
283    
284     if(localIndex == -1) {
285     sprintf(painCave.errMsg, "Molecule not found on node %d\n", worldRank);
286     haveError = 1;
287     simError();
288     }
289    
290     integrableObjects = (simnfo->molecules[localIndex]).getIntegrableObjects();
291    
292     nCurObj = integrableObjects.size();
293    
294     MPI_Send(&nCurObj, 1, MPI_INT, 0,
295     TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
296    
297     for(j = 0; j < integrableObjects.size(); j++){
298    
299     MPI_Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0,
300     TAKE_THIS_TAG_CHAR, MPI_COMM_WORLD, &istatus);
301    
302     parseErr = parseIdealLine(read_buffer, integrableObjects[j]);
303    
304     if( parseErr != NULL ){
305     strcpy( painCave.errMsg, parseErr );
306     simError();
307     }
308     }
309     }
310     }
311     }
312     #endif
313     }
314    
315     char* RestraintReader::parseIdealLine(char* readLine, StuntDouble* sd){
316    
317     char *foo; // the pointer to the current string token
318    
319     double pos[3]; // position place holders
320     double q[4]; // the quaternions
321     double RfromQ[3][3]; // the rotation matrix
322     double normalize; // to normalize the reference unit vector
323     double uX, uY, uZ; // reference unit vector place holders
324    
325     // set the string tokenizer
326    
327     foo = strtok(readLine, " ,;\t");
328    
329     // check the atom name to the current atom
330    
331     if( strcmp( foo, sd->getType() ) ){
332     sprintf( painCave.errMsg,
333     "RestraintReader error. Does not"
334     " match the meta-data atom %s.\n",
335     sd->getType() );
336     return strdup( painCave.errMsg );
337     }
338    
339     // get the positions
340    
341     foo = strtok(NULL, " ,;\t");
342     if(foo == NULL){
343     sprintf( painCave.errMsg,
344     "error in reading position x from %s\n",
345     inIdealFileName.c_str());
346     return strdup( painCave.errMsg );
347     }
348     pos[0] = atof( foo );
349    
350     foo = strtok(NULL, " ,;\t");
351     if(foo == NULL){
352     sprintf( painCave.errMsg,
353     "error in reading position y from %s\n",
354     inIdealFileName.c_str());
355     return strdup( painCave.errMsg );
356     }
357     pos[1] = atof( foo );
358    
359     foo = strtok(NULL, " ,;\t");
360     if(foo == NULL){
361     sprintf( painCave.errMsg,
362     "error in reading position z from %s\n",
363     inIdealFileName.c_str());
364     return strdup( painCave.errMsg );
365     }
366     pos[2] = atof( foo );
367    
368     // store the positions in the stuntdouble as generic data doubles
369     DoubleGenericData* refPosX = new DoubleGenericData();
370     refPosX->setID("refPosX");
371     refPosX->setData(pos[0]);
372     sd->addProperty(refPosX);
373    
374     DoubleGenericData* refPosY = new DoubleGenericData();
375     refPosY->setID("refPosY");
376     refPosY->setData(pos[1]);
377     sd->addProperty(refPosY);
378    
379     DoubleGenericData* refPosZ = new DoubleGenericData();
380     refPosZ->setID("refPosZ");
381     refPosZ->setData(pos[2]);
382     sd->addProperty(refPosZ);
383    
384     // we don't need the velocities
385     foo = strtok(NULL, " ,;\t");
386     foo = strtok(NULL, " ,;\t");
387     foo = strtok(NULL, " ,;\t");
388    
389     if (!sd->isDirectional())
390     return NULL;
391    
392     // get the quaternions
393     if( sd->isDirectional() ){
394    
395     foo = strtok(NULL, " ,;\t");
396     if(foo == NULL){
397     sprintf( painCave.errMsg,
398     "error in reading quaternion 0 from %s\n",
399     inIdealFileName.c_str() );
400     return strdup( painCave.errMsg );
401     }
402     q[0] = atof( foo );
403    
404     foo = strtok(NULL, " ,;\t");
405     if(foo == NULL){
406     sprintf( painCave.errMsg,
407     "error in reading quaternion 1 from %s\n",
408     inIdealFileName.c_str() );
409     return strdup( painCave.errMsg );
410     }
411     q[1] = atof( foo );
412    
413     foo = strtok(NULL, " ,;\t");
414     if(foo == NULL){
415     sprintf( painCave.errMsg,
416     "error in reading quaternion 2 from %s\n",
417     inIdealFileName.c_str() );
418     return strdup( painCave.errMsg );
419     }
420     q[2] = atof( foo );
421    
422     foo = strtok(NULL, " ,;\t");
423     if(foo == NULL){
424     sprintf( painCave.errMsg,
425     "error in reading quaternion 3 from %s\n",
426     inIdealFileName.c_str() );
427     return strdup( painCave.errMsg );
428     }
429     q[3] = atof( foo );
430    
431     // now build the rotation matrix and find the unit vectors
432     RfromQ[0][0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
433     RfromQ[0][1] = 2*(q[1]*q[2] + q[0]*q[3]);
434     RfromQ[0][2] = 2*(q[1]*q[3] - q[0]*q[2]);
435     RfromQ[1][0] = 2*(q[1]*q[2] - q[0]*q[3]);
436     RfromQ[1][1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
437     RfromQ[1][2] = 2*(q[2]*q[3] + q[0]*q[1]);
438     RfromQ[2][0] = 2*(q[1]*q[3] + q[0]*q[2]);
439     RfromQ[2][1] = 2*(q[2]*q[3] - q[0]*q[1]);
440     RfromQ[2][2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
441    
442     normalize = sqrt(RfromQ[2][0]*RfromQ[2][0] + RfromQ[2][1]*RfromQ[2][1]
443     + RfromQ[2][2]*RfromQ[2][2]);
444     uX = RfromQ[2][0]/normalize;
445     uY = RfromQ[2][1]/normalize;
446     uZ = RfromQ[2][2]/normalize;
447    
448     // store reference unit vectors as generic data in the stuntdouble
449     DoubleGenericData* refVectorX = new DoubleGenericData();
450     refVectorX->setID("refVectorX");
451     refVectorX->setData(uX);
452     sd->addProperty(refVectorX);
453    
454     DoubleGenericData* refVectorY = new DoubleGenericData();
455     refVectorY->setID("refVectorY");
456     refVectorY->setData(uY);
457     sd->addProperty(refVectorY);
458    
459     DoubleGenericData* refVectorZ = new DoubleGenericData();
460     refVectorZ->setID("refVectorZ");
461     refVectorZ->setData(uZ);
462     sd->addProperty(refVectorZ);
463     }
464    
465     // we don't need the angular velocities, so let's exit the line
466     return NULL;
467     }
468    
469     #ifdef IS_MPI
470     void RestraintReader::nodeZeroError( void ){
471     int j, myStatus;
472    
473     myStatus = 0;
474     for (j = 0; j < mpiSim->getNProcessors(); j++) {
475     MPI_Send( &myStatus, 1, MPI_INT, j,
476     TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
477     }
478    
479    
480     MPI_Finalize();
481     exit (0);
482    
483     }
484    
485     void RestraintReader::anonymousNodeDie( void ){
486    
487     MPI_Finalize();
488     exit (0);
489     }
490     #endif
491    
492     void RestraintReader::readZangle( const char *in_name ){
493    
494     int i;
495     unsigned int j;
496    
497     #ifdef IS_MPI
498     int done, which_node, which_atom; // loop counter
499    
500     int *potatoes;
501     int myPotato;
502    
503     int nProc;
504     #endif //is_mpi
505    
506     const int BUFFERSIZE = 2000; // size of the read buffer
507     int nTotObjs; // the number of atoms
508     char read_buffer[BUFFERSIZE]; //the line buffer for reading
509    
510     char *eof_test; // ptr to see when we reach the end of the file
511     char *parseErr;
512    
513     vector<StuntDouble*> vecParticles;
514     vector<double> tempZangs;
515    
516     // open the omega value file for reading
517     #ifdef IS_MPI
518     if (worldRank == 0) {
519     #endif
520    
521     inAngFile = fopen(in_name, "r");
522     if(!inAngFile){
523     sprintf(painCave.errMsg,
524     "Restraints Warning: %s file is not present\n"
525     "\tAll omega values will be initialized to zero. If the\n"
526     "\tsimulation is starting from the idealCrystal.in reference\n"
527     "\tconfiguration, this is the desired action. If this is not\n"
528     "\tthe case, the energy calculations will be incorrect.\n",
529     in_name);
530     painCave.severity = OOPSE_WARNING;
531     painCave.isFatal = 0;
532     simError();
533     return;
534     }
535    
536     inAngFileName = in_name;
537     #ifdef IS_MPI
538     }
539     strcpy( checkPointMsg, "zAngle file opened successfully for reading." );
540     MPIcheckPoint();
541     #endif
542    
543     #ifndef IS_MPI
544    
545     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
546     if( eof_test == NULL ){
547     sprintf( painCave.errMsg,
548     "RestraintReader error: error reading 1st line of \"%s\"\n",
549     inAngFileName.c_str() );
550     painCave.isFatal = 1;
551     simError();
552     }
553    
554     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
555     while ( eof_test != NULL ) {
556     // check for and ignore blank lines
557     if ( read_buffer != NULL )
558     tempZangs.push_back( atof(read_buffer) );
559     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
560     }
561    
562     nTotObjs = simnfo->getTotIntegrableObjects();
563    
564     if( nTotObjs != tempZangs.size() ){
565     sprintf( painCave.errMsg,
566     "RestraintReader zAngle reading error. %s nIntegrable, %d, "
567     "does not match the meta-data file's nIntegrable, %d.\n",
568     inAngFileName.c_str(), tempZangs.size(), nTotObjs );
569     painCave.isFatal = 1;
570     simError();
571     }
572    
573     // load the zAngles into the integrable objects
574     vecParticles = simnfo->integrableObjects;
575    
576     for ( i=0; i<vecParticles.size(); i++ ) {
577     vecParticles[i]->setZangle(tempZangs[i]);
578     }
579    
580     // MPI Section of code..........
581     #else //IS_MPI
582    
583     // first thing first, suspend fatalities.
584     painCave.isEventLoop = 1;
585    
586     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
587     int haveError, index;
588    
589     MPI_Status istatus;
590     int *MolToProcMap = mpiSim->getMolToProcMap();
591     int localIndex;
592     int nCurObj;
593     double angleTranfer;
594    
595     nTotObjs = simnfo->getTotIntegrableObjects();
596     haveError = 0;
597     if (worldRank == 0) {
598    
599     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
600     if( eof_test == NULL ){
601     sprintf( painCave.errMsg,
602     "Error reading 1st line of %s \n ",inAngFileName.c_str());
603     haveError = 1;
604     simError();
605     }
606    
607     // let node 0 load the temporary angle vector
608     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
609     while ( eof_test != NULL ) {
610     // check for and ignore blank lines
611     if ( read_buffer != NULL )
612     tempZangs.push_back( atof(read_buffer) );
613     eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
614     }
615    
616     // Check to see that the number of integrable objects in the
617     // intial configuration file is the same as derived from the
618     // meta-data file.
619     if( nTotObjs != tempZangs.size() ){
620     sprintf( painCave.errMsg,
621     "RestraintReader zAngle reading Error. %s nIntegrable, %d, "
622     "does not match the meta-data file's nIntegrable, %d.\n",
623     inAngFileName.c_str(), tempZangs.size(), nTotObjs);
624     haveError= 1;
625     simError();
626     }
627    
628     }
629     // At this point, node 0 has a tempZangs vector completed, and
630     // everyone else has nada
631     index = 0;
632    
633     for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
634     // Get the Node number which has this atom
635     which_node = MolToProcMap[i];
636    
637     if (worldRank == 0) {
638     if (which_node == 0) {
639     localIndex = mpiSim->getGlobalToLocalMol(i);
640    
641     if(localIndex == -1) {
642     strcpy(painCave.errMsg, "Molecule not found on node 0!");
643     haveError = 1;
644     simError();
645     }
646    
647     vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
648     for(j = 0; j < vecParticles.size(); j++){
649     vecParticles[j]->setZangle(tempZangs[index]);
650     index++;
651     }
652    
653     // restraints is limited to a single zAngle per molecule
654     vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
655     for(j=0; j < vecParticles.size(); j++)
656     vecParticles[j]->setZangle(tempZangs[i]);
657    
658     } else {
659     // I am MASTER OF THE UNIVERSE, but I don't own this molecule
660    
661     MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
662     TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
663    
664     for(j=0; j < nCurObj; j++){
665     angleTransfer = tempZangs[index];
666     MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
667     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);
668     index++;
669     }
670    
671     }
672    
673     } else {
674     // I am SLAVE TO THE MASTER
675    
676     if (which_node == worldRank) {
677    
678     // BUT I OWN THIS MOLECULE!!!
679    
680     localIndex = mpiSim->getGlobalToLocalMol(i);
681     vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
682     nCurObj = vecParticles.size();
683    
684     MPI_Send(&nCurObj, 1, MPI_INT, 0,
685     TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
686    
687     for(j = 0; j < vecParticles.size(); j++){
688    
689     MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
690     TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
691     vecParticles[j]->setZangle(angleTransfer);
692     }
693     }
694     }
695     }
696     #endif
697     }
698    
699     void RestraintReader :: zeroZangle(){
700    
701     int i;
702     unsigned int j;
703    
704     vector<StuntDouble*> vecParticles;
705    
706     #ifndef IS_MPI
707     // set all zAngles to 0.0
708     vecParticles = simnfo->integrableObjects;
709    
710     for ( i=0; i<vecParticles.size(); i++ ) {
711     vecParticles[i]->setZangle( 0.0 );
712     }
713    
714     // MPI Section of code..........
715     #else //IS_MPI
716    
717     // first thing first, suspend fatalities.
718     painCave.isEventLoop = 1;
719    
720     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
721     int haveError;
722    
723     MPI_Status istatus;
724     int *MolToProcMap = mpiSim->getMolToProcMap();
725     int localIndex;
726     int which_node;
727    
728     haveError = 0;
729    
730     for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
731     which_node = MolToProcMap[i];
732    
733     if(which_node == worldRank){
734     //molecule with global index i belongs to this processor
735    
736     localIndex = mpiSim->getGlobalToLocalMol(i);
737    
738     if(localIndex == -1) {
739     sprintf(painCave.errMsg, "Molecule not found on node %d\n", worldRank);
740     haveError = 1;
741     simError();
742     }
743    
744     vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
745    
746     // set zAngle to 0.0 for all integrable objects
747     for(j = 0; j < vecParticles.size(); j++){
748     vecParticles[j]->setZangle( 0.0 );
749     }
750     }
751     }
752     #endif
753     }