Commit 96d0b4bc authored by Siqi Ling's avatar Siqi Ling
Browse files

change in arh, parh file. update with meshconv

parent 92b1e9ce
...@@ -5,6 +5,12 @@ ...@@ -5,6 +5,12 @@
#include "SystemVector.h" #include "SystemVector.h"
#include "detail/Arh3Writer.h" #include "detail/Arh3Writer.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#define WRITE_MACRO false
#else
#define WRITE_MACRO true
#endif
namespace AMDiS { namespace io { namespace AMDiS { namespace io {
/** \ingroup Output /** \ingroup Output
...@@ -45,21 +51,23 @@ namespace AMDiS { namespace io { ...@@ -45,21 +51,23 @@ namespace AMDiS { namespace io {
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
std::vector<DOFVector<double>*> vecs; std::vector<DOFVector<double>*> vecs;
for (int i = 0; i < sysVec->getSize(); i++) for (int i = 0; i < sysVec->getSize(); i++)
vecs.push_back(sysVec->getDOFVector(i)); vecs.push_back(sysVec->getDOFVector(i));
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat); detail::write(filename, NULL, vecs, writeParallel, cps, dataformat, writeMacro);
} }
inline void writeFile(SystemVector &sysVec, inline void writeFile(SystemVector &sysVec,
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
writeFile(&sysVec, filename, writeParallel, cps, dataformat); writeFile(&sysVec, filename, writeParallel, cps, dataformat, writeMacro);
} }
/// write the meshstructure and the dof values of DOFVectors in vec0 /// write the meshstructure and the dof values of DOFVectors in vec0
...@@ -68,11 +76,12 @@ namespace AMDiS { namespace io { ...@@ -68,11 +76,12 @@ namespace AMDiS { namespace io {
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
std::vector<DOFVector<double>*> vecs; std::vector<DOFVector<double>*> vecs;
vecs.push_back(vec0); vecs.push_back(vec0);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat); detail::write(filename, NULL, vecs, writeParallel, cps, dataformat, writeMacro);
} }
/// write the meshstructure and the dof values of DOFVectors in vec0 /// write the meshstructure and the dof values of DOFVectors in vec0
...@@ -81,9 +90,10 @@ namespace AMDiS { namespace io { ...@@ -81,9 +90,10 @@ namespace AMDiS { namespace io {
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
writeFile(&vec0, filename, writeParallel, cps, dataformat); writeFile(&vec0, filename, writeParallel, cps, dataformat, writeMacro);
} }
/// write the meshstructure and the dof values of DOFVectors in vecs /// write the meshstructure and the dof values of DOFVectors in vecs
...@@ -92,9 +102,10 @@ namespace AMDiS { namespace io { ...@@ -92,9 +102,10 @@ namespace AMDiS { namespace io {
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat); detail::write(filename, NULL, vecs, writeParallel, cps, dataformat, writeMacro);
} }
/// write the meshstructure of the mesh to arh file. /// write the meshstructure of the mesh to arh file.
...@@ -102,10 +113,11 @@ namespace AMDiS { namespace io { ...@@ -102,10 +113,11 @@ namespace AMDiS { namespace io {
std::string filename, std::string filename,
bool writeParallel = true, bool writeParallel = true,
Cpsformat cps = NONE, Cpsformat cps = NONE,
std::string dataformat = "SF64") std::string dataformat = "SF64",
bool writeMacro = WRITE_MACRO)
{ {
std::vector<DOFVector<double>*> vecs; std::vector<DOFVector<double>*> vecs;
detail::write(filename, mesh, vecs, writeParallel, cps, dataformat); detail::write(filename, mesh, vecs, writeParallel, cps, dataformat, writeMacro);
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
......
...@@ -73,6 +73,13 @@ namespace AMDiS ...@@ -73,6 +73,13 @@ namespace AMDiS
for (size_t i = 0; i < solutionVecs.size(); i++) for (size_t i = 0; i < solutionVecs.size(); i++)
solutionNames.push_back(solutionVecs[i]->getName()); solutionNames.push_back(solutionVecs[i]->getName());
std::set<Mesh*> meshset;
for (size_t i = 0; i < solutionVecs.size(); i++)
if (solutionVecs[i])
meshset.insert(solutionVecs[i]->getFeSpace()->getMesh());
multiMesh = meshset.size() > 1;
} }
...@@ -201,8 +208,17 @@ namespace AMDiS ...@@ -201,8 +208,17 @@ namespace AMDiS
Arh2Writer::writeFile(solutionVecs, fn_ + ".arh"); Arh2Writer::writeFile(solutionVecs, fn_ + ".arh");
else if (writeArh1) else if (writeArh1)
ArhWriter::write(fn_ + ".arh", feSpace->getMesh(), solutionVecs); ArhWriter::write(fn_ + ".arh", feSpace->getMesh(), solutionVecs);
else if (writeArh3 || writeArhFormat) else if (writeArh3 || writeArhFormat) {
Arh3Writer::writeFile(solutionVecs, fn_ + ".arh"); #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,
feSpace->getMesh(),
createSubDir > 0);
}
#endif
Arh3Writer::writeFile(solutionVecs, fn + ".arh");
}
#ifdef HAVE_PNG #ifdef HAVE_PNG
......
...@@ -102,6 +102,9 @@ namespace AMDiS { ...@@ -102,6 +102,9 @@ namespace AMDiS {
/// Reads all file writer dependend parameters from the init file. /// Reads all file writer dependend parameters from the init file.
virtual void readParameters(std::string name) override; virtual void readParameters(std::string name) override;
/// Multi mesh flag
bool multiMesh;
/// Name of the writer. /// Name of the writer.
std::string name; std::string name;
...@@ -117,6 +120,12 @@ namespace AMDiS { ...@@ -117,6 +120,12 @@ namespace AMDiS {
/// Parallel VTK file extension. /// Parallel VTK file extension.
std::string paraviewParallelFileExt; std::string paraviewParallelFileExt;
/// Parallel ARH file extension.
std::string arhParallelFileExt;
/// Time ARH file extension.
std::string arhTimeFileExt;
/// Periodic file extension. /// Periodic file extension.
std::string periodicFileExt; std::string periodicFileExt;
......
...@@ -119,10 +119,13 @@ namespace AMDiS ...@@ -119,10 +119,13 @@ namespace AMDiS
template<typename T> template<typename T>
void FileWriter<T>::initialize() void FileWriter<T>::initialize()
{ {
multiMesh = false;
amdisMeshExt = ".mesh"; amdisMeshExt = ".mesh";
amdisDataExt = ".dat"; amdisDataExt = ".dat";
paraviewFileExt = ".vtu"; paraviewFileExt = ".vtu";
paraviewParallelFileExt = ".pvtu"; paraviewParallelFileExt = ".pvtu";
arhParallelFileExt = ".parh";
arhTimeFileExt = ".tarh";
periodicFileExt = ".per"; periodicFileExt = ".per";
writeAMDiSFormat = 0; writeAMDiSFormat = 0;
writeParaViewFormat = 0; writeParaViewFormat = 0;
......
...@@ -24,6 +24,20 @@ namespace AMDiS { namespace io { ...@@ -24,6 +24,20 @@ namespace AMDiS { namespace io {
{ {
namespace detail namespace detail
{ {
void firstRead(std::string id_, uint8_t major_, uint8_t minor_, //version in file
std::string id, uint8_t major, uint8_t minor) //class version
{
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: Arh2Reader major version is %i, the file major version is %i. \n",
major, major_);
TEST_EXIT(minor >= minor_)
("Cannot read Arh format: ArhReader minor version is %i is smaller than the file minor version %i.\n",
minor, minor_);
}
void firstRead(ifstream& file, string id, uint8_t major, uint8_t minor) void firstRead(ifstream& file, string id, uint8_t major, uint8_t minor)
{ {
...@@ -34,18 +48,10 @@ namespace AMDiS { namespace io { ...@@ -34,18 +48,10 @@ namespace AMDiS { namespace io {
string typeId(4, ' '); string typeId(4, ' ');
file.read(const_cast<char*>(typeId.data()), 4); file.read(const_cast<char*>(typeId.data()), 4);
TEST_EXIT(typeId == id)
("Cannot read Arh format: this file is not \"%s\" format.\n", id.c_str());
file.read(reinterpret_cast<char*>(&major_), 1); file.read(reinterpret_cast<char*>(&major_), 1);
TEST_EXIT(major == major_)
("Cannot read Arh format: Arh2Reader major version is %i, the file major version is %i. \n",
major, major_);
file.read(reinterpret_cast<char*>(&minor_), 1); file.read(reinterpret_cast<char*>(&minor_), 1);
TEST_EXIT(minor <= minor_)
("Cannot read Arh format: ArhReader minor version is %i is smaller than the file minor version %i.\n", firstRead(typeId, major_, minor_, id, major, minor);
minor, minor_);
} }
void setDofValues(int macroElIndex, Mesh *mesh, void setDofValues(int macroElIndex, Mesh *mesh,
...@@ -315,7 +321,19 @@ namespace AMDiS { namespace io { ...@@ -315,7 +321,19 @@ namespace AMDiS { namespace io {
tmpString.resize(4, ' '); tmpString.resize(4, ' ');
file.read(const_cast<char*>(tmpString.data()), 4); file.read(const_cast<char*>(tmpString.data()), 4);
dataformat.push_back(tmpString); dataformat.push_back(tmpString);
} }
// Read macroFile_nl
uint32_t macroFile_nl = 0;
file.read(reinterpret_cast<char*>(&macroFile_nl), 4);
if (macroFile_nl > 0) {
string tmpString("");
tmpString.resize(macroFile_nl, ' ');
file.read(const_cast<char*>(tmpString.data()), macroFile_nl);
}
//================header is over==================//
// Adjust and check vecs // Adjust and check vecs
if(byName) if(byName)
{ {
...@@ -546,38 +564,49 @@ namespace AMDiS { namespace io { ...@@ -546,38 +564,49 @@ namespace AMDiS { namespace io {
} }
if (writeParallel) { if (writeParallel) {
using boost::lexical_cast; using boost::lexical_cast;
using namespace boost::filesystem;
path file_name = filename;
path file_onlyname = file_name.filename();
int sPos = filename.find(".arh"); int sPos = filename.find(".arh");
TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n"); string filenameWithoutExt = filename.substr(0, sPos);
string name = filename.substr(0, sPos); 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_);
if (basedir != "")
filenameWithoutExt = file_path.string() + '/' + basedir + onlynameWithoutExt;
if (nProcs == -1) { if (nProcs == -1) {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string procFilename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh"; string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
read(procFilename, mesh, vecs, byName); read(procFilename, mesh, vecs, byName);
MSG("ARH file read from: %s\n", procFilename.c_str()); MSG("ARH file read from: %s\n", procFilename.c_str());
#else #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"); 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 #endif
} else { } else {
string parhfn = name + ".parh", filenameType = ""; if (!parhExists) {
int nProcs_ = 0, nMacros_ = 0, nMacros = 0;
vector<int> partition;
bool parh = boost::filesystem::exists(parhfn);
if (parh)
readParallelFile(parhfn, filenameType, partition, nProcs_, nMacros_);
else {
for (; nProcs_ < nProcs + 1; nProcs_++) { for (; nProcs_ < nProcs + 1; nProcs_++) {
string fn = name + "-p" + boost::lexical_cast<string>(nProcs_) + "-.arh"; string fn = filenameWithoutExt + "-p" + boost::lexical_cast<string>(nProcs_) + "-.arh";
if(!boost::filesystem::exists(fn)) break; if(!boost::filesystem::exists(fn)) break;
} }
} }
TEST_EXIT(nProcs_ == nProcs) TEST_EXIT(nProcs_ == nProcs)
("Number of arh files doesn't match number of processors: %d vs %d\n", nProcs_, nProcs); ("Number of arh files doesn't match number of processors: %d vs %d\n", nProcs_, nProcs);
if (!parh) { if (!parhExists) {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if(MPI::COMM_WORLD.Get_rank() == 0) if (MPI::COMM_WORLD.Get_rank() == 0)
#endif #endif
for(int i = 0; i < nProcs; i++) for(int i = 0; i < nProcs; i++)
nMacros_ += readNumOfMacrosFromSgArh(filename, i); nMacros_ += readNumOfMacrosFromSgArh(filename, i);
...@@ -594,9 +623,9 @@ namespace AMDiS { namespace io { ...@@ -594,9 +623,9 @@ namespace AMDiS { namespace io {
nMacros, nMacros_); nMacros, nMacros_);
} }
if (!parh) { if (!parhExists) {
for (int i = 0; i < nProcs; i++) { for (int i = 0; i < nProcs; i++) {
string procFilename = name + "-p" + lexical_cast<string>(i) + "-.arh"; string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(i) + "-.arh";
read(procFilename, mesh, vecs, byName); read(procFilename, mesh, vecs, byName);
} }
} else { } else {
...@@ -607,7 +636,7 @@ namespace AMDiS { namespace io { ...@@ -607,7 +636,7 @@ namespace AMDiS { namespace io {
std::set<int>::iterator it2 = needFiles.begin(); std::set<int>::iterator it2 = needFiles.begin();
for (;it2 != needFiles.end(); it2++) { for (;it2 != needFiles.end(); it2++) {
string procFilename = name + "-p" + lexical_cast<string>(*it2) + "-.arh"; string procFilename = filenameWithoutExt + "-p" + lexical_cast<string>(*it2) + "-.arh";
read(procFilename, mesh, vecs, byName); read(procFilename, mesh, vecs, byName);
} }
} }
...@@ -693,7 +722,15 @@ namespace AMDiS { namespace io { ...@@ -693,7 +722,15 @@ namespace AMDiS { namespace io {
tmpString.resize(4, ' '); tmpString.resize(4, ' ');
file.read(const_cast<char*>(tmpString.data()), 4); file.read(const_cast<char*>(tmpString.data()), 4);
dataformat.push_back(tmpString); dataformat.push_back(tmpString);
} }
// Read macroFile_nl
uint32_t macroFile_nl = 0;
file.read(reinterpret_cast<char*>(&macroFile_nl), 4);
string tmpString("");
file.read(const_cast<char*>(tmpString.data()), macroFile_nl);
//================header is over==================//
for (uint32_t i = 0; i < nMacroElements; i++) { for (uint32_t i = 0; i < nMacroElements; i++) {
stringstream dataStream(ios::out | ios::in | ios::binary); stringstream dataStream(ios::out | ios::in | ios::binary);
...@@ -799,32 +836,41 @@ namespace AMDiS { namespace io { ...@@ -799,32 +836,41 @@ namespace AMDiS { namespace io {
return nMacroElements; return nMacroElements;
} }
void readParallelFile(string filename, string& filenameType, vector<int>& partition, int& nFiles, int& nMacros) std::string readParallelFile(string filename, vector<int>& partition, int& nFiles, int& nMacros)
{ {
ifstream file; ifstream file;
file.open(filename.c_str(), ios::in | ios::binary); file.open(filename.c_str(), ios::in | ios::binary);
TEST_EXIT(file.is_open()) TEST_EXIT(file.is_open())
("Cannot open file %s\n", filename.c_str()); ("Cannot open file %s\n", filename.c_str());
firstRead(file, "parh", 1, 0);
uint32_t macroFile_nl = 0; string fd(16, ' ');
string macroFilename; file.read(const_cast<char*>(fd.data()), 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));
firstRead(Id, major, minor, "parh", 1, 0);
filenameType.resize(4, ' '); uint32_t baseDirLen = 0, macroFile_nl = 0;
string baseDir, macroFilename;
file.read(reinterpret_cast<char*>(&baseDirLen), 4);
baseDir.resize(baseDirLen, ' ');
file.read(const_cast<char*>(baseDir.data()), baseDirLen);
file.read(reinterpret_cast<char*>(&nFiles), 4); file.read(reinterpret_cast<char*>(&nFiles), 4);
file.read(const_cast<char*>(filenameType.data()), 4);
file.read(reinterpret_cast<char*>(&nMacros), 4);
file.read(reinterpret_cast<char*>(&macroFile_nl), 4); file.read(reinterpret_cast<char*>(&macroFile_nl), 4);
macroFilename.resize(macroFile_nl, ' '); if (macroFile_nl > 0) {
file.read(const_cast<char*>(macroFilename.data()), macroFile_nl); macroFilename.resize(macroFile_nl, ' ');
file.read(const_cast<char*>(macroFilename.data()), macroFile_nl);
}
file.read(reinterpret_cast<char*>(&nMacros), 4);
uint32_t rank = 0; uint32_t rank = 0;
for (int i = 0; i < nMacros; i++) { for (int i = 0; i < nMacros; i++) {
file.read(reinterpret_cast<char*>(&rank), 4); file.read(reinterpret_cast<char*>(&rank), 4);
partition.push_back(rank); partition.push_back(rank);
} }
return baseDir;
} }
} // end namespace detail } // end namespace detail
......
...@@ -23,6 +23,8 @@ namespace AMDiS { namespace io { ...@@ -23,6 +23,8 @@ namespace AMDiS { namespace io {
* 3. the minor version of Arh2Reader is bigger than the one in the file. * 3. the minor version of Arh2Reader is bigger than the one in the file.
* return value: minor version * return value: minor version
*/ */
void firstRead(std::string, uint8_t, uint8_t, std::string, uint8_t, uint8_t);
void firstRead(std::ifstream& file, std::string, uint8_t, uint8_t); void firstRead(std::ifstream& file, std::string, uint8_t, uint8_t);
void setDofValues(int macroElIndex, Mesh *mesh, void setDofValues(int macroElIndex, Mesh *mesh,
...@@ -80,8 +82,7 @@ namespace AMDiS { namespace io { ...@@ -80,8 +82,7 @@ namespace AMDiS { namespace io {
int readNumOfMacrosFromSgArh(std::string filename, int nProc = -1); int readNumOfMacrosFromSgArh(std::string filename, int nProc = -1);
void readParallelFile(std::string filename, std::string readParallelFile(std::string filename,
std::string& filenameType,
std::vector<int>& partition, std::vector<int>& partition,
int& nFiles, int& nFiles,
int& nMacros); int& nMacros);
......
#include <fstream> #include <fstream>
#include <stdint.h> #include <stdint.h>
#include <iostream> #include <iostream>
#include <streambuf>
#include "Arh3Writer.h" #include "Arh3Writer.h"
#include "Mesh.h" #include "Mesh.h"
...@@ -31,7 +32,7 @@ namespace AMDiS { namespace io { ...@@ -31,7 +32,7 @@ namespace AMDiS { namespace io {
bool writeParallel, bool writeParallel,
Cpsformat cps, Cpsformat cps,
string dataformat, string dataformat,
string filenameType) bool writeMacro)
{ {
vector<DOFVector<double>*> vecs(0); vector<DOFVector<double>*> vecs(0);
if (vec0 != NULL) if (vec0 != NULL)
...@@ -41,35 +42,53 @@ namespace AMDiS { namespace io { ...@@ -41,35 +42,53 @@ namespace AMDiS { namespace io {
if (vec2 != NULL) if (vec2 != NULL)
vecs.push_back(vec2); vecs.push_back(vec2);
write(filename, NULL, vecs, writeParallel, cps, dataformat, filenameType); write(filename, NULL, vecs, writeParallel, cps, dataformat, writeMacro);
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
void writeParallelFile(string filename, Mesh* mesh, string filenameType) void writeParallelFile(string filename, Mesh* mesh, bool createSubDir, bool writeMacro)
{ {
TEST_EXIT(filenameType == "cont")("Unsupported filename type.\n");
ofstream file; ofstream file;
file.open(filename.c_str(), ios::out | ios::binary | ios::trunc); file.open(filename.c_str(), ios::out | ios::binary | ios::trunc);
string typeId = "parh", macroFilename = ""; string typeId = "parh", macroFilename = "", perFilename = "";
string baseDir = createSubDir ? "./data/" : "";
string macroData = "", periodicData = "";
uint32_t baseDirLen = baseDir.length();
Parameters::get(mesh->getName() + "->macro file name", macroFilename); Parameters::get(mesh->getName() + "->macro file name", macroFilename);
uint8_t major = 1; Parameters::get(mesh->getName() + "->periodic file", perFilename);
uint8_t minor = 0;