From 7acfe3ad94a386c0a5be06d6afbb76fba141a442 Mon Sep 17 00:00:00 2001
From: Siqi Ling <lsq0473@gmail.com>
Date: Tue, 20 Oct 2015 16:02:02 +0000
Subject: [PATCH] add write tarh

---
 AMDiS/src/io/Arh3Reader.h         |  4 +++
 AMDiS/src/io/FileWriter.cc        | 14 ++++++++
 AMDiS/src/io/FileWriter.h         | 11 ++++++
 AMDiS/src/io/FileWriter.hh        |  5 ++-
 AMDiS/src/io/detail/Arh3Reader.cc |  7 ++--
 AMDiS/src/io/detail/Arh3Writer.cc | 56 +++++++++++++++++++++++++++++--
 AMDiS/src/io/detail/Arh3Writer.h  |  8 +++++
 7 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/AMDiS/src/io/Arh3Reader.h b/AMDiS/src/io/Arh3Reader.h
index ae73d1df..f83e6f9d 100644
--- a/AMDiS/src/io/Arh3Reader.h
+++ b/AMDiS/src/io/Arh3Reader.h
@@ -25,6 +25,10 @@ namespace AMDiS { namespace io {
   {
     const uint8_t MAJOR = 3;
     const uint8_t MINOR = 0;
+    const uint8_t PARH_MAJOR = 1;
+    const uint8_t PARH_MINOR = 0;
+    const uint8_t TARH_MAJOR = 1;
+    const uint8_t TARH_MINOR = 0;
   
     /** 
      * \brief Read MeshStructure, refine the mesh and read dof values to sysVec by order.
diff --git a/AMDiS/src/io/FileWriter.cc b/AMDiS/src/io/FileWriter.cc
index c2b39ee4..77e25e6a 100644
--- a/AMDiS/src/io/FileWriter.cc
+++ b/AMDiS/src/io/FileWriter.cc
@@ -197,6 +197,20 @@ namespace AMDiS
 					filename + ".pvd");
 	}
       }
+      
+      if (writeArhAnimation) {
+#if HAVE_PARALLEL_DOMAIN_AMDIS
+	if (MPI::COMM_WORLD.Get_rank() == 0)
+#endif	
+	{
+	  Arh3Writer::detail::updateAnimationFile(adaptInfo, 
+						  &arhAnimationFrames,
+						  createSubDir > 0,
+						  indexLength,
+						  indexDecimals,
+						  filename + ".tarh");
+	}
+      }
   
 
       if (writeDofFormat) {
diff --git a/AMDiS/src/io/FileWriter.h b/AMDiS/src/io/FileWriter.h
index 2341b46f..5d9f845d 100644
--- a/AMDiS/src/io/FileWriter.h
+++ b/AMDiS/src/io/FileWriter.h
@@ -83,6 +83,11 @@ namespace AMDiS {
       {
 	return paraviewAnimationFrames;
       }
+      
+      std::vector<double>& getArhAnimationFrames()
+      {
+	return arhAnimationFrames;
+      }
 
       bool getWriteParaViewFormat() const 
       { 
@@ -177,6 +182,9 @@ namespace AMDiS {
       
       /// write Arh2 version 3.0,  prior to writeArhFormat
       int writeArh3;
+      
+      /// 0: Don't write Arh animation file; 1: Write Arh animation file.
+      int writeArhAnimation;
 
       /// camera position for povray script files
       std::string povrayCameraLocation;
@@ -191,6 +199,9 @@ namespace AMDiS {
       /// Stores a set of std::pairs of timepoint and filename to write a ParaView 
       /// animation file.
       std::vector<std::pair<double, std::string> > paraviewAnimationFrames;
+      
+      /// Stores a set of timepoint to write a ParaView animation file.
+      std::vector<double> arhAnimationFrames;
 
       ///
       int timestepNumber;
diff --git a/AMDiS/src/io/FileWriter.hh b/AMDiS/src/io/FileWriter.hh
index b060e9ca..74ef0743 100644
--- a/AMDiS/src/io/FileWriter.hh
+++ b/AMDiS/src/io/FileWriter.hh
@@ -142,9 +142,11 @@ namespace AMDiS
       writeArh1 = 0;
       writeArh2 = 0;
       writeArh3 = 0;
+      writeArhAnimation = 0;
       pngType = 0;
       nTmpSolutions = 0;
-      paraviewAnimationFrames.resize(0),
+      paraviewAnimationFrames.resize(0);
+      arhAnimationFrames.resize(0);
       compression = NONE;
 
       readParameters(name);
@@ -181,6 +183,7 @@ namespace AMDiS
       Parameters::get(name + "->ARH1 format", writeArh1);
       Parameters::get(name + "->ARH2 format", writeArh2);
       Parameters::get(name + "->ARH3 format", writeArh3);
+      Parameters::get(name + "->Arh animation", writeArhAnimation);
 
       std::string compressionStr = "";
       Parameters::get(name + "->compression", compressionStr);
diff --git a/AMDiS/src/io/detail/Arh3Reader.cc b/AMDiS/src/io/detail/Arh3Reader.cc
index 3cbe5b6c..38285fdb 100644
--- a/AMDiS/src/io/detail/Arh3Reader.cc
+++ b/AMDiS/src/io/detail/Arh3Reader.cc
@@ -573,7 +573,7 @@ namespace AMDiS { namespace io {
 	  sPos = file_onlyname.string().find(".arh");
 	  string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
 	  string parh = filenameWithoutExt + ".parh";
-	  string basedir = "";
+	  string basedir = "./";
 	  path file_path = file_name.remove_filename();
 	  
 	  int nProcs_ = 0, nMacros_ = 0, nMacros = 0;
@@ -583,8 +583,7 @@ namespace AMDiS { namespace io {
 	  if (parhExists)
 	    basedir = readParallelFile(parh, partition, nProcs_, nMacros_);
 
-	  if (basedir != "")
-	    filenameWithoutExt = file_path.string() + '/' + basedir + onlynameWithoutExt;
+	  filenameWithoutExt = file_path.string() + '/' + basedir + onlynameWithoutExt;
 	    
 	  if (nProcs == -1) {
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -848,7 +847,7 @@ namespace AMDiS { namespace io {
 	string Id = fd.substr(0, 4);
 	int major = boost::lexical_cast<int>(fd.substr(5, 1));
 	int minor = boost::lexical_cast<int>(fd.substr(7, 1));
-	firstRead(Id, major, minor, "parh", 1, 0);
+	firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR);
 	
 	uint32_t baseDirLen = 0, macroFile_nl = 0;
 	string baseDir, macroFilename;
diff --git a/AMDiS/src/io/detail/Arh3Writer.cc b/AMDiS/src/io/detail/Arh3Writer.cc
index 6d010420..1ba137c4 100644
--- a/AMDiS/src/io/detail/Arh3Writer.cc
+++ b/AMDiS/src/io/detail/Arh3Writer.cc
@@ -10,7 +10,9 @@
 #include "DOFVector.h"
 #include "../Arh3Reader.h"
 
+#include <boost/iostreams/filtering_stream.hpp>
 #include <boost/iostreams/filtering_streambuf.hpp>
+#include <boost/iostreams/device/file_descriptor.hpp>
 #include <boost/iostreams/copy.hpp>
 #ifdef HAVE_COMPRESSION
 #include <boost/iostreams/filter/zlib.hpp>
@@ -44,6 +46,55 @@ namespace AMDiS { namespace io {
 
         write(filename, NULL, vecs, writeParallel, cps, dataformat, writeMacro);
       }
+      
+      void updateAnimationFile(AdaptInfo *adaptInfo, 
+			       std::vector<double>* arhAnimationFrames,
+			       bool createSubDir,
+			       int indexLength,
+			       int indexDecimals,
+			       std::string animationFilename)
+      {
+	FUNCNAME("updateAnimationFile()");
+
+	arhAnimationFrames->push_back(adaptInfo->getTime());
+
+	boost::iostreams::filtering_ostream file;
+	{
+	  ofstream swapfile(animationFilename.c_str(), 
+			    ios::out | ios::trunc | ios::binary);
+	  TEST_EXIT(swapfile.is_open())
+	    ("Cannot open file %s for writing!\n", animationFilename.c_str());
+	  swapfile.close();
+	}
+	file.push(boost::iostreams::file_descriptor_sink(animationFilename, 
+							  ios::trunc | ios::binary));
+	
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+	string typeId = "tparh";
+#else
+	string typeId = "tarh";
+#endif
+	string baseDir = createSubDir ?  "./data/" : "./";
+	uint32_t baseDirLen = baseDir.length();
+	int major = AMDiS::io::Arh3Reader::TARH_MAJOR; 
+        int minor = AMDiS::io::Arh3Reader::TARH_MINOR;
+	typeId += '_' + boost::lexical_cast<string>(major) + '.' + boost::lexical_cast<string>(minor);
+	if (typeId.length() <= 16) {	// 16 is the Id size
+	  string rest(16 - typeId.length(), ' ');
+	  typeId.append(rest);
+	}
+	uint32_t indexLength_ = indexLength;
+	uint32_t indexDecimals_ = indexDecimals;
+	
+	file.write(typeId.c_str(), 16);
+	file.write(reinterpret_cast<char*>(&baseDirLen), 4);
+	file.write(baseDir.c_str(), baseDirLen);
+	file.write(reinterpret_cast<char*>(&indexLength_), 4);
+	file.write(reinterpret_cast<char*>(&indexDecimals_), 4);
+	
+	for (size_t i = 0; i < arhAnimationFrames->size(); i++)
+	  file.write(reinterpret_cast<char*>(&arhAnimationFrames[i]), 8);
+      }
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS  
       void writeParallelFile(string filename, Mesh* mesh, bool createSubDir, bool writeMacro)
@@ -52,13 +103,14 @@ namespace AMDiS { namespace io {
         file.open(filename.c_str(), ios::out | ios::binary | ios::trunc);
 	
 	string typeId = "parh", macroFilename = "", perFilename = "";
-	string baseDir = createSubDir ?  "./data/" : "";
+	string baseDir = createSubDir ?  "./data/" : "./";
 	string macroData = "", periodicData = "";
 	uint32_t baseDirLen = baseDir.length();
 	Parameters::get(mesh->getName() + "->macro file name", macroFilename);
 	Parameters::get(mesh->getName() + "->periodic file", perFilename);
 	
-	int major = 1, minor = 0;
+	int major = AMDiS::io::Arh3Reader::PARH_MAJOR; 
+        int minor = AMDiS::io::Arh3Reader::PARH_MINOR;
 	uint32_t nFiles = MPI::COMM_WORLD.Get_size();
 	uint32_t macroFile_nl = 0;
 	map<int, int> partitionMap = 
diff --git a/AMDiS/src/io/detail/Arh3Writer.h b/AMDiS/src/io/detail/Arh3Writer.h
index 6e46649d..fdc36077 100644
--- a/AMDiS/src/io/detail/Arh3Writer.h
+++ b/AMDiS/src/io/detail/Arh3Writer.h
@@ -6,6 +6,7 @@
 #include "MeshStructure.h"
 #include "DOFVector.h"
 #include "SystemVector.h"
+#include "AdaptInfo.h"
 #include "boost/assign.hpp"
 
 namespace AMDiS { namespace io {
@@ -111,6 +112,13 @@ namespace AMDiS { namespace io {
        
        void readFileToString(std::string filename, std::string& data);
        
+       void updateAnimationFile(AdaptInfo *adaptInfo, 
+				std::vector<double>* arhAnimationFrames,
+				bool createSubDir,
+				int indexLength,
+				int indexDecimals,
+				std::string animationFilename);
+       
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS         
        void writeParallelFile(std::string filename,
 			      Mesh* mesh,
-- 
GitLab