ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/DumpWriter.cpp
Revision: 916
Committed: Fri Jan 9 20:29:32 2004 UTC (20 years, 5 months ago) by gezelter
File size: 22281 byte(s)
Log Message:
New DumpWriter (Attempt #4)

File Contents

# User Rev Content
1 mmeineke 723 #define _FILE_OFFSET_BITS 64
2    
3 gezelter 829 #include <string.h>
4 mmeineke 377 #include <iostream>
5     #include <fstream>
6    
7     #ifdef IS_MPI
8     #include <mpi.h>
9     #include "mpiSimulation.hpp"
10 mmeineke 440
11     namespace dWrite{
12 gezelter 907 void DieDieDie( void );
13 mmeineke 440 }
14    
15     using namespace dWrite;
16 mmeineke 377 #endif //is_mpi
17    
18     #include "ReadWrite.hpp"
19     #include "simError.h"
20    
21     DumpWriter::DumpWriter( SimInfo* the_entry_plug ){
22    
23     entry_plug = the_entry_plug;
24    
25     #ifdef IS_MPI
26     if(worldRank == 0 ){
27     #endif // is_mpi
28 tim 837
29 mmeineke 377 strcpy( outName, entry_plug->sampleName );
30 tim 837
31 mmeineke 377 outFile.open(outName, ios::out | ios::trunc );
32 tim 837
33 mmeineke 377 if( !outFile ){
34 tim 837
35 mmeineke 377 sprintf( painCave.errMsg,
36     "Could not open \"%s\" for dump output.\n",
37     outName);
38     painCave.isFatal = 1;
39     simError();
40     }
41 mmeineke 469
42 mmeineke 377 //outFile.setf( ios::scientific );
43    
44     #ifdef IS_MPI
45     }
46    
47     sprintf( checkPointMsg,
48     "Sucessfully opened output file for dumping.\n");
49     MPIcheckPoint();
50     #endif // is_mpi
51     }
52    
53     DumpWriter::~DumpWriter( ){
54    
55     #ifdef IS_MPI
56     if(worldRank == 0 ){
57     #endif // is_mpi
58    
59     outFile.close();
60    
61     #ifdef IS_MPI
62     }
63     #endif // is_mpi
64     }
65    
66     void DumpWriter::writeDump( double currentTime ){
67 tim 837
68 mmeineke 377 const int BUFFERSIZE = 2000;
69 gezelter 912 const int MINIBUFFERSIZE = 100;
70 gezelter 907
71 mmeineke 377 char tempBuffer[BUFFERSIZE];
72     char writeLine[BUFFERSIZE];
73    
74 mmeineke 787 int i;
75 gezelter 916
76 mmeineke 787 #ifdef IS_MPI
77 gezelter 916
78     int *potatoes;
79     int myPotato;
80    
81     int nProc;
82 mmeineke 787 int j, which_node, done, which_atom, local_index;
83 gezelter 916 double atomData6[6];
84     double atomData13[13];
85 gezelter 907 int isDirectional;
86     char* atomTypeString;
87 gezelter 910 char MPIatomTypeString[MINIBUFFERSIZE];
88 gezelter 916
89 mmeineke 787 #else //is_mpi
90     int nAtoms = entry_plug->n_atoms;
91     #endif //is_mpi
92    
93 mmeineke 377 double q[4];
94     DirectionalAtom* dAtom;
95     Atom** atoms = entry_plug->atoms;
96 mmeineke 670 double pos[3], vel[3];
97 tim 837
98 mmeineke 804 // write current frame to the eor file
99 mmeineke 377
100 mmeineke 804 this->writeFinal( currentTime );
101    
102 mmeineke 377 #ifndef IS_MPI
103 tim 837
104 mmeineke 377 outFile << nAtoms << "\n";
105 tim 837
106     outFile << currentTime << ";\t"
107 mmeineke 590 << entry_plug->Hmat[0][0] << "\t"
108     << entry_plug->Hmat[1][0] << "\t"
109     << entry_plug->Hmat[2][0] << ";\t"
110 mmeineke 572
111 mmeineke 590 << entry_plug->Hmat[0][1] << "\t"
112     << entry_plug->Hmat[1][1] << "\t"
113     << entry_plug->Hmat[2][1] << ";\t"
114 mmeineke 572
115 mmeineke 590 << entry_plug->Hmat[0][2] << "\t"
116     << entry_plug->Hmat[1][2] << "\t"
117 tim 837 << entry_plug->Hmat[2][2] << ";";
118     //write out additional parameters, such as chi and eta
119     outFile << entry_plug->the_integrator->getAdditionalParameters();
120     outFile << endl;
121    
122 mmeineke 377 for( i=0; i<nAtoms; i++ ){
123 tim 837
124 mmeineke 670 atoms[i]->getPos(pos);
125     atoms[i]->getVel(vel);
126 mmeineke 377
127     sprintf( tempBuffer,
128     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
129     atoms[i]->getType(),
130 mmeineke 670 pos[0],
131     pos[1],
132     pos[2],
133     vel[0],
134     vel[1],
135     vel[2]);
136 mmeineke 377 strcpy( writeLine, tempBuffer );
137    
138     if( atoms[i]->isDirectional() ){
139 tim 837
140 mmeineke 377 dAtom = (DirectionalAtom *)atoms[i];
141     dAtom->getQ( q );
142 tim 837
143 mmeineke 377 sprintf( tempBuffer,
144     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
145     q[0],
146     q[1],
147     q[2],
148     q[3],
149     dAtom->getJx(),
150     dAtom->getJy(),
151     dAtom->getJz());
152     strcat( writeLine, tempBuffer );
153     }
154     else
155     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
156 tim 837
157 mmeineke 377 outFile << writeLine;
158     }
159     outFile.flush();
160    
161     #else // is_mpi
162 gezelter 416
163 chuckv 913 /* code to find maximum tag value */
164     int *tagub, flag, MAXTAG;
165     MPI_Attr_get(MPI_COMM_WORLD, MPI_TAG_UB, &tagub, &flag);
166     if (flag) {
167     MAXTAG = *tagub;
168     } else {
169     MAXTAG = 32767;
170 gezelter 916 }
171 mmeineke 440
172     int haveError;
173    
174 mmeineke 447 MPI_Status istatus;
175 gezelter 416 int *AtomToProcMap = mpiSim->getAtomToProcMap();
176 tim 837
177 mmeineke 377 // write out header and node 0's coordinates
178 tim 837
179 mmeineke 377 if( worldRank == 0 ){
180 gezelter 916
181     // Node 0 needs a list of the magic potatoes for each processor;
182    
183     nProc = mpiSim->getNumberProcessors();
184     potatoes = new int[nProc];
185    
186     for (i = 0; i < nProc; i++)
187     potatoes[i] = 0;
188    
189 mmeineke 377 outFile << mpiSim->getTotAtoms() << "\n";
190 tim 837
191     outFile << currentTime << ";\t"
192 gezelter 591 << entry_plug->Hmat[0][0] << "\t"
193     << entry_plug->Hmat[1][0] << "\t"
194     << entry_plug->Hmat[2][0] << ";\t"
195 tim 837
196 gezelter 591 << entry_plug->Hmat[0][1] << "\t"
197     << entry_plug->Hmat[1][1] << "\t"
198     << entry_plug->Hmat[2][1] << ";\t"
199 tim 837
200 gezelter 591 << entry_plug->Hmat[0][2] << "\t"
201     << entry_plug->Hmat[1][2] << "\t"
202 tim 837 << entry_plug->Hmat[2][2] << ";";
203    
204     outFile << entry_plug->the_integrator->getAdditionalParameters();
205     outFile << endl;
206 chuckv 434 outFile.flush();
207 chuckv 913
208 gezelter 416 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
209 chuckv 913
210 gezelter 417 // Get the Node number which has this atom;
211 chuckv 913
212 tim 837 which_node = AtomToProcMap[i];
213 chuckv 913
214 gezelter 907 if (which_node != 0) {
215 gezelter 916
216     if (potatoes[which_node] + 3 >= MAXTAG) {
217     // The potato was going to exceed the maximum value,
218     // so wrap this processor potato back to 0:
219    
220     potatoes[which_node] = 0;
221     MPI_Send(0, 1, MPI_INT, which_node, 0, MPI_COMM_WORLD);
222    
223     }
224    
225     myPotato = potatoes[which_node];
226 gezelter 907
227 gezelter 910 MPI_Recv(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, which_node,
228 gezelter 916 myPotato, MPI_COMM_WORLD, &istatus);
229 gezelter 907
230 gezelter 910 strncpy(atomTypeString, MPIatomTypeString, MINIBUFFERSIZE);
231 gezelter 912
232     // Null terminate the atomTypeString just in case:
233 gezelter 910
234 gezelter 912 atomTypeString[strlen(atomTypeString) - 1] = '\0';
235    
236 gezelter 916 myPotato++;
237    
238 gezelter 907 MPI_Recv(&isDirectional, 1, MPI_INT, which_node,
239 gezelter 916 myPotato, MPI_COMM_WORLD, &istatus);
240    
241     myPotato++;
242 gezelter 907
243 gezelter 916 if (isDirectional) {
244     MPI_Recv(atomData13, 13, MPI_DOUBLE, which_node,
245     myPotato, MPI_COMM_WORLD, &istatus);
246     } else {
247     MPI_Recv(atomData6, 6, MPI_DOUBLE, which_node,
248     myPotato, MPI_COMM_WORLD, &istatus);
249 gezelter 907 }
250 gezelter 916
251     myPotato++;
252     potatoes[which_node] = myPotato;
253 gezelter 907
254     } else {
255    
256 mmeineke 440 haveError = 0;
257 chuckv 436 which_atom = i;
258 tim 837 local_index=-1;
259 gezelter 916
260 chuckv 436 for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
261     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
262     }
263 gezelter 916
264 chuckv 436 if (local_index != -1) {
265 gezelter 916
266 gezelter 907 atomTypeString = atoms[local_index]->getType();
267    
268 mmeineke 670 atoms[local_index]->getPos(pos);
269 gezelter 916 atoms[local_index]->getVel(vel);
270 mmeineke 670
271 gezelter 916 atomData6[0] = pos[0];
272     atomData6[1] = pos[1];
273     atomData6[2] = pos[2];
274 tim 837
275 gezelter 916 atomData6[3] = vel[0];
276     atomData6[4] = vel[1];
277     atomData6[5] = vel[2];
278 gezelter 907
279     isDirectional = 0;
280    
281 chuckv 436 if( atoms[local_index]->isDirectional() ){
282 tim 837
283 gezelter 907 isDirectional = 1;
284    
285 chuckv 436 dAtom = (DirectionalAtom *)atoms[local_index];
286     dAtom->getQ( q );
287 gezelter 916
288     for (int j = 0; j < 6 ; j++)
289     atomData13[j] = atomData6[j];
290 gezelter 907
291 gezelter 916 atomData13[6] = q[0];
292     atomData13[7] = q[1];
293     atomData13[8] = q[2];
294     atomData13[9] = q[3];
295    
296     atomData13[10] = dAtom->getJx();
297     atomData13[11] = dAtom->getJy();
298     atomData13[12] = dAtom->getJz();
299 gezelter 907 }
300 gezelter 916
301 gezelter 907 } else {
302 mmeineke 440 sprintf(painCave.errMsg,
303     "Atom %d not found on processor %d\n",
304     i, worldRank );
305     haveError= 1;
306     simError();
307 tim 837 }
308 gezelter 916
309 gezelter 907 if(haveError) DieDieDie();
310 gezelter 916
311 gezelter 907 // If we've survived to here, format the line:
312    
313 gezelter 916 if (!isDirectional) {
314 mmeineke 440
315 gezelter 916 sprintf( tempBuffer,
316     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
317     atomTypeString,
318     atomData6[0],
319     atomData6[1],
320     atomData6[2],
321     atomData6[3],
322     atomData6[4],
323     atomData6[5]);
324    
325     strcpy( writeLine, tempBuffer );
326     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
327 tim 837
328 gezelter 916 } else {
329    
330 gezelter 907 sprintf( tempBuffer,
331 gezelter 916 "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
332     atomTypeString,
333     atomData13[0],
334     atomData13[1],
335     atomData13[2],
336     atomData13[3],
337     atomData13[4],
338     atomData13[5],
339     atomData13[6],
340     atomData13[7],
341     atomData13[8],
342     atomData13[9],
343     atomData13[10],
344     atomData13[11],
345     atomData13[12]);
346    
347 gezelter 907 strcat( writeLine, tempBuffer );
348 gezelter 916
349 gezelter 907 }
350 gezelter 916
351 gezelter 907 outFile << writeLine;
352     outFile.flush();
353     }
354 mmeineke 377 }
355    
356 gezelter 907 outFile.flush();
357     sprintf( checkPointMsg,
358     "Sucessfully took a dump.\n");
359     MPIcheckPoint();
360    
361 gezelter 415 } else {
362 tim 837
363 gezelter 907 // worldRank != 0, so I'm a remote node.
364 gezelter 916
365     // Set my magic potato to 0:
366    
367     myPotato = 0;
368 gezelter 907
369     for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
370    
371     // Am I the node which has this atom?
372    
373     if (AtomToProcMap[i] == worldRank) {
374 tim 837
375 gezelter 916 if (myPotato + 3 >= MAXTAG) {
376    
377     // The potato was going to exceed the maximum value,
378     // so wrap this processor potato back to 0 (and block until
379     // node 0 says we can go:
380    
381     MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &istatus);
382    
383     }
384    
385 gezelter 907 local_index=-1;
386     for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
387     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
388     }
389     if (local_index != -1) {
390    
391     atomTypeString = atoms[local_index]->getType();
392 mmeineke 440
393 gezelter 907 atoms[local_index]->getPos(pos);
394     atoms[local_index]->getVel(vel);
395 tim 837
396 gezelter 916 atomData6[0] = pos[0];
397     atomData6[1] = pos[1];
398     atomData6[2] = pos[2];
399 mmeineke 440
400 gezelter 916 atomData6[3] = vel[0];
401     atomData6[4] = vel[1];
402     atomData6[5] = vel[2];
403 gezelter 907
404     isDirectional = 0;
405 tim 837
406 gezelter 907 if( atoms[local_index]->isDirectional() ){
407 mmeineke 670
408 gezelter 907 isDirectional = 1;
409    
410     dAtom = (DirectionalAtom *)atoms[local_index];
411     dAtom->getQ( q );
412    
413 gezelter 916 for (int j = 0; j < 6 ; j++)
414     atomData13[j] = atomData6[j];
415    
416     atomData13[6] = q[0];
417     atomData13[7] = q[1];
418     atomData13[8] = q[2];
419     atomData13[9] = q[3];
420 mmeineke 670
421 gezelter 916 atomData13[10] = dAtom->getJx();
422     atomData13[11] = dAtom->getJy();
423     atomData13[12] = dAtom->getJz();
424 gezelter 907 }
425 tim 837
426 gezelter 907 } else {
427     sprintf(painCave.errMsg,
428     "Atom %d not found on processor %d\n",
429     i, worldRank );
430     haveError= 1;
431     simError();
432     }
433 tim 837
434 gezelter 910 strncpy(MPIatomTypeString, atomTypeString, MINIBUFFERSIZE);
435    
436 gezelter 912 // null terminate the string before sending (just in case):
437     MPIatomTypeString[MINIBUFFERSIZE-1] = '\0';
438    
439 gezelter 910 MPI_Send(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, 0,
440 gezelter 916 myPotato, MPI_COMM_WORLD);
441 gezelter 907
442 gezelter 916 myPotato++;
443    
444 gezelter 907 MPI_Send(&isDirectional, 1, MPI_INT, 0,
445 gezelter 916 myPotato, MPI_COMM_WORLD);
446 gezelter 907
447 gezelter 916 myPotato++;
448    
449 gezelter 907 if (isDirectional) {
450    
451 gezelter 916 MPI_Send(atomData13, 13, MPI_DOUBLE, 0,
452     myPotato, MPI_COMM_WORLD);
453 gezelter 907
454 gezelter 916 } else {
455    
456     MPI_Send(atomData6, 6, MPI_DOUBLE, 0,
457     myPotato, MPI_COMM_WORLD);
458 gezelter 907 }
459 gezelter 916
460     myPotato++;
461 mmeineke 377 }
462 gezelter 907 }
463 mmeineke 440
464 gezelter 907 sprintf( checkPointMsg,
465     "Sucessfully took a dump.\n");
466     MPIcheckPoint();
467    
468 gezelter 916 }
469 gezelter 907
470 mmeineke 377 #endif // is_mpi
471     }
472    
473 mmeineke 572 void DumpWriter::writeFinal(double finalTime){
474 gezelter 416
475 mmeineke 377 char finalName[500];
476     ofstream finalOut;
477 gezelter 416
478     const int BUFFERSIZE = 2000;
479 gezelter 912 const int MINIBUFFERSIZE = 100;
480 gezelter 416 char tempBuffer[BUFFERSIZE];
481 tim 837 char writeLine[BUFFERSIZE];
482 gezelter 416
483     double q[4];
484     DirectionalAtom* dAtom;
485 mmeineke 787 Atom** atoms = entry_plug->atoms;
486     int i;
487     #ifdef IS_MPI
488 gezelter 916
489     int *potatoes;
490     int myPotato;
491    
492     int nProc;
493 mmeineke 787 int j, which_node, done, which_atom, local_index;
494 gezelter 916 double atomData6[6];
495     double atomData13[13];
496 gezelter 907 int isDirectional;
497     char* atomTypeString;
498 gezelter 910 char MPIatomTypeString[MINIBUFFERSIZE];
499 gezelter 916
500 mmeineke 787 #else //is_mpi
501 gezelter 416 int nAtoms = entry_plug->n_atoms;
502 mmeineke 787 #endif //is_mpi
503 tim 837
504 mmeineke 670 double pos[3], vel[3];
505 tim 837
506 mmeineke 377 #ifdef IS_MPI
507     if(worldRank == 0 ){
508     #endif // is_mpi
509 tim 837
510 mmeineke 377 strcpy( finalName, entry_plug->finalName );
511 tim 837
512 mmeineke 377 finalOut.open( finalName, ios::out | ios::trunc );
513     if( !finalOut ){
514     sprintf( painCave.errMsg,
515     "Could not open \"%s\" for final dump output.\n",
516     finalName );
517     painCave.isFatal = 1;
518     simError();
519     }
520 tim 837
521 mmeineke 377 // finalOut.setf( ios::scientific );
522 tim 837
523 mmeineke 377 #ifdef IS_MPI
524     }
525 tim 837
526 mmeineke 377 sprintf(checkPointMsg,"Opened file for final configuration\n");
527 tim 837 MPIcheckPoint();
528    
529 mmeineke 377 #endif //is_mpi
530    
531 tim 837
532 mmeineke 377 #ifndef IS_MPI
533 tim 837
534 mmeineke 377 finalOut << nAtoms << "\n";
535 tim 837
536 gezelter 591 finalOut << finalTime << ";\t"
537 mmeineke 590 << entry_plug->Hmat[0][0] << "\t"
538     << entry_plug->Hmat[1][0] << "\t"
539 gezelter 591 << entry_plug->Hmat[2][0] << ";\t"
540 tim 837
541 mmeineke 590 << entry_plug->Hmat[0][1] << "\t"
542     << entry_plug->Hmat[1][1] << "\t"
543 gezelter 591 << entry_plug->Hmat[2][1] << ";\t"
544 tim 837
545 mmeineke 590 << entry_plug->Hmat[0][2] << "\t"
546     << entry_plug->Hmat[1][2] << "\t"
547 tim 837 << entry_plug->Hmat[2][2] << ";";
548    
549     //write out additional parameters, such as chi and eta
550     finalOut << entry_plug->the_integrator->getAdditionalParameters();
551     finalOut << endl;
552    
553 mmeineke 377 for( i=0; i<nAtoms; i++ ){
554 tim 837
555 mmeineke 670 atoms[i]->getPos(pos);
556     atoms[i]->getVel(vel);
557 tim 837
558 mmeineke 377 sprintf( tempBuffer,
559     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
560     atoms[i]->getType(),
561 mmeineke 670 pos[0],
562     pos[1],
563     pos[2],
564     vel[0],
565     vel[1],
566     vel[2]);
567 mmeineke 377 strcpy( writeLine, tempBuffer );
568    
569     if( atoms[i]->isDirectional() ){
570 tim 837
571 mmeineke 377 dAtom = (DirectionalAtom *)atoms[i];
572     dAtom->getQ( q );
573 tim 837
574 mmeineke 377 sprintf( tempBuffer,
575     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
576     q[0],
577     q[1],
578     q[2],
579     q[3],
580     dAtom->getJx(),
581     dAtom->getJy(),
582     dAtom->getJz());
583     strcat( writeLine, tempBuffer );
584     }
585     else
586     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
587 tim 837
588 mmeineke 377 finalOut << writeLine;
589     }
590     finalOut.flush();
591 gezelter 415 finalOut.close();
592 mmeineke 377
593     #else // is_mpi
594 tim 837
595 gezelter 916 /* code to find maximum tag value */
596     int *tagub, flag, MAXTAG;
597     MPI_Attr_get(MPI_COMM_WORLD, MPI_TAG_UB, &tagub, &flag);
598     if (flag) {
599     MAXTAG = *tagub;
600     } else {
601     MAXTAG = 32767;
602     }
603 mmeineke 440
604     int haveError;
605    
606 mmeineke 447 MPI_Status istatus;
607 gezelter 416 int *AtomToProcMap = mpiSim->getAtomToProcMap();
608    
609 mmeineke 377 // write out header and node 0's coordinates
610 tim 837
611 mmeineke 377 if( worldRank == 0 ){
612 gezelter 916
613     // Node 0 needs a list of the magic potatoes for each processor;
614    
615     nProc = mpiSim->getNumberProcessors();
616     potatoes = new int[nProc];
617    
618     for (i = 0; i < nProc; i++)
619     potatoes[i] = 0;
620    
621 mmeineke 377 finalOut << mpiSim->getTotAtoms() << "\n";
622 tim 837
623 gezelter 591 finalOut << finalTime << ";\t"
624 gezelter 907 << entry_plug->Hmat[0][0] << "\t"
625     << entry_plug->Hmat[1][0] << "\t"
626     << entry_plug->Hmat[2][0] << ";\t"
627 tim 837
628 gezelter 907 << entry_plug->Hmat[0][1] << "\t"
629     << entry_plug->Hmat[1][1] << "\t"
630     << entry_plug->Hmat[2][1] << ";\t"
631 tim 837
632 gezelter 907 << entry_plug->Hmat[0][2] << "\t"
633     << entry_plug->Hmat[1][2] << "\t"
634     << entry_plug->Hmat[2][2] << ";";
635 tim 837
636     finalOut << entry_plug->the_integrator->getAdditionalParameters();
637     finalOut << endl;
638 gezelter 907 finalOut.flush();
639 gezelter 916
640 gezelter 416 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
641 gezelter 916
642 gezelter 907 // Get the Node number which has this atom;
643 gezelter 916
644 tim 837 which_node = AtomToProcMap[i];
645 gezelter 916
646     if (which_node != 0) {
647 tim 837
648 gezelter 916 if (potatoes[which_node] + 3 >= MAXTAG) {
649     // The potato was going to exceed the maximum value,
650     // so wrap this processor potato back to 0:
651    
652     potatoes[which_node] = 0;
653     MPI_Send(0, 1, MPI_INT, which_node, 0, MPI_COMM_WORLD);
654    
655     }
656    
657     myPotato = potatoes[which_node];
658 gezelter 907
659 gezelter 910 MPI_Recv(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, which_node,
660 gezelter 916 myPotato, MPI_COMM_WORLD, &istatus);
661 gezelter 907
662 gezelter 910 strncpy(atomTypeString, MPIatomTypeString, MINIBUFFERSIZE);
663 gezelter 907
664 gezelter 916 // Null terminate the atomTypeString just in case:
665 gezelter 907
666 gezelter 916 atomTypeString[strlen(atomTypeString) - 1] = '\0';
667 gezelter 907
668 gezelter 916 myPotato++;
669 gezelter 907
670 gezelter 916 MPI_Recv(&isDirectional, 1, MPI_INT, which_node,
671     myPotato, MPI_COMM_WORLD, &istatus);
672    
673     myPotato++;
674    
675     if (isDirectional) {
676     MPI_Recv(atomData13, 13, MPI_DOUBLE, which_node,
677     myPotato, MPI_COMM_WORLD, &istatus);
678     } else {
679     MPI_Recv(atomData6, 6, MPI_DOUBLE, which_node,
680     myPotato, MPI_COMM_WORLD, &istatus);
681 gezelter 907 }
682 gezelter 916
683     myPotato++;
684     potatoes[which_node] = myPotato;
685 gezelter 907
686     } else {
687    
688     haveError = 0;
689 chuckv 437 which_atom = i;
690 tim 837 local_index=-1;
691 gezelter 916
692 chuckv 437 for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
693     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
694     }
695 gezelter 916
696 tim 837 if (local_index != -1) {
697 gezelter 916
698 gezelter 907 atomTypeString = atoms[local_index]->getType();
699    
700 mmeineke 670 atoms[local_index]->getPos(pos);
701 gezelter 916 atoms[local_index]->getVel(vel);
702 tim 837
703 gezelter 916 atomData6[0] = pos[0];
704     atomData6[1] = pos[1];
705     atomData6[2] = pos[2];
706 tim 837
707 gezelter 916 atomData6[3] = vel[0];
708     atomData6[4] = vel[1];
709     atomData6[5] = vel[2];
710 gezelter 907
711     isDirectional = 0;
712 tim 837
713 gezelter 907 if( atoms[local_index]->isDirectional() ){
714 tim 837
715 gezelter 907 isDirectional = 1;
716    
717     dAtom = (DirectionalAtom *)atoms[local_index];
718     dAtom->getQ( q );
719 gezelter 916
720     for (int j = 0; j < 6 ; j++)
721     atomData13[j] = atomData6[j];
722 gezelter 907
723 gezelter 916 atomData13[6] = q[0];
724     atomData13[7] = q[1];
725     atomData13[8] = q[2];
726     atomData13[9] = q[3];
727    
728     atomData13[10] = dAtom->getJx();
729     atomData13[11] = dAtom->getJy();
730     atomData13[12] = dAtom->getJz();
731 gezelter 907 }
732 gezelter 916
733 gezelter 907 } else {
734 mmeineke 440 sprintf(painCave.errMsg,
735     "Atom %d not found on processor %d\n",
736     i, worldRank );
737     haveError= 1;
738     simError();
739 tim 837 }
740 gezelter 916
741 gezelter 907 if(haveError) DieDieDie();
742 gezelter 916
743 gezelter 907 // If we've survived to here, format the line:
744    
745 gezelter 916 if (!isDirectional) {
746 tim 837
747 gezelter 916 sprintf( tempBuffer,
748     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
749     atomTypeString,
750     atomData6[0],
751     atomData6[1],
752     atomData6[2],
753     atomData6[3],
754     atomData6[4],
755     atomData6[5]);
756    
757     strcpy( writeLine, tempBuffer );
758     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
759 tim 837
760 gezelter 916 } else {
761    
762 gezelter 907 sprintf( tempBuffer,
763 gezelter 916 "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
764     atomTypeString,
765     atomData13[0],
766     atomData13[1],
767     atomData13[2],
768     atomData13[3],
769     atomData13[4],
770     atomData13[5],
771     atomData13[6],
772     atomData13[7],
773     atomData13[8],
774     atomData13[9],
775     atomData13[10],
776     atomData13[11],
777     atomData13[12]);
778    
779 gezelter 907 strcat( writeLine, tempBuffer );
780 gezelter 916
781 gezelter 907 }
782 gezelter 916
783 gezelter 907 finalOut << writeLine;
784     finalOut.flush();
785     }
786 mmeineke 377 }
787    
788 gezelter 907 finalOut.flush();
789     sprintf( checkPointMsg,
790     "Sucessfully took a dump.\n");
791     MPIcheckPoint();
792    
793 gezelter 415 } else {
794 tim 837
795 gezelter 907 // worldRank != 0, so I'm a remote node.
796 gezelter 916
797     // Set my magic potato to 0:
798    
799     myPotato = 0;
800 gezelter 907
801     for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
802    
803     // Am I the node which has this atom?
804    
805     if (AtomToProcMap[i] == worldRank) {
806 mmeineke 440
807 gezelter 916 if (myPotato + 3 >= MAXTAG) {
808    
809     // The potato was going to exceed the maximum value,
810     // so wrap this processor potato back to 0 (and block until
811     // node 0 says we can go:
812    
813     MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &istatus);
814    
815     }
816    
817 gezelter 907 local_index=-1;
818     for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
819     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
820     }
821     if (local_index != -1) {
822    
823     atomTypeString = atoms[local_index]->getType();
824 tim 837
825 gezelter 907 atoms[local_index]->getPos(pos);
826     atoms[local_index]->getVel(vel);
827 tim 837
828 gezelter 916 atomData6[0] = pos[0];
829     atomData6[1] = pos[1];
830     atomData6[2] = pos[2];
831 tim 837
832 gezelter 916 atomData6[3] = vel[0];
833     atomData6[4] = vel[1];
834     atomData6[5] = vel[2];
835 gezelter 907
836     isDirectional = 0;
837 tim 837
838 gezelter 907 if( atoms[local_index]->isDirectional() ){
839 mmeineke 377
840 gezelter 907 isDirectional = 1;
841    
842     dAtom = (DirectionalAtom *)atoms[local_index];
843     dAtom->getQ( q );
844    
845 gezelter 916 for (int j = 0; j < 6 ; j++)
846     atomData13[j] = atomData6[j];
847    
848     atomData13[6] = q[0];
849     atomData13[7] = q[1];
850     atomData13[8] = q[2];
851     atomData13[9] = q[3];
852 mmeineke 670
853 gezelter 916 atomData13[10] = dAtom->getJx();
854     atomData13[11] = dAtom->getJy();
855     atomData13[12] = dAtom->getJz();
856 gezelter 907 }
857 tim 837
858 gezelter 907 } else {
859     sprintf(painCave.errMsg,
860     "Atom %d not found on processor %d\n",
861     i, worldRank );
862     haveError= 1;
863     simError();
864     }
865 tim 837
866 gezelter 916 strncpy(MPIatomTypeString, atomTypeString, MINIBUFFERSIZE);
867 tim 837
868 gezelter 916 // null terminate the string before sending (just in case):
869     MPIatomTypeString[MINIBUFFERSIZE-1] = '\0';
870 tim 837
871 gezelter 910 MPI_Send(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, 0,
872 gezelter 916 myPotato, MPI_COMM_WORLD);
873 gezelter 907
874 gezelter 916 myPotato++;
875    
876 gezelter 907 MPI_Send(&isDirectional, 1, MPI_INT, 0,
877 gezelter 916 myPotato, MPI_COMM_WORLD);
878 gezelter 907
879 gezelter 916 myPotato++;
880    
881 gezelter 907 if (isDirectional) {
882    
883 gezelter 916 MPI_Send(atomData13, 13, MPI_DOUBLE, 0,
884     myPotato, MPI_COMM_WORLD);
885 gezelter 907
886 gezelter 916 } else {
887    
888     MPI_Send(atomData6, 6, MPI_DOUBLE, 0,
889     myPotato, MPI_COMM_WORLD);
890 gezelter 907 }
891 gezelter 916
892     myPotato++;
893 mmeineke 377 }
894 gezelter 907 }
895 mmeineke 440
896 gezelter 907 sprintf( checkPointMsg,
897 gezelter 916 "Sucessfully took a dump.\n");
898 gezelter 907 MPIcheckPoint();
899    
900 gezelter 916 }
901 gezelter 907
902 tim 837 if( worldRank == 0 ) finalOut.close();
903 mmeineke 377 #endif // is_mpi
904     }
905 mmeineke 440
906    
907    
908     #ifdef IS_MPI
909    
910     // a couple of functions to let us escape the write loop
911    
912 gezelter 907 void dWrite::DieDieDie( void ){
913 tim 837
914 mmeineke 440 MPI_Finalize();
915     exit (0);
916     }
917    
918     #endif //is_mpi