Skip to content
Snippets Groups Projects
FileWriter.hh 7.67 KiB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.

/** \file FileWriter.hh */

#ifndef AMDIS_FILEWRITER_HH
#define AMDIS_FILEWRITER_HH

#include "boost/lexical_cast.hpp"
#include "FileWriter.h"
#include "Initfile.h"
#include "ValueWriter.h"
#include "MacroWriter.h"
#include "VtkWriter.h"
#include "VtkVectorWriter.h"
#include "VtkVectorWriter.hh"
#include "PngWriter.h"
#include "PovrayWriter.h"
#include "DofWriter.h"
#include "ArhWriter.h"
#include "FiniteElemSpace.h"
#include "AdaptInfo.h"
#include "Flag.h"
#include "ElInfo.h"
#include "Mesh.h"
#include "SystemVector.h"
#include "DataCollector.hh"

#if HAVE_PARALLEL_DOMAIN_AMDIS
#include <mpi.h>
#endif

namespace AMDiS {

  using boost::lexical_cast;

  template<typename T>
  FileWriterTemplated<T>::FileWriterTemplated(std::string str, Mesh *m, DOFVector<T> *vec)
    : name(str),
      mesh(m)
  {
    FUNCNAME("FileWriterTemplated<T>::FileWriter()");

    initialize();

    feSpace = vec->getFeSpace();

    solutionVecs.resize(1);
    solutionVecs[0] = vec;
  }


  template<typename T>
  FileWriterTemplated<T>::FileWriterTemplated(std::string name_,
			 Mesh *mesh_, 
			 std::vector<DOFVector<T>*> vecs)
    : name(name_),
      mesh(mesh_)
  {
    FUNCNAME("FileWriterTemplated<T>::FileWriterTemplated()");

    initialize();

    for (int i = 0; i < static_cast<int>(vecs.size()); i++)
      TEST_EXIT(vecs[0]->getFeSpace() == vecs[i]->getFeSpace())
	("All FeSpace have to be equal!\n");

    feSpace = vecs[0]->getFeSpace();
    solutionVecs = vecs;
  }


  template<typename T>
  FileWriterTemplated<T>::FileWriterTemplated(std::string name_,
			 Mesh *mesh_,
			 SystemVector *vecs)
    : name(name_),
      mesh(mesh_)
  {
    ERROR("SystemVector contains DOFVectors of type double, so the FileWriterTemplated<not double> can not be used!\n");
  }


  template<typename T>
  FileWriterTemplated<T>::~FileWriterTemplated()
  {
    // Do not forget to delete temporal solution vector, if there have been
    // some created in the constructor.
    if (nTmpSolutions > 0)
      for (int i = 0; i < nTmpSolutions; i++)
        delete solutionVecs[i]; 
  }
  

  template<typename T>
  void FileWriterTemplated<T>::initialize()
  {
    amdisMeshExt = ".mesh";
    amdisDataExt = ".dat";
    paraviewFileExt = ".vtu";
    paraviewParallelFileExt = ".pvtu";
    periodicFileExt = ".per";
    writeAMDiSFormat = 0;
    writeParaViewFormat = 0;
    writeParaViewVectorFormat = 0;
    writeAs3dVector = false;
    writeParaViewAnimation = 0;
    writePeriodicFormat = 0;
    writePngFormat = 0;
    writePovrayFormat = 0;
    writeDofFormat = 0;
    writeArhFormat = 0;
    pngType = 0;
    appendIndex = 0;
    indexLength = 5;
    indexDecimals = 3;
    tsModulo = 1;
    nTmpSolutions = 0;
    paraviewAnimationFrames.resize(0),
    compression = NONE;

    readParameters();
  }


  template<typename T>
  void FileWriterTemplated<T>::readParameters()
  {
    FUNCNAME("FileWriterTemplated<T>::readParamters()");

    Parameters::get(name + "->filename", filename);
    Parameters::get(name + "->AMDiS format", writeAMDiSFormat);
    Parameters::get(name + "->AMDiS mesh ext", amdisMeshExt);
    Parameters::get(name + "->AMDiS data ext", amdisDataExt);
    Parameters::get(name + "->ParaView format", writeParaViewFormat);
    Parameters::get(name + "->ParaView vector format", writeParaViewVectorFormat);
    Parameters::get(name + "->write vector as 3d vector", writeAs3dVector);
    Parameters::get(name + "->ParaView animation", writeParaViewAnimation);
    Parameters::get(name + "->ParaView ext", paraviewFileExt);    
    Parameters::get(name + "->Periodic format", writePeriodicFormat);
    Parameters::get(name + "->Periodic ext", periodicFileExt);
    Parameters::get(name + "->PNG format", writePngFormat);
    Parameters::get(name + "->PNG type", pngType);
    Parameters::get(name + "->append index", appendIndex);
    Parameters::get(name + "->index length", indexLength);
    Parameters::get(name + "->index decimals", indexDecimals);
    Parameters::get(name + "->write every i-th timestep", tsModulo);

    Parameters::get(name + "->Povray format", writePovrayFormat);
    Parameters::get(name + "->Povray template", povrayTemplate);
    Parameters::get(name + "->Povray camera location", povrayCameraLocation);
    Parameters::get(name + "->Povray camera look_at", povrayCameraLookAt);

    Parameters::get(name + "->DOF format", writeDofFormat);
    Parameters::get(name + "->ARH format", writeArhFormat);

    std::string compressionStr = "";
    Parameters::get(name + "->compression", compressionStr);
    if (compressionStr == "gzip" || compressionStr == "gz") {
      compression = GZIP;
    } else if (compressionStr == "bzip2" || compressionStr == "bz2") {
      compression = BZIP2;
    }
  }


  template<typename T>
  void FileWriterTemplated<T>::writeFiles(AdaptInfo *adaptInfo,
			      bool force,
			      int level,
			      Flag flag,
			      bool (*writeElem)(ElInfo*))
  {
    FUNCNAME("FileWriterTemplated<T>::writeFiles()");

    if ((adaptInfo->getTimestepNumber() % tsModulo != 0) && !force) 
      return;

    // Containers, which store the data to be written;
    std::vector<DataCollector<T>*> dataCollectors(solutionVecs.size());

    if (writeElem) {
      for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
	dataCollectors[i] = new DataCollector<T>(feSpace, solutionVecs[i], 
					      level, flag, writeElem);
    } else {
      for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
	dataCollectors[i] = new DataCollector<T>(feSpace, solutionVecs[i], 
					      traverseLevel, 
					      flag | traverseFlag, 
					      writeElement);
    }

    std::string fn = filename;

#if HAVE_PARALLEL_DOMAIN_AMDIS
    std::string paraFilename = fn;
    fn += "-p" + lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-";
    std::string postfix = "";
#endif

    if (appendIndex) {
      TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
      TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
      TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
    
      char formatStr[9];
      char timeStr[20];

      sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
      sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);

      fn += timeStr;
#if HAVE_PARALLEL_DOMAIN_AMDIS
      paraFilename += timeStr;
      postfix += timeStr + paraviewFileExt;
#endif
    } else {
#if HAVE_PARALLEL_DOMAIN_AMDIS
      postfix += paraviewFileExt;
#endif
    }

    if (writeParaViewVectorFormat) {
      VtkVectorWriter::Impl<T> vtkVectorWriter(&dataCollectors, writeAs3dVector);
      vtkVectorWriter.setCompression(compression);
      vtkVectorWriter.writeFile(fn + paraviewFileExt);

#if HAVE_PARALLEL_DOMAIN_AMDIS
      if (MPI::COMM_WORLD.Get_rank() == 0)
	vtkVectorWriter.writeParallelFile(paraFilename + paraviewParallelFileExt,
					  MPI::COMM_WORLD.Get_size(),
					  filename, postfix);
#endif
	
      MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str());
    }
    
    if (writeParaViewAnimation) {
#if HAVE_PARALLEL_DOMAIN_AMDIS
      if (MPI::COMM_WORLD.Get_rank() == 0) {
	VtkWriter::updateAnimationFile(adaptInfo,
				      paraFilename + paraviewParallelFileExt,
				      &paraviewAnimationFrames,
				      filename + ".pvd");

      }
#else
      VtkWriter::updateAnimationFile(adaptInfo,
				    fn + paraviewFileExt,
				    &paraviewAnimationFrames,
				    filename + ".pvd");
#endif
    }
    
    for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
      delete dataCollectors[i];
  }
}

#endif