Commit d5add584 authored by Siqi Ling's avatar Siqi Ling

arh2 2.0 3.0 work together

parent dfa3f029
......@@ -171,9 +171,13 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/io/detail/ArhReader.cc
${SOURCE_DIR}/io/Arh2Reader.cc
${SOURCE_DIR}/io/Arh2Writer.cc
${SOURCE_DIR}/io/Arh3Reader.cc
${SOURCE_DIR}/io/Arh3Writer.cc
${SOURCE_DIR}/io/detail/Arh2Reader.cc
${SOURCE_DIR}/io/detail/ArhWriter.cc
${SOURCE_DIR}/io/detail/Arh2Writer.cc
${SOURCE_DIR}/io/detail/Arh3Reader.cc
${SOURCE_DIR}/io/detail/Arh3Writer.cc
${SOURCE_DIR}/io/DofWriter.cc
${SOURCE_DIR}/io/ElementFileWriter.cc
${SOURCE_DIR}/io/FileWriterInterface.cc
......
......@@ -117,8 +117,10 @@
#include "io/ArhReader.h"
#include "io/Arh2Reader.h"
#include "io/Arh3Reader.h"
#include "io/ArhWriter.h"
#include "io/Arh2Writer.h"
#include "io/Arh3Writer.h"
#include "io/DataCollector.h"
#include "io/FileWriter.h"
#include "io/GNUPlotWriter.h"
......
......@@ -145,7 +145,7 @@ namespace AMDiS { namespace io {
uint32_t nValueVectors = 0;
detail::firstRead(file, "sarh", MAJOR, MINOR);
detail::firstRead(file);
long pos = file.tellg();
file.seekg(pos + 16);
file.read(reinterpret_cast<char*>(&nValueVectors), 4);
......@@ -176,7 +176,7 @@ namespace AMDiS { namespace io {
("Cannot open file %s\n", filename.c_str());
uint32_t headerLen = 0;
detail::firstRead(file, "sarh", MAJOR, MINOR);
detail::firstRead(file);
file.read(reinterpret_cast<char*>(&headerLen), 4);
file.close();
......@@ -212,7 +212,7 @@ namespace AMDiS { namespace io {
file.read(reinterpret_cast<char*>(&minor), 1);
file.close();
return (typeId == "sarh" && major == MAJOR && minor <= MINOR) ? true : false;
return (typeId == "arh2" && major == MAJOR && minor <= MINOR) ? true : false;
}
void readMeta(string filename,
......@@ -394,4 +394,4 @@ namespace AMDiS { namespace io {
}
} // end namespace Arh2Reader
} } // end namespace io, AMDiS
} } // end namespace io, AMDiS
\ No newline at end of file
......@@ -23,8 +23,8 @@ namespace AMDiS { namespace io {
**/
namespace Arh2Reader
{
const uint8_t MAJOR = 3;
const uint8_t MINOR = 0;
const uint8_t MAJOR = 2;
const uint8_t MINOR = 1;
/**
* \brief Read MeshStructure, refine the mesh and read dof values to sysVec by order.
......@@ -206,4 +206,4 @@ namespace AMDiS { namespace io {
} } // end namespace io, AMDiS
#endif
#endif
\ No newline at end of file
......@@ -107,4 +107,4 @@ namespace AMDiS { namespace io {
#endif
}
} }
} }
\ No newline at end of file
......@@ -14,7 +14,9 @@ namespace AMDiS { namespace io {
* ARH-files.
**/
namespace Arh2Writer
{
{
const uint8_t MAJOR = 2;
const uint8_t MINOR = 1;
/**
* \brief write the meshstructure and the dof values of DOFVectors in sysVec
......@@ -43,76 +45,65 @@ namespace AMDiS { namespace io {
*/
inline void writeFile(SystemVector *sysVec,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
std::vector<DOFVector<double>*> vecs;
for (int i = 0; i < sysVec->getSize(); i++)
vecs.push_back(sysVec->getDOFVector(i));
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
detail::write(filename, NULL, vecs, writeParallel);
}
inline void writeFile(SystemVector &sysVec,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
writeFile(&sysVec, filename, writeParallel, cps, dataformat);
writeFile(&sysVec, filename, writeParallel);
}
/// write the meshstructure and the dof values of DOFVectors in vec0
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(DOFVector<double>* vec0,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
std::vector<DOFVector<double>*> vecs;
vecs.push_back(vec0);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
detail::write(filename, NULL, vecs, writeParallel);
}
/// write the meshstructure and the dof values of DOFVectors in vec0
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(DOFVector<double>& vec0,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
writeFile(&vec0, filename, writeParallel, cps, dataformat);
writeFile(&vec0, filename, writeParallel);
}
/// write the meshstructure and the dof values of DOFVectors in vecs
/// the behavior is equal to writeFile(SystemVector* sysVec, string filename).
inline void writeFile(std::vector<DOFVector<double>*> vecs,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
detail::write(filename, NULL, vecs, writeParallel);
}
/// write the meshstructure of the mesh to arh file.
inline void writeFile(Mesh *mesh,
std::string filename,
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
bool writeParallel = true)
{
std::vector<DOFVector<double>*> vecs;
detail::write(filename, mesh, vecs, writeParallel, cps, dataformat);
detail::write(filename, mesh, vecs, writeParallel);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
void writeMetaData(Mesh *mesh, std::string filename);
#endif
} // end namespace Arh2Writer
} } // end namespace io, AMDiS
#endif
#endif
\ No newline at end of file
/******************************************************************************
*
* AMDiS - Adaptive multidimensional simulations
*
* Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
* Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
*
* Authors:
* Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* This file is part of AMDiS
*
* See also license.opensource.txt in the distribution.
*
******************************************************************************/
#include <fstream>
#include <stdint.h>
#include <boost/filesystem.hpp>
#include "Arh3Reader.h"
#include "detail/Arh3Reader.h"
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
namespace AMDiS { namespace io {
namespace Arh3Reader
{
using namespace std;
void readByName(string filename,
DOFVector<double>& vec,
bool writeParallel,
int nProcs)
{
readByName(filename, &vec, writeParallel, nProcs);
}
void readByName(string filename,
DOFVector<double>* vec,
bool writeParallel,
int nProcs)
{
vector<DOFVector<double>*> vecs(0);
vecs.push_back(vec);
detail::readFile(filename, NULL, vecs, writeParallel, nProcs, true);
}
void readByName(string filename,
vector<DOFVector<double>*> vecs,
bool writeParallel,
int nProcs)
{
detail::readFile(filename, NULL, vecs, writeParallel, nProcs, true);
}
void readByName(string filename,
SystemVector *sysVec,
bool writeParallel,
int nProcs)
{
vector<DOFVector<double>*> vecs(0);
for(int i = 0 ; i < sysVec->getSize(); i++)
{
vecs.push_back(sysVec->getDOFVector(i));
}
detail::readFile(filename, NULL, vecs, writeParallel, nProcs, true);
}
void readFile(string filename,
SystemVector *sysVec,
bool writeParallel,
int nProcs)
{
vector<DOFVector<double>*> vecs(0);
for(int i = 0 ; i < sysVec->getSize(); i++)
{
vecs.push_back(sysVec->getDOFVector(i));
}
detail::readFile(filename, NULL, vecs, writeParallel, nProcs);
}
void readFile(string filename,
DOFVector<double>* vec0,
DOFVector<double>* vec1,
DOFVector<double>* vec2,
bool writeParallel,
int nProcs)
{
vector<DOFVector<double>*> vecs(0);
if(vec0 || vec1 || vec2)
vecs.push_back(vec0);
if(vec1 || vec2)
vecs.push_back(vec1);
if(vec2)
vecs.push_back(vec2);
detail::readFile(filename, NULL, vecs, writeParallel, nProcs);
}
void readFile(string filename,
vector<DOFVector<double>*> vecs,
bool writeParallel,
int nProcs)
{
detail::readFile(filename, NULL, vecs, writeParallel, nProcs);
}
void readFile(string filename,
Mesh* mesh,
bool writeParallel,
int nProcs)
{
vector<DOFVector<double>*> vecs(0);
detail::readFile(filename, mesh, vecs, writeParallel, nProcs);
}
int readNumOfValueVectors(string filename, bool writeParallel)
{
FUNCNAME("Arh3Reader::readNumOfValueVectors");
ifstream file;
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);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
#endif
}
file.open(filename.c_str(), ios::in | ios::binary);
TEST_EXIT(file.is_open())
("Cannot open file %s\n", filename.c_str());
uint32_t nValueVectors = 0;
detail::firstRead(file, "sarh", MAJOR, MINOR);
long pos = file.tellg();
file.seekg(pos + 16);
file.read(reinterpret_cast<char*>(&nValueVectors), 4);
file.close();
return nValueVectors;
}
int readHeaderSize(string filename, bool writeParallel)
{
FUNCNAME("Arh3Reader::readHeaderSize");
ifstream file;
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);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
#endif
}
file.open(filename.c_str(), ios::in | ios::binary);
TEST_EXIT(file.is_open())
("Cannot open file %s\n", filename.c_str());
uint32_t headerLen = 0;
detail::firstRead(file, "sarh", MAJOR, MINOR);
file.read(reinterpret_cast<char*>(&headerLen), 4);
file.close();
return headerLen;
}
bool isReadable(string filename, bool writeParallel)
{
FUNCNAME("Arh3Reader::isReadable");
ifstream file;
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);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
#endif
}
file.open(filename.c_str(), ios::in | ios::binary);
TEST_EXIT(file.is_open())
("Cannot open file %s\n", filename.c_str());
string typeId(4, ' ');
uint8_t major = 0, minor = 0;
file.read(const_cast<char*>(typeId.data()), 4);
file.read(reinterpret_cast<char*>(&major), 1);
file.read(reinterpret_cast<char*>(&minor), 1);
file.close();
return (typeId == "sarh" && major == MAJOR && minor <= MINOR) ? true : false;
}
void readMeta(string filename,
DOFVector<double>* vec0,
DOFVector<double>* vec1,
DOFVector<double>* vec2)
{
vector<DOFVector<double>*> vecs;
if (vec0)
vecs.push_back(vec0);
if (vec1)
vecs.push_back(vec1);
if (vec2)
vecs.push_back(vec2);
readMeta(filename, vecs);
}
void readMeta(string filename, vector<DOFVector<double>*> vecs)
{
FUNCNAME("Arh3Reader::readMeta()");
Mesh* mesh = NULL;
for (size_t i = 0; i < vecs.size(); i++)
{
if(vecs[i])
{
if(!mesh)
mesh = vecs[i]->getFeSpace()->getMesh();
else
TEST_EXIT(mesh == vecs[i]->getFeSpace()->getMesh())
("The mesh of the DOFVectors should be the same for Reader because in one file there is only one mesh.\n");
}
}
if(!mesh)
{
WARNING("You haven't specified the target.\n");
return;
}
// === Read the meta arh file. ===
string arhPrefix = "";
map<int, int> elInRank;
map<int, int> elCodeSize;
int nProc = readMetaData(filename, elInRank, elCodeSize, arhPrefix);
// === Check which arh files must be read by current rank. ===
// Set of all file indices which should be read to restore all macro elements.
std::set<int> readArhFiles;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL);
while (elInfo) {
int macroElIndex = elInfo->getElement()->getIndex();
TEST_EXIT(elInRank.count(macroElIndex))("Should not happen!\n");
readArhFiles.insert(elInRank[macroElIndex]);
elInfo = stack.traverseNext(elInfo);
}
// === Read the individual arh files. ===
boost::filesystem::path p(filename.c_str());
boost::filesystem::path directory = p.parent_path();
for (std::set<int>::iterator it = readArhFiles.begin();
it != readArhFiles.end(); ++it) {
string arhFilename = directory.string() + "/" + arhPrefix;
if (nProc == 1)
arhFilename += ".arh";
else
arhFilename += "-p" + boost::lexical_cast<string>(*it) + "-.arh";
MSG("ARH2 file read from: %s\n", arhFilename.c_str());
detail::read(arhFilename, mesh, vecs);
}
}
int readMetaData(string filename,
map<int, int> &elInRank,
map<int, int> &elCodeSize,
string &arhPrefix)
{
FUNCNAME("Arh3Reader::readMetaData()");
ifstream file;
file.open(filename.c_str());
TEST_EXIT(file.is_open())
("Cannot open arh meta file \"%s\"\n", filename.c_str());
string readStr = "";
file >> readStr;
arhPrefix = "";
file >> arhPrefix;
int nProc;
file >> nProc;
MSG("found nProc %d in file %s \n",nProc,filename.c_str());
// Maps to each macro element index the arh file index it is stored in.
for (int i = 0; i < nProc; i++) {
int tmp;
file >> tmp;
TEST_EXIT(tmp == i)("Should not happen!\n");
int nMacroEl;
file >> nMacroEl;
for (int j = 0; j < nMacroEl; j++) {
int elIndex, codeSize;
file >> elIndex;
file >> codeSize;
elInRank[elIndex] = i;
elCodeSize[elIndex] = codeSize;
}
}
file.close();
return nProc;
}
int readMetaData(string filename)
{
FUNCNAME("Arh3Reader::readMetaData()");
ifstream file;
file.open(filename.c_str());
TEST_EXIT(file.is_open())
("Cannot open arh meta file \"%s\"\n", filename.c_str());
string readStr = "";
file >> readStr;
file >> readStr;
int nProc;
file >> nProc;
file.close();
return nProc;
}
int readMetaFromArh(std::string filename,
std::map<int, int> &elInRank,
std::map<int, int> &elCodeSize)
{
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
int nProcs = MPI::COMM_WORLD.Get_size();
#else
int nProcs = -1;
#endif
// check for consistency
// That is, if there are no more or less files as nProcs
int i = 0;
for (; i < nProcs + 1; i++) {
string fn = filename + "-p" + boost::lexical_cast<string>(i) + "-.arh";
if(!boost::filesystem::exists(fn)) break;
}
TEST_EXIT(i == nProcs)
("Number of arh files doesn't match number of processors \n");
// data format: (rank ; (elIndex; elCodeSize) )
vector<std::set<pair<int, int> > > data(nProcs);
//collect data
for (int i = 0; i < nProcs; i++) {
string fn = filename + "-p" + boost::lexical_cast<string>(i) + "-.arh";
detail::readMetaFromSgArh(fn, i, data);
}
//make elInRank and elCodeSize-Map
for (int i = 0; i < nProcs; i++) {
for (std::set<pair<int, int> >::iterator it = data[i].begin();
it != data[i].end(); ++it){
elInRank[it->first]=i;
elCodeSize[it->first]=it->second;
}
}
return nProcs;
}
} // end namespace Arh3Reader
} } // end namespace io, AMDiS
#ifndef AMDIS_ARH_READER3_H
#define AMDIS_ARH_READER3_H
/** \file Arh3Reader.h */
#include "AMDiS_fwd.h"
#include "Global.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#define WRITE_PARALLEL true
#else
#define WRITE_PARALLEL false
#endif
namespace AMDiS { namespace io {
/** \ingroup Input
* \brief Reader for the AMDiS ARH-format - version 3
*
* A collection of methods to read to various container types from
* ARH-files.
**/
namespace Arh3Reader
{
const uint8_t MAJOR = 3;
const uint8_t MINOR = 0;
/**
* \brief Read MeshStructure, refine the mesh and read dof values to sysVec by order.
* When reading dof values, it puts the data into the correspond DOFVector
* (according to their order in the sysVec and in the file, which is the same as the old ArhReader).
* Normally, just use the default value of \ref writeParallel and \ref nProcs.
*
* You should notice these:
* 1. DOFVectors in SystemVector are not allowed to have identical name.
* 2. The length of DOFVectors in SystemVector is less than the length of values in the file.
* 3. NULL of DOFVector is allowed in SystemVector. But all the non-null DOFvector have the same fespace
* (number of Dofs per position) as the correspond value in the file.
*
* \param writeParallel
* the default value in Sequential Model is false.
* the default value in Parallel Model is true.
* if the value is set to false, no matter in sequential or parallel mode, the processor(s) will
* read the file of the same given name, without adding thier process numbers: for example: "-p1-".
* if the value is set to true, in Parallel Model, the behavior depends on \ref nProcs.
* But in Sequential Model, an error will be thrown.
* \param nProcs
* the default value is -1. But it only affects when \ref writeParallel is set to true.
* If nProcs is -1, and it's in Parallel Model, every processor reads their own filename (with processor
* numbers). But in Sequential Model, an error will be thrown.
* And you can also set nProcs to a value which is smaller than the number of Processors. Then every
* processor will read all the files with names from -p0- to -p[nProcs]-.
*/
void readFile(std::string filename,
SystemVector* sysVec,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
inline
void readFile(std::string filename,
SystemVector& sysVec,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1)
{
readFile(filename, &sysVec, writeParallel, nProcs);
}
/// Read MeshStructure, refine the mesh and read dof values to vec0, vec1 and vec2 by order.
/// the behavior is equal to readFile(string filename, SystemVector* sysVec).
void readFile(std::string filename,
DOFVector<double>* vec0 = NULL,
DOFVector<double>* vec1 = NULL,
DOFVector<double>* vec2 = NULL,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
inline
void readFile(std::string filename,
DOFVector<double>& vec0,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1)
{
readFile(filename, &vec0, NULL, NULL, writeParallel, nProcs);
}
/// Read MeshStructure, refine the mesh and read dof values to vecs by order.
/// the behavior is equal to readFile(string filename, SystemVector* sysVec).
void readFile(std::string filename,
std::vector<DOFVector<double>*> vecs,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
/// Read MeshStructure and refine the mesh from arh file.
void readFile(std::string filename,
Mesh* mesh,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
inline
void readFile(std::string filename,
Mesh& mesh,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1)
{
readFile(filename, &mesh, writeParallel, nProcs);
}
/**
* \brief Read MeshStructure, refine the mesh and read dof values to sysVec by name.
* It traverses all the values in the file to get the first matching value with the same name
* and fespace, and then reads the data. If it doesn't find any matching, an error will be thrown.
* Normally, just use the default value of \ref writeParallel and \ref nProcs. See readFile for
* detail information.
*
* You should notice these:
* 1. DOFVectors in SystemVector are not allowed to have identical name.
* 2. The length of SystemVector is less than the length of values in the file.
* 3. There is at least one value in the file has the same name and fespace as the DOFVector in SystemVector.
*/
void readByName(std::string filename,
SystemVector *sysVec,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
/// Read MeshStructure, refine the mesh and read dof values to vecs by name.
/// the behavior is equal to readByName(string filename, SystemVector* sysVec).
void readByName(std::string filename,
std::vector<DOFVector<double>*> vecs,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
/// Read MeshStructure, refine the mesh and read dof values to vec by name.
/// the behavior is equal to readByName(string filename, SystemVector* sysVec).
void readByName(std::string filename,
DOFVector<double>& vec,
bool writeParallel = WRITE_PARALLEL,
int nProcs = -1);
/// Read MeshStructure, refine the mesh and read dof values to vec by name.
/// the behavior is equal to readByName(string filename, SystemVector* sysVec).