ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/DumpWriter.cpp
Revision: 440
Committed: Tue Apr 1 16:49:17 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 14296 byte(s)
Log Message:
Fixed DumpWriter to be more robust to errors. also added a little namespace to InitFromFile to wrap it's helper functions in MPI

File Contents

# User Rev Content
1 mmeineke 377 #include <cstring>
2     #include <iostream>
3     #include <fstream>
4    
5     #ifdef IS_MPI
6     #include <mpi.h>
7 gezelter 416 #include <mpi++.h>
8 mmeineke 377 #include "mpiSimulation.hpp"
9 chuckv 436 #define TAKE_THIS_TAG_CHAR 1
10     #define TAKE_THIS_TAG_INT 2
11 mmeineke 440
12     namespace dWrite{
13     void nodeZeroError( void );
14     void anonymousNodeDie( void );
15     }
16    
17     using namespace dWrite;
18 mmeineke 377 #endif //is_mpi
19    
20     #include "ReadWrite.hpp"
21     #include "simError.h"
22    
23     DumpWriter::DumpWriter( SimInfo* the_entry_plug ){
24    
25     entry_plug = the_entry_plug;
26    
27     #ifdef IS_MPI
28     if(worldRank == 0 ){
29     #endif // is_mpi
30    
31    
32    
33     strcpy( outName, entry_plug->sampleName );
34    
35     outFile.open(outName, ios::out | ios::trunc );
36    
37     if( !outFile ){
38    
39     sprintf( painCave.errMsg,
40     "Could not open \"%s\" for dump output.\n",
41     outName);
42     painCave.isFatal = 1;
43     simError();
44     }
45    
46     //outFile.setf( ios::scientific );
47    
48     #ifdef IS_MPI
49     }
50    
51     sprintf( checkPointMsg,
52     "Sucessfully opened output file for dumping.\n");
53     MPIcheckPoint();
54     #endif // is_mpi
55     }
56    
57     DumpWriter::~DumpWriter( ){
58    
59     #ifdef IS_MPI
60     if(worldRank == 0 ){
61     #endif // is_mpi
62    
63     outFile.close();
64    
65     #ifdef IS_MPI
66     }
67     #endif // is_mpi
68     }
69    
70     void DumpWriter::writeDump( double currentTime ){
71    
72     const int BUFFERSIZE = 2000;
73     char tempBuffer[BUFFERSIZE];
74     char writeLine[BUFFERSIZE];
75    
76 gezelter 419 int i, j, which_node, done, game_over, which_atom, local_index;
77 mmeineke 377 double q[4];
78     DirectionalAtom* dAtom;
79     int nAtoms = entry_plug->n_atoms;
80     Atom** atoms = entry_plug->atoms;
81    
82    
83     #ifndef IS_MPI
84    
85     outFile << nAtoms << "\n";
86    
87     outFile << currentTime << "\t"
88     << entry_plug->box_x << "\t"
89     << entry_plug->box_y << "\t"
90     << entry_plug->box_z << "\n";
91    
92     for( i=0; i<nAtoms; i++ ){
93    
94    
95     sprintf( tempBuffer,
96     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
97     atoms[i]->getType(),
98     atoms[i]->getX(),
99     atoms[i]->getY(),
100     atoms[i]->getZ(),
101     atoms[i]->get_vx(),
102     atoms[i]->get_vy(),
103     atoms[i]->get_vz());
104     strcpy( writeLine, tempBuffer );
105    
106     if( atoms[i]->isDirectional() ){
107    
108     dAtom = (DirectionalAtom *)atoms[i];
109     dAtom->getQ( q );
110    
111     sprintf( tempBuffer,
112     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
113     q[0],
114     q[1],
115     q[2],
116     q[3],
117     dAtom->getJx(),
118     dAtom->getJy(),
119     dAtom->getJz());
120     strcat( writeLine, tempBuffer );
121     }
122     else
123     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
124    
125     outFile << writeLine;
126     }
127     outFile.flush();
128    
129     #else // is_mpi
130 gezelter 416
131 mmeineke 440 // first thing first, suspend fatalities.
132     painCave.isEventLoop = 1;
133    
134     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
135     int haveError;
136    
137 gezelter 416 MPI::Status istatus;
138     int *AtomToProcMap = mpiSim->getAtomToProcMap();
139 gezelter 415
140 mmeineke 377 // write out header and node 0's coordinates
141 gezelter 415
142 mmeineke 377 if( worldRank == 0 ){
143     outFile << mpiSim->getTotAtoms() << "\n";
144 gezelter 415
145 mmeineke 377 outFile << currentTime << "\t"
146     << entry_plug->box_x << "\t"
147     << entry_plug->box_y << "\t"
148     << entry_plug->box_z << "\n";
149 chuckv 434 outFile.flush();
150 gezelter 416 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
151 gezelter 417 // Get the Node number which has this atom;
152 mmeineke 377
153 gezelter 415 which_node = AtomToProcMap[i];
154    
155 chuckv 436 if (which_node == 0 ) {
156 mmeineke 377
157 mmeineke 440 haveError = 0;
158 chuckv 436 which_atom = i;
159     local_index=-1;
160     for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
161     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
162     }
163     if (local_index != -1) {
164     //format the line
165     sprintf( tempBuffer,
166     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
167     atoms[local_index]->getType(),
168     atoms[local_index]->getX(),
169     atoms[local_index]->getY(),
170     atoms[local_index]->getZ(),
171     atoms[local_index]->get_vx(),
172     atoms[local_index]->get_vy(),
173     atoms[local_index]->get_vz()); // check here.
174     strcpy( writeLine, tempBuffer );
175 mmeineke 377
176 chuckv 436 if( atoms[local_index]->isDirectional() ){
177    
178     dAtom = (DirectionalAtom *)atoms[local_index];
179     dAtom->getQ( q );
180    
181     sprintf( tempBuffer,
182     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
183     q[0],
184     q[1],
185     q[2],
186     q[3],
187     dAtom->getJx(),
188     dAtom->getJy(),
189     dAtom->getJz());
190     strcat( writeLine, tempBuffer );
191    
192     }
193     else
194     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
195     }
196     else {
197 mmeineke 440 sprintf(painCave.errMsg,
198     "Atom %d not found on processor %d\n",
199     i, worldRank );
200     haveError= 1;
201     simError();
202 chuckv 436 }
203 mmeineke 440
204     if(haveError) nodeZeroError();
205    
206     }
207 chuckv 436 else {
208 mmeineke 440 myStatus = 1;
209     MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node,
210     TAKE_THIS_TAG_INT);
211 chuckv 436 MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT);
212 gezelter 416 MPI::COMM_WORLD.Recv(writeLine, BUFFERSIZE, MPI_CHAR, which_node,
213 chuckv 436 TAKE_THIS_TAG_CHAR, istatus);
214 mmeineke 440 MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, which_node,
215     TAKE_THIS_TAG_INT, istatus);
216    
217     if(!myStatus) nodeZeroError();
218    
219 mmeineke 377 }
220 gezelter 415
221 mmeineke 377 outFile << writeLine;
222 chuckv 434 outFile.flush();
223 mmeineke 377 }
224    
225 gezelter 415 // kill everyone off:
226 mmeineke 440 myStatus = -1;
227 gezelter 416 for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
228 mmeineke 440 MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, j,
229     TAKE_THIS_TAG_INT);
230 mmeineke 377 }
231    
232 gezelter 415 } else {
233    
234     done = 0;
235     while (!done) {
236 mmeineke 440
237     MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, 0,
238     TAKE_THIS_TAG_INT, istatus);
239    
240     if(!myStatus) anonymousNodeDie();
241    
242     if(myStatus < 0) break;
243    
244 gezelter 416 MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0,
245 chuckv 436 TAKE_THIS_TAG_INT, istatus);
246 mmeineke 440
247     myStatus = 1;
248     local_index=-1;
249     for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
250     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
251     }
252     if (local_index != -1) {
253     //format the line
254     sprintf( tempBuffer,
255     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
256     atoms[local_index]->getType(),
257     atoms[local_index]->getX(),
258     atoms[local_index]->getY(),
259     atoms[local_index]->getZ(),
260     atoms[local_index]->get_vx(),
261     atoms[local_index]->get_vy(),
262     atoms[local_index]->get_vz()); // check here.
263     strcpy( writeLine, tempBuffer );
264    
265     if( atoms[local_index]->isDirectional() ){
266 mmeineke 377
267 mmeineke 440 dAtom = (DirectionalAtom *)atoms[local_index];
268     dAtom->getQ( q );
269    
270     sprintf( tempBuffer,
271     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
272     q[0],
273     q[1],
274     q[2],
275     q[3],
276     dAtom->getJx(),
277     dAtom->getJy(),
278     dAtom->getJz());
279     strcat( writeLine, tempBuffer );
280     }
281     else{
282     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
283     }
284     }
285     else {
286     sprintf(painCave.errMsg,
287     "Atom %d not found on processor %d\n",
288     which_atom, worldRank );
289     myStatus = 0;
290     simError();
291    
292     strcpy( writeLine, "Hello, I'm an error.\n");
293 mmeineke 377 }
294 mmeineke 440
295     MPI::COMM_WORLD.Send(writeLine, BUFFERSIZE, MPI_CHAR, 0,
296     TAKE_THIS_TAG_CHAR);
297     MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0,
298     TAKE_THIS_TAG_INT);
299 mmeineke 377 }
300 gezelter 415 }
301     outFile.flush();
302     sprintf( checkPointMsg,
303     "Sucessfully took a dump.\n");
304     MPIcheckPoint();
305 mmeineke 440
306     // last thing last, enable fatalities.
307     painCave.isEventLoop = 0;
308    
309 mmeineke 377 #endif // is_mpi
310     }
311    
312     void DumpWriter::writeFinal(){
313 gezelter 416
314 mmeineke 377 char finalName[500];
315     ofstream finalOut;
316 gezelter 416
317     const int BUFFERSIZE = 2000;
318     char tempBuffer[BUFFERSIZE];
319     char writeLine[BUFFERSIZE];
320    
321     double q[4];
322     DirectionalAtom* dAtom;
323     int nAtoms = entry_plug->n_atoms;
324     Atom** atoms = entry_plug->atoms;
325 gezelter 419 int i, j, which_node, done, game_over, which_atom, local_index;
326 mmeineke 377
327 gezelter 416
328 mmeineke 377 #ifdef IS_MPI
329     if(worldRank == 0 ){
330     #endif // is_mpi
331    
332     strcpy( finalName, entry_plug->finalName );
333    
334     finalOut.open( finalName, ios::out | ios::trunc );
335     if( !finalOut ){
336     sprintf( painCave.errMsg,
337     "Could not open \"%s\" for final dump output.\n",
338     finalName );
339     painCave.isFatal = 1;
340     simError();
341     }
342    
343     // finalOut.setf( ios::scientific );
344    
345     #ifdef IS_MPI
346     }
347    
348     sprintf(checkPointMsg,"Opened file for final configuration\n");
349     MPIcheckPoint();
350    
351     #endif //is_mpi
352    
353 gezelter 415
354 mmeineke 377 #ifndef IS_MPI
355    
356     finalOut << nAtoms << "\n";
357    
358     finalOut << entry_plug->box_x << "\t"
359     << entry_plug->box_y << "\t"
360     << entry_plug->box_z << "\n";
361 gezelter 416
362 mmeineke 377 for( i=0; i<nAtoms; i++ ){
363    
364     sprintf( tempBuffer,
365     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
366     atoms[i]->getType(),
367     atoms[i]->getX(),
368     atoms[i]->getY(),
369     atoms[i]->getZ(),
370     atoms[i]->get_vx(),
371     atoms[i]->get_vy(),
372     atoms[i]->get_vz());
373     strcpy( writeLine, tempBuffer );
374    
375     if( atoms[i]->isDirectional() ){
376    
377     dAtom = (DirectionalAtom *)atoms[i];
378     dAtom->getQ( q );
379    
380     sprintf( tempBuffer,
381     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
382     q[0],
383     q[1],
384     q[2],
385     q[3],
386     dAtom->getJx(),
387     dAtom->getJy(),
388     dAtom->getJz());
389     strcat( writeLine, tempBuffer );
390     }
391     else
392     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
393    
394     finalOut << writeLine;
395     }
396     finalOut.flush();
397 gezelter 415 finalOut.close();
398 mmeineke 377
399     #else // is_mpi
400 gezelter 415
401 mmeineke 440 // first thing first, suspend fatalities.
402     painCave.isEventLoop = 1;
403    
404     int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone
405     int haveError;
406    
407 gezelter 416 MPI::Status istatus;
408     int *AtomToProcMap = mpiSim->getAtomToProcMap();
409    
410 mmeineke 377 // write out header and node 0's coordinates
411 gezelter 415
412 mmeineke 440 haveError = 0;
413 mmeineke 377 if( worldRank == 0 ){
414     finalOut << mpiSim->getTotAtoms() << "\n";
415 gezelter 415
416 mmeineke 377 finalOut << entry_plug->box_x << "\t"
417 gezelter 415 << entry_plug->box_y << "\t"
418     << entry_plug->box_z << "\n";
419 mmeineke 377
420 gezelter 416 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
421 gezelter 415 // Get the Node number which has this molecule:
422 mmeineke 377
423 gezelter 415 which_node = AtomToProcMap[i];
424    
425 gezelter 416 if (which_node == mpiSim->getMyNode()) {
426 chuckv 437
427     which_atom = i;
428     local_index=-1;
429     for (j=0; (j<mpiSim->getMyNlocal()) && (local_index < 0); j++) {
430     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
431     }
432     if (local_index != -1) {
433     sprintf( tempBuffer,
434     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
435     atoms[local_index]->getType(),
436     atoms[local_index]->getX(),
437     atoms[local_index]->getY(),
438     atoms[local_index]->getZ(),
439     atoms[local_index]->get_vx(),
440     atoms[local_index]->get_vy(),
441     atoms[local_index]->get_vz());
442     strcpy( writeLine, tempBuffer );
443 mmeineke 377
444 chuckv 437 if( atoms[local_index]->isDirectional() ){
445    
446     dAtom = (DirectionalAtom *)atoms[local_index];
447     dAtom->getQ( q );
448    
449     sprintf( tempBuffer,
450     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
451     q[0],
452     q[1],
453     q[2],
454     q[3],
455     dAtom->getJx(),
456     dAtom->getJy(),
457     dAtom->getJz());
458     strcat( writeLine, tempBuffer );
459     }
460     else
461     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
462     }
463     else {
464 mmeineke 440 sprintf(painCave.errMsg,
465     "Atom %d not found on processor %d\n",
466     i, worldRank );
467     haveError= 1;
468     simError();
469 chuckv 437 }
470 mmeineke 440
471     if(haveError) nodeZeroError();
472 chuckv 437
473 mmeineke 440 }
474     else {
475 gezelter 415
476 mmeineke 440 myStatus = 1;
477     MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node,
478     TAKE_THIS_TAG_INT);
479 chuckv 436 MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT);
480 gezelter 416 MPI::COMM_WORLD.Recv(writeLine, BUFFERSIZE, MPI_CHAR, which_node,
481 mmeineke 440 TAKE_THIS_TAG_CHAR, istatus);
482     MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, which_node,
483     TAKE_THIS_TAG_INT, istatus);
484    
485     if(!myStatus) nodeZeroError();
486 mmeineke 377 }
487 gezelter 415
488 mmeineke 377 finalOut << writeLine;
489     }
490    
491 gezelter 415 // kill everyone off:
492 mmeineke 440 myStatus = -1;
493     for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
494     MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, j,
495     TAKE_THIS_TAG_INT);
496 mmeineke 377 }
497    
498 gezelter 415 } else {
499    
500     done = 0;
501     while (!done) {
502 mmeineke 440
503     MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, 0,
504     TAKE_THIS_TAG_INT, istatus);
505    
506     if(!myStatus) anonymousNodeDie();
507    
508     if(myStatus < 0) break;
509    
510 gezelter 416 MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0,
511 chuckv 436 TAKE_THIS_TAG_INT, istatus);
512 mmeineke 440
513     myStatus = 1;
514     local_index=-1;
515     for (j=0; j < mpiSim->getMyNlocal(); j++) {
516     if (atoms[j]->getGlobalIndex() == which_atom) local_index = j;
517     }
518     if (local_index != -1) {
519 mmeineke 377
520 mmeineke 440 //format the line
521     sprintf( tempBuffer,
522     "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
523     atoms[local_index]->getType(),
524     atoms[local_index]->getX(),
525     atoms[local_index]->getY(),
526     atoms[local_index]->getZ(),
527     atoms[local_index]->get_vx(),
528     atoms[local_index]->get_vy(),
529     atoms[local_index]->get_vz()); // check here.
530     strcpy( writeLine, tempBuffer );
531    
532     if( atoms[local_index]->isDirectional() ){
533 mmeineke 377
534 mmeineke 440 dAtom = (DirectionalAtom *)atoms[local_index];
535     dAtom->getQ( q );
536    
537     sprintf( tempBuffer,
538     "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",
539     q[0],
540     q[1],
541     q[2],
542     q[3],
543     dAtom->getJx(),
544     dAtom->getJy(),
545     dAtom->getJz());
546     strcat( writeLine, tempBuffer );
547     }
548     else{
549     strcat( writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n" );
550     }
551     }
552     else {
553     sprintf(painCave.errMsg,
554     "Atom %d not found on processor %d\n",
555     which_atom, worldRank );
556     myStatus = 0;
557     simError();
558    
559     strcpy( writeLine, "Hello, I'm an error.\n");
560 mmeineke 377 }
561 mmeineke 440
562     MPI::COMM_WORLD.Send(writeLine, BUFFERSIZE, MPI_CHAR, 0,
563     TAKE_THIS_TAG_CHAR);
564     MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0,
565     TAKE_THIS_TAG_INT);
566 mmeineke 377 }
567 gezelter 419 }
568 gezelter 415 finalOut.flush();
569     sprintf( checkPointMsg,
570     "Sucessfully took a dump.\n");
571     MPIcheckPoint();
572 mmeineke 440
573 gezelter 415 if( worldRank == 0 ) finalOut.close();
574 mmeineke 377 #endif // is_mpi
575     }
576 mmeineke 440
577    
578    
579     #ifdef IS_MPI
580    
581     // a couple of functions to let us escape the write loop
582    
583     void dWrite::nodeZeroError( void ){
584     int j, myStatus;
585    
586     myStatus = 0;
587     for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
588     MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j,
589     TAKE_THIS_TAG_INT);
590     }
591    
592    
593     MPI_Finalize();
594     exit (0);
595    
596     }
597    
598     void dWrite::anonymousNodeDie( void ){
599    
600     MPI_Finalize();
601     exit (0);
602     }
603    
604     #endif //is_mpi