text: #include "tarch/plotter/griddata/regular/vtk/VTKTextFileWriter.h"
  
  #include "tarch/parallel/NodePool.h"
  
  #include <stdio.h>
  #include <fstream>
  #include <iomanip>
  
  
  
  const std::string tarch::plotter::griddata::regular::vtk::VTKTextFileWriter::HEADER =
    "# vtk DataFile Version 2.0\n "\
    "Generated by Peano2 output component $Revision: 1.2 $ Author: Atanas Atanasov\n "\
    "ASCII\n ";
  
  
  tarch::plotter::griddata::regular::vtk::VTKTextFileWriter::VTKTextFileWriter(
    const tarch::la::Vector<2,int>&     numberOfGridPoints,
    const tarch::la::Vector<2,double>&  domainSize,
    const tarch::la::Vector<2,double>&  origin,
    const int precision
  ):
    tarch::plotter::griddata::regular::CartesianGridArrayWriter(
      numberOfGridPoints,
      domainSize,
      origin
    ),
    _precision(precision),
    _doubleOrFloat(setDoubleOrFloatString(precision)){}
  
  
  
  tarch::plotter::griddata::regular::vtk::VTKTextFileWriter::VTKTextFileWriter(
    const tarch::la::Vector<3,int>&     numberOfGridPoints,
    const tarch::la::Vector<3,double>&  domainSize,
    const tarch::la::Vector<3,double>&  origin,
    const int precision
  ):
    tarch::plotter::griddata::regular::CartesianGridArrayWriter(
      numberOfGridPoints,
      domainSize,
      origin
    ),
    _precision(precision),
    _doubleOrFloat(setDoubleOrFloatString(precision)){}
  
  
  tarch::plotter::griddata::regular::vtk::VTKTextFileWriter::~VTKTextFileWriter() {
  }
  
  
  bool tarch::plotter::griddata::regular::vtk::VTKTextFileWriter::writeToFile( const std::string& filenamePrefix ) {
    logTraceInWith5Arguments( "writeToFile(filename)", filenamePrefix, _writtenToFile, _numberOfGridPoints, _domainSize, _origin );
  
    if (filenamePrefix.rfind(".vtk")!=std::string::npos) {
      logWarning( "writeToFile()", "filename should not end with .vtk as routine adds extension automatically. Chosen filename prefix=" << filenamePrefix );
    }
    std::ostringstream filenameStream;
    filenameStream << filenamePrefix
      #ifdef Parallel
                   << "-rank-" << tarch::parallel::Node::getInstance().getRank()
      #endif
                   << ".vtk";
    const std::string filename = filenameStream.str();
  
    std::ofstream out;
    out.open( filename.c_str() );
    if ( (!out.fail()) && out.is_open() ) {
      _log.debug( "close()", "opened data file " + filename );
      out << std::setprecision(_precision);
  
      out << HEADER << std::endl << std::endl;
  
      out << "DATASET STRUCTURED_POINTS" << std::endl
          << "DIMENSIONS  "
            << _numberOfGridPoints(0) << " "
            << _numberOfGridPoints(1) << " "
            << _numberOfGridPoints(2)
            << std::endl << std::endl;
      out << "ORIGIN "
            << _origin(0) << " "
            << _origin(1) << " "
            << _origin(2)
            << std::endl << std::endl;
      out << "SPACING "
            << getH()(0) << " "
            << getH()(1) << " "
            << getH()(2)
            << std::endl << std::endl;
  
      assertion(getH()(0)>0);
      assertion(getH()(1)>0);
      assertion(getH()(2)>=0);
  
      if (!_vertexData.empty()) {
        out << "POINT_DATA " << tarch::la::volume(_numberOfGridPoints) << std::endl << std::endl;
  
        for (int i=0; i<static_cast<int>(_vertexData.size()); i++) {
      	if (_vertexData[i]._recordsPerEntry == 3) {
            out << "VECTORS " << _vertexData[i]._identifier << " " << _doubleOrFloat << " " << std::endl;
      	}
      	else {
            out << "SCALARS " << _vertexData[i]._identifier << " " << _doubleOrFloat << " " << _vertexData[i]._recordsPerEntry << std::endl;
            out << "LOOKUP_TABLE default" << std::endl;
      	}
          for (int j=0; j<tarch::la::volume(_numberOfGridPoints); j++) {
            for (int k=0; k<_vertexData[i]._recordsPerEntry; k++) {
              out << _vertexData[i]._data[j*_vertexData[i]._recordsPerEntry+k] << " ";
            }
            out << std::endl;
          }
          out << std::endl << std::endl;
        }
      }
      if (!_cellData.empty()) {
        out << "CELL_DATA " << tarch::la::volume(_numberOfGridPoints-1) << std::endl << std::endl;
  
        for (int i=0; i<static_cast<int>(_cellData.size()); i++) {
          if (_cellData[i]._recordsPerEntry == 3) {
            out << "VECTORS " << _cellData[i]._identifier << " " << _doubleOrFloat << " " << std::endl;
          }
          else {
            out << "SCALARS " << _cellData[i]._identifier << " " << _doubleOrFloat << " " << _cellData[i]._recordsPerEntry << std::endl;
          }
          for (int j=0; j<tarch::la::volume(_numberOfGridPoints-1); j++) {
            for (int k=0; k<_cellData[i]._recordsPerEntry; k++) {
              out << _cellData[i]._data[j*_cellData[i]._recordsPerEntry+k] << " ";
            }
            out << std::endl;
          }
          out << std::endl << std::endl;
        }
      }
  
      _writtenToFile = true;
      logTraceOut( "writeToFile(filename)" );
      return true;
    }
    else {
      logError( "writeToFile(filename)", "failed to write to file " << filename );
      logTraceOut( "writeToFile(filename)" );
      return false;
    }
  }
  