ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/DumpWriter.cpp
Revision: 1024
Committed: Wed Aug 30 18:42:29 2006 UTC (18 years, 8 months ago) by tim
Original Path: trunk/src/io/DumpWriter.cpp
File size: 11857 byte(s)
Log Message:
Massive changes preparing for release of OOPSE-4: The main difference
is that the new MD file format (.md, .dump, .eor) now contains meta-data
information along with the configuration information.

File Contents

# Content
1 /*
2 * 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 #include "io/basic_teebuf.hpp"
46 #include "io/gzstream.hpp"
47 #include "io/Globals.hpp"
48
49 #ifdef IS_MPI
50 #include <mpi.h>
51 #endif //is_mpi
52
53 namespace oopse {
54
55 DumpWriter::DumpWriter(SimInfo* info)
56 : info_(info), filename_(info->getDumpFileName()), eorFilename_(info->getFinalConfigFileName()){
57
58 Globals* simParams = info->getSimParams();
59 needCompression_ = simParams->getCompressDumpFile();
60 needForceVector_ = simParams->getOutputForceVector();
61 createDumpFile_ = true;
62 #ifdef HAVE_LIBZ
63 if (needCompression_) {
64 filename_ += ".gz";
65 eorFilename_ += ".gz";
66 }
67 #endif
68
69 #ifdef IS_MPI
70
71 if (worldRank == 0) {
72 #endif // is_mpi
73
74 dumpFile_ = createOStream(filename_);
75
76 if (!dumpFile_) {
77 sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
78 filename_.c_str());
79 painCave.isFatal = 1;
80 simError();
81 }
82
83 #ifdef IS_MPI
84
85 }
86
87 #endif // is_mpi
88
89 }
90
91
92 DumpWriter::DumpWriter(SimInfo* info, const std::string& filename)
93 : info_(info), filename_(filename){
94
95 Globals* simParams = info->getSimParams();
96 eorFilename_ = filename_.substr(0, filename_.rfind(".")) + ".eor";
97
98 needCompression_ = simParams->getCompressDumpFile();
99 needForceVector_ = simParams->getOutputForceVector();
100 createDumpFile_ = true;
101 #ifdef HAVE_LIBZ
102 if (needCompression_) {
103 filename_ += ".gz";
104 eorFilename_ += ".gz";
105 }
106 #endif
107
108 #ifdef IS_MPI
109
110 if (worldRank == 0) {
111 #endif // is_mpi
112
113
114 dumpFile_ = createOStream(filename_);
115
116 if (!dumpFile_) {
117 sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
118 filename_.c_str());
119 painCave.isFatal = 1;
120 simError();
121 }
122
123 #ifdef IS_MPI
124
125 }
126
127 #endif // is_mpi
128
129 }
130
131 DumpWriter::DumpWriter(SimInfo* info, const std::string& filename, bool writeDumpFile)
132 : info_(info), filename_(filename){
133
134 Globals* simParams = info->getSimParams();
135 eorFilename_ = filename_.substr(0, filename_.rfind(".")) + ".eor";
136
137 needCompression_ = simParams->getCompressDumpFile();
138 needForceVector_ = simParams->getOutputForceVector();
139
140 #ifdef HAVE_LIBZ
141 if (needCompression_) {
142 filename_ += ".gz";
143 eorFilename_ += ".gz";
144 }
145 #endif
146
147 #ifdef IS_MPI
148
149 if (worldRank == 0) {
150 #endif // is_mpi
151
152 createDumpFile_ = writeDumpFile;
153 if (createDumpFile_) {
154 dumpFile_ = createOStream(filename_);
155
156 if (!dumpFile_) {
157 sprintf(painCave.errMsg, "Could not open \"%s\" for dump output.\n",
158 filename_.c_str());
159 painCave.isFatal = 1;
160 simError();
161 }
162 }
163 #ifdef IS_MPI
164
165 }
166
167
168 #endif // is_mpi
169
170 }
171
172 DumpWriter::~DumpWriter() {
173
174 #ifdef IS_MPI
175
176 if (worldRank == 0) {
177 #endif // is_mpi
178 if (createDumpFile_){
179 writeClosing(*dumpFile_);
180 delete dumpFile_;
181 }
182 #ifdef IS_MPI
183
184 }
185
186 #endif // is_mpi
187
188 }
189
190 void DumpWriter::writeFrameProperties(std::ostream& os, Snapshot* s) {
191
192 char buffer[1024];
193
194 os << " <FrameData>\n";
195
196 RealType currentTime = s->getTime();
197 sprintf(buffer, " Time: %.10g\n", time);
198 os << buffer;
199
200 Mat3x3d hmat;
201 hmat = s->getHmat();
202 sprintf(buffer, " Hmat: {{ %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }}\n",
203 hmat(0, 0), hmat(1, 0), hmat(2, 0),
204 hmat(0, 1), hmat(1, 1), hmat(2, 1),
205 hmat(0, 2), hmat(1, 2), hmat(2, 2));
206 os << buffer;
207
208 RealType chi = s->getChi();
209 RealType integralOfChiDt = s->getIntegralOfChiDt();
210 sprintf(buffer, " Thermostat: %.10g , %.10g\n", chi, integralOfChiDt);
211 os << buffer;
212
213 Mat3x3d eta;
214 eta = s->getEta();
215 sprintf(buffer, " Barostat: {{ %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }}\n",
216 eta(0, 0), eta(1, 0), eta(2, 0),
217 eta(0, 1), eta(1, 1), eta(2, 1),
218 eta(0, 2), eta(1, 2), eta(2, 2));
219 os << buffer;
220
221 os << " </FrameData>\n";
222 }
223
224 void DumpWriter::writeFrame(std::ostream& os) {
225
226 #ifdef IS_MPI
227 MPI_Status istatus;
228 #endif
229
230 Molecule* mol;
231 StuntDouble* integrableObject;
232 SimInfo::MoleculeIterator mi;
233 Molecule::IntegrableObjectIterator ii;
234
235 #ifndef IS_MPI
236 os << " <Snapshot>\n";
237
238 writeFrameProperties(os, info_->getSnapshotManager()->getCurrentSnapshot());
239
240 os << " <StuntDoubles>\n";
241 for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
242
243 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
244 integrableObject = mol->nextIntegrableObject(ii)) {
245 os << prepareDumpLine(integrableObject);
246
247 }
248 }
249 os << " </StuntDoubles>\n";
250
251 os << " </Snapshot>\n";
252
253 os.flush();
254 #else
255 //every node prepares the dump lines for integrable objects belong to itself
256 std::string buffer;
257 for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
258
259 for (integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
260 integrableObject = mol->nextIntegrableObject(ii)) {
261 buffer += prepareDumpLine(integrableObject);
262 }
263 }
264
265 const int masterNode = 0;
266
267 if (worldRank == masterNode) {
268 os << " <Snapshot>\n";
269 writeFrameProperties(os, info_->getSnapshotManager()->getCurrentSnapshot());
270 os << buffer;
271 os << " <StuntDoubles>\n";
272
273 int nProc;
274 MPI_Comm_size(MPI_COMM_WORLD, &nProc);
275 for (int i = 1; i < nProc; ++i) {
276
277 // receive the length of the string buffer that was
278 // prepared by processor i
279
280 int recvLength;
281 MPI_Recv(&recvLength, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &istatus);
282 char* recvBuffer = new char[recvLength];
283 if (recvBuffer == NULL) {
284
285 } else {
286 MPI_Recv(&recvBuffer, recvLength, MPI_CHAR, i, 0, MPI_COMM_WORLD, &istatus);
287 os << recvBuffer;
288 delete recvBuffer;
289 }
290
291 }
292 os << " </StuntDoubles>\n";
293
294 os << " </Snapshot>\n";
295 os.flush();
296 } else {
297 int sendBufferLength = buffer.size();
298 MPI_Send(&sendBufferLength, 1, MPI_INT, masterNode, 0, MPI_COMM_WORLD);
299 MPI_Send((void *)buffer.c_str(), sendBufferLength, MPI_CHAR, masterNode, 0, MPI_COMM_WORLD);
300 }
301
302 #endif // is_mpi
303
304 }
305
306 std::string DumpWriter::prepareDumpLine(StuntDouble* integrableObject) {
307
308 int index = integrableObject->getGlobalIntegrableObjectIndex();
309 std::string type("pv");
310 std::string line;
311 char tempBuffer[4096];
312
313 Vector3d pos;
314 Vector3d vel;
315 pos = integrableObject->getPos();
316 vel = integrableObject->getVel();
317 sprintf(tempBuffer, "%18.10g\t%18.10g\t%18.10g\t%14.10g\t%14.10g\t%14.10g",
318 pos[0], pos[1], pos[2],
319 vel[0], vel[1], vel[2]);
320 line += tempBuffer;
321
322 if (integrableObject->isDirectional()) {
323 type += "qj";
324 Quat4d q;
325 Vector3d ji;
326 q = integrableObject->getQ();
327 ji = integrableObject->getJ();
328 sprintf(tempBuffer, "\t%14.10g\t%14.10g\t%14.10g\t%14.10g\t%14.10g\t%14.10g\t%14.10g",
329 q[0], q[1], q[2], q[3],
330 ji[0], ji[1], ji[2]);
331 line += tempBuffer;
332 }
333
334 if (needForceVector_) {
335 type += "ft";
336 Vector3d frc;
337 Vector3d trq;
338 frc = integrableObject->getFrc();
339 trq = integrableObject->getTrq();
340
341 sprintf(tempBuffer, "\t%14.10g\t%14.10g\t%14.10g\t%14.10g\t%14.10g\t%14.10g",
342 frc[0], frc[1], frc[2],
343 trq[0], trq[1], trq[2]);
344 line += tempBuffer;
345 }
346
347 sprintf(tempBuffer, "%d\t%s\t%s\n", index, type.c_str(), line.c_str());
348 return std::string(tempBuffer);
349 }
350
351 void DumpWriter::writeDump() {
352 writeFrame(*dumpFile_);
353 }
354
355 void DumpWriter::writeEor() {
356 std::ostream* eorStream;
357
358 #ifdef IS_MPI
359 if (worldRank == 0) {
360 #endif // is_mpi
361
362 eorStream = createOStream(eorFilename_);
363
364 #ifdef IS_MPI
365 }
366 #endif // is_mpi
367
368 writeFrame(*eorStream);
369
370 #ifdef IS_MPI
371 if (worldRank == 0) {
372 #endif // is_mpi
373 writeClosing(*eorStream);
374 delete eorStream;
375 #ifdef IS_MPI
376 }
377 #endif // is_mpi
378
379 }
380
381
382 void DumpWriter::writeDumpAndEor() {
383 std::vector<std::streambuf*> buffers;
384 std::ostream* eorStream;
385 #ifdef IS_MPI
386 if (worldRank == 0) {
387 #endif // is_mpi
388
389 buffers.push_back(dumpFile_->rdbuf());
390
391 eorStream = createOStream(eorFilename_);
392
393 buffers.push_back(eorStream->rdbuf());
394
395 #ifdef IS_MPI
396 }
397 #endif // is_mpi
398
399 TeeBuf tbuf(buffers.begin(), buffers.end());
400 std::ostream os(&tbuf);
401
402 writeFrame(os);
403
404 #ifdef IS_MPI
405 if (worldRank == 0) {
406 #endif // is_mpi
407 writeClosing(*eorStream);
408 delete eorStream;
409 #ifdef IS_MPI
410 }
411 #endif // is_mpi
412
413 }
414
415 std::ostream* DumpWriter::createOStream(const std::string& filename) {
416
417 std::ostream* newOStream;
418 #ifdef HAVE_LIBZ
419 if (needCompression_) {
420 newOStream = new ogzstream(filename.c_str());
421 } else {
422 newOStream = new std::ofstream(filename.c_str());
423 }
424 #else
425 newOStream = new std::ofstream(filename.c_str());
426 #endif
427 //write out MetaData first
428 (*newOStream) << "<OOPSE version=4>" << std::endl;
429 (*newOStream) << " <MetaData>" << std::endl;
430 (*newOStream) << info_->getRawMetaData();
431 (*newOStream) << " </MetaData>" << std::endl;
432 return newOStream;
433 }
434
435 void DumpWriter::writeClosing(std::ostream& os) {
436
437 os << "</OOPSE>\n";
438 os.flush();
439 }
440
441 }//end namespace oopse