ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/io/RestraintReader.cpp
Revision: 1778
Committed: Wed Nov 24 18:06:34 2004 UTC (19 years, 7 months ago) by chrisfen
File size: 21432 byte(s)
Log Message:
improved restraints - mpi should work fine

File Contents

# Content
1 #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 int isPresent;
497
498 #ifdef IS_MPI
499 int done, which_node, which_atom; // loop counter
500 int nProc;
501 MPI_Status istatus;
502 #endif //is_mpi
503
504 const int BUFFERSIZE = 2000; // size of the read buffer
505 int nTotObjs; // the number of atoms
506 char read_buffer[BUFFERSIZE]; //the line buffer for reading
507
508 char *eof_test; // ptr to see when we reach the end of the file
509 char *parseErr;
510
511 vector<StuntDouble*> vecParticles;
512 vector<double> tempZangs;
513
514 // open the omega value file for reading
515 #ifdef IS_MPI
516 if (worldRank == 0) {
517 #endif
518 isPresent = 1;
519 inAngFile = fopen(in_name, "r");
520 if(!inAngFile){
521 sprintf(painCave.errMsg,
522 "Restraints Warning: %s file is not present\n"
523 "\tAll omega values will be initialized to zero. If the\n"
524 "\tsimulation is starting from the idealCrystal.in reference\n"
525 "\tconfiguration, this is the desired action. If this is not\n"
526 "\tthe case, the energy calculations will be incorrect.\n",
527 in_name);
528 painCave.severity = OOPSE_WARNING;
529 painCave.isFatal = 0;
530 simError();
531 isPresent = 0;
532 }
533
534 #ifdef IS_MPI
535 // let the other nodes know the status of the file search
536 MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
537 #endif // is_mpi
538
539 if (!isPresent)
540 return;
541
542 inAngFileName = in_name;
543 #ifdef IS_MPI
544 }
545
546 // listen to node 0 to see if we should exit this function
547 if (worldRank != 0) {
548 MPI_Bcast(&isPresent, 1, MPI_INT, 0, MPI_COMM_WORLD);
549 if (!isPresent)
550 return;
551 }
552
553 strcpy( checkPointMsg, "zAngle file opened successfully for reading." );
554 MPIcheckPoint();
555 #endif
556
557 #ifndef IS_MPI
558
559 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
560 if( eof_test == NULL ){
561 sprintf( painCave.errMsg,
562 "RestraintReader error: error reading 1st line of \"%s\"\n",
563 inAngFileName.c_str() );
564 painCave.isFatal = 1;
565 simError();
566 }
567
568 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
569 while ( eof_test != NULL ) {
570 // check for and ignore blank lines
571 if ( read_buffer != NULL )
572 tempZangs.push_back( atof(read_buffer) );
573 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
574 }
575
576 nTotObjs = simnfo->getTotIntegrableObjects();
577
578 if( nTotObjs != tempZangs.size() ){
579 sprintf( painCave.errMsg,
580 "RestraintReader zAngle reading error. %s nIntegrable, %d, "
581 "does not match the meta-data file's nIntegrable, %d.\n",
582 inAngFileName.c_str(), tempZangs.size(), nTotObjs );
583 painCave.isFatal = 1;
584 simError();
585 }
586
587 // load the zAngles into the integrable objects
588 vecParticles = simnfo->integrableObjects;
589
590 for ( i=0; i<vecParticles.size(); i++ ) {
591 vecParticles[i]->setZangle(tempZangs[i]);
592 }
593
594 // MPI Section of code..........
595 #else //IS_MPI
596
597 // first thing first, suspend fatalities.
598 painCave.isEventLoop = 1;
599
600 int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
601 int haveError, index;
602
603 int *MolToProcMap = mpiSim->getMolToProcMap();
604 int localIndex;
605 int nCurObj;
606 double angleTranfer;
607
608 nTotObjs = simnfo->getTotIntegrableObjects();
609 haveError = 0;
610 if (worldRank == 0) {
611
612 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
613 if( eof_test == NULL ){
614 sprintf( painCave.errMsg,
615 "Error reading 1st line of %s \n ",inAngFileName.c_str());
616 haveError = 1;
617 simError();
618 }
619
620 // let node 0 load the temporary angle vector
621 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
622 while ( eof_test != NULL ) {
623 // check for and ignore blank lines
624 if ( read_buffer != NULL )
625 tempZangs.push_back( atof(read_buffer) );
626 eof_test = fgets(read_buffer, sizeof(read_buffer), inAngFile);
627 }
628
629 // Check to see that the number of integrable objects in the
630 // intial configuration file is the same as derived from the
631 // meta-data file.
632 if( nTotObjs != tempZangs.size() ){
633 sprintf( painCave.errMsg,
634 "RestraintReader zAngle reading Error. %s nIntegrable, %d, "
635 "does not match the meta-data file's nIntegrable, %d.\n",
636 inAngFileName.c_str(), tempZangs.size(), nTotObjs);
637 haveError= 1;
638 simError();
639 }
640
641 }
642 // At this point, node 0 has a tempZangs vector completed, and
643 // everyone else has nada
644 index = 0;
645
646 for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
647 // Get the Node number which has this atom
648 which_node = MolToProcMap[i];
649
650 if (worldRank == 0) {
651 if (which_node == 0) {
652 localIndex = mpiSim->getGlobalToLocalMol(i);
653
654 if(localIndex == -1) {
655 strcpy(painCave.errMsg, "Molecule not found on node 0!");
656 haveError = 1;
657 simError();
658 }
659
660 vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
661 for(j = 0; j < vecParticles.size(); j++){
662 vecParticles[j]->setZangle(tempZangs[index]);
663 index++;
664 }
665
666 // // restraints is limited to a single zAngle per molecule
667 // vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
668 // for(j=0; j < vecParticles.size(); j++)
669 // vecParticles[j]->setZangle(tempZangs[i]);
670
671 } else {
672 // I am MASTER OF THE UNIVERSE, but I don't own this molecule
673
674 MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
675 TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
676
677 for(j=0; j < nCurObj; j++){
678 angleTransfer = tempZangs[index];
679 MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
680 TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);
681 index++;
682 }
683
684 }
685
686 } else {
687 // I am SLAVE TO THE MASTER
688
689 if (which_node == worldRank) {
690
691 // BUT I OWN THIS MOLECULE!!!
692
693 localIndex = mpiSim->getGlobalToLocalMol(i);
694 vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
695 nCurObj = vecParticles.size();
696
697 MPI_Send(&nCurObj, 1, MPI_INT, 0,
698 TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
699
700 for(j = 0; j < vecParticles.size(); j++){
701
702 MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
703 TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
704 vecParticles[j]->setZangle(angleTransfer);
705 }
706 }
707 }
708 }
709 #endif
710 }
711
712 void RestraintReader :: zeroZangle(){
713
714 int i;
715 unsigned int j;
716 int nTotObjs; // the number of atoms
717
718 vector<StuntDouble*> vecParticles;
719
720 #ifndef IS_MPI
721 // set all zAngles to 0.0
722 vecParticles = simnfo->integrableObjects;
723
724 for ( i=0; i<vecParticles.size(); i++ ) {
725 vecParticles[i]->setZangle( 0.0 );
726 }
727
728 // MPI Section of code..........
729 #else //IS_MPI
730
731 // first thing first, suspend fatalities.
732 painCave.isEventLoop = 1;
733
734 int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
735 int haveError, index;
736 int which_node;
737
738 MPI_Status istatus;
739 int *MolToProcMap = mpiSim->getMolToProcMap();
740 int localIndex;
741 int nCurObj;
742 double angleTranfer;
743
744 nTotObjs = simnfo->getTotIntegrableObjects();
745 haveError = 0;
746
747 for (i=0 ; i < mpiSim->getNMolGlobal(); i++) {
748 // Get the Node number which has this atom
749 which_node = MolToProcMap[i];
750
751 // let's let node 0 pass out constant values to all the processors
752 if (worldRank == 0) {
753 if (which_node == 0) {
754 localIndex = mpiSim->getGlobalToLocalMol(i);
755
756 if(localIndex == -1) {
757 strcpy(painCave.errMsg, "Molecule not found on node 0!");
758 haveError = 1;
759 simError();
760 }
761
762 vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
763 for(j = 0; j < vecParticles.size(); j++){
764 vecParticles[j]->setZangle( 0.0 );
765 }
766
767 } else {
768 // I am MASTER OF THE UNIVERSE, but I don't own this molecule
769
770 MPI_Recv(&nCurObj, 1, MPI_INT, which_node,
771 TAKE_THIS_TAG_INT, MPI_COMM_WORLD, &istatus);
772
773 for(j=0; j < nCurObj; j++){
774 angleTransfer = 0.0;
775 MPI_Send(&angleTransfer, 1, MPI_DOUBLE, which_node,
776 TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD);
777 index++;
778 }
779 }
780 } else {
781 // I am SLAVE TO THE MASTER
782
783 if (which_node == worldRank) {
784
785 // BUT I OWN THIS MOLECULE!!!
786
787 localIndex = mpiSim->getGlobalToLocalMol(i);
788 vecParticles = (simnfo->molecules[localIndex]).getIntegrableObjects();
789 nCurObj = vecParticles.size();
790
791 MPI_Send(&nCurObj, 1, MPI_INT, 0,
792 TAKE_THIS_TAG_INT, MPI_COMM_WORLD);
793
794 for(j = 0; j < vecParticles.size(); j++){
795
796 MPI_Recv(&angleTransfer, 1, MPI_DOUBLE, 0,
797 TAKE_THIS_TAG_DOUBLE, MPI_COMM_WORLD, &istatus);
798 vecParticles[j]->setZangle(angleTransfer);
799 }
800 }
801 }
802 }
803 #endif
804 }