Tools/VTKData.h
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 #ifndef TOOLS_VTKDATA_H
27 #define TOOLS_VTKDATA_H
28 
29 #include <fstream>
30 #include <iostream>
31 #include <string>
32 #include <sstream>
33 #include <functional>
34 #include <map>
35 #include <vector>
36 #include <type_traits>
37 #include <cmath>
38 
39 //Namespace Detail contains black magic.
40 namespace Detail {
44  template<typename T>
46  {
47  std::string name_;
48  public:
53  VTKPointDescriptorEntry(std::string fieldName)
54  : name_(fieldName)
55  {
56  }
57 
59  {
60  }
61 
67  virtual void emit(std::ostream& out, const T& t) const = 0;
72  virtual std::string getTypeName() const = 0;
76  std::string getName() const
77  {
78  return name_;
79  }
83  virtual std::size_t getNumberOfComponents() const = 0;
84  };
85 
87  template<typename V>
88  typename std::enable_if<std::is_floating_point<V>::value, std::string>::type
90  {
91  return "Float32";
92  }
93 
94  template<typename V>
95  typename std::enable_if<std::is_integral<V>::value && std::is_unsigned<V>::value, std::string>::type
97  {
98  return "UInt32";
99  }
100 
101  template<typename V>
102  typename std::enable_if<std::is_integral<V>::value && std::is_signed<V>::value, std::string>::type
104  {
105  return "Int32";
106  }
107 
108  template<typename V>
109  typename std::enable_if<std::is_array<V>::value, std::string>::type
111  {
112  return toVTKDataType< typename std::remove_extent<V>::type >();
113  }
114 
115  template<typename V>
116  V round(V in) {
117  return in;
118  }
119 
120  template<>
121  double round(double in) {
122  //logger.assert_debug(fabs(in)>1e-33 or fabs(in)==0, "Detected underflow: corrected double value % to 0", in);
123  logger.assert_debug(std::isfinite(in), "Detected nans!");
124  return (fabs(in)<1e-33)?0.0:in;
125  }
126 
128  template<typename T, typename V>
129  typename std::enable_if<std::is_array<V>::value || std::is_pointer<V>::value, void>::type
130  emitProxy(std::ostream& out, const T& t, std::size_t nComponents, V T::*member)
131  {
132  for (std::size_t i = 0; i < nComponents; i++)
133  {
134  out << round((t.*member)[i]) << " ";
135  }
136  }
137 
138  template<typename T, typename V>
139  typename std::enable_if<!(std::is_array<V>::value || std::is_pointer<V>::value), void>::type
140  emitProxy(std::ostream& out, const T& t, std::size_t nComponents, V T::*member)
141  {
142  out << round(t.*member) << " ";
143  }
144 
148  template<typename T, typename V>
150  {
151  const V T::* member_;
152  const std::size_t nComponents_;
153  public:
154  VTKPointDescriptorEntryImpl(std::string name, V T::*member, std::size_t nComponents)
155  : VTKPointDescriptorEntry<T>(name), member_(member), nComponents_(nComponents)
156  { }
157 
158  std::string getTypeName() const override
159  {
160  return toVTKDataType<V>();
161  }
162 
163  void emit(std::ostream& out, const T& t) const override
164  {
165  emitProxy(out, t, nComponents_, member_);
166  }
167 
168  std::size_t getNumberOfComponents() const override
169  {
170  return nComponents_;
171  }
172  };
173 }
174 
183 template<typename T>
185 {
186  std::vector< Detail::VTKPointDescriptorEntry<T>* > entries_;
188  public:
190  {
191  }
192 
194  {
195  for (auto * d : entries_)
196  delete d;
197  }
198 
199  template<typename DATATYPE>
200  typename std::enable_if<std::is_array<DATATYPE>::value, VTKPointDescriptor&>::type
201  addProperty(std::string name, DATATYPE T::*m, bool isPrimary = false)
202  {
204  = new Detail::VTKPointDescriptorEntryImpl<T,DATATYPE>(name, m, std::extent<DATATYPE>::value);
205  entries_.push_back(data);
206  if (isPrimary)
207  positionEntry_ = entries_.back();
208 
209  return *this;
210  }
211 
212  template<typename DATATYPE>
213  typename std::enable_if<!std::is_array<DATATYPE>::value, VTKPointDescriptor&>::type
214  addProperty(std::string name, DATATYPE T::*m, bool isPrimary = false)
215  {
218  entries_.push_back(data);
219  if (isPrimary)
220  positionEntry_ = entries_.back();
221 
222  return *this;
223  }
224 
225  template<typename DATATYPE>
226  VTKPointDescriptor& addProperty(std::string name, DATATYPE T::*m, std::size_t nComponents, bool isPrimary = false)
227  {
230  entries_.push_back(data);
231  if (isPrimary)
232  positionEntry_ = entries_.back();
233 
234  return *this;
235  }
236 
237 
238  template<typename VT>
239  friend class VTKUnstructuredGrid;
240 };
241 
242 /* \brief VTKCollection output file writer
243 *
244 * This is templated by the VTKDescriptor DESCR.
245 * \param T the backing output type
246 */
248 {
249  std::ofstream outFile_;
252  std::size_t recordID_;
253 
254  void writeHeader()
255  {
256  outFile_ <<
257  "<?xml version=\"1.0\"?>\n"
258  "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
259  " <Collection>\n";
260  hasHeader_ = true;
261  }
262 
263  void writeFooter()
264  {
265  outFile_ <<
266  " </Collection>\n"
267  "</VTKFile>\n";
268  hasFooter_ = true;
269  }
270 
271  public:
272  VTKCollection(std::string fileName)
273  : outFile_(fileName), hasHeader_(false), hasFooter_(false), recordID_(0)
274  {
275  }
276 
278  {
279  if (hasHeader_ && !hasFooter_)
280  writeFooter();
281  }
282 
283  /* Returns true if the output file is valid and no error bits are set. */
284  operator bool() const
285  {
286  return outFile_.good();
287  }
288 
289  /* Appends the (relative) path to this index file. */
290  void append(std::string filename)
291  {
292  if (!hasHeader_)
293  writeHeader();
294 
295  outFile_ <<
296  "<DataSet group=\"\" part=\"0\" timestep=\"" << recordID_ << "\" file=\"" << filename << "\" />\n";
297 
298  recordID_++;
299  }
300 };
301 
306 template<typename T>
308 {
310  std::ofstream outFile_;
311  public:
316  VTKUnstructuredGrid(std::string filename, const VTKPointDescriptor<T>* descr)
317  : descriptor_(descr), outFile_(filename)
318  {
319  }
320 
322  operator bool() const
323  {
324  return outFile_.good();
325  }
326 
332  template<typename C>
333  void write(const C& container)
334  {
335  outFile_ <<
336  "<?xml version=\"1.0\"?>\n"
337  "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
338  " <UnstructuredGrid>\n"
339  " <Piece NumberOfPoints=\"" << container.size() << "\" NumberOfCells=\"0\">\n"
340  " <Cells>\n"
341  " <DataArray type=\"Int32\" name=\"connectivity\" format=\"ascii\">\n"
342  " 0\n"
343  " </DataArray>\n"
344  " <DataArray type=\"Float32\" name=\"offset\" format=\"ascii\">\n"
345  " 0\n"
346  " </DataArray>\n"
347  " <DataArray type=\"UInt8\" name=\"types\" format=\"ascii\">\n"
348  " 1\n"
349  " </DataArray>\n"
350  " </Cells>\n"
351  " <Points>\n";
352  Detail::VTKPointDescriptorEntry<T>* pDescr = descriptor_->positionEntry_;
353  outFile_ << "<DataArray type=\"" << pDescr->getTypeName() << "\" "
354  "NumberOfComponents=\"" << pDescr->getNumberOfComponents() << "\" "
355  "format=\"ascii\">\n";
356  for (const T& mem : container)
357  {
358  pDescr->emit(outFile_, mem);
359  }
360  outFile_ << "\n</DataArray>\n";
361 
362  outFile_ <<
363  " </Points>\n"
364  " <PointData>\n";
365 
366  for (Detail::VTKPointDescriptorEntry<T>* descr : descriptor_->entries_)
367  {
368  outFile_ << "<DataArray type=\"" << descr->getTypeName() << "\" "
369  "Name=\"" << descr->getName() << "\" "
370  "NumberOfComponents=\"" << descr->getNumberOfComponents() << "\" "
371  "format=\"ascii\">\n";
372  for (const T& mem : container)
373  {
374  descr->emit(outFile_, mem);
375  }
376  outFile_ << "\n</DataArray>\n";
377  }
378  outFile_ <<
379  " </PointData>\n"
380  " <CellData/>\n"
381  " </Piece>\n"
382  " </UnstructuredGrid>\n"
383  "</VTKFile>\n";
384  }
385 };
386 
387 #endif
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
Definition: Tools/VTKData.h:150
const std::size_t nComponents_
Definition: Tools/VTKData.h:152
std::size_t getNumberOfComponents() const override
Returns the number of components in this type.
Definition: Tools/VTKData.h:168
void emit(std::ostream &out, const T &t) const override
writes this VTKData to the given output stream for a single T
Definition: Tools/VTKData.h:163
std::string getTypeName() const override
Gives the VTKDataType for VTK.
Definition: Tools/VTKData.h:158
VTKPointDescriptorEntryImpl(std::string name, V T::*member, std::size_t nComponents)
Definition: Tools/VTKData.h:154
const V T::* member_
Definition: Tools/VTKData.h:151
Definition: Tools/VTKData.h:46
std::string name_
Definition: Tools/VTKData.h:47
virtual ~VTKPointDescriptorEntry()
Definition: Tools/VTKData.h:58
std::string getName() const
Returns the name associated with this field.
Definition: Tools/VTKData.h:76
virtual void emit(std::ostream &out, const T &t) const =0
writes this VTKData to the given output stream for a single T
virtual std::size_t getNumberOfComponents() const =0
Returns the number of components in this type.
VTKPointDescriptorEntry(std::string fieldName)
initialises this data member with given name.
Definition: Tools/VTKData.h:53
virtual std::string getTypeName() const =0
Gives the VTKDataType for VTK.
Definition: Tools/VTKData.h:248
VTKCollection(std::string fileName)
Definition: Tools/VTKData.h:272
std::ofstream outFile_
Definition: Tools/VTKData.h:249
bool hasHeader_
Definition: Tools/VTKData.h:250
~VTKCollection()
Definition: Tools/VTKData.h:277
void writeFooter()
Definition: Tools/VTKData.h:263
std::size_t recordID_
Definition: Tools/VTKData.h:252
bool hasFooter_
Definition: Tools/VTKData.h:251
void append(std::string filename)
Definition: Tools/VTKData.h:290
void writeHeader()
Definition: Tools/VTKData.h:254
Definition: Tools/VTKData.h:185
std::enable_if<!std::is_array< DATATYPE >::value, VTKPointDescriptor & >::type addProperty(std::string name, DATATYPE T::*m, bool isPrimary=false)
Definition: Tools/VTKData.h:214
Detail::VTKPointDescriptorEntry< T > * positionEntry_
Definition: Tools/VTKData.h:187
VTKPointDescriptor()
Definition: Tools/VTKData.h:189
~VTKPointDescriptor()
Definition: Tools/VTKData.h:193
std::vector< Detail::VTKPointDescriptorEntry< T > * > entries_
Definition: Tools/VTKData.h:186
VTKPointDescriptor & addProperty(std::string name, DATATYPE T::*m, std::size_t nComponents, bool isPrimary=false)
Definition: Tools/VTKData.h:226
std::enable_if< std::is_array< DATATYPE >::value, VTKPointDescriptor & >::type addProperty(std::string name, DATATYPE T::*m, bool isPrimary=false)
Definition: Tools/VTKData.h:201
Definition: Tools/VTKData.h:308
const VTKPointDescriptor< T > * descriptor_
Definition: Tools/VTKData.h:309
VTKUnstructuredGrid(std::string filename, const VTKPointDescriptor< T > *descr)
Definition: Tools/VTKData.h:316
std::ofstream outFile_
Definition: Tools/VTKData.h:310
void write(const C &container)
Definition: Tools/VTKData.h:333
Definition: MpiContainer.h:91
V round(V in)
Definition: Tools/VTKData.h:116
std::enable_if< std::is_floating_point< V >::value, std::string >::type toVTKDataType()
Definition: Tools/VTKData.h:89
std::enable_if< std::is_array< V >::value||std::is_pointer< V >::value, void >::type emitProxy(std::ostream &out, const T &t, std::size_t nComponents, V T::*member)
This function actually writes the correct datatype to ostream.
Definition: Tools/VTKData.h:130
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
std::string name
Definition: MercuryProb.h:48