Commit 72990c0d authored by Siqi Ling's avatar Siqi Ling

arh3.0 finished with test_suit test_arh_3.0

parent dfd9bc02
......@@ -842,7 +842,7 @@ namespace AMDiS {
std::cout << "(" << elCoords[i][0] << ", " << elCoords[i][1]<< ", " << elCoords[i][2] << ") ";
std::cout << "another is: ";
std::cout << "(" << coords[el->getIndex()][i][0] << ", " << coords[el->getIndex()][i][1]
<< ". " << coords[el->getIndex()][i][2] << ")\n";
<< ", " << coords[el->getIndex()][i][2] << ")\n";
break;
default:
ERROR_EXIT("What is this?\n");
......
......@@ -145,7 +145,7 @@ namespace AMDiS { namespace io {
uint32_t nValueVectors = 0;
detail::firstRead(file);
detail::firstRead(file, "sarh", MAJOR, MINOR);
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);
detail::firstRead(file, "sarh", MAJOR, MINOR);
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 == "arh2" && major == MAJOR && minor <= MINOR) ? true : false;
return (typeId == "sarh" && major == MAJOR && minor <= MINOR) ? true : false;
}
void readMeta(string filename,
......
......@@ -23,8 +23,8 @@ namespace AMDiS { namespace io {
**/
namespace Arh2Reader
{
const uint8_t MAJOR = 2;
const uint8_t MINOR = 1;
const uint8_t MAJOR = 3;
const uint8_t MINOR = 0;
/**
* \brief Read MeshStructure, refine the mesh and read dof values to sysVec by order.
......
......@@ -14,9 +14,7 @@ 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
......@@ -45,57 +43,69 @@ namespace AMDiS { namespace io {
*/
inline void writeFile(SystemVector *sysVec,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
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);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
inline void writeFile(SystemVector &sysVec,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
writeFile(&sysVec, filename, writeParallel);
writeFile(&sysVec, filename, writeParallel, cps, dataformat);
}
/// 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)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
std::vector<DOFVector<double>*> vecs;
vecs.push_back(vec0);
detail::write(filename, NULL, vecs, writeParallel);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
/// 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)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
writeFile(&vec0, filename, writeParallel);
writeFile(&vec0, filename, writeParallel, cps, dataformat);
}
/// 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)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
detail::write(filename, NULL, vecs, writeParallel);
detail::write(filename, NULL, vecs, writeParallel, cps, dataformat);
}
/// write the meshstructure of the mesh to arh file.
inline void writeFile(Mesh *mesh,
std::string filename,
bool writeParallel = true)
bool writeParallel = true,
Cpsformat cps = NONE,
std::string dataformat = "SF64")
{
std::vector<DOFVector<double>*> vecs;
detail::write(filename, mesh, vecs, writeParallel);
detail::write(filename, mesh, vecs, writeParallel, cps, dataformat);
}
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
......
This diff is collapsed.
......@@ -23,7 +23,7 @@ namespace AMDiS { namespace io {
* 3. the minor version of Arh2Reader is bigger than the one in the file.
* return value: minor version
*/
uint8_t firstRead(std::ifstream& file);
void firstRead(std::ifstream& file, std::string, uint8_t, uint8_t);
void setDofValues(int macroElIndex, Mesh *mesh,
std::vector<std::vector<double> >& values,
......@@ -60,6 +60,11 @@ namespace AMDiS { namespace io {
std::vector<DOFVector<double>*> vecs,
bool byName = false);
void readValues(std::stringstream&, std::string dataformat, std::vector<double>&);
template<typename T>
void readValues(std::stringstream&, std::vector<double>&);
void readFile(std::string filename,
Mesh *mesh,
std::vector<DOFVector<double>*> vecs,
......@@ -73,6 +78,13 @@ namespace AMDiS { namespace io {
int readNumOfMacrosFromSgArh(std::string filename, int nProc = -1);
void readParallelFile(std::string filename,
std::string& filenameType,
std::vector<int>& partition,
int& nFiles,
int& nMacros);
}//end namespace detail
} // end namespace Arh2Reader
......
......@@ -7,12 +7,13 @@
#include "MeshStructure.h"
#include "Traverse.h"
#include "DOFVector.h"
#include "../Arh2Writer.h"
#include "../Arh2Reader.h"
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#ifdef HAVE_COMPRESSION
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#endif
namespace AMDiS { namespace io {
......@@ -27,7 +28,10 @@ namespace AMDiS { namespace io {
DOFVector<double>* vec0,
DOFVector<double>* vec1,
DOFVector<double>* vec2,
bool writeParallel)
bool writeParallel,
Cpsformat cps,
string dataformat,
string filenameType)
{
vector<DOFVector<double>*> vecs(0);
if (vec0 != NULL)
......@@ -37,16 +41,63 @@ namespace AMDiS { namespace io {
if (vec2 != NULL)
vecs.push_back(vec2);
write(filename, NULL, vecs, writeParallel);
write(filename, NULL, vecs, writeParallel, cps, dataformat, filenameType);
}
void write(std::string filename,
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
void writeParallelFile(string filename, Mesh* mesh, string filenameType)
{
TEST_EXIT(filenameType == "cont")("Unsupported filename type.\n");
ofstream file;
file.open(filename.c_str(), ios::out | ios::binary | ios::trunc);
string typeId = "parh", macroFilename = "";
Parameters::get(mesh->getName() + "->macro file name", macroFilename);
uint8_t major = 1;
uint8_t minor = 1;
uint32_t nFiles = MPI::COMM_WORLD.Get_size();
uint32_t macroFile_nl = macroFilename.length();
map<int, int> partitionMap =
Parallel::MeshDistributor::globalMeshDistributor->getPartitionMap();
uint32_t nMacros =partitionMap.size();
file.write(typeId.c_str(), 4);
file.write(reinterpret_cast<char*>(&major), 1);
file.write(reinterpret_cast<char*>(&minor), 1);
file.write(reinterpret_cast<char*>(&nFiles), 4);
file.write(filenameType.c_str(), 4);
file.write(reinterpret_cast<char*>(&nMacros), 4);
file.write(reinterpret_cast<char*>(&macroFile_nl), 4);
file.write(macroFilename.c_str(), macroFile_nl);
map<int, int>::const_iterator it = partitionMap.begin();
uint32_t rank = 0;
for (;it != partitionMap.end(); it++) {
rank = it->second;
file.write(reinterpret_cast<char*>(&rank), 4);
}
}
#endif
void write(string filename,
Mesh* mesh,
std::vector<DOFVector<double>*> vecs,
bool writeParallel)
vector<DOFVector<double>*> vecs,
bool writeParallel,
Cpsformat cps,
string dataformat,
string filenameType)
{
FUNCNAME("Arh2Writer::detail::write()");
if (!mesh && vecs.empty()) {
WARNING("There is nothing to be writen.\n");
return;
}
map<string,Valformat>::const_iterator it = dataformatMap.find(dataformat);
TEST_EXIT(it != dataformatMap.end())("Wrong data format.\n");
std::set<string> nameSet;
pair<std::set<string>::iterator,bool> ret;
......@@ -56,6 +107,28 @@ namespace AMDiS { namespace io {
ret = nameSet.insert(vecs[i]->getName());
TEST_EXIT(ret.second)("DOFVectors in vecs cannot have idential name. Please check.\n");
}
#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;
Mesh* mesh_ = mesh ? mesh : vecs[0]->getFeSpace()->getMesh();
if (MPI::COMM_WORLD.Get_rank() == 0) {
writeParallelFile(name + ".parh",
mesh ? mesh : vecs[0]->getFeSpace()->getMesh(),
filenameType);
}
TEST_EXIT(filenameType == "cont")("Only filename type \"cont\".\n");
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
}
#endif
//if mesh exists, the meshes in vecs should be the same.
if(mesh)
{
......@@ -64,16 +137,11 @@ namespace AMDiS { namespace io {
TEST_EXIT(mesh == vecs[i]->getFeSpace()->getMesh())
("The mesh of DOFVector %i in vecs is not equal to the second parameter.\n", i);
}
writeAux(filename, mesh, vecs, writeParallel);
writeAux(filename, mesh, vecs, writeParallel, cps, dataformat);
}
//multiple meshes are allowed here.
else
{
if(vecs.empty())
{
WARNING("There is nothing to be writen.\n");
return;
}
vector<bool> visited(vecs.size(), false);
vector<DOFVector<double>*> splitedVecs(0);
bool moreMesh = false;
......@@ -113,23 +181,32 @@ namespace AMDiS { namespace io {
newfilename = filename + "." + tmpMesh->getName() + ".arh";
}
writeAux(newfilename, splitedVecs[0]->getFeSpace()->getMesh(), splitedVecs, writeParallel);
writeAux(newfilename, splitedVecs[0]->getFeSpace()->getMesh(), splitedVecs, writeParallel, cps, dataformat);
}
}
}
}
}
int writeHeader(ofstream& file,
Mesh *mesh,
vector<DOFVector<double>*> vecs,
map<const FiniteElemSpace*, vector<int> >& feSpaces)
map<const FiniteElemSpace*, vector<int> >& feSpaces,
Cpsformat cps,
string dataformat)
{
FUNCNAME("Arh2Writer::detail::writeHeader()");
int nbits = boost::lexical_cast<int>(dataformat.substr(2, 2));
TEST_EXIT(file.is_open())("the file is not open. should not happen.\n");
uint32_t namesLen = 0;
for(size_t i = 0; i < vecs.size(); i++)
namesLen += vecs[i]->getName().length();
map<const FiniteElemSpace*, string> AFEDfileName;
uint32_t valueNamesLen = 0, fileNamesLen = 0;
for (size_t i = 0; i < vecs.size(); i++)
valueNamesLen += vecs[i]->getName().length();
map<const FiniteElemSpace*, vector<int> >::iterator feSpaceIt;
for (feSpaceIt = feSpaces.begin(); feSpaceIt != feSpaces.end(); feSpaceIt++)
AFEDfileName.insert(make_pair(feSpaceIt->first, string()));
uint32_t nValueVectors = vecs.size();
uint32_t nFeSpaces = feSpaces.size();
......@@ -145,17 +222,20 @@ namespace AMDiS { namespace io {
uint32_t dow = mesh->getGeo(WORLD);
uint32_t dim = mesh->getDim();
uint32_t headerLen = 34 + //fixed part of header
nMacroElements * 8 + //macroElemnts table
nFeSpaces * 16 + //feSpaces table
namesLen + //value vector table
nValueVectors * 8; //also value vector table
string typeId = "arh2", cps("null");
#ifdef HAVE_COMPRESSION
cps = "zlib";
uint32_t headerLen = 34 + //fixed part of header
nMacroElements * 12 + 12 + //macroElemnts table
fileNamesLen + //feSpaces table
nFeSpaces * 20 + //feSpaces table
valueNamesLen + //value vector table
nValueVectors * 12; //also value vector table
string typeId = "sarh";
#ifndef HAVE_COMPRESSION
cps = NONE;
#endif
uint8_t *major = const_cast<uint8_t*>(&(AMDiS::io::Arh2Writer::MAJOR));
uint8_t *minor = const_cast<uint8_t*>(&(AMDiS::io::Arh2Writer::MINOR));
uint8_t *major = const_cast<uint8_t*>(&(AMDiS::io::Arh2Reader::MAJOR));
uint8_t *minor = const_cast<uint8_t*>(&(AMDiS::io::Arh2Reader::MINOR));
int cpsflag = static_cast<int>(cps);
uint32_t minus1 = -1;
//fixed header
file.write(typeId.c_str(), 4);
......@@ -167,78 +247,79 @@ namespace AMDiS { namespace io {
file.write(reinterpret_cast<char*>(&nFeSpaces), 4);
file.write(reinterpret_cast<char*>(&nValueVectors), 4);
file.write(reinterpret_cast<char*>(&nMacroElements), 4);
file.write(cps.c_str(), 4);
file.write(reinterpret_cast<char*>(&cpsflag), 4);
//macro table
deque<MacroElement*>::const_iterator macroIter = mesh->firstMacroElement();
while(macroIter != mesh->endOfMacroElements())
{
uint32_t macroIndex = (*macroIter)->getIndex(), macroPos = 0;
uint32_t macroIndex = (*macroIter)->getIndex();
file.write(reinterpret_cast<char*>(&macroIndex), 4);
file.write(reinterpret_cast<char*>(&macroPos), 4);
file.write(reinterpret_cast<char*>(&minus1), 4);
file.write(reinterpret_cast<char*>(&minus1), 4);
macroIter++;
}
file.write(reinterpret_cast<char*>(&minus1), 4);
file.write(reinterpret_cast<char*>(&minus1), 4);
file.write(reinterpret_cast<char*>(&minus1), 4);
map<const FiniteElemSpace*, vector<int> >::iterator feSpaceIt;
vector<int> feSpaceNumOfVecs(vecs.size());
uint32_t posDOFs = 0, vecNameLen = 0;
string vecName("");
uint32_t posDOFs = 0, nameStrLen = 0;
string nameStr("");
size_t i = 0;
//feSpace table
for(feSpaceIt = feSpaces.begin(); feSpaceIt != feSpaces.end(); feSpaceIt++, i++)
{
nameStr = AFEDfileName[feSpaceIt->first];
nameStrLen = nameStr.length();
file.write(reinterpret_cast<char*>(&nameStrLen), 4);
file.write(nameStr.c_str(), nameStrLen);
DimVec<int>* nDOF = feSpaceIt->first->getBasisFcts()->getNumberOfDofs();
for(int j = 0; j < nDOF->getSize(); j++)
{
//
for(size_t j = 1; j < nDOF->getSize(); j++) {
posDOFs = (*nDOF)[j];
file.write(reinterpret_cast<char*>(&posDOFs), 4);
}
for(size_t j = nDOF->getSize(); j < 4 ; j++)
{
for(size_t j = nDOF->getSize(); j < 4 ; j++) {
posDOFs = 0;
file.write(reinterpret_cast<char*>(&posDOFs), 4);
}
posDOFs = (*nDOF)[0];
file.write(reinterpret_cast<char*>(&posDOFs), 4);
//
for(size_t j = 0; j < feSpaceIt->second.size(); j++)
{
feSpaceNumOfVecs[feSpaceIt->second[j]] = i;
}
}
//vector table
for(i = 0; i < vecs.size(); i++)
{
vecName = vecs[i]->getName();
vecNameLen = vecs[i]->getName().length();
file.write(reinterpret_cast<char*>(&vecNameLen), 4);
file.write(vecName.c_str(), vecNameLen);
nameStr = vecs[i]->getName();
nameStrLen = nameStr.length();
file.write(reinterpret_cast<char*>(&nameStrLen), 4);
file.write(nameStr.c_str(), nameStrLen);
file.write(reinterpret_cast<char*>(&feSpaceNumOfVecs[i]), 4);
file.write(dataformat.c_str(), 4);
}
return headerLen;
}
void writeAux(string filename, Mesh *mesh,
vector<DOFVector<double>*> vecs,
bool writeParallel)
bool writeParallel,
Cpsformat cps,
string dataformat)
{
FUNCNAME("Arh2Writer::detail::writeAux()");
#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);
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
}
#endif
//initialization
ofstream file;
file.open(filename.c_str(), ios::out | ios::binary | ios::trunc);
map<const FiniteElemSpace*, vector<int> > sortedFeSpaces;
map<const FiniteElemSpace*, vector<int> >::iterator feSpaceIt;
vector<int> macroBlockSize;
vector<pair<int, int> > macroSize; // (uncompressed size, compressed size)
DegreeOfFreedom globalDof;
size_t i = 0, j = 0;
......@@ -250,7 +331,7 @@ namespace AMDiS { namespace io {
vector<std::set<DegreeOfFreedom> > visited(sortedFeSpaces.size());
pair<std::set<DegreeOfFreedom>::iterator,bool> ret;
//file header information
writeHeader(file, mesh, vecs, sortedFeSpaces);
int headerLen = writeHeader(file, mesh, vecs, sortedFeSpaces, cps, dataformat);
//macro elements information
MeshStructure elementStructure;
......@@ -263,18 +344,17 @@ namespace AMDiS { namespace io {
if (elInfo->getLevel() == 0) {
if (macroElIndex != -1) {
elementStructure.commit();
macroBlockSize.push_back(writeMacroElement(file, elementStructure, values, sortedFeSpaces));
macroSize.push_back(writeMacroElement(file, elementStructure, values, sortedFeSpaces, cps, dataformat));
}
elementStructure.clear();
macroElIndex = elInfo->getElement()->getIndex();
for (j = 0; j < vecs.size(); j++) {
for (j = 0; j < vecs.size(); j++)
values[j].clear();
}
for (j = 0; j < sortedFeSpaces.size(); j++)
{
visited[j].clear();
}
visited[j].clear();
}
elementStructure.insertElement(elInfo->getElement()->isLeaf());
......@@ -371,30 +451,39 @@ namespace AMDiS { namespace io {
// And write the last macro element to file.
TEST_EXIT_DBG(macroElIndex != -1)("Should not happen!\n");
elementStructure.commit();
macroBlockSize.push_back(writeMacroElement(file, elementStructure, values, sortedFeSpaces));
TEST_EXIT(macroBlockSize.size() == (unsigned)mesh->getNumberOfMacros())("Should not happen.\n");
macroSize.push_back(writeMacroElement(file, elementStructure, values, sortedFeSpaces, cps, dataformat));
TEST_EXIT(macroSize.size() == (unsigned)mesh->getNumberOfMacros())("Should not happen.\n");
//reset the macro positions in file
setMacrosPos(file, macroBlockSize);
setMacrosPos(file, headerLen, macroSize);
file.close();
MSG("ARH file written to: %s\n", filename.c_str());
}
void setMacrosPos(ofstream& file,
vector<int>& macroBlockSize)
void setMacrosPos(ofstream& file, int headerLen,
vector<pair<int, int> >& macroSize)
{
file.seekp(34);
for(size_t i = 0; i < macroBlockSize.size(); i++)
long pos = 0;
int startPos = headerLen;
for(size_t i = 0; i < macroSize.size(); i++)
{
long pos = file.tellp();
pos = file.tellp();
file.seekp(pos + 4);
file.write(reinterpret_cast<char*>(&macroBlockSize[i]), 4);
file.write(reinterpret_cast<char*>(&startPos), 4);
file.write(reinterpret_cast<char*>(&macroSize[i].first), 4);
startPos += macroSize[i].second;
}
pos = file.tellp();
file.seekp(pos + 4);
file.write(reinterpret_cast<char*>(&startPos), 4);
}
int writeMacroElement(ofstream &file,
pair<int, int> writeMacroElement(ofstream &file,
MeshStructure &code,
vector<vector<double> >& values,
map<const FiniteElemSpace*, vector<int> >& feSpaces)
map<const FiniteElemSpace*, vector<int> >& feSpaces,
Cpsformat cps,
string dataformat)
{
stringstream dataStream(ios::out | ios::in | ios::binary);
......@@ -417,24 +506,92 @@ namespace AMDiS { namespace io {
moreSize += 4;
for (size_t i = 0; i < it->second.size(); i++)
{
dataStream.write(reinterpret_cast<char*>(&(values[valuePos + i][0])), 8 * nValuesPerVector);
moreSize += 8 * nValuesPerVector;
}
moreSize += writeValues(dataStream, dataformat, values[valuePos + i]);
valuePos += it->second.size();
}
}
stringstream tmp(ios::out | ios::in | ios::binary);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
#ifdef HAVE_COMPRESSION
in.push(boost::iostreams::zlib_compressor());
switch(cps)
{
case ZLIB:
in.push(boost::iostreams::zlib_compressor());
break;
case BZIP2:
in.push(boost::iostreams::bzip2_compressor());
break;
case NONE:
break;
default:
MSG("NOT correct compression flag.\n");
}
#endif
in.push(dataStream);
boost::iostreams::copy(in, tmp);
file << tmp.rdbuf();
return tmp.str().length();
return make_pair(dataStream.str().length(), tmp.str().length());
}