MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
data2pvd.cpp
Go to the documentation of this file.
1 //Copyright (c) 2015, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #include <iostream>
27 #include <fstream>
28 
29 #include <Logger.h>
30 
31 #include "MercuryData.h"
32 #include "VTKData.h"
33 
35 template<std::size_t NDIMS>
36 int transformMercuryToVTK(MercuryDataFile& file, std::string prefix);
37 
38 /*
39 * This program converts Mercury .data files to ParaView
40 * .pvd and VTK .vtu XML-files. Every timestep is written to
41 * an independent .vtu Unstructured Grid file.
42 *
43 * Because of ParaView limitations, the actual time information
44 * is discarded; Using the timestep attribute of the DataSet
45 * element in the main .pvd file does not produce desired
46 * results.
47 *
48 */
49 
50 int main(int argc, char** argv)
51 {
52  //Check to see if we actually received two arguments
53  if (argc != 3)
54  {
55  //We didn't. Print a usage and exit the program.
56  logger(FATAL, "Usage: % [infile] [outfilePrefix]\n"
57  " This program converts MercuryDPM .data files to ParaView .pvd data files.\n"
58  " which can then be used directly into ParaView, to visualize your particles.\n"
59  "\n"
60  " infile: MercuryDPM .data file\n"
61  "\n"
62  " outfilePrefix: Prefix to prepend to the output files generated.\n"
63  " The following files will be generated:\n"
64  " - prefix.pvd\n"
65  " - prefix_0.vtu\n"
66  " - prefix_1.vtu\n"
67  " ( ... )\n"
68  " - prefix_987654321.vtu\n"
69  " depending on the amount of timesteps.", argv[0]);
70  }
71 
72  // Open our Mercury 3D data file.
73  MercuryDataFile infile(argv[1]);
74 
75  // Was it readable?
76  if (!infile)
77  {
78  logger(FATAL, "Could not open ''%' for input.\n"
79  "Please make sure the file exists and you have the appropriate rights.", argv[1]);
80  }
81  //make sure we don't end in a slash, as this both breaks the creation of a relative path right now,
82  //and it's really not what you want to end up with...
83  if (std::string(argv[2]).back() == '/')
84  {
85  logger(ERROR, "The output prefix ends in a slash. This is not allowed.");
86  }
87 
88  //And were we using a 3D file format?
89  if (infile.isMercuryDataFile<3>())
90  {
91  logger(VERBOSE, "Assuming 3D data format.");
92  return transformMercuryToVTK<3>(infile, argv[2]);
93  }//Or a 2d format?
94  else if (infile.isMercuryDataFile<2>())
95  {
96  logger(VERBOSE, "Assuming 2D data format.");
97  return transformMercuryToVTK<2>(infile, argv[2]);
98  }//halp...
99  else
100  {
101  logger(ERROR, "The file '%' does not seem to be a Mercury .data file.\n"
102  "Please make sure you are reading the correct file.", argv[1]);
103  return 4;
104  }
105 }
106 
110 template<std::size_t NDIMS>
111 int transformMercuryToVTK(MercuryDataFile& infile, std::string prefix)
112 {
113  //We really want to describe our exit code.
114  int exitCode = 0;
115 
116  //We'll set up a descriptor.
117  //Let the compiler figure out what the types / dimensions are, that's too
118  //much work anyway. Oh and make sure position is used as both a datafield
119  //and the actual position of the object.
121  descriptor
122  .addProperty( "Position", & MercuryParticle< NDIMS >::position , true)
123  .addProperty( "Velocity", & MercuryParticle< NDIMS >::velocity )
124  .addProperty( "Rotation", & MercuryParticle< NDIMS >::rotation )
125  .addProperty( "AngVelocity", & MercuryParticle< NDIMS >::angularV )
126  .addProperty( "Radius", & MercuryParticle< NDIMS >::radius )
127  .addProperty( "Species", & MercuryParticle< NDIMS >::speciesID );
128 
129  // We want a Collection file which lists all individual files
130  VTKCollection collection( prefix + ".pvd" );
131  // First, make sure it is sane.
132  if (!collection)
133  logger( FATAL, "Could not open '%.pvd' for output.\n"
134  "Please make sure you have the appropriate permissions and try again.", prefix);
135 
136  std::size_t timestepCount = 0;
137 
138  //Now, read all the timesteps as if they were NDIMS long.
139  for (const MercuryTimeStep<NDIMS> & ts : infile.as<NDIMS>())
140  {
141  //Generate the filename for the individual data files.
142  std::ostringstream filename;
143  filename << prefix << '_' << ts.getTimeStepID() << ".vtu";
144 
145  //We'll set up a datafile containing the individual timestep.
146  VTKUnstructuredGrid< MercuryParticle<NDIMS> > timeStepFile(filename.str(), &descriptor);
147  if (!timeStepFile) //but not after we've done some sanity checking!
148  {
149  logger(WARN, "Could not open '%' for output.\n"
150  "Please make sure you have the appropriate permissions and try again.", filename.str());
151  exitCode = 6;
152  break;
153  }
154 
155  if (!infile) //Some sanity checking? More sanity checking! ALL the sanity checking!!!
156  {
157  logger(WARN, "An IOError occurred during the reading of the input file.\n"
158  "Please make sure you are feeding this tool mercury data files.");
159  exitCode = 5;
160  break;
161  }
162  //Okay. we done.
163  //Let's write.
164  timeStepFile.write(ts);
165 
166  //So, a user may give an output path which is in a different directory.
167  // However, since the index files resides in the same output directory
168  // as the timestep files, we need to specify relative paths.
169  std::string strippedPath = filename.str();
170  //so, we try to find the last / - because to hell with everybody with other
171  //path seperators...
172  std::string::size_type slashPosition = strippedPath.rfind('/');
173  //and take only the last part. It's not the last character, trust me.
174  //we checked for that in main().
175  if (slashPosition != std::string::npos)
176  strippedPath = strippedPath.substr(slashPosition + 1);
177  //And now put the relative path in the listing file
178  collection.append(strippedPath);
179 
180  timestepCount++;
181  }
182 
183  logger(INFO, "Written % timesteps in a %D system.", timestepCount, NDIMS);
184 
185  return exitCode;
186 }
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
LL< Log::INFO > INFO
Info log level.
Definition: Logger.cc:53
IteratorProxy< NDIMS > as()
Definition: MercuryData.h:525
bool isMercuryDataFile()
Checks if this file is a valid Mercury 3D data file. This function jumps to the start of the file...
Definition: MercuryData.h:470
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:51
LL< Log::WARN > WARN
Warning log level.
Definition: Logger.cc:52
void append(std::string filename)
Definition: VTKData.h:277
LL< Log::FATAL > FATAL
Fatal log level.
Definition: Logger.cc:50
LL< Log::VERBOSE > VERBOSE
Verbose information.
Definition: Logger.cc:55
std::enable_if< std::is_array< DATATYPE >::value, VTKPointDescriptor & >::type addProperty(std::string name, DATATYPE T::*m, bool isPrimary=false)
Definition: VTKData.h:188
int transformMercuryToVTK(MercuryDataFile &file, std::string prefix)
Templated version to automagically generate VTK output files.
Definition: data2pvd.cpp:111
int main(int argc, char **argv)
Definition: data2pvd.cpp:50