ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/DumpWriter.cpp
Revision: 966
Committed: Fri May 19 21:26:41 2006 UTC (18 years, 11 months ago) by chrisfen
File size: 21374 byte(s)
Log Message:
Last bug showed up in 2 places, fixed the other one.

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Acknowledgement of the program authors must be made in any
10     * publication of scientific results based in part on use of the
11     * program. An acceptable form of acknowledgement is citation of
12     * the article in which the program was described (Matthew
13     * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     * Parallel Simulation Engine for Molecular Dynamics,"
16     * J. Comput. Chem. 26, pp. 252-271 (2005))
17     *
18     * 2. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 3. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in the
23     * documentation and/or other materials provided with the
24     * distribution.
25     *
26     * This software is provided "AS IS," without a warranty of any
27     * kind. All express or implied conditions, representations and
28     * warranties, including any implied warranty of merchantability,
29     * fitness for a particular purpose or non-infringement, are hereby
30     * excluded. The University of Notre Dame and its licensors shall not
31     * be liable for any damages suffered by licensee as a result of
32     * using, modifying or distributing the software or its
33     * derivatives. In no event will the University of Notre Dame or its
34     * licensors be liable for any lost revenue, profit or data, or for
35     * direct, indirect, special, consequential, incidental or punitive
36     * damages, however caused and regardless of the theory of liability,
37     * arising out of the use of or inability to use software, even if the
38     * University of Notre Dame has been advised of the possibility of
39     * such damages.
40     */
41    
42     #include "io/DumpWriter.hpp"
43     #include "primitives/Molecule.hpp"
44     #include "utils/simError.h"
45 tim 376 #include "io/basic_teebuf.hpp"
46 tim 615 #include "io/gzstream.hpp"
47     #include "io/Globals.hpp"
48    
49 gezelter 2 #ifdef IS_MPI
50     #include <mpi.h>
51 gezelter 246 #endif //is_mpi
52 gezelter 2
53 gezelter 246 namespace oopse {
54 gezelter 2
55 gezelter 507 DumpWriter::DumpWriter(SimInfo* info)
56     : info_(info), filename_(info->getDumpFileName()), eorFilename_(info->getFinalConfigFileName()){
57 tim 615
58     Globals* simParams = info->getSimParams();
59     needCompression_ = simParams->getCompressDumpFile();
60 chrisfen 726 needForceVector_ = simParams->getOutputForceVector();
61 chuckv 791 createDumpFile_ = true;
62 tim 619 #ifdef HAVE_LIBZ
63 tim 615 if (needCompression_) {
64     filename_ += ".gz";
65     eorFilename_ += ".gz";
66     }
67 tim 619 #endif
68 tim 615
69 tim 376 #ifdef IS_MPI
70    
71 gezelter 507 if (worldRank == 0) {
72 tim 376 #endif // is_mpi
73    
74 chuckv 791
75 tim 615 dumpFile_ = createOStream(filename_);
76    
77 tim 376 if (!dumpFile_) {
78 gezelter 507 sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
79     filename_.c_str());
80     painCave.isFatal = 1;
81     simError();
82 tim 376 }
83    
84     #ifdef IS_MPI
85    
86 gezelter 507 }
87 tim 376
88 gezelter 507 sprintf(checkPointMsg, "Sucessfully opened output file for dumping.\n");
89     MPIcheckPoint();
90 tim 376
91     #endif // is_mpi
92    
93 gezelter 507 }
94 tim 376
95    
96 gezelter 507 DumpWriter::DumpWriter(SimInfo* info, const std::string& filename)
97     : info_(info), filename_(filename){
98 tim 615
99     Globals* simParams = info->getSimParams();
100     eorFilename_ = filename_.substr(0, filename_.rfind(".")) + ".eor";
101    
102     needCompression_ = simParams->getCompressDumpFile();
103 chrisfen 726 needForceVector_ = simParams->getOutputForceVector();
104 chuckv 791 createDumpFile_ = true;
105 tim 619 #ifdef HAVE_LIBZ
106 tim 615 if (needCompression_) {
107     filename_ += ".gz";
108     eorFilename_ += ".gz";
109     }
110 tim 619 #endif
111 tim 615
112 gezelter 246 #ifdef IS_MPI
113 gezelter 2
114 gezelter 507 if (worldRank == 0) {
115 gezelter 246 #endif // is_mpi
116 gezelter 2
117 chuckv 791
118 tim 615 dumpFile_ = createOStream(filename_);
119    
120 gezelter 246 if (!dumpFile_) {
121 gezelter 507 sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
122     filename_.c_str());
123     painCave.isFatal = 1;
124     simError();
125 gezelter 246 }
126 gezelter 2
127     #ifdef IS_MPI
128    
129 gezelter 507 }
130 gezelter 2
131 gezelter 507 sprintf(checkPointMsg, "Sucessfully opened output file for dumping.\n");
132     MPIcheckPoint();
133 gezelter 2
134     #endif // is_mpi
135 gezelter 246
136 gezelter 507 }
137 chuckv 791
138     DumpWriter::DumpWriter(SimInfo* info, const std::string& filename, bool writeDumpFile)
139     : info_(info), filename_(filename){
140    
141     Globals* simParams = info->getSimParams();
142     eorFilename_ = filename_.substr(0, filename_.rfind(".")) + ".eor";
143    
144     needCompression_ = simParams->getCompressDumpFile();
145     needForceVector_ = simParams->getOutputForceVector();
146    
147     #ifdef HAVE_LIBZ
148     if (needCompression_) {
149     filename_ += ".gz";
150     eorFilename_ += ".gz";
151     }
152     #endif
153    
154     #ifdef IS_MPI
155    
156     if (worldRank == 0) {
157     #endif // is_mpi
158    
159     createDumpFile_ = writeDumpFile;
160     if (createDumpFile_) {
161     dumpFile_ = createOStream(filename_);
162    
163     if (!dumpFile_) {
164     sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
165     filename_.c_str());
166     painCave.isFatal = 1;
167     simError();
168     }
169     }
170     #ifdef IS_MPI
171    
172     }
173    
174     sprintf(checkPointMsg, "Sucessfully opened output file for dumping.\n");
175     MPIcheckPoint();
176    
177     #endif // is_mpi
178    
179     }
180    
181    
182    
183    
184    
185 gezelter 2
186 gezelter 507 DumpWriter::~DumpWriter() {
187 gezelter 2
188     #ifdef IS_MPI
189 gezelter 246
190     if (worldRank == 0) {
191 gezelter 2 #endif // is_mpi
192 chuckv 791 if (createDumpFile_){
193     delete dumpFile_;
194     }
195 gezelter 2 #ifdef IS_MPI
196 gezelter 246
197     }
198    
199 gezelter 2 #endif // is_mpi
200 gezelter 246
201 gezelter 507 }
202 gezelter 2
203 gezelter 507 void DumpWriter::writeCommentLine(std::ostream& os, Snapshot* s) {
204 gezelter 2
205 tim 963 RealType currentTime;
206 gezelter 246 Mat3x3d hmat;
207 tim 963 RealType chi;
208     RealType integralOfChiDt;
209 gezelter 246 Mat3x3d eta;
210    
211     currentTime = s->getTime();
212     hmat = s->getHmat();
213     chi = s->getChi();
214     integralOfChiDt = s->getIntegralOfChiDt();
215     eta = s->getEta();
216    
217     os << currentTime << ";\t"
218 gezelter 507 << hmat(0, 0) << "\t" << hmat(1, 0) << "\t" << hmat(2, 0) << ";\t"
219     << hmat(0, 1) << "\t" << hmat(1, 1) << "\t" << hmat(2, 1) << ";\t"
220     << hmat(0, 2) << "\t" << hmat(1, 2) << "\t" << hmat(2, 2) << ";\t";
221 gezelter 2
222 gezelter 246 //write out additional parameters, such as chi and eta
223    
224 chuckv 854 os << chi << "\t" << integralOfChiDt << ";\t";
225 gezelter 246
226     os << eta(0, 0) << "\t" << eta(1, 0) << "\t" << eta(2, 0) << ";\t"
227 gezelter 507 << eta(0, 1) << "\t" << eta(1, 1) << "\t" << eta(2, 1) << ";\t"
228     << eta(0, 2) << "\t" << eta(1, 2) << "\t" << eta(2, 2) << ";";
229 gezelter 246
230 tim 376 os << "\n";
231 gezelter 507 }
232 gezelter 2
233 gezelter 507 void DumpWriter::writeFrame(std::ostream& os) {
234 gezelter 246 const int BUFFERSIZE = 2000;
235     const int MINIBUFFERSIZE = 100;
236    
237     char tempBuffer[BUFFERSIZE];
238     char writeLine[BUFFERSIZE];
239    
240     Quat4d q;
241     Vector3d ji;
242     Vector3d pos;
243     Vector3d vel;
244 chrisfen 721 Vector3d frc;
245     Vector3d trq;
246 gezelter 246
247     Molecule* mol;
248     StuntDouble* integrableObject;
249     SimInfo::MoleculeIterator mi;
250     Molecule::IntegrableObjectIterator ii;
251 gezelter 2
252 gezelter 246 int nTotObjects;
253     nTotObjects = info_->getNGlobalIntegrableObjects();
254 gezelter 2
255 gezelter 246 #ifndef IS_MPI
256 gezelter 2
257    
258 gezelter 246 os << nTotObjects << "\n";
259    
260     writeCommentLine(os, info_->getSnapshotManager()->getCurrentSnapshot());
261 gezelter 2
262 gezelter 246 for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
263 gezelter 2
264 gezelter 507 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
265     integrableObject = mol->nextIntegrableObject(ii)) {
266 gezelter 246
267 gezelter 2
268 gezelter 507 pos = integrableObject->getPos();
269     vel = integrableObject->getVel();
270 gezelter 2
271 gezelter 507 sprintf(tempBuffer, "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
272     integrableObject->getType().c_str(),
273     pos[0], pos[1], pos[2],
274     vel[0], vel[1], vel[2]);
275 gezelter 2
276 gezelter 507 strcpy(writeLine, tempBuffer);
277 gezelter 2
278 gezelter 507 if (integrableObject->isDirectional()) {
279     q = integrableObject->getQ();
280     ji = integrableObject->getJ();
281 gezelter 2
282 chrisfen 721 sprintf(tempBuffer, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
283 gezelter 507 q[0], q[1], q[2], q[3],
284     ji[0], ji[1], ji[2]);
285     strcat(writeLine, tempBuffer);
286     } else {
287 chrisfen 721 strcat(writeLine, "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0");
288 gezelter 507 }
289 gezelter 2
290 chrisfen 721 if (needForceVector_) {
291     frc = integrableObject->getFrc();
292     trq = integrableObject->getTrq();
293    
294     sprintf(tempBuffer, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
295     frc[0], frc[1], frc[2],
296     trq[0], trq[1], trq[2]);
297     strcat(writeLine, tempBuffer);
298     }
299    
300     strcat(writeLine, "\n");
301 gezelter 507 os << writeLine;
302 gezelter 2
303 gezelter 507 }
304 gezelter 2 }
305    
306 tim 324 os.flush();
307 gezelter 246 #else // is_mpi
308     /*********************************************************************
309     * Documentation? You want DOCUMENTATION?
310     *
311     * Why all the potatoes below?
312     *
313     * To make a long story short, the original version of DumpWriter
314     * worked in the most inefficient way possible. Node 0 would
315     * poke each of the node for an individual atom's formatted data
316     * as node 0 worked its way down the global index. This was particularly
317     * inefficient since the method blocked all processors at every atom
318     * (and did it twice!).
319     *
320     * An intermediate version of DumpWriter could be described from Node
321     * zero's perspective as follows:
322     *
323     * 1) Have 100 of your friends stand in a circle.
324     * 2) When you say go, have all of them start tossing potatoes at
325     * you (one at a time).
326     * 3) Catch the potatoes.
327     *
328     * It was an improvement, but MPI has buffers and caches that could
329     * best be described in this analogy as "potato nets", so there's no
330     * need to block the processors atom-by-atom.
331     *
332     * This new and improved DumpWriter works in an even more efficient
333     * way:
334     *
335     * 1) Have 100 of your friend stand in a circle.
336     * 2) When you say go, have them start tossing 5-pound bags of
337     * potatoes at you.
338     * 3) Once you've caught a friend's bag of potatoes,
339     * toss them a spud to let them know they can toss another bag.
340     *
341     * How's THAT for documentation?
342     *
343     *********************************************************************/
344     const int masterNode = 0;
345 gezelter 2
346 gezelter 246 int * potatoes;
347     int myPotato;
348     int nProc;
349     int which_node;
350 tim 963 RealType atomData[19];
351 gezelter 246 int isDirectional;
352     char MPIatomTypeString[MINIBUFFERSIZE];
353     int msgLen; // the length of message actually recieved at master nodes
354     int haveError;
355     MPI_Status istatus;
356     int nCurObj;
357    
358     // code to find maximum tag value
359     int * tagub;
360     int flag;
361     int MAXTAG;
362     MPI_Attr_get(MPI_COMM_WORLD, MPI_TAG_UB, &tagub, &flag);
363 gezelter 2
364 gezelter 246 if (flag) {
365 gezelter 507 MAXTAG = *tagub;
366 gezelter 246 } else {
367 gezelter 507 MAXTAG = 32767;
368 gezelter 246 }
369 gezelter 2
370 gezelter 246 if (worldRank == masterNode) { //master node (node 0) is responsible for writing the dump file
371 gezelter 2
372 gezelter 507 // Node 0 needs a list of the magic potatoes for each processor;
373 gezelter 2
374 gezelter 507 MPI_Comm_size(MPI_COMM_WORLD, &nProc);
375     potatoes = new int[nProc];
376 gezelter 2
377 gezelter 507 //write out the comment lines
378     for(int i = 0; i < nProc; i++) {
379     potatoes[i] = 0;
380     }
381 gezelter 2
382    
383 gezelter 507 os << nTotObjects << "\n";
384     writeCommentLine(os, info_->getSnapshotManager()->getCurrentSnapshot());
385 gezelter 2
386 gezelter 507 for(int i = 0; i < info_->getNGlobalMolecules(); i++) {
387 gezelter 2
388 gezelter 507 // Get the Node number which has this atom;
389 gezelter 2
390 gezelter 507 which_node = info_->getMolToProc(i);
391 gezelter 2
392 gezelter 507 if (which_node != masterNode) { //current molecule is in slave node
393     if (potatoes[which_node] + 1 >= MAXTAG) {
394     // The potato was going to exceed the maximum value,
395     // so wrap this processor potato back to 0:
396 gezelter 2
397 gezelter 507 potatoes[which_node] = 0;
398     MPI_Send(&potatoes[which_node], 1, MPI_INT, which_node, 0,
399     MPI_COMM_WORLD);
400     }
401 gezelter 2
402 gezelter 507 myPotato = potatoes[which_node];
403 gezelter 2
404 gezelter 507 //recieve the number of integrableObject in current molecule
405     MPI_Recv(&nCurObj, 1, MPI_INT, which_node, myPotato,
406     MPI_COMM_WORLD, &istatus);
407     myPotato++;
408 gezelter 2
409 gezelter 507 for(int l = 0; l < nCurObj; l++) {
410     if (potatoes[which_node] + 2 >= MAXTAG) {
411     // The potato was going to exceed the maximum value,
412     // so wrap this processor potato back to 0:
413 gezelter 2
414 gezelter 507 potatoes[which_node] = 0;
415     MPI_Send(&potatoes[which_node], 1, MPI_INT, which_node,
416     0, MPI_COMM_WORLD);
417     }
418 gezelter 2
419 gezelter 507 MPI_Recv(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR,
420     which_node, myPotato, MPI_COMM_WORLD,
421     &istatus);
422 gezelter 2
423 gezelter 507 myPotato++;
424 gezelter 2
425 tim 963 MPI_Recv(atomData, 19, MPI_REALTYPE, which_node, myPotato,
426 gezelter 507 MPI_COMM_WORLD, &istatus);
427     myPotato++;
428 gezelter 2
429 tim 963 MPI_Get_count(&istatus, MPI_REALTYPE, &msgLen);
430 gezelter 2
431 chrisfen 721 if (msgLen == 13 || msgLen == 19)
432 gezelter 507 isDirectional = 1;
433     else
434     isDirectional = 0;
435 gezelter 2
436 gezelter 507 // If we've survived to here, format the line:
437 gezelter 2
438 gezelter 507 if (!isDirectional) {
439     sprintf(writeLine, "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
440     MPIatomTypeString, atomData[0],
441     atomData[1], atomData[2],
442     atomData[3], atomData[4],
443     atomData[5]);
444 gezelter 2
445 gezelter 507 strcat(writeLine,
446 chrisfen 721 "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0");
447 gezelter 507 } else {
448     sprintf(writeLine,
449 chrisfen 721 "%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",
450 gezelter 507 MPIatomTypeString,
451     atomData[0],
452     atomData[1],
453     atomData[2],
454     atomData[3],
455     atomData[4],
456     atomData[5],
457     atomData[6],
458     atomData[7],
459     atomData[8],
460     atomData[9],
461     atomData[10],
462     atomData[11],
463     atomData[12]);
464     }
465 chrisfen 721
466     if (needForceVector_) {
467     if (!isDirectional) {
468     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
469     atomData[6],
470     atomData[7],
471     atomData[8],
472     atomData[9],
473     atomData[10],
474     atomData[11]);
475     } else {
476     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
477     atomData[13],
478     atomData[14],
479     atomData[15],
480     atomData[16],
481     atomData[17],
482     atomData[18]);
483     }
484     }
485 gezelter 2
486 chrisfen 966 os << writeLine << "\n";
487 gezelter 2
488 gezelter 507 } // end for(int l =0)
489 gezelter 2
490 gezelter 507 potatoes[which_node] = myPotato;
491     } else { //master node has current molecule
492 gezelter 2
493 gezelter 507 mol = info_->getMoleculeByGlobalIndex(i);
494 gezelter 2
495 gezelter 507 if (mol == NULL) {
496     sprintf(painCave.errMsg, "Molecule not found on node %d!", worldRank);
497     painCave.isFatal = 1;
498     simError();
499     }
500 gezelter 246
501 gezelter 507 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
502     integrableObject = mol->nextIntegrableObject(ii)) {
503 gezelter 2
504 gezelter 507 pos = integrableObject->getPos();
505     vel = integrableObject->getVel();
506 gezelter 2
507 gezelter 507 atomData[0] = pos[0];
508     atomData[1] = pos[1];
509     atomData[2] = pos[2];
510 gezelter 2
511 gezelter 507 atomData[3] = vel[0];
512     atomData[4] = vel[1];
513     atomData[5] = vel[2];
514 gezelter 2
515 gezelter 507 isDirectional = 0;
516 gezelter 2
517 gezelter 507 if (integrableObject->isDirectional()) {
518     isDirectional = 1;
519 gezelter 2
520 gezelter 507 q = integrableObject->getQ();
521     ji = integrableObject->getJ();
522 gezelter 2
523 gezelter 507 for(int j = 0; j < 6; j++) {
524     atomData[j] = atomData[j];
525     }
526 gezelter 2
527 gezelter 507 atomData[6] = q[0];
528     atomData[7] = q[1];
529     atomData[8] = q[2];
530     atomData[9] = q[3];
531 gezelter 2
532 gezelter 507 atomData[10] = ji[0];
533     atomData[11] = ji[1];
534     atomData[12] = ji[2];
535     }
536 gezelter 2
537 chrisfen 721 if (needForceVector_) {
538     frc = integrableObject->getFrc();
539     trq = integrableObject->getTrq();
540    
541     if (!isDirectional) {
542     atomData[6] = frc[0];
543     atomData[7] = frc[1];
544     atomData[8] = frc[2];
545     atomData[9] = trq[0];
546     atomData[10] = trq[1];
547     atomData[11] = trq[2];
548     } else {
549     atomData[13] = frc[0];
550     atomData[14] = frc[1];
551     atomData[15] = frc[2];
552     atomData[16] = trq[0];
553     atomData[17] = trq[1];
554     atomData[18] = trq[2];
555     }
556     }
557    
558 gezelter 507 // If we've survived to here, format the line:
559 gezelter 2
560 gezelter 507 if (!isDirectional) {
561     sprintf(writeLine, "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
562     integrableObject->getType().c_str(), atomData[0],
563     atomData[1], atomData[2],
564     atomData[3], atomData[4],
565     atomData[5]);
566 gezelter 2
567 gezelter 507 strcat(writeLine,
568 chrisfen 721 "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0");
569 gezelter 507 } else {
570     sprintf(writeLine,
571 chrisfen 721 "%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",
572 gezelter 507 integrableObject->getType().c_str(),
573     atomData[0],
574     atomData[1],
575     atomData[2],
576     atomData[3],
577     atomData[4],
578     atomData[5],
579     atomData[6],
580     atomData[7],
581     atomData[8],
582     atomData[9],
583     atomData[10],
584     atomData[11],
585     atomData[12]);
586     }
587 gezelter 2
588 chrisfen 721 if (needForceVector_) {
589     if (!isDirectional) {
590     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
591     atomData[6],
592     atomData[7],
593     atomData[8],
594     atomData[9],
595     atomData[10],
596     atomData[11]);
597     } else {
598     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
599     atomData[13],
600     atomData[14],
601     atomData[15],
602     atomData[16],
603     atomData[17],
604     atomData[18]);
605     }
606     }
607 gezelter 2
608 tim 965 os << writeLine << "\n";
609 gezelter 2
610 gezelter 507 } //end for(iter = integrableObject.begin())
611     }
612     } //end for(i = 0; i < mpiSim->getNmol())
613 gezelter 2
614 gezelter 507 os.flush();
615 tim 251
616 gezelter 507 sprintf(checkPointMsg, "Sucessfully took a dump.\n");
617     MPIcheckPoint();
618 gezelter 2
619 gezelter 507 delete [] potatoes;
620 gezelter 246 } else {
621 gezelter 2
622 gezelter 507 // worldRank != 0, so I'm a remote node.
623 gezelter 2
624 gezelter 507 // Set my magic potato to 0:
625 gezelter 2
626 gezelter 507 myPotato = 0;
627 gezelter 2
628 gezelter 507 for(int i = 0; i < info_->getNGlobalMolecules(); i++) {
629 gezelter 2
630 gezelter 507 // Am I the node which has this integrableObject?
631     int whichNode = info_->getMolToProc(i);
632     if (whichNode == worldRank) {
633     if (myPotato + 1 >= MAXTAG) {
634 gezelter 2
635 gezelter 507 // The potato was going to exceed the maximum value,
636     // so wrap this processor potato back to 0 (and block until
637     // node 0 says we can go:
638 gezelter 2
639 gezelter 507 MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
640     &istatus);
641     }
642 gezelter 2
643 gezelter 507 mol = info_->getMoleculeByGlobalIndex(i);
644 gezelter 246
645 gezelter 2
646 gezelter 507 nCurObj = mol->getNIntegrableObjects();
647 gezelter 2
648 gezelter 507 MPI_Send(&nCurObj, 1, MPI_INT, 0, myPotato, MPI_COMM_WORLD);
649     myPotato++;
650 gezelter 2
651 gezelter 507 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
652     integrableObject = mol->nextIntegrableObject(ii)) {
653 gezelter 2
654 gezelter 507 if (myPotato + 2 >= MAXTAG) {
655 gezelter 2
656 gezelter 507 // The potato was going to exceed the maximum value,
657     // so wrap this processor potato back to 0 (and block until
658     // node 0 says we can go:
659 gezelter 2
660 gezelter 507 MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
661     &istatus);
662     }
663 gezelter 2
664 gezelter 507 pos = integrableObject->getPos();
665     vel = integrableObject->getVel();
666 gezelter 2
667 gezelter 507 atomData[0] = pos[0];
668     atomData[1] = pos[1];
669     atomData[2] = pos[2];
670 gezelter 2
671 gezelter 507 atomData[3] = vel[0];
672     atomData[4] = vel[1];
673     atomData[5] = vel[2];
674 gezelter 2
675 gezelter 507 isDirectional = 0;
676 gezelter 2
677 gezelter 507 if (integrableObject->isDirectional()) {
678     isDirectional = 1;
679 gezelter 2
680 gezelter 507 q = integrableObject->getQ();
681     ji = integrableObject->getJ();
682 gezelter 2
683 gezelter 507 atomData[6] = q[0];
684     atomData[7] = q[1];
685     atomData[8] = q[2];
686     atomData[9] = q[3];
687 gezelter 246
688 gezelter 507 atomData[10] = ji[0];
689     atomData[11] = ji[1];
690     atomData[12] = ji[2];
691     }
692 gezelter 246
693 chrisfen 721 if (needForceVector_) {
694     frc = integrableObject->getFrc();
695     trq = integrableObject->getTrq();
696    
697     if (!isDirectional) {
698     atomData[6] = frc[0];
699     atomData[7] = frc[1];
700     atomData[8] = frc[2];
701    
702     atomData[9] = trq[0];
703     atomData[10] = trq[1];
704     atomData[11] = trq[2];
705     } else {
706     atomData[13] = frc[0];
707     atomData[14] = frc[1];
708     atomData[15] = frc[2];
709    
710     atomData[16] = trq[0];
711     atomData[17] = trq[1];
712     atomData[18] = trq[2];
713     }
714     }
715    
716 gezelter 507 strncpy(MPIatomTypeString, integrableObject->getType().c_str(), MINIBUFFERSIZE);
717 gezelter 246
718 gezelter 507 // null terminate the std::string before sending (just in case):
719     MPIatomTypeString[MINIBUFFERSIZE - 1] = '\0';
720 gezelter 246
721 gezelter 507 MPI_Send(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, 0,
722     myPotato, MPI_COMM_WORLD);
723 gezelter 246
724 gezelter 507 myPotato++;
725 gezelter 246
726 chrisfen 721 if (isDirectional && needForceVector_) {
727 tim 963 MPI_Send(atomData, 19, MPI_REALTYPE, 0, myPotato,
728 chrisfen 721 MPI_COMM_WORLD);
729     } else if (isDirectional) {
730 tim 963 MPI_Send(atomData, 13, MPI_REALTYPE, 0, myPotato,
731 gezelter 507 MPI_COMM_WORLD);
732 chrisfen 721 } else if (needForceVector_) {
733 tim 963 MPI_Send(atomData, 12, MPI_REALTYPE, 0, myPotato,
734 chrisfen 721 MPI_COMM_WORLD);
735 gezelter 507 } else {
736 tim 963 MPI_Send(atomData, 6, MPI_REALTYPE, 0, myPotato,
737 gezelter 507 MPI_COMM_WORLD);
738     }
739 gezelter 246
740 gezelter 507 myPotato++;
741     }
742 gezelter 246
743 gezelter 507 }
744 gezelter 246
745 gezelter 507 }
746     sprintf(checkPointMsg, "Sucessfully took a dump.\n");
747     MPIcheckPoint();
748 gezelter 246 }
749    
750     #endif // is_mpi
751    
752 gezelter 507 }
753 gezelter 2
754 gezelter 507 void DumpWriter::writeDump() {
755 tim 615 writeFrame(*dumpFile_);
756 gezelter 507 }
757 tim 376
758 gezelter 507 void DumpWriter::writeEor() {
759 tim 615 std::ostream* eorStream;
760 tim 376
761     #ifdef IS_MPI
762     if (worldRank == 0) {
763     #endif // is_mpi
764    
765 tim 615 eorStream = createOStream(eorFilename_);
766 tim 376
767     #ifdef IS_MPI
768     }
769     #endif // is_mpi
770    
771 tim 615 writeFrame(*eorStream);
772    
773     #ifdef IS_MPI
774     if (worldRank == 0) {
775     #endif // is_mpi
776     delete eorStream;
777    
778     #ifdef IS_MPI
779     }
780     #endif // is_mpi
781    
782 gezelter 507 }
783 tim 376
784    
785 gezelter 507 void DumpWriter::writeDumpAndEor() {
786 tim 376 std::vector<std::streambuf*> buffers;
787 tim 615 std::ostream* eorStream;
788 tim 376 #ifdef IS_MPI
789     if (worldRank == 0) {
790     #endif // is_mpi
791    
792 tim 615 buffers.push_back(dumpFile_->rdbuf());
793 tim 376
794 tim 615 eorStream = createOStream(eorFilename_);
795 tim 376
796 tim 615 buffers.push_back(eorStream->rdbuf());
797 tim 376
798     #ifdef IS_MPI
799     }
800     #endif // is_mpi
801    
802     TeeBuf tbuf(buffers.begin(), buffers.end());
803     std::ostream os(&tbuf);
804    
805     writeFrame(os);
806 tim 615
807     #ifdef IS_MPI
808     if (worldRank == 0) {
809     #endif // is_mpi
810     delete eorStream;
811    
812     #ifdef IS_MPI
813     }
814     #endif // is_mpi
815 tim 376
816 gezelter 507 }
817 tim 376
818 tim 615 std::ostream* DumpWriter::createOStream(const std::string& filename) {
819 tim 619
820 tim 615 std::ostream* newOStream;
821 tim 619 #ifdef HAVE_LIBZ
822 tim 615 if (needCompression_) {
823     newOStream = new ogzstream(filename.c_str());
824     } else {
825     newOStream = new std::ofstream(filename.c_str());
826     }
827 tim 619 #else
828     newOStream = new std::ofstream(filename.c_str());
829     #endif
830 tim 615 return newOStream;
831     }
832 tim 376
833 gezelter 246 }//end namespace oopse