From 87484a0ab5f8fc7a872d0f6d07b0b3b696aa8dc8 Mon Sep 17 00:00:00 2001
From: Siqi Ling <lsq0473@gmail.com>
Date: Mon, 18 Jan 2016 17:21:48 +0000
Subject: [PATCH] Arh3 change parh to 2.0, reading parh directly load seq arh

---
 AMDiS/src/io/Arh2Reader.cc          |  16 ++-
 AMDiS/src/io/Arh3Reader.cc          |  99 +++++++++++++----
 AMDiS/src/io/Arh3Reader.h           |   2 +-
 AMDiS/src/io/FileWriter.cc          |  10 +-
 AMDiS/src/io/FileWriter.hh          |   4 +-
 AMDiS/src/io/FileWriterInterface.cc |   3 +-
 AMDiS/src/io/FileWriterInterface.h  |   2 +-
 AMDiS/src/io/detail/Arh2Reader.cc   |   4 +-
 AMDiS/src/io/detail/Arh3Reader.cc   | 165 +++++++++++++++++++++++-----
 AMDiS/src/io/detail/Arh3Reader.h    |   8 +-
 AMDiS/src/io/detail/Arh3Writer.cc   |  34 ++++--
 11 files changed, 271 insertions(+), 76 deletions(-)

diff --git a/AMDiS/src/io/Arh2Reader.cc b/AMDiS/src/io/Arh2Reader.cc
index 201355fd..37f273f4 100644
--- a/AMDiS/src/io/Arh2Reader.cc
+++ b/AMDiS/src/io/Arh2Reader.cc
@@ -132,9 +132,9 @@ namespace AMDiS { namespace io {
       {
 	using boost::lexical_cast;
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+	string name = filename.substr(0, sPos);
 	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
 #endif
       }
@@ -164,9 +164,9 @@ namespace AMDiS { namespace io {
       {
 	using boost::lexical_cast;
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+	string name = filename.substr(0, sPos);
 	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
 #endif
       }
@@ -193,10 +193,14 @@ namespace AMDiS { namespace io {
       {
 	using boost::lexical_cast;
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+	string filename_ = filename;
+	string name = filename.substr(0, sPos);
 	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	if(!boost::filesystem::exists(filename))
+	  filename = name + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
+	TEST_EXIT(boost::filesystem::exists(filename))("Arh data file not found in: %s\n", filename.c_str());
 #endif
       }
       
diff --git a/AMDiS/src/io/Arh3Reader.cc b/AMDiS/src/io/Arh3Reader.cc
index ab808581..4ef18df5 100644
--- a/AMDiS/src/io/Arh3Reader.cc
+++ b/AMDiS/src/io/Arh3Reader.cc
@@ -124,18 +124,37 @@ namespace AMDiS { namespace io {
 
     int readNumOfValueVectors(string filename, bool writeParallel)
     {
-      FUNCNAME("Arh3Reader::readNumOfValueVectors");
+      FUNCNAME("Arh3Reader::readNumOfValueVectors()");
       
       ifstream file;
       
-      if(writeParallel) 
-      {
+      if (writeParallel) {
+	
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 	using boost::lexical_cast;
+	using boost::filesystem::path;
+	  
+	path file_name = filename;
+	path file_onlyname = file_name.filename();
+	path file_path = file_name.remove_filename();
+	  
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
-#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	string filenameWithoutExt = filename.substr(0, sPos);
+	string parh = filenameWithoutExt + ".parh";
+	  
+	sPos = file_onlyname.string().find(".arh");
+	string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
+	  
+	bool parhExists = boost::filesystem::exists(parh);
+	string basedir =  parhExists ? detail::readParallelFile(parh) : ".";
+	
+	filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
+	
+	filename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
+	if(!boost::filesystem::exists(filename))
+	  filename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	
+	TEST_EXIT(boost::filesystem::exists(filename))("Arh data file not found in: %s\n", filename.c_str());
 #endif
       }
       
@@ -156,18 +175,37 @@ namespace AMDiS { namespace io {
 
     int readHeaderSize(string filename, bool writeParallel)
     {
-      FUNCNAME("Arh3Reader::readHeaderSize");
+      FUNCNAME("Arh3Reader::readHeaderSize()");
       
       ifstream file;
       
-      if (writeParallel)
-      {
+      if (writeParallel) {
+	
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 	using boost::lexical_cast;
+	using boost::filesystem::path;
+	  
+	path file_name = filename;
+	path file_onlyname = file_name.filename();
+	path file_path = file_name.remove_filename();
+	  
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
-#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	string filenameWithoutExt = filename.substr(0, sPos);
+	string parh = filenameWithoutExt + ".parh";
+	  
+	sPos = file_onlyname.string().find(".arh");
+	string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
+	  
+	bool parhExists = boost::filesystem::exists(parh);
+	string basedir =  parhExists ? detail::readParallelFile(parh) : ".";
+	
+	filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
+	
+	filename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
+	if(!boost::filesystem::exists(filename))
+	  filename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	
+	TEST_EXIT(boost::filesystem::exists(filename))("Arh data file not found in: %s\n", filename.c_str());
 #endif
       }
       
@@ -185,18 +223,37 @@ namespace AMDiS { namespace io {
 
     bool isReadable(string filename, bool writeParallel)
     {
-      FUNCNAME("Arh3Reader::isReadable");
+      FUNCNAME("Arh3Reader::isReadable()");
       
       ifstream file;
       
-      if(writeParallel)
-      {
+      if (writeParallel) {
+	
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 	using boost::lexical_cast;
+	using boost::filesystem::path;
+	  
+	path file_name = filename;
+	path file_onlyname = file_name.filename();
+	path file_path = file_name.remove_filename();
+	  
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	string name = filename.substr(0, sPos);
-#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	string filenameWithoutExt = filename.substr(0, sPos);
+	string parh = filenameWithoutExt + ".parh";
+	  
+	sPos = file_onlyname.string().find(".arh");
+	string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
+	  
+	bool parhExists = boost::filesystem::exists(parh);
+	string basedir =  parhExists ? detail::readParallelFile(parh) : ".";
+	
+	filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
+	
+	filename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
+	if(!boost::filesystem::exists(filename))
+	  filename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	
+	TEST_EXIT(boost::filesystem::exists(filename))("Arh data file not found in: %s\n", filename.c_str());
 #endif
       }
       
diff --git a/AMDiS/src/io/Arh3Reader.h b/AMDiS/src/io/Arh3Reader.h
index a1b5d59a..8a3aa935 100644
--- a/AMDiS/src/io/Arh3Reader.h
+++ b/AMDiS/src/io/Arh3Reader.h
@@ -25,7 +25,7 @@ namespace AMDiS { namespace io {
   {
     const uint8_t MAJOR = 3;
     const uint8_t MINOR = 1;
-    const uint8_t PARH_MAJOR = 1;
+    const uint8_t PARH_MAJOR = 2;
     const uint8_t PARH_MINOR = 0;
     const uint8_t TARH_MAJOR = 1;
     const uint8_t TARH_MINOR = 0;
diff --git a/AMDiS/src/io/FileWriter.cc b/AMDiS/src/io/FileWriter.cc
index 84c588fa..835cc328 100644
--- a/AMDiS/src/io/FileWriter.cc
+++ b/AMDiS/src/io/FileWriter.cc
@@ -121,15 +121,15 @@ namespace AMDiS
 						writeElement);
       }
       
-     std::string fn, fn_;
+     std::string fn, fn2, fn_;
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
       std::string paraFilename, postfix;
-      super::getFilename(adaptInfo, fn, paraFilename, postfix);
+      super::getFilename(adaptInfo, fn, fn2, paraFilename, postfix);
       postfix += paraviewFileExt;
       fn_ = paraFilename;
 #else
       super::getFilename(adaptInfo, fn);
-      fn_ = fn;
+      fn_ = fn2 = fn;
 #endif
     
 
@@ -226,12 +226,12 @@ namespace AMDiS
 #if HAVE_PARALLEL_DOMAIN_AMDIS
 	if (MPI::COMM_WORLD.Get_rank() == 0) {
 	  TEST_EXIT(!multiMesh) ("Multi mesh arh writer is not supported in parallel.\n");
-	  Arh3Writer::detail::writeParallelFile(paraFilename + arhParallelFileExt, 
+	  Arh3Writer::detail::writeParallelFile(paraFilename + arhParallelFileExt,
 						feSpace->getMesh(), 
 						createSubDir > 0);
 	}
 #endif
-	Arh3Writer::writeFile(solutionVecs, fn + ".arh", false);
+	Arh3Writer::writeFile(solutionVecs, fn2 + ".arh", false);
       }
     
     
diff --git a/AMDiS/src/io/FileWriter.hh b/AMDiS/src/io/FileWriter.hh
index 74ef0743..c0505ec1 100644
--- a/AMDiS/src/io/FileWriter.hh
+++ b/AMDiS/src/io/FileWriter.hh
@@ -222,10 +222,10 @@ namespace AMDiS
 						  writeElement);
       }
       
-     std::string fn;
+     std::string fn, fn2;
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
       std::string paraFilename, postfix;
-      super::getFilename(adaptInfo, fn, paraFilename, postfix);
+      super::getFilename(adaptInfo, fn, fn2, paraFilename, postfix);
       postfix += paraviewFileExt;
 #else
       super::getFilename(adaptInfo, fn);
diff --git a/AMDiS/src/io/FileWriterInterface.cc b/AMDiS/src/io/FileWriterInterface.cc
index 6d696200..296b90ba 100644
--- a/AMDiS/src/io/FileWriterInterface.cc
+++ b/AMDiS/src/io/FileWriterInterface.cc
@@ -63,7 +63,7 @@ namespace AMDiS {
   }
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-  void FileWriterInterface::getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& paraFilename, std::string& postfix)
+  void FileWriterInterface::getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& fn2, std::string& paraFilename, std::string& postfix)
 #else
   void FileWriterInterface::getFilename(AdaptInfo* adaptInfo, std::string& fn)
 #endif
@@ -85,6 +85,7 @@ namespace AMDiS {
 
 #if HAVE_PARALLEL_DOMAIN_AMDIS
     paraFilename = filename;
+    fn2 = fn + "_p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank());
     fn += "-p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-";
     postfix = "";
 #endif
diff --git a/AMDiS/src/io/FileWriterInterface.h b/AMDiS/src/io/FileWriterInterface.h
index a45bb10f..cbd9434d 100644
--- a/AMDiS/src/io/FileWriterInterface.h
+++ b/AMDiS/src/io/FileWriterInterface.h
@@ -99,7 +99,7 @@ namespace AMDiS {
     
     /// create a filename that includes the timestep and possibly a processor ID in parallel mode
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-    void getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& paraFilename, std::string& postfix);
+    void getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& fn2, std::string& paraFilename, std::string& postfix);
 #else
     void getFilename(AdaptInfo* adaptInfo, std::string& fn);
 #endif
diff --git a/AMDiS/src/io/detail/Arh2Reader.cc b/AMDiS/src/io/detail/Arh2Reader.cc
index d5c8dc5b..a8e38274 100644
--- a/AMDiS/src/io/detail/Arh2Reader.cc
+++ b/AMDiS/src/io/detail/Arh2Reader.cc
@@ -463,7 +463,7 @@ namespace AMDiS { namespace io {
 	if (writeParallel) {
 	  using boost::lexical_cast;
 	  int sPos = filename.find(".arh");
-	  TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
+	  TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 	  string name = filename.substr(0, sPos);
 
 	  if (nProcs == -1) {
@@ -639,7 +639,7 @@ namespace AMDiS { namespace io {
 	using boost::lexical_cast;
 	
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 	
 	if (nProc >= 0) {
 	  string name = filename.substr(0, sPos);
diff --git a/AMDiS/src/io/detail/Arh3Reader.cc b/AMDiS/src/io/detail/Arh3Reader.cc
index c16fd3af..a8bb4365 100644
--- a/AMDiS/src/io/detail/Arh3Reader.cc
+++ b/AMDiS/src/io/detail/Arh3Reader.cc
@@ -29,7 +29,7 @@ namespace AMDiS { namespace io {
       {
 	TEST_EXIT(id == id_)
 	  ("Cannot read Arh format: this file is not \"%s\" format.\n", id.c_str());
-	  
+	
 	TEST_EXIT(major == major_)
 	  ("Cannot read Arh format: Arh3Reader major version is %i, the file major version is %i. \n",
 	  major, major_);
@@ -333,7 +333,7 @@ namespace AMDiS { namespace io {
 	TEST_EXIT_DBG(headerLen_ <= headerLen) 
 	  ("Header length (without macro file name) is already larger than the header specified in the file.\n");
 	
-	// Read macroFile_nl //TODO
+	// TODO read macro from arh
 	if (headerLen_ < headerLen) {
 	  uint32_t macroFile_nl = 0;
 	  file.read(reinterpret_cast<char*>(&macroFile_nl), 4);
@@ -575,51 +575,84 @@ namespace AMDiS { namespace io {
 	}
 	if (writeParallel) {
 	  using boost::lexical_cast;
-	  using namespace boost::filesystem;
+	  using boost::filesystem::path;
 	  
 	  path file_name = filename;
 	  path file_onlyname = file_name.filename();
+	  path file_path = file_name.remove_filename();
+	  
 	  int sPos = filename.find(".arh");
 	  string filenameWithoutExt = filename.substr(0, sPos);
+	  string parh = filenameWithoutExt + ".parh";
+	  
 	  sPos = file_onlyname.string().find(".arh");
 	  string onlynameWithoutExt = file_onlyname.string().substr(0, sPos);
-	  string parh = filenameWithoutExt + ".parh";
-	  string basedir = "./";
-	  path file_path = file_name.remove_filename();
+	  
 	  
 	  int nProcs_ = 0, nMacros_ = 0, nMacros = 0;
 	  vector<int> partition;
-	  bool parhExists = exists(parh);
 	  
-	  if (parhExists)
-	    basedir = readParallelFile(parh, partition, nProcs_, nMacros_);
+	  bool parhExists = boost::filesystem::exists(parh);
+	  bool newFilename = parhExists;
+	  string basedir =  parhExists ? readParallelFile(parh, partition, nProcs_, nMacros_) : ".";
 
-	  filenameWithoutExt = file_path.string() + '/' + basedir + onlynameWithoutExt;
-	    
+	  filenameWithoutExt = file_path.string() + '/' + basedir + '/' + onlynameWithoutExt;
+	  
 	  if (nProcs == -1) {
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	    string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	    string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
+	    
+	    if (!boost::filesystem::exists(procFilename))
+	      procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	    
+	    TEST_EXIT(boost::filesystem::exists(procFilename))("Arh data file not found in: %s\n", procFilename.c_str());
+	    
 	    read(procFilename, mesh, vecs, byName);
-	    MSG("ARH file read from: %s\n", procFilename.c_str());
 #else
 	    ERROR_EXIT("Reading parallel ARH files in sequential computations requires to specify the number of nodes on which the ARH file was created!\n");
 #endif
 	  } else {
+	      
+	    int nProc_f = 0;
 	    if (!parhExists) {
-	      for (; nProcs_ < nProcs + 1; nProcs_++) {
-		string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProcs_) + "-.arh";
+	      for (; nProc_f < nProcs + 1; nProc_f++) {
+		string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProc_f) + "-.arh";
+		if(!boost::filesystem::exists(fn)) break;
+	      }
+	      if (nProc_f != nProcs) {
+		newFilename = true;
+		for (nProc_f = 0; nProc_f < nProcs + 1; nProc_f++) {
+		  string fn = filenameWithoutExt + "_p" + boost::lexical_cast<string>(nProc_f) + ".arh";
+		  if(!boost::filesystem::exists(fn)) break;
+		}
+	      }
+	    } else {
+	      for (nProc_f; nProc_f < nProcs + 1; nProc_f++) {
+		string fn = filenameWithoutExt + "_p" + boost::lexical_cast<string>(nProc_f) + ".arh";
 		if(!boost::filesystem::exists(fn)) break;
 	      }
+	      if (nProc_f != nProcs) {
+		newFilename = false;
+		for (nProc_f = 0; nProc_f < nProcs + 1; nProc_f++) {
+		  string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProc_f) + "-.arh";
+		  if(!boost::filesystem::exists(fn)) break;
+		}
+	      }
 	    }
-	    TEST_EXIT(nProcs_ == nProcs)
-	      ("Number of arh files doesn't match number of processors: %d vs %d\n", nProcs_, nProcs);
+	    
+	    TEST_EXIT(nProc_f == nProcs)
+	      ("Number of arh files doesn't match number of processors: %d vs %d\n", nProc_f, nProcs);
+	      
+	    if (parhExists)
+	      TEST_EXIT(nProc_f == nProcs_)
+		("Number of arh files doesn't match the label in parh file: %d vs %d", nProc_f, nProcs_);
 	      
 	    if (!parhExists) {
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS	      
 	      if (MPI::COMM_WORLD.Get_rank() == 0)
 #endif
 	        for(int i = 0; i < nProcs; i++)
-		  nMacros_ += readNumOfMacrosFromSgArh(filename, i);
+		  nMacros_ += readNumOfMacrosFromSgArh(filename, i, newFilename);
 	    }
 	      
 	    nMacros = mesh->getNumberOfMacros();
@@ -634,9 +667,17 @@ namespace AMDiS { namespace io {
 	    }
 
 	    if (!parhExists) {
-	      for (int i = 0; i < nProcs; i++) {
-		string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(i) + "-.arh";
-		read(procFilename, mesh, vecs, byName);
+	      if (newFilename) {
+		for (int i = 0; i < nProcs; i++) {
+		  string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(i) + ".arh";
+		  read(procFilename, mesh, vecs, byName);
+		}
+	      } else
+	      {
+		for (int i = 0; i < nProcs; i++) {
+		  string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(i) + "-.arh";
+		  read(procFilename, mesh, vecs, byName);
+		}
 	      }
 	    } else {
 	      std::set<int> needFiles;
@@ -645,9 +686,16 @@ namespace AMDiS { namespace io {
 		needFiles.insert(partition[(*it)->getIndex()]);
 	      
 	      std::set<int>::iterator it2 = needFiles.begin();
-	      for (;it2 != needFiles.end(); it2++) {
-		string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(*it2) + "-.arh";
-		read(procFilename, mesh, vecs, byName);
+	      if (newFilename) {
+		for (;it2 != needFiles.end(); it2++) {
+		  string procFilename = filenameWithoutExt + "_p" + lexical_cast<string>(*it2) + ".arh";
+		  read(procFilename, mesh, vecs, byName);
+		}
+	      } else {
+		for (;it2 != needFiles.end(); it2++) {
+		  string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(*it2) + "-.arh";
+		  read(procFilename, mesh, vecs, byName);
+		}
 	      }
 	    }
 	  }
@@ -818,17 +866,20 @@ namespace AMDiS { namespace io {
       } // end readMetaFromSgArh
     
   
-      int readNumOfMacrosFromSgArh(std::string filename, int nProc)
+      int readNumOfMacrosFromSgArh(std::string filename, int nProc, bool newFilename)
       {
 	FUNCNAME("Arh3Reader::readHeaderSize");
 	using boost::lexical_cast;
 	
 	int sPos = filename.find(".arh");
-	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix: \"arh \"!\n");
 	
 	if (nProc >= 0) {
 	  string name = filename.substr(0, sPos);
-	  filename = name + "-p" + lexical_cast<string>(nProc) + "-.arh";
+	  if (newFilename)
+	    filename = name + "_p" + lexical_cast<string>(nProc) + ".arh";
+	  else
+	    filename = name + "-p" + lexical_cast<string>(nProc) + "-.arh";
 	}
 	
 	ifstream file;
@@ -845,9 +896,63 @@ namespace AMDiS { namespace io {
 	
 	return nMacroElements;
       }
+      
+      void checkMeshconvParh1_0(std::string filename)
+      {
+	FUNCNAME("Arh3Reader::detail::checkMeshconvParh1_0()");
+	
+	ifstream file;
+	file.open(filename.c_str(), ios::in | ios::binary);
+	TEST_EXIT(file.is_open())
+	  ("Cannot open file %s\n", filename.c_str());
+	
+	string Id(4, ' ');
+	uint8_t major = 0, minor = 0;
+  
+	file.read(&Id[0], 4);
+	file.read(reinterpret_cast<char*>(&major), 1);
+	file.read(reinterpret_cast<char*>(&minor), 1);
+	
+	if (Id == "parh" && major == 1 && minor == 1)
+	  ERROR_EXIT("Parh file 1.0 is not supported in AMDiS anymore, you can use tools/arhTools/parh_change to update it to 2.0.\n");
+      }
+      
+      std::string readParallelFile(std::string filename)
+      {
+	FUNCNAME("Arh3Reader::detail::readParallelFile()");
+	
+	checkMeshconvParh1_0(filename);
+	
+	ifstream file;
+	file.open(filename.c_str(), ios::in | ios::binary);
+	TEST_EXIT(file.is_open())
+	  ("Cannot open file %s\n", filename.c_str());
+	
+	string fd(16, ' ');
+	file.read(&fd[0], 16);
+	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));
+	
+	if (Id == "parh" && major == 1 && minor == 0)
+	  ERROR_EXIT("Parh file 1.0 is not supported in AMDiS anymore, you can use tools/arhTools/parh_change to update it to 2.0.\n");
+	  
+	firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR);
+	
+	uint32_t baseDirLen = 0;
+	string baseDir = "";
+	file.read(reinterpret_cast<char*>(&baseDirLen), 4);
+	baseDir.resize(baseDirLen, ' ');
+	file.read(&baseDir[0], baseDirLen);
+	return baseDir;
+      }
         
       std::string readParallelFile(string filename, vector<int>& partition, int& nFiles, int& nMacros)
       {
+	FUNCNAME("Arh3Reader::detail::readParallelFile()");
+	
+	checkMeshconvParh1_0(filename);
+	
 	ifstream file;
 	file.open(filename.c_str(), ios::in | ios::binary);
 	TEST_EXIT(file.is_open())
@@ -858,6 +963,10 @@ 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));
+	
+	if (major == 1 && minor == 0)
+	  ERROR_EXIT("Parh file 1.0 is not supported in AMDiS anymore, you can use tools/arhTools/parh_change to update it to 2.0.\n");
+	  
 	firstRead(Id, major, minor, "parh", PARH_MAJOR, PARH_MINOR);
 	
 	uint32_t baseDirLen = 0, macroFile_nl = 0;
@@ -868,7 +977,7 @@ namespace AMDiS { namespace io {
 	file.read(&baseDir[0], baseDirLen);
 	file.read(reinterpret_cast<char*>(&nFiles), 4);
 	file.read(reinterpret_cast<char*>(&macroFile_nl), 4);
-	if (macroFile_nl > 0) { //TODO
+	if (macroFile_nl > 0) { //TODO read macro from arh
 	  macroFilename.resize(macroFile_nl, ' ');
 	  file.read(&macroFilename[0], macroFile_nl);
 	}
diff --git a/AMDiS/src/io/detail/Arh3Reader.h b/AMDiS/src/io/detail/Arh3Reader.h
index 857266c4..12fe599a 100644
--- a/AMDiS/src/io/detail/Arh3Reader.h
+++ b/AMDiS/src/io/detail/Arh3Reader.h
@@ -79,13 +79,19 @@ namespace AMDiS { namespace io {
 			   std::vector< std::set<std::pair<int, int> > >& data);
 
       
-      int readNumOfMacrosFromSgArh(std::string filename, int nProc = -1);
+      int readNumOfMacrosFromSgArh(std::string filename, int nProc = -1, bool newFilename = false);
       
      
+      // Pass excat parh path
       std::string readParallelFile(std::string filename,
 			    std::vector<int>& partition, 
 			    int& nFiles,
 			    int& nMacros);
+      
+      // Pass excat parh path
+      std::string readParallelFile(std::string filename);
+      
+      void checkMeshconvParh1_0(std::string filename);
 
     }//end namespace detail
   } // end namespace Arh3Reader
diff --git a/AMDiS/src/io/detail/Arh3Writer.cc b/AMDiS/src/io/detail/Arh3Writer.cc
index 015d00f7..81b21af1 100644
--- a/AMDiS/src/io/detail/Arh3Writer.cc
+++ b/AMDiS/src/io/detail/Arh3Writer.cc
@@ -10,6 +10,7 @@
 #include "DOFVector.h"
 #include "../Arh3Reader.h"
 
+#include <boost/filesystem.hpp>
 #include <boost/iostreams/filtering_stream.hpp>
 #include <boost/iostreams/filtering_streambuf.hpp>
 #include <boost/iostreams/device/file_descriptor.hpp>
@@ -103,7 +104,7 @@ 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 macroFile = "";
 	uint32_t macroFile_nl = 0;
 	string macroData = "", periodicData = "";
@@ -199,6 +200,9 @@ namespace AMDiS { namespace io {
       {
 	FUNCNAME("Arh3Writer::detail::write()");
 	
+	int sPos = filename.find(".arh");
+	TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
+	  
 	map<string,Valformat>::const_iterator it = dataformatMap.find(dataformat);
 	TEST_EXIT(it != dataformatMap.end())("Wrong data format.\n");
 	
@@ -223,18 +227,32 @@ namespace AMDiS { namespace io {
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 	if (writeParallel) {
 	  using boost::lexical_cast;
-	  
-	  int sPos = filename.find(".arh");
-	  TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-	  string name = filename.substr(0, sPos);
-	  std::vector<int> macroIdx;
+	  using boost::filesystem::path;
 	  
 	  Mesh* mesh_ = mesh ? mesh : vecs[0]->getFeSpace()->getMesh();
 	  
+	  bool arh3CreateSubDur = false;
+	  Parameters::get("arh3->create subdirectory", arh3CreateSubDur);
+	  
+	  string parhname = filename.substr(0, sPos);
+	  string sarhname = parhname;
+	  
+	  if (arh3CreateSubDur) {
+	    path vtu_path = parhname;
+	    path data_basedir("data");
+	    path vtu_filename = vtu_path.filename();
+	    vtu_path.remove_filename() /= data_basedir;
+	    try {
+	      create_directory(vtu_path); 
+	      vtu_path /= vtu_filename;	  
+	      sarhname = vtu_path.string();
+	    } catch (...) {}
+	  }
+	  
 	  if (MPI::COMM_WORLD.Get_rank() == 0)
-	    writeParallelFile(name + ".parh", mesh_, false);
+	    writeParallelFile(parhname + ".parh", mesh_, arh3CreateSubDur);
 	  
-	  filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
+	  filename = sarhname + "_p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + ".arh";
 	}
 #endif	  
 	  
-- 
GitLab