VtkWriter.h 9.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
 * 
 ******************************************************************************/



/** \file VtkVector.h */

#ifndef AMDIS_VTKWRITER_DETAIL_H
#define AMDIS_VTKWRITER_DETAIL_H

#include <string>
#include <vector>
30
31
32
#include <sstream>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
33
34
35
36

#include "AdaptInfo.h"
#include "io/DataCollector.h"

37
#define AMDIS_ZLIB_BLOCK_SIZE 32768
38
39
40
41
42

namespace AMDiS  { namespace io {
  
    namespace VtkWriter
    {
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
      
      typedef enum{
	ASCII = 0,
	APPENDED = 1,
	APPENDED_COMPRESSED = 2
      } Vtuformat;
	  
    }
  }
  
  // conversion function used in Initfile parser
  namespace detail 
  {
    /// convert special enums
    inline void convert(const std::string valStr, ::AMDiS::io::VtkWriter::Vtuformat& value) 
    {
      using namespace ::AMDiS::io::VtkWriter;
      std::string swapStr = boost::to_upper_copy(valStr);

      value = static_cast< Vtuformat >(ASCII);
      if (swapStr == "ASCII")
        value = static_cast< Vtuformat >(ASCII);
      else if (swapStr == "APPENDED")
        value = static_cast< Vtuformat >(APPENDED);
      else if (swapStr == "APPENDED_COMPRESSED")
        value = static_cast< Vtuformat >(APPENDED_COMPRESSED);
      else {
        throw std::runtime_error("Unknown ParaView mode.");
      }
    }
  } // end namespace detail 
    
  namespace io {
  
    namespace VtkWriter
    {
      
      using namespace std;
      
82
83
84
85
86
      // A class definition of a VtkWriter, to accept Datacollectors in 
      // the constructor.
      class Aux
      {
      public:
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	
	class BinaryStream: public stringstream
	{
	  public:
	    explicit BinaryStream(bool hp = false, ios_base::openmode mode = ios_base::in | ios_base::out | ios_base::binary) :
	    stringstream(mode | ios_base::binary){
	      highPrecision = hp;
	    }
	    
	    inline bool isHighPrecision()
	    {
	      return highPrecision;
	    }
	    
	    inline int getSize()
	    {
	      seekp(0, ios::end);
	      return boost::lexical_cast<int>(tellp());
	    }
	    
	  private:
	    /// True: write data using FLOAT64; False: write data using FLOAT32.
	    bool highPrecision;
	};

Praetorius, Simon's avatar
Praetorius, Simon committed
112
113
114
115
116
	Aux(std::vector<DataCollector<>*> *dc, 
	    std::vector<std::string>& names_, 
	    Vtuformat f = ASCII, 
	    bool hp = false, 
	    bool writeAsVector_ = false)
117
	  : dataCollector(dc),
Praetorius, Simon's avatar
Praetorius, Simon committed
118
119
120
	    componentNames(names_),
	    bstream(hp),
	    writeAsVector(writeAsVector_)
121
	{
122
123
124
125
126
127
128
129
#ifndef HAVE_COMPRESSION
	  FUNCNAME("VtkWriter::Aux::Aux()");
	  if(f == APPENDED_COMPRESSED) {
	    f = APPENDED;
	    WARNING("HAVE_COMPRESSION OFF. So vtuformat is automatically changed from APPENDED_COMPRESSED to APPENDED.\n");
	  }
#endif
          degree = (*dataCollector)[0]->getFeSpace()->getBasisFcts()->getDegree();    
130
	  dim = (*dataCollector)[0]->getMesh()->getDim();
131
	  format = f;
132
133
134
135
	}  

	/// Writes a ParaView-VTK file.
	int writeFile(std::string name);
136
137
	
	void setFormat(Vtuformat f)
138
	{
139
	  format = f;
140
141
142
143
144
145
	}

      protected:
	/// Writes the VTK file to an arbitrary stream.
	template<typename T>
	void writeFileToStream(T &file);
146
147
148
149
	
	/// Writes tje VTL file to an arbitrary stream using appended mode.
	template<typename T>
	void writeFileToStreamAppended(T &file);
150
151
152
153
154
155
156
157
158
159

	/// Writes all coordinates of vertices and interpolation points to an 
	/// output file.
	template<typename T>
	void writeVertexCoords(T &file);

	/// Writes all values of vertices and interpolation point to an output file.
	template<typename T>
	void writeVertexValues(T &file, int componentNo);

Praetorius, Simon's avatar
Praetorius, Simon committed
160
161
162
163
	/// Writes all values of vertices and interpolation point as vector to an output file.
	template<typename T>
	void writeVertexValues(T &file);

164
165
166
	/// Writes the connectivity of all simplices to an output file.
	template<typename OutputStream>
	void writeConnectivity(OutputStream &file);
167
	
Praetorius, Simon's avatar
Praetorius, Simon committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	template<typename Stream>
	Stream& print(const WorldVector<double> &l, Stream &o) 
	{
	  for (size_t i = 0; i < static_cast<size_t>(l.getSize()); i++) {
	    o << (fabs(l[i]) < 1e-40 ? 0.0 : l[i]) << " ";
	  }
	  for (int i = l.getSize(); i < 3; i++)
	    o << 0.0 << " ";
	  return o;
	}
	
	template<typename Stream>
	Stream& print(const std::vector<double> &l, Stream &o) 
	{
	  for (size_t i = 0; i < l.size(); i++) {
	    o << (fabs(l[i]) < 1e-40 ? 0.0 : l[i]) << " ";
	  }
	  for (int i = l.size(); i < 3; i++)
	    o << 0.0 << " ";
	  return o;
	}

	template<typename T, typename Stream>
	Stream& print(const T &value, Stream &o) 
	{
	  o << (fabs(value) < 1e-40 ? 0.0 : value);
	  return o;
	}

      private:	
198
199
	std::string getStreamData();
      
200
201
	/// List of DataCollectors, for each component of the problem one.
	std::vector<DataCollector<>*> *dataCollector;
Praetorius, Simon's avatar
Praetorius, Simon committed
202
203
	
	std::vector<std::string> componentNames;
204
205
206
207
208
209

	/// Degree of the basis function of the problem.
	int degree;
	
	/// Dimension of the geometry.
	int dim;
210
211
212
213
214
215
	
	/// 0:ascii mode; 1:append mode; 2:appended_compressed mode.
	Vtuformat format;
	
	/// The binary stream for filtering data. Only used in append and appended_compressed mode.
	BinaryStream bstream; 
Praetorius, Simon's avatar
Praetorius, Simon committed
216
217
218
	
	/// write data-vectors as vector-valued component
	bool writeAsVector;
219
220
      };
      
221
222
223
224
225
      template <class T> 
      Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const T& param)
      {
	return stream;
      }
226
      
227
228
      template <> 
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const double& param)
229
      {
230
231
232
233
234
235
236
	double* param_ = const_cast<double*>(&param);
	
	if(stream.isHighPrecision()) {
	  stream.write(reinterpret_cast<char*>(param_), 8);
	} else {
	  float param__ = static_cast<float>(*param_);
	  stream.write(reinterpret_cast<char*>(&param__), 4);
237
	}
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
	return stream;
      }
      
      template <> 
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const uint64_t& param)
      {
	uint64_t* param_ = const_cast<uint64_t*>(&param);
	stream.write(reinterpret_cast<char*>(param_), 8);
	return stream;
      }
      
      template <> 
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const int& param)
      {
	int* param_ = const_cast<int*>(&param);
	stream.write(reinterpret_cast<char*>(param_), 4);
	return stream;
      }   
      
      template <> 
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const uint32_t& param)
      {
	uint32_t* param_ = const_cast<uint32_t*>(&param);
	stream.write(reinterpret_cast<char*>(param_), 4);
	return stream;
      }   
      
      template <>
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const uint8_t& param)
      {
	uint8_t* param_ = const_cast<uint8_t*>(&param);
	stream.write(reinterpret_cast<char*>(param_), 1);
	return stream;
      }
      
      namespace detail
      {
	typedef 
	  boost::archive::iterators::base64_from_binary<      // convert binary values to base64 characters
	    boost::archive::iterators::transform_width<       // retrieve 6 bit integers from a sequence of 8 bit bytes
	      std::string::const_iterator, 6, 8
	    > 
	  > binary_base64;
281

282
283
	std::string base64Encode(std::string text);
	
284
285
	std::string extract_relative_path(std::string valueFilename, std::string animationFilename);
	
286
287
288
289
290
291
292
293
294
	/// Adds a new entry to a ParaView animation file.
	int updateAnimationFile(AdaptInfo *adaptInfo,
				std::string valueFilename,
				std::vector< std::pair<double, std::string> > *paraViewAnimationFrames,
				std::string animationFilename);

	/// Writes a pvtu file, which contains the links to all the rank files.
	void writeParallelFile(std::string name, int nRanks,
			      std::string fnPrefix, std::string fnPostfix,
295
296
297
298
299
300
301
302
303
304
			      const std::vector<std::string> &componentNames,
			      ::AMDiS::io::VtkWriter::Vtuformat format = ::AMDiS::io::VtkWriter::ASCII,
			      bool highPrecision = false,
			      bool writeAsVector = false
			      );

	/// Writes a pvtu file which contains the links to the rank files in @subNames
	void writeParallelFile(std::string name, int nRanks,
			      std::vector<std::string>& subNames,
			      const std::vector<std::string> &componentNames,
305
			      ::AMDiS::io::VtkWriter::Vtuformat format = ::AMDiS::io::VtkWriter::ASCII,
Praetorius, Simon's avatar
Praetorius, Simon committed
306
307
308
			      bool highPrecision = false,
			      bool writeAsVector = false
			      );
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

	/// Writes the connectivity for the case dim = 2 and degree = 2 to an output file.
	template<typename S, typename OutputStream>
	void writeConnectivity_dim2_degree2(DataCollector<S>* dataCollector, OutputStream &file);

	/// Writes the connectivity for the case dim = 2 and degree = 3 to an output file.
	template<typename S, typename OutputStream>
	void writeConnectivity_dim2_degree3(DataCollector<S>* dataCollector, OutputStream &file);

	/// Writes the connectivity for the case dim = 2 and degree = 4 to an output file.
	template<typename S, typename OutputStream>
	void writeConnectivity_dim2_degree4(DataCollector<S>* dataCollector, OutputStream &file);
	
	/// Writes a world coordinate to a given file.
	template<typename OutputStream>
	void writeCoord(OutputStream &file, WorldVector<double> coord)
	{
	  file << std::scientific;
	  file.precision(15);
	  
	  for (int i = 0; i < Global::getGeo(WORLD); i++)
	    file << " " << coord[i];
	  for (int i = Global::getGeo(WORLD); i < 3; i++)
	    file << " "<<0.0;

	  file << "\n";
	}

      } // end namespace detail
    } // end namespace VtkWriter
} } // end namespace io, AMDiS

#include "VtkWriter.hh"

#endif // AMDIS_VTKWRITER_DETAIL_H