ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/DumpWriter.cpp
Revision: 963
Committed: Wed May 17 21:51:42 2006 UTC (18 years, 11 months ago) by tim
File size: 21420 byte(s)
Log Message:
Adding single precision capabilities to c++ side

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 721 sprintf(writeLine, "\n");
487 gezelter 507 os << writeLine;
488 gezelter 2
489 gezelter 507 } // end for(int l =0)
490 gezelter 2
491 gezelter 507 potatoes[which_node] = myPotato;
492     } else { //master node has current molecule
493 gezelter 2
494 gezelter 507 mol = info_->getMoleculeByGlobalIndex(i);
495 gezelter 2
496 gezelter 507 if (mol == NULL) {
497     sprintf(painCave.errMsg, "Molecule not found on node %d!", worldRank);
498     painCave.isFatal = 1;
499     simError();
500     }
501 gezelter 246
502 gezelter 507 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
503     integrableObject = mol->nextIntegrableObject(ii)) {
504 gezelter 2
505 gezelter 507 pos = integrableObject->getPos();
506     vel = integrableObject->getVel();
507 gezelter 2
508 gezelter 507 atomData[0] = pos[0];
509     atomData[1] = pos[1];
510     atomData[2] = pos[2];
511 gezelter 2
512 gezelter 507 atomData[3] = vel[0];
513     atomData[4] = vel[1];
514     atomData[5] = vel[2];
515 gezelter 2
516 gezelter 507 isDirectional = 0;
517 gezelter 2
518 gezelter 507 if (integrableObject->isDirectional()) {
519     isDirectional = 1;
520 gezelter 2
521 gezelter 507 q = integrableObject->getQ();
522     ji = integrableObject->getJ();
523 gezelter 2
524 gezelter 507 for(int j = 0; j < 6; j++) {
525     atomData[j] = atomData[j];
526     }
527 gezelter 2
528 gezelter 507 atomData[6] = q[0];
529     atomData[7] = q[1];
530     atomData[8] = q[2];
531     atomData[9] = q[3];
532 gezelter 2
533 gezelter 507 atomData[10] = ji[0];
534     atomData[11] = ji[1];
535     atomData[12] = ji[2];
536     }
537 gezelter 2
538 chrisfen 721 if (needForceVector_) {
539     frc = integrableObject->getFrc();
540     trq = integrableObject->getTrq();
541    
542     if (!isDirectional) {
543     atomData[6] = frc[0];
544     atomData[7] = frc[1];
545     atomData[8] = frc[2];
546     atomData[9] = trq[0];
547     atomData[10] = trq[1];
548     atomData[11] = trq[2];
549     } else {
550     atomData[13] = frc[0];
551     atomData[14] = frc[1];
552     atomData[15] = frc[2];
553     atomData[16] = trq[0];
554     atomData[17] = trq[1];
555     atomData[18] = trq[2];
556     }
557     }
558    
559 gezelter 507 // If we've survived to here, format the line:
560 gezelter 2
561 gezelter 507 if (!isDirectional) {
562     sprintf(writeLine, "%s\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t",
563     integrableObject->getType().c_str(), atomData[0],
564     atomData[1], atomData[2],
565     atomData[3], atomData[4],
566     atomData[5]);
567 gezelter 2
568 gezelter 507 strcat(writeLine,
569 chrisfen 721 "0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0");
570 gezelter 507 } else {
571     sprintf(writeLine,
572 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",
573 gezelter 507 integrableObject->getType().c_str(),
574     atomData[0],
575     atomData[1],
576     atomData[2],
577     atomData[3],
578     atomData[4],
579     atomData[5],
580     atomData[6],
581     atomData[7],
582     atomData[8],
583     atomData[9],
584     atomData[10],
585     atomData[11],
586     atomData[12]);
587     }
588 gezelter 2
589 chrisfen 721 if (needForceVector_) {
590     if (!isDirectional) {
591     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
592     atomData[6],
593     atomData[7],
594     atomData[8],
595     atomData[9],
596     atomData[10],
597     atomData[11]);
598     } else {
599     sprintf(writeLine, "\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf",
600     atomData[13],
601     atomData[14],
602     atomData[15],
603     atomData[16],
604     atomData[17],
605     atomData[18]);
606     }
607     }
608 gezelter 2
609 chrisfen 721 sprintf(writeLine, "\n");
610 gezelter 507 os << writeLine;
611 gezelter 2
612 gezelter 507 } //end for(iter = integrableObject.begin())
613     }
614     } //end for(i = 0; i < mpiSim->getNmol())
615 gezelter 2
616 gezelter 507 os.flush();
617 tim 251
618 gezelter 507 sprintf(checkPointMsg, "Sucessfully took a dump.\n");
619     MPIcheckPoint();
620 gezelter 2
621 gezelter 507 delete [] potatoes;
622 gezelter 246 } else {
623 gezelter 2
624 gezelter 507 // worldRank != 0, so I'm a remote node.
625 gezelter 2
626 gezelter 507 // Set my magic potato to 0:
627 gezelter 2
628 gezelter 507 myPotato = 0;
629 gezelter 2
630 gezelter 507 for(int i = 0; i < info_->getNGlobalMolecules(); i++) {
631 gezelter 2
632 gezelter 507 // Am I the node which has this integrableObject?
633     int whichNode = info_->getMolToProc(i);
634     if (whichNode == worldRank) {
635     if (myPotato + 1 >= MAXTAG) {
636 gezelter 2
637 gezelter 507 // The potato was going to exceed the maximum value,
638     // so wrap this processor potato back to 0 (and block until
639     // node 0 says we can go:
640 gezelter 2
641 gezelter 507 MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
642     &istatus);
643     }
644 gezelter 2
645 gezelter 507 mol = info_->getMoleculeByGlobalIndex(i);
646 gezelter 246
647 gezelter 2
648 gezelter 507 nCurObj = mol->getNIntegrableObjects();
649 gezelter 2
650 gezelter 507 MPI_Send(&nCurObj, 1, MPI_INT, 0, myPotato, MPI_COMM_WORLD);
651     myPotato++;
652 gezelter 2
653 gezelter 507 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
654     integrableObject = mol->nextIntegrableObject(ii)) {
655 gezelter 2
656 gezelter 507 if (myPotato + 2 >= MAXTAG) {
657 gezelter 2
658 gezelter 507 // The potato was going to exceed the maximum value,
659     // so wrap this processor potato back to 0 (and block until
660     // node 0 says we can go:
661 gezelter 2
662 gezelter 507 MPI_Recv(&myPotato, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
663     &istatus);
664     }
665 gezelter 2
666 gezelter 507 pos = integrableObject->getPos();
667     vel = integrableObject->getVel();
668 gezelter 2
669 gezelter 507 atomData[0] = pos[0];
670     atomData[1] = pos[1];
671     atomData[2] = pos[2];
672 gezelter 2
673 gezelter 507 atomData[3] = vel[0];
674     atomData[4] = vel[1];
675     atomData[5] = vel[2];
676 gezelter 2
677 gezelter 507 isDirectional = 0;
678 gezelter 2
679 gezelter 507 if (integrableObject->isDirectional()) {
680     isDirectional = 1;
681 gezelter 2
682 gezelter 507 q = integrableObject->getQ();
683     ji = integrableObject->getJ();
684 gezelter 2
685 gezelter 507 atomData[6] = q[0];
686     atomData[7] = q[1];
687     atomData[8] = q[2];
688     atomData[9] = q[3];
689 gezelter 246
690 gezelter 507 atomData[10] = ji[0];
691     atomData[11] = ji[1];
692     atomData[12] = ji[2];
693     }
694 gezelter 246
695 chrisfen 721 if (needForceVector_) {
696     frc = integrableObject->getFrc();
697     trq = integrableObject->getTrq();
698    
699     if (!isDirectional) {
700     atomData[6] = frc[0];
701     atomData[7] = frc[1];
702     atomData[8] = frc[2];
703    
704     atomData[9] = trq[0];
705     atomData[10] = trq[1];
706     atomData[11] = trq[2];
707     } else {
708     atomData[13] = frc[0];
709     atomData[14] = frc[1];
710     atomData[15] = frc[2];
711    
712     atomData[16] = trq[0];
713     atomData[17] = trq[1];
714     atomData[18] = trq[2];
715     }
716     }
717    
718 gezelter 507 strncpy(MPIatomTypeString, integrableObject->getType().c_str(), MINIBUFFERSIZE);
719 gezelter 246
720 gezelter 507 // null terminate the std::string before sending (just in case):
721     MPIatomTypeString[MINIBUFFERSIZE - 1] = '\0';
722 gezelter 246
723 gezelter 507 MPI_Send(MPIatomTypeString, MINIBUFFERSIZE, MPI_CHAR, 0,
724     myPotato, MPI_COMM_WORLD);
725 gezelter 246
726 gezelter 507 myPotato++;
727 gezelter 246
728 chrisfen 721 if (isDirectional && needForceVector_) {
729 tim 963 MPI_Send(atomData, 19, MPI_REALTYPE, 0, myPotato,
730 chrisfen 721 MPI_COMM_WORLD);
731     } else if (isDirectional) {
732 tim 963 MPI_Send(atomData, 13, MPI_REALTYPE, 0, myPotato,
733 gezelter 507 MPI_COMM_WORLD);
734 chrisfen 721 } else if (needForceVector_) {
735 tim 963 MPI_Send(atomData, 12, MPI_REALTYPE, 0, myPotato,
736 chrisfen 721 MPI_COMM_WORLD);
737 gezelter 507 } else {
738 tim 963 MPI_Send(atomData, 6, MPI_REALTYPE, 0, myPotato,
739 gezelter 507 MPI_COMM_WORLD);
740     }
741 gezelter 246
742 gezelter 507 myPotato++;
743     }
744 gezelter 246
745 gezelter 507 }
746 gezelter 246
747 gezelter 507 }
748     sprintf(checkPointMsg, "Sucessfully took a dump.\n");
749     MPIcheckPoint();
750 gezelter 246 }
751    
752     #endif // is_mpi
753    
754 gezelter 507 }
755 gezelter 2
756 gezelter 507 void DumpWriter::writeDump() {
757 tim 615 writeFrame(*dumpFile_);
758 gezelter 507 }
759 tim 376
760 gezelter 507 void DumpWriter::writeEor() {
761 tim 615 std::ostream* eorStream;
762 tim 376
763     #ifdef IS_MPI
764     if (worldRank == 0) {
765     #endif // is_mpi
766    
767 tim 615 eorStream = createOStream(eorFilename_);
768 tim 376
769     #ifdef IS_MPI
770     }
771     #endif // is_mpi
772    
773 tim 615 writeFrame(*eorStream);
774    
775     #ifdef IS_MPI
776     if (worldRank == 0) {
777     #endif // is_mpi
778     delete eorStream;
779    
780     #ifdef IS_MPI
781     }
782     #endif // is_mpi
783    
784 gezelter 507 }
785 tim 376
786    
787 gezelter 507 void DumpWriter::writeDumpAndEor() {
788 tim 376 std::vector<std::streambuf*> buffers;
789 tim 615 std::ostream* eorStream;
790 tim 376 #ifdef IS_MPI
791     if (worldRank == 0) {
792     #endif // is_mpi
793    
794 tim 615 buffers.push_back(dumpFile_->rdbuf());
795 tim 376
796 tim 615 eorStream = createOStream(eorFilename_);
797 tim 376
798 tim 615 buffers.push_back(eorStream->rdbuf());
799 tim 376
800     #ifdef IS_MPI
801     }
802     #endif // is_mpi
803    
804     TeeBuf tbuf(buffers.begin(), buffers.end());
805     std::ostream os(&tbuf);
806    
807     writeFrame(os);
808 tim 615
809     #ifdef IS_MPI
810     if (worldRank == 0) {
811     #endif // is_mpi
812     delete eorStream;
813    
814     #ifdef IS_MPI
815     }
816     #endif // is_mpi
817 tim 376
818 gezelter 507 }
819 tim 376
820 tim 615 std::ostream* DumpWriter::createOStream(const std::string& filename) {
821 tim 619
822 tim 615 std::ostream* newOStream;
823 tim 619 #ifdef HAVE_LIBZ
824 tim 615 if (needCompression_) {
825     newOStream = new ogzstream(filename.c_str());
826     } else {
827     newOStream = new std::ofstream(filename.c_str());
828     }
829 tim 619 #else
830     newOStream = new std::ofstream(filename.c_str());
831     #endif
832 tim 615 return newOStream;
833     }
834 tim 376
835 gezelter 246 }//end namespace oopse