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

# Content
1 #include <cstring>
2 #include <iostream>
3 #include <fstream>
4
5 #ifdef IS_MPI
6 #include <mpi.h>
7 #include <mpi++.h>
8 #include "mpiSimulation.hpp"
9 #define TAKE_THIS_TAG_CHAR 1
10 #define TAKE_THIS_TAG_INT 2
11
12 namespace dWrite{
13 void nodeZeroError( void );
14 void anonymousNodeDie( void );
15 }
16
17 using namespace dWrite;
18 #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 int i, j, which_node, done, game_over, which_atom, local_index;
77 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
131 // 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 MPI::Status istatus;
138 int *AtomToProcMap = mpiSim->getAtomToProcMap();
139
140 // write out header and node 0's coordinates
141
142 if( worldRank == 0 ){
143 outFile << mpiSim->getTotAtoms() << "\n";
144
145 outFile << currentTime << "\t"
146 << entry_plug->box_x << "\t"
147 << entry_plug->box_y << "\t"
148 << entry_plug->box_z << "\n";
149 outFile.flush();
150 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
151 // Get the Node number which has this atom;
152
153 which_node = AtomToProcMap[i];
154
155 if (which_node == 0 ) {
156
157 haveError = 0;
158 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
176 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 sprintf(painCave.errMsg,
198 "Atom %d not found on processor %d\n",
199 i, worldRank );
200 haveError= 1;
201 simError();
202 }
203
204 if(haveError) nodeZeroError();
205
206 }
207 else {
208 myStatus = 1;
209 MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node,
210 TAKE_THIS_TAG_INT);
211 MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT);
212 MPI::COMM_WORLD.Recv(writeLine, BUFFERSIZE, MPI_CHAR, which_node,
213 TAKE_THIS_TAG_CHAR, istatus);
214 MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, which_node,
215 TAKE_THIS_TAG_INT, istatus);
216
217 if(!myStatus) nodeZeroError();
218
219 }
220
221 outFile << writeLine;
222 outFile.flush();
223 }
224
225 // kill everyone off:
226 myStatus = -1;
227 for (j = 0; j < mpiSim->getNumberProcessors(); j++) {
228 MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, j,
229 TAKE_THIS_TAG_INT);
230 }
231
232 } else {
233
234 done = 0;
235 while (!done) {
236
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 MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0,
245 TAKE_THIS_TAG_INT, istatus);
246
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
267 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 }
294
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 }
300 }
301 outFile.flush();
302 sprintf( checkPointMsg,
303 "Sucessfully took a dump.\n");
304 MPIcheckPoint();
305
306 // last thing last, enable fatalities.
307 painCave.isEventLoop = 0;
308
309 #endif // is_mpi
310 }
311
312 void DumpWriter::writeFinal(){
313
314 char finalName[500];
315 ofstream finalOut;
316
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 int i, j, which_node, done, game_over, which_atom, local_index;
326
327
328 #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
354 #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
362 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 finalOut.close();
398
399 #else // is_mpi
400
401 // 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 MPI::Status istatus;
408 int *AtomToProcMap = mpiSim->getAtomToProcMap();
409
410 // write out header and node 0's coordinates
411
412 haveError = 0;
413 if( worldRank == 0 ){
414 finalOut << mpiSim->getTotAtoms() << "\n";
415
416 finalOut << entry_plug->box_x << "\t"
417 << entry_plug->box_y << "\t"
418 << entry_plug->box_z << "\n";
419
420 for (i = 0 ; i < mpiSim->getTotAtoms(); i++ ) {
421 // Get the Node number which has this molecule:
422
423 which_node = AtomToProcMap[i];
424
425 if (which_node == mpiSim->getMyNode()) {
426
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
444 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 sprintf(painCave.errMsg,
465 "Atom %d not found on processor %d\n",
466 i, worldRank );
467 haveError= 1;
468 simError();
469 }
470
471 if(haveError) nodeZeroError();
472
473 }
474 else {
475
476 myStatus = 1;
477 MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node,
478 TAKE_THIS_TAG_INT);
479 MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT);
480 MPI::COMM_WORLD.Recv(writeLine, BUFFERSIZE, MPI_CHAR, which_node,
481 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 }
487
488 finalOut << writeLine;
489 }
490
491 // kill everyone off:
492 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 }
497
498 } else {
499
500 done = 0;
501 while (!done) {
502
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 MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0,
511 TAKE_THIS_TAG_INT, istatus);
512
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
520 //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
534 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 }
561
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 }
567 }
568 finalOut.flush();
569 sprintf( checkPointMsg,
570 "Sucessfully took a dump.\n");
571 MPIcheckPoint();
572
573 if( worldRank == 0 ) finalOut.close();
574 #endif // is_mpi
575 }
576
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