2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 // Maintainer: joaander
52 /*! \file HOOMDDumpWriter.cc
53 \brief Defines the HOOMDDumpWriter class
57 #pragma warning( push )
58 #pragma warning( disable : 4244 )
61 #include <boost/python.hpp>
62 using namespace boost::python
;
68 #include <boost/shared_ptr.hpp>
70 #include "HOOMDDumpWriter.h"
71 #include "BondedGroupData.h"
75 #include "Communicator.h"
79 using namespace boost
;
81 /*! \param sysdef SystemDefinition containing the ParticleData to dump
82 \param base_fname The base name of the file xml file to output the information
84 \note .timestep.xml will be apended to the end of \a base_fname when analyze() is called.
86 HOOMDDumpWriter::HOOMDDumpWriter(boost::shared_ptr
<SystemDefinition
> sysdef
, std::string base_fname
)
87 : Analyzer(sysdef
), m_base_fname(base_fname
), m_output_position(true),
88 m_output_image(false), m_output_velocity(false), m_output_mass(false), m_output_diameter(false),
89 m_output_type(false), m_output_bond(false), m_output_angle(false), m_output_wall(false),
90 m_output_dihedral(false), m_output_improper(false), m_output_accel(false), m_output_body(false),
91 m_output_charge(false), m_output_orientation(false), m_output_moment_inertia(false), m_vizsigma_set(false)
93 m_exec_conf
->msg
->notice(5) << "Constructing HOOMDDumpWriter: " << base_fname
<< endl
;
96 HOOMDDumpWriter::~HOOMDDumpWriter()
98 m_exec_conf
->msg
->notice(5) << "Destroying HOOMDDumpWriter" << endl
;
101 /*! \param enable Set to true to enable the writing of particle positions to the files in analyze()
103 void HOOMDDumpWriter::setOutputPosition(bool enable
)
105 m_output_position
= enable
;
108 /*! \param enable Set to true to enable the writing of particle images to the files in analyze()
110 void HOOMDDumpWriter::setOutputImage(bool enable
)
112 m_output_image
= enable
;
115 /*!\param enable Set to true to output particle velocities to the XML file on the next call to analyze()
117 void HOOMDDumpWriter::setOutputVelocity(bool enable
)
119 m_output_velocity
= enable
;
122 /*!\param enable Set to true to output particle masses to the XML file on the next call to analyze()
124 void HOOMDDumpWriter::setOutputMass(bool enable
)
126 m_output_mass
= enable
;
129 /*!\param enable Set to true to output particle diameters to the XML file on the next call to analyze()
131 void HOOMDDumpWriter::setOutputDiameter(bool enable
)
133 m_output_diameter
= enable
;
136 /*! \param enable Set to true to output particle types to the XML file on the next call to analyze()
138 void HOOMDDumpWriter::setOutputType(bool enable
)
140 m_output_type
= enable
;
142 /*! \param enable Set to true to output bonds to the XML file on the next call to analyze()
144 void HOOMDDumpWriter::setOutputBond(bool enable
)
146 m_output_bond
= enable
;
148 /*! \param enable Set to true to output angles to the XML file on the next call to analyze()
150 void HOOMDDumpWriter::setOutputAngle(bool enable
)
152 m_output_angle
= enable
;
154 /*! \param enable Set to true to output walls to the XML file on the next call to analyze()
156 void HOOMDDumpWriter::setOutputWall(bool enable
)
158 m_output_wall
= enable
;
160 /*! \param enable Set to true to output dihedrals to the XML file on the next call to analyze()
162 void HOOMDDumpWriter::setOutputDihedral(bool enable
)
164 m_output_dihedral
= enable
;
166 /*! \param enable Set to true to output impropers to the XML file on the next call to analyze()
168 void HOOMDDumpWriter::setOutputImproper(bool enable
)
170 m_output_improper
= enable
;
172 /*! \param enable Set to true to output acceleration to the XML file on the next call to analyze()
174 void HOOMDDumpWriter::setOutputAccel(bool enable
)
176 m_output_accel
= enable
;
178 /*! \param enable Set to true to output body to the XML file on the next call to analyze()
180 void HOOMDDumpWriter::setOutputBody(bool enable
)
182 m_output_body
= enable
;
185 /*! \param enable Set to true to output body to the XML file on the next call to analyze()
187 void HOOMDDumpWriter::setOutputCharge(bool enable
)
189 m_output_charge
= enable
;
192 /*! \param enable Set to true to output orientation to the XML file on the next call to analyze()
194 void HOOMDDumpWriter::setOutputOrientation(bool enable
)
196 m_output_orientation
= enable
;
199 /*! \param enable Set to true to output moment_inertia to the XML file on the next call to analyze()
201 void HOOMDDumpWriter::setOutputMomentInertia(bool enable
)
203 m_output_moment_inertia
= enable
;
206 /*! \param fname File name to write
207 \param timestep Current time step of the simulation
209 void HOOMDDumpWriter::writeFile(std::string fname
, unsigned int timestep
)
211 // acquire the particle data
212 SnapshotParticleData
snapshot(m_pdata
->getNGlobal());
214 m_pdata
->takeSnapshot(snapshot
);
216 BondData::Snapshot
bdata_snapshot(m_sysdef
->getBondData()->getNGlobal());
217 if (m_output_bond
) m_sysdef
->getBondData()->takeSnapshot(bdata_snapshot
);
219 AngleData::Snapshot
adata_snapshot(m_sysdef
->getAngleData()->getNGlobal());
220 if (m_output_angle
) m_sysdef
->getAngleData()->takeSnapshot(adata_snapshot
);
222 DihedralData::Snapshot
ddata_snapshot(m_sysdef
->getDihedralData()->getNGlobal());
223 if (m_output_dihedral
) m_sysdef
->getDihedralData()->takeSnapshot(ddata_snapshot
);
225 ImproperData::Snapshot
idata_snapshot(m_sysdef
->getImproperData()->getNGlobal());
226 if (m_output_improper
) m_sysdef
->getImproperData()->takeSnapshot(idata_snapshot
);
229 // only the root processor writes the output file
230 if (m_pdata
->getDomainDecomposition() && ! m_exec_conf
->isRoot())
234 // open the file for writing
235 ofstream
f(fname
.c_str());
239 m_exec_conf
->msg
->error() << "dump.xml: Unable to open dump file for writing: " << fname
<< endl
;
240 throw runtime_error("Error writting hoomd_xml dump file");
243 BoxDim box
= m_pdata
->getGlobalBox();
244 Scalar3 L
= box
.getL();
245 Scalar xy
= box
.getTiltFactorXY();
246 Scalar xz
= box
.getTiltFactorXZ();
247 Scalar yz
= box
.getTiltFactorYZ();
250 f
<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << "\n";
251 f
<< "<hoomd_xml version=\"1.5\">" << "\n";
252 f
<< "<configuration time_step=\"" << timestep
<< "\" "
253 << "dimensions=\"" << m_sysdef
->getNDimensions() << "\" "
254 << "natoms=\"" << m_pdata
->getNGlobal() << "\" ";
256 f
<< "vizsigma=\"" << m_vizsigma
<< "\" ";
258 f
<< "<box " << "lx=\"" << L
.x
<< "\" ly=\""<< L
.y
<< "\" lz=\""<< L
.z
259 << "\" xy=\"" << xy
<< "\" xz=\"" << xz
<< "\" yz=\"" << yz
<< "\"/>" << "\n";
263 // If the position flag is true output the position of all particles to the file
264 if (m_output_position
)
266 f
<< "<position num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
267 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
269 Scalar3 pos
= snapshot
.pos
[j
];
271 f
<< pos
.x
<< " " << pos
.y
<< " "<< pos
.z
<< "\n";
275 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
276 throw runtime_error("Error writting HOOMD dump file");
279 f
<<"</position>" << "\n";
282 // If the image flag is true, output the image of each particle to the file
285 f
<< "<image num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
286 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
288 int3 image
= snapshot
.image
[j
];
290 f
<< image
.x
<< " " << image
.y
<< " "<< image
.z
<< "\n";
294 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
295 throw runtime_error("Error writting HOOMD dump file");
298 f
<<"</image>" << "\n";
301 // If the velocity flag is true output the velocity of all particles to the file
302 if (m_output_velocity
)
304 f
<<"<velocity num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
306 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
308 Scalar3 vel
= snapshot
.vel
[j
];
309 f
<< vel
.x
<< " " << vel
.y
<< " " << vel
.z
<< "\n";
312 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
313 throw runtime_error("Error writting HOOMD dump file");
317 f
<<"</velocity>" << "\n";
320 // If the velocity flag is true output the velocity of all particles to the file
323 f
<<"<acceleration num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
325 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
327 Scalar3 accel
= snapshot
.accel
[j
];
329 f
<< accel
.x
<< " " << accel
.y
<< " " << accel
.z
<< "\n";
332 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
333 throw runtime_error("Error writting HOOMD dump file");
337 f
<<"</acceleration>" << "\n";
340 // If the mass flag is true output the mass of all particles to the file
343 f
<<"<mass num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
345 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
347 Scalar mass
= snapshot
.mass
[j
];
352 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
353 throw runtime_error("Error writting HOOMD dump file");
357 f
<<"</mass>" << "\n";
360 // If the diameter flag is true output the mass of all particles to the file
361 if (m_output_diameter
)
363 f
<<"<diameter num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
365 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
367 Scalar diameter
= snapshot
.diameter
[j
];
368 f
<< diameter
<< "\n";
371 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
372 throw runtime_error("Error writting HOOMD dump file");
376 f
<<"</diameter>" << "\n";
379 // If the Type flag is true output the types of all particles to an xml file
382 f
<<"<type num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
383 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
385 unsigned int type
= snapshot
.type
[j
];
386 f
<< m_pdata
->getNameByType(type
) << "\n";
388 f
<<"</type>" << "\n";
391 // If the body flag is true output the bodies of all particles to an xml file
394 f
<<"<body num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
395 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
399 body
= snapshot
.body
[j
];
407 f
<<"</body>" << "\n";
410 // if the bond flag is true, output the bonds to the xml file
413 f
<< "<bond num=\"" << bdata_snapshot
.groups
.size() << "\">" << "\n";
414 boost::shared_ptr
<BondData
> bond_data
= m_sysdef
->getBondData();
416 // loop over all bonds and write them out
417 for (unsigned int i
= 0; i
< bdata_snapshot
.groups
.size(); i
++)
419 BondData::members_t bond
= bdata_snapshot
.groups
[i
];
420 unsigned int bond_type
= bdata_snapshot
.type_id
[i
];
421 f
<< bond_data
->getNameByType(bond_type
) << " " << bond
.tag
[0] << " " << bond
.tag
[1] << "\n";
424 f
<< "</bond>" << "\n";
427 // if the angle flag is true, output the angles to the xml file
430 f
<< "<angle num=\"" << adata_snapshot
.groups
.size() << "\">" << "\n";
431 boost::shared_ptr
<AngleData
> angle_data
= m_sysdef
->getAngleData();
433 // loop over all angles and write them out
434 for (unsigned int i
= 0; i
< adata_snapshot
.groups
.size(); i
++)
436 AngleData::members_t angle
= adata_snapshot
.groups
[i
];
437 unsigned int angle_type
= adata_snapshot
.type_id
[i
];
438 f
<< angle_data
->getNameByType(angle_type
) << " " << angle
.tag
[0] << " " << angle
.tag
[1] << " " << angle
.tag
[2] << "\n";
441 f
<< "</angle>" << "\n";
444 // if dihedral is true, write out dihedrals to the xml file
445 if (m_output_dihedral
)
447 f
<< "<dihedral num=\"" << ddata_snapshot
.groups
.size() << "\">" << "\n";
448 boost::shared_ptr
<DihedralData
> dihedral_data
= m_sysdef
->getDihedralData();
450 // loop over all angles and write them out
451 for (unsigned int i
= 0; i
< ddata_snapshot
.groups
.size(); i
++)
453 DihedralData::members_t dihedral
= ddata_snapshot
.groups
[i
];
454 unsigned int dihedral_type
= ddata_snapshot
.type_id
[i
];
455 f
<< dihedral_data
->getNameByType(dihedral_type
) << " " << dihedral
.tag
[0] << " " << dihedral
.tag
[1] << " "
456 << dihedral
.tag
[2] << " " << dihedral
.tag
[3] << "\n";
459 f
<< "</dihedral>" << "\n";
462 // if improper is true, write out impropers to the xml file
463 if (m_output_improper
)
465 f
<< "<improper num=\"" << idata_snapshot
.groups
.size() << "\">" << "\n";
466 boost::shared_ptr
<ImproperData
> improper_data
= m_sysdef
->getImproperData();
468 // loop over all angles and write them out
469 for (unsigned int i
= 0; i
< idata_snapshot
.groups
.size(); i
++)
471 ImproperData::members_t improper
= idata_snapshot
.groups
[i
];
472 unsigned int improper_type
= idata_snapshot
.type_id
[i
];
473 f
<< improper_data
->getNameByType(improper_type
) << " " << improper
.tag
[0] << " " << improper
.tag
[1] << " "
474 << improper
.tag
[2] << " " << improper
.tag
[3] << "\n";
477 f
<< "</improper>" << "\n";
480 // if the wall flag is true, output the walls to the xml file
483 f
<< "<wall>" << "\n";
484 boost::shared_ptr
<WallData
> wall_data
= m_sysdef
->getWallData();
486 // loop over all walls and write them out
487 for (unsigned int i
= 0; i
< wall_data
->getNumWalls(); i
++)
489 Wall wall
= wall_data
->getWall(i
);
490 f
<< "<coord ox=\"" << wall
.origin_x
<< "\" oy=\"" << wall
.origin_y
<< "\" oz=\"" << wall
.origin_z
<<
491 "\" nx=\"" << wall
.normal_x
<< "\" ny=\"" << wall
.normal_y
<< "\" nz=\"" << wall
.normal_z
<< "\" />" << "\n";
493 f
<< "</wall>" << "\n";
496 // If the charge flag is true output the mass of all particles to the file
499 f
<<"<charge num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
501 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
503 Scalar charge
= snapshot
.charge
[j
];
507 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
508 throw runtime_error("Error writting HOOMD dump file");
512 f
<<"</charge>" << "\n";
515 // if the orientation flag is set, write out the orientation quaternion to the XML file
516 if (m_output_orientation
)
518 f
<< "<orientation num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
520 for (unsigned int j
= 0; j
< m_pdata
->getNGlobal(); j
++)
522 // use the rtag data to output the particles in the order they were read in
523 Scalar4 orientation
= snapshot
.orientation
[j
];
524 f
<< orientation
.x
<< " " << orientation
.y
<< " " << orientation
.z
<< " " << orientation
.w
<< "\n";
527 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
528 throw runtime_error("Error writting HOOMD dump file");
531 f
<< "</orientation>" << "\n";
534 // if the moment_inertia flag is set, write out the orientation quaternion to the XML file
535 if (m_output_moment_inertia
)
537 f
<< "<moment_inertia num=\"" << m_pdata
->getNGlobal() << "\">" << "\n";
539 for (unsigned int i
= 0; i
< m_pdata
->getNGlobal(); i
++)
541 // inertia tensors are stored by tag
542 InertiaTensor I
= snapshot
.inertia_tensor
[i
];
543 for (unsigned int c
= 0; c
< 5; c
++)
544 f
<< I
.components
[c
] << " ";
545 f
<< I
.components
[5] << "\n";
549 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
550 throw runtime_error("Error writting HOOMD dump file");
553 f
<< "</moment_inertia>" << "\n";
556 f
<< "</configuration>" << "\n";
557 f
<< "</hoomd_xml>" << "\n";
561 m_exec_conf
->msg
->error() << "dump.xml: I/O error while writing HOOMD dump file" << endl
;
562 throw runtime_error("Error writting HOOMD dump file");
569 /*! \param timestep Current time step of the simulation
570 Writes a snapshot of the current state of the ParticleData to a hoomd_xml file.
572 void HOOMDDumpWriter::analyze(unsigned int timestep
)
575 m_prof
->push("Dump XML");
577 ostringstream full_fname
;
578 string filetype
= ".xml";
580 // Generate a filename with the timestep padded to ten zeros
581 full_fname
<< m_base_fname
<< "." << setfill('0') << setw(10) << timestep
<< filetype
;
582 writeFile(full_fname
.str(), timestep
);
588 void export_HOOMDDumpWriter()
590 class_
<HOOMDDumpWriter
, boost::shared_ptr
<HOOMDDumpWriter
>, bases
<Analyzer
>, boost::noncopyable
>
591 ("HOOMDDumpWriter", init
< boost::shared_ptr
<SystemDefinition
>, std::string
>())
592 .def("setOutputPosition", &HOOMDDumpWriter::setOutputPosition
)
593 .def("setOutputImage", &HOOMDDumpWriter::setOutputImage
)
594 .def("setOutputVelocity", &HOOMDDumpWriter::setOutputVelocity
)
595 .def("setOutputMass", &HOOMDDumpWriter::setOutputMass
)
596 .def("setOutputDiameter", &HOOMDDumpWriter::setOutputDiameter
)
597 .def("setOutputType", &HOOMDDumpWriter::setOutputType
)
598 .def("setOutputBody", &HOOMDDumpWriter::setOutputBody
)
599 .def("setOutputBond", &HOOMDDumpWriter::setOutputBond
)
600 .def("setOutputAngle", &HOOMDDumpWriter::setOutputAngle
)
601 .def("setOutputDihedral", &HOOMDDumpWriter::setOutputDihedral
)
602 .def("setOutputImproper", &HOOMDDumpWriter::setOutputImproper
)
603 .def("setOutputWall", &HOOMDDumpWriter::setOutputWall
)
604 .def("setOutputAccel", &HOOMDDumpWriter::setOutputAccel
)
605 .def("setOutputCharge", &HOOMDDumpWriter::setOutputCharge
)
606 .def("setOutputOrientation", &HOOMDDumpWriter::setOutputOrientation
)
607 .def("setVizSigma", &HOOMDDumpWriter::setVizSigma
)
608 .def("writeFile", &HOOMDDumpWriter::writeFile
)
613 #pragma warning( pop )