VtkWriter.h 9.77 KB
Newer Older
1 2 3 4 5 6 7
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
8
 * Authors:
9 10 11 12 13 14 15 16 17
 * 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.
18
 *
19 20 21 22 23 24 25 26 27 28 29
 ******************************************************************************/



/** \file VtkVector.h */

#ifndef AMDIS_VTKWRITER_DETAIL_H
#define AMDIS_VTKWRITER_DETAIL_H

#include <string>
#include <vector>
30
#include <sstream>
31 32
// #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

namespace AMDiS  { namespace io {
40

41 42
    namespace VtkWriter
    {
43

44 45 46 47 48
      typedef enum{
	ASCII = 0,
	APPENDED = 1,
	APPENDED_COMPRESSED = 2
      } Vtuformat;
49

50 51
    }
  }
52

53
  // conversion function used in Initfile parser
54
  namespace detail
55 56
  {
    /// convert special enums
57
    inline void convert(const std::string valStr, ::AMDiS::io::VtkWriter::Vtuformat& value)
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    {
      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.");
      }
    }
73 74
  } // end namespace detail

75
  namespace io {
76

77 78
    namespace VtkWriter
    {
79

80
      using namespace std;
81 82

      // A class definition of a VtkWriter, to accept Datacollectors in
83 84 85 86
      // the constructor.
      class Aux
      {
      public:
87

88 89 90 91 92 93 94
	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;
	    }
95

96 97 98 99
	    inline bool isHighPrecision()
	    {
	      return highPrecision;
	    }
100

101 102 103 104 105
	    inline int getSize()
	    {
	      seekp(0, ios::end);
	      return boost::lexical_cast<int>(tellp());
	    }
106

107 108 109 110 111
	  private:
	    /// True: write data using FLOAT64; False: write data using FLOAT32.
	    bool highPrecision;
	};

112 113 114 115
	Aux(std::vector<DataCollector<>*> *dc,
	    std::vector<std::string>& names_,
	    Vtuformat f = ASCII,
	    bool hp = false,
Praetorius, Simon's avatar
Praetorius, Simon committed
116
	    bool writeAsVector_ = false)
117
	  : dataCollector(dc),
Praetorius, Simon's avatar
Praetorius, Simon committed
118 119 120
	    componentNames(names_),
	    bstream(hp),
	    writeAsVector(writeAsVector_)
121
	{
122
#ifndef AMDIS_HAS_COMPRESSION
123 124 125
	  FUNCNAME("VtkWriter::Aux::Aux()");
	  if(f == APPENDED_COMPRESSED) {
	    f = APPENDED;
126
	    WARNING("AMDIS_HAS_COMPRESSION OFF. So vtuformat is automatically changed from APPENDED_COMPRESSED to APPENDED.\n");
127 128
	  }
#endif
129
          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
	/// Writes all coordinates of vertices and interpolation points to an
152 153 154 155 156 157 158 159
	/// 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
	template<typename Stream>
169
	Stream& print(const WorldVector<double> &l, Stream &o)
Praetorius, Simon's avatar
Praetorius, Simon committed
170 171 172 173 174 175 176 177
	{
	  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;
	}
178

Praetorius, Simon's avatar
Praetorius, Simon committed
179
	template<typename Stream>
180
	Stream& print(const std::vector<double> &l, Stream &o)
Praetorius, Simon's avatar
Praetorius, Simon committed
181 182 183 184 185 186 187 188 189 190
	{
	  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>
191
	Stream& print(const T &value, Stream &o)
Praetorius, Simon's avatar
Praetorius, Simon committed
192 193 194 195 196
	{
	  o << (fabs(value) < 1e-40 ? 0.0 : value);
	  return o;
	}

197
      private:
198
	std::string getStreamData();
199

200 201
	/// List of DataCollectors, for each component of the problem one.
	std::vector<DataCollector<>*> *dataCollector;
202

Praetorius, Simon's avatar
Praetorius, Simon committed
203
	std::vector<std::string> componentNames;
204 205 206

	/// Degree of the basis function of the problem.
	int degree;
207

208 209
	/// Dimension of the geometry.
	int dim;
210

211 212
	/// 0:ascii mode; 1:append mode; 2:appended_compressed mode.
	Vtuformat format;
213

214
	/// The binary stream for filtering data. Only used in append and appended_compressed mode.
215 216
	BinaryStream bstream;

Praetorius, Simon's avatar
Praetorius, Simon committed
217 218
	/// write data-vectors as vector-valued component
	bool writeAsVector;
219
      };
220 221

      template <class T>
222 223 224 225
      Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const T& param)
      {
	return stream;
      }
226 227

      template <>
228
      inline Aux::BinaryStream& operator<< (Aux::BinaryStream& stream, const double& param)
229
      {
230
	double* param_ = const_cast<double*>(&param);
231

232 233 234 235 236
	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
	return stream;
      }
240 241

      template <>
242 243 244 245 246 247
      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;
      }
248 249

      template <>
250 251 252 253 254
      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;
255 256 257
      }

      template <>
258 259 260 261 262
      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;
263 264
      }

265 266 267 268 269 270 271
      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;
      }
272

273 274
      namespace detail
      {
275
// 	typedef
276 277 278
// 	  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
279
// 	    >
280
// 	  > binary_base64;
281
//
282
// 	std::string base64Encode(std::string text);
283

284
	std::string extract_relative_path(std::string valueFilename, std::string animationFilename);
285

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
			      const std::vector<std::string> &componentNames,
			      ::AMDiS::io::VtkWriter::Vtuformat format = ::AMDiS::io::VtkWriter::ASCII,
			      bool highPrecision = false,
298 299
			      bool writeAsVector = false,
			      bool createSubDir = false
300 301 302 303 304 305
			      );

	/// 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,
306
			      ::AMDiS::io::VtkWriter::Vtuformat format = ::AMDiS::io::VtkWriter::ASCII,
Praetorius, Simon's avatar
Praetorius, Simon committed
307
			      bool highPrecision = false,
308 309
			      bool writeAsVector = false,
			      bool createSubDir = false
Praetorius, Simon's avatar
Praetorius, Simon committed
310
			      );
311 312 313 314 315 316 317 318 319 320 321 322

	/// 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);
323

324 325 326 327 328 329
	/// Writes a world coordinate to a given file.
	template<typename OutputStream>
	void writeCoord(OutputStream &file, WorldVector<double> coord)
	{
	  file << std::scientific;
	  file.precision(15);
330

331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
	  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