Commit 682a54ee authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Compression support added to VtkWriter

parent 76fe101c
...@@ -57,7 +57,7 @@ namespace AMDiS ...@@ -57,7 +57,7 @@ namespace AMDiS
{ {
initialize(); initialize();
/** /*
* Removed by Siqi. not sure. * Removed by Siqi. not sure.
* for (int i = 0; i < static_cast<int>(vecs->getSize()); i++) * for (int i = 0; i < static_cast<int>(vecs->getSize()); i++)
* TEST_EXIT(vecs->getDOFVector(0)->getFeSpace() == vecs->getDOFVector(i)->getFeSpace()) * TEST_EXIT(vecs->getDOFVector(0)->getFeSpace() == vecs->getDOFVector(i)->getFeSpace())
...@@ -171,10 +171,7 @@ namespace AMDiS ...@@ -171,10 +171,7 @@ namespace AMDiS
} }
if (writeParaViewFormat) { if (writeParaViewFormat) {
VtkWriter::Aux vtkWriter(&dataCollectors); VtkWriter::Aux vtkWriter(&dataCollectors, VtkWriter::Vtuformat(paraViewMode), (paraViewPrecision == 1));
#ifdef HAVE_COMPRESSION
vtkWriter.setCompression(compression);
#endif
vtkWriter.writeFile(fn + paraviewFileExt); vtkWriter.writeFile(fn + paraviewFileExt);
#if HAVE_PARALLEL_DOMAIN_AMDIS #if HAVE_PARALLEL_DOMAIN_AMDIS
...@@ -187,7 +184,9 @@ namespace AMDiS ...@@ -187,7 +184,9 @@ namespace AMDiS
MPI::COMM_WORLD.Get_size(), MPI::COMM_WORLD.Get_size(),
filename, filename,
postfix, postfix,
componentNames); componentNames,
VtkWriter::Vtuformat(paraViewMode),
(paraViewPrecision == 1));
} }
#endif #endif
......
...@@ -161,6 +161,12 @@ namespace AMDiS { ...@@ -161,6 +161,12 @@ namespace AMDiS {
/// 0: Don't write ParaView files; 1: Write ParaView files. /// 0: Don't write ParaView files; 1: Write ParaView files.
int writeParaViewFormat; int writeParaViewFormat;
/// 0: ASCII mode; 1: Appended mode; 2:Appended_compressed mode.
int paraViewMode;
/// 0: FLOAT32 precision; 1: FLOAT64 precision. Only works in appended and appended_compressed mode.
int paraViewPrecision;
/// 0: Don't write ParaView std::vector files; 1: Write ParaView std::vector files. /// 0: Don't write ParaView std::vector files; 1: Write ParaView std::vector files.
int writeParaViewVectorFormat; int writeParaViewVectorFormat;
......
...@@ -117,6 +117,8 @@ namespace AMDiS ...@@ -117,6 +117,8 @@ namespace AMDiS
periodicFileExt = ".per"; periodicFileExt = ".per";
writeAMDiSFormat = 0; writeAMDiSFormat = 0;
writeParaViewFormat = 0; writeParaViewFormat = 0;
paraViewMode = 0;
paraViewPrecision = 0;
writeParaViewVectorFormat = 0; writeParaViewVectorFormat = 0;
writeAs3dVector = false; writeAs3dVector = false;
writeParaViewAnimation = 0; writeParaViewAnimation = 0;
...@@ -149,6 +151,8 @@ namespace AMDiS ...@@ -149,6 +151,8 @@ namespace AMDiS
Parameters::get(name + "->AMDiS mesh ext", amdisMeshExt); Parameters::get(name + "->AMDiS mesh ext", amdisMeshExt);
Parameters::get(name + "->AMDiS data ext", amdisDataExt); Parameters::get(name + "->AMDiS data ext", amdisDataExt);
Parameters::get(name + "->ParaView format", writeParaViewFormat); Parameters::get(name + "->ParaView format", writeParaViewFormat);
Parameters::get(name + "->ParaView mode", paraViewMode);
Parameters::get(name + "->ParaView precision", paraViewPrecision);
Parameters::get(name + "->ParaView vector format", writeParaViewVectorFormat); Parameters::get(name + "->ParaView vector format", writeParaViewVectorFormat);
Parameters::get(name + "->write vector as 3d vector", writeAs3dVector); Parameters::get(name + "->write vector as 3d vector", writeAs3dVector);
Parameters::get(name + "->ParaView animation", writeParaViewAnimation); Parameters::get(name + "->ParaView animation", writeParaViewAnimation);
......
...@@ -43,6 +43,7 @@ namespace AMDiS ...@@ -43,6 +43,7 @@ namespace AMDiS
std::vector<DOFVector<T>*> dofVectors, std::vector<DOFVector<T>*> dofVectors,
std::vector<std::string> componentNames) std::vector<std::string> componentNames)
{ {
using namespace std;
using namespace pugi; using namespace pugi;
using namespace AMDiS::io::VtkReader; using namespace AMDiS::io::VtkReader;
...@@ -58,31 +59,103 @@ namespace AMDiS ...@@ -58,31 +59,103 @@ namespace AMDiS
TEST_EXIT(vtu.load_file(filename.c_str()))("Could not load vtu file! Error in xml structure.\n"); TEST_EXIT(vtu.load_file(filename.c_str()))("Could not load vtu file! Error in xml structure.\n");
xml_node VTKFile = vtu.child("VTKFile"); xml_node VTKFile = vtu.child("VTKFile");
string zlib = VTKFile.attribute("compressor").value();
TEST_EXIT(zlib == "" || zlib == "vtkZLibDataCompressor")("The only supported compressor is Zlib.\n Should not happen.\n ");
xml_node UnstructuredGrid = VTKFile.child("UnstructuredGrid"); xml_node UnstructuredGrid = VTKFile.child("UnstructuredGrid");
xml_node Piece = UnstructuredGrid.child("Piece"); xml_node Piece = UnstructuredGrid.child("Piece");
xml_node PointData = Piece.child("PointData");
xml_node Points = Piece.child("Points"); xml_node Points = Piece.child("Points");
xml_node PointsDataArray = Points.child("DataArray");
std::string points = Points.child_value("DataArray"); xml_node AppendedData = VTKFile.child("AppendedData");
typedef std::vector<WorldVector<double> > PL;
typedef vector<WorldVector<double> > PL;
PL pointList; PL pointList;
detail::string2pointList(points, pointList); vector<vector<T> > valueList(dofVectors.size());
std::vector<std::vector<T> > valueList(dofVectors.size()); if(!AppendedData) {
T test;
xml_node PointData = Piece.child("PointData");
for (xml_node DataArray = PointData.child("DataArray"); DataArray; DataArray = DataArray.next_sibling("DataArray")) { string points = Points.child_value("DataArray");
std::string Name = DataArray.attribute("Name").value(); detail::string2pointList(points, pointList);
for (size_t i = 0; i < componentNames.size(); i++) {
if (Name == componentNames[i]) { T test;
std::string values = DataArray.last_child().value();
int nComponents = -1; for (xml_node DataArray = PointData.child("DataArray"); DataArray; DataArray = DataArray.next_sibling("DataArray")) {
if (DataArray.attribute("NumberOfComponents")) string Name = DataArray.attribute("Name").value();
nComponents = DataArray.attribute("NumberOfComponents").as_int(); for (size_t i = 0; i < componentNames.size(); i++) {
TEST_EXIT(nComponents == -1 || static_cast<int>(vector_operations::num_rows(test)) <= nComponents) if (Name == componentNames[i]) {
("Can not read values in DOFVector with given value type. Too many components!\n"); string values = DataArray.last_child().value();
detail::string2valueList(values, valueList[i], vector_operations::num_rows(test), nComponents); int nComponents = -1;
break; if (DataArray.attribute("NumberOfComponents"))
nComponents = DataArray.attribute("NumberOfComponents").as_int();
TEST_EXIT(nComponents == -1 || static_cast<int>(vector_operations::num_rows(test)) <= nComponents)
("Can not read values in DOFVector with given value type. Too many components!\n");
detail::string2valueList(values, valueList[i], vector_operations::num_rows(test), nComponents);
break;
}
}
}
} else {
string encoding = AppendedData.attribute("encoding").value();
TEST_EXIT(encoding == "base64")
("Currently the encoding of AppendedData only supports base64. But it's easy to extend to raw.\n");
string appendedData = AppendedData.last_child().value();
int start = appendedData.find("_");
appendedData = appendedData.substr(start + 1, appendedData.length() - 1);
vector<int> offsetVec;
int pointsIndex = 0, index = 0;
vector<pair<xml_node, int> > pointDataIndex;
for (xml_node Parent = Piece.first_child(); Parent; Parent = Parent.next_sibling()) {
for(xml_node Data = Parent.child("DataArray"); Data; Data = Data.next_sibling("DataArray"), index++) {
string parentName = Data.parent().name();
if(parentName == "Points")
pointsIndex = index;
if(parentName == "PointData")
pointDataIndex.push_back(make_pair(Data, index));
offsetVec.push_back(Data.attribute("offset").as_int());
}
}
string format = PointsDataArray.attribute("format").value();
string type = PointsDataArray.attribute("type").value();
TEST_EXIT(format == "appended")("The format of DataArray is not appended in appended mode. Should not happen.\n");
TEST_EXIT(type == "Float32" || type == "Float64")("Currently only supports Points with type Float32 and Float64.\n");
int len = ((unsigned)(pointsIndex + 1) == offsetVec.size()) ?
appendedData.length() - offsetVec[pointsIndex] :
offsetVec[pointsIndex + 1] - offsetVec[pointsIndex];
string points = appendedData.substr(offsetVec[pointsIndex], len);
detail::binary2pointList(points, type, (zlib != ""), pointList);
T test;
for (size_t i = 0 ; i < pointDataIndex.size(); i++) {
string Name = pointDataIndex[i].first.attribute("Name").value();
for (size_t j = 0; j < componentNames.size(); j++) {
if(Name == componentNames[j]) {
format = pointDataIndex[i].first.attribute("format").value();
type = pointDataIndex[i].first.attribute("type").value();
TEST_EXIT(format == "appended")("The format of DataArray is not appended in appended mode. Should not happen.\n");
TEST_EXIT(type == "Float32" || type == "Float64")("Currently only supports PointData with type Float32 and Float64.\n");
len = ((unsigned)(pointDataIndex[i].second + 1) == offsetVec.size())?
appendedData.length() - offsetVec[pointDataIndex[i].second]:
offsetVec[pointDataIndex[i].second + 1] - offsetVec[pointDataIndex[i].second];
string values = appendedData.substr(offsetVec[pointDataIndex[i].second], len);
int nComponents = -1;
if (pointDataIndex[i].first.attribute("NumberOfComponents"))
nComponents = pointDataIndex[i].first.attribute("NumberOfComponents").as_int();
TEST_EXIT(nComponents == -1 || static_cast<int>(vector_operations::num_rows(test)) <= nComponents)
("Can not read values in DOFVector with given value type. Too many components!\n");
detail::binary2valueList(values, type, (zlib != ""), valueList[j], vector_operations::num_rows(test), nComponents);
break;
}
} }
} }
} }
...@@ -100,7 +173,7 @@ namespace AMDiS ...@@ -100,7 +173,7 @@ namespace AMDiS
tree.index->buildIndex(); tree.index->buildIndex();
DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS); DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
std::vector<DOFIterator<T>*> it_results; vector<DOFIterator<T>*> it_results;
for (size_t i = 0; i < dofVectors.size(); i++) { for (size_t i = 0; i < dofVectors.size(); i++) {
it_results.push_back(new DOFIterator<T>(dofVectors[i], USED_DOFS)); it_results.push_back(new DOFIterator<T>(dofVectors[i], USED_DOFS));
it_results[i]->reset(); it_results[i]->reset();
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "ElementRegion_ED.h" #include "ElementRegion_ED.h"
#include "AdaptInfo.h" #include "AdaptInfo.h"
#include "detail/VtkWriter.h"
namespace AMDiS namespace AMDiS
{ {
...@@ -53,23 +53,29 @@ namespace AMDiS ...@@ -53,23 +53,29 @@ namespace AMDiS
void writeFile(DOFVector<double> *values, void writeFile(DOFVector<double> *values,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
DataCollector<> dc(values->getFeSpace(), values); DataCollector<> dc(values->getFeSpace(), values);
vector<DataCollector<>*> dcList(0); vector<DataCollector<>*> dcList(0);
dcList.push_back(&dc); dcList.push_back(&dc);
writeFile(dcList, filename, writeParallel); writeFile(dcList, filename, format, highPrecision, writeParallel);
} }
void writeFile(vector<DOFVector<double>* > &values, void writeFile(vector<DOFVector<double>* > &values,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
vector<DataCollector<>*> dcList(0); vector<DataCollector<>*> dcList(0);
for (size_t i = 0; i < values.size(); i++) for (size_t i = 0; i < values.size(); i++)
dcList.push_back(new DataCollector<>(values[i]->getFeSpace(), values[i])); dcList.push_back(new DataCollector<>(values[i]->getFeSpace(), values[i]));
writeFile(dcList, filename, writeParallel); writeFile(dcList, filename, format, highPrecision, writeParallel);
for (size_t i = 0; i < values.size(); i++) for (size_t i = 0; i < values.size(); i++)
delete dcList[i]; delete dcList[i];
} }
...@@ -77,12 +83,15 @@ namespace AMDiS ...@@ -77,12 +83,15 @@ namespace AMDiS
void writeFile(WorldVector<DOFVector<double>* > &values, void writeFile(WorldVector<DOFVector<double>* > &values,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
vector<DataCollector<>*> dcList(0); vector<DataCollector<>*> dcList(0);
for (int i = 0; i < values.getSize(); i++) for (int i = 0; i < values.getSize(); i++)
dcList.push_back(new DataCollector<>(values[i]->getFeSpace(), values[i])); dcList.push_back(new DataCollector<>(values[i]->getFeSpace(), values[i]));
writeFile(dcList, filename, writeParallel); writeFile(dcList, filename, format, highPrecision, writeParallel);
for (int i = 0; i < values.getSize(); i++) for (int i = 0; i < values.getSize(); i++)
delete dcList[i]; delete dcList[i];
} }
...@@ -90,14 +99,17 @@ namespace AMDiS ...@@ -90,14 +99,17 @@ namespace AMDiS
void writeFile(DOFVector<WorldVector<double> > *values, void writeFile(DOFVector<WorldVector<double> > *values,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
WorldVector<DOFVector<double>*> valuesWV; WorldVector<DOFVector<double>*> valuesWV;
for (int i =0 ; i < valuesWV.getSize(); i++) for (int i =0 ; i < valuesWV.getSize(); i++)
valuesWV[i] = new DOFVector<double>(values->getFeSpace(), valuesWV[i] = new DOFVector<double>(values->getFeSpace(),
"values["+boost::lexical_cast<std::string>(i)+"]"); "values["+boost::lexical_cast<std::string>(i)+"]");
transform(values, &valuesWV); transform(values, &valuesWV);
writeFile(valuesWV, filename, writeParallel); writeFile(valuesWV, filename, format, highPrecision, writeParallel);
for (int i = 0; i < valuesWV.getSize(); i++) for (int i = 0; i < valuesWV.getSize(); i++)
delete valuesWV[i]; delete valuesWV[i];
} }
...@@ -105,13 +117,16 @@ namespace AMDiS ...@@ -105,13 +117,16 @@ namespace AMDiS
void writeFile(SystemVector *values, void writeFile(SystemVector *values,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
vector<DataCollector<>*> dcList(0); vector<DataCollector<>*> dcList(0);
for (int i = 0; i < values->getSize(); i++) for (int i = 0; i < values->getSize(); i++)
dcList.push_back(new DataCollector<>(values->getDOFVector(i)->getFeSpace(), dcList.push_back(new DataCollector<>(values->getDOFVector(i)->getFeSpace(),
values->getDOFVector(i))); values->getDOFVector(i)));
writeFile(dcList, filename, writeParallel); writeFile(dcList, filename, format, highPrecision, writeParallel);
for (size_t i = 0; i < dcList.size(); i++) for (size_t i = 0; i < dcList.size(); i++)
delete dcList[i]; delete dcList[i];
} }
...@@ -119,9 +134,12 @@ namespace AMDiS ...@@ -119,9 +134,12 @@ namespace AMDiS
void writeFile(vector<DataCollector<>*> &dcList, void writeFile(vector<DataCollector<>*> &dcList,
string filename, string filename,
bool writeParallel) Vtuformat format,
bool highPrecision,
bool writeParallel
)
{ {
::AMDiS::io::VtkWriter::Aux writer(&dcList); ::AMDiS::io::VtkWriter::Aux writer(&dcList, format, highPrecision);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (writeParallel) { if (writeParallel) {
...@@ -137,7 +155,7 @@ namespace AMDiS ...@@ -137,7 +155,7 @@ namespace AMDiS
componentNames.push_back(dcList[i]->getValues()->getName()); componentNames.push_back(dcList[i]->getValues()->getName());
detail::writeParallelFile(name + ".pvtu", MPI::COMM_WORLD.Get_size(), detail::writeParallelFile(name + ".pvtu", MPI::COMM_WORLD.Get_size(),
name, ".vtu", componentNames); name, ".vtu", componentNames, format, highPrecision);
} }
filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.vtu"; filename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.vtu";
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "DOFVector.h" #include "DOFVector.h"
#include "FixVec.h" #include "FixVec.h"
#include "SystemVector.h" #include "SystemVector.h"
#include "detail/VtkWriter.h"
namespace AMDiS { namespace io { namespace AMDiS { namespace io {
...@@ -39,11 +40,14 @@ namespace AMDiS { namespace io { ...@@ -39,11 +40,14 @@ namespace AMDiS { namespace io {
* VTU-files. The files generated are text-based XML-structured * VTU-files. The files generated are text-based XML-structured
* files and can be read by ParaView. * files and can be read by ParaView.
**/ **/
namespace VtkWriter namespace VtkWriter
{ {
/// Interface for general containers not implemented. Specializations below. /// Interface for general containers not implemented. Specializations below.
template<typename Container> template<typename Container>
void writeFile(Container& vec, std::string filename, void writeFile(Container& vec, std::string filename,
Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true) bool writeParallel = true)
{ {
ERROR_EXIT("VtkWriter not implemented for this container type!\n"); ERROR_EXIT("VtkWriter not implemented for this container type!\n");
...@@ -52,33 +56,48 @@ namespace AMDiS { namespace io { ...@@ -52,33 +56,48 @@ namespace AMDiS { namespace io {
/// Write a \ref DOFVector to a file. Using a container pointer. /// Write a \ref DOFVector to a file. Using a container pointer.
void writeFile(DOFVector<double> *values, void writeFile(DOFVector<double> *values,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
/// Write a \ref DOFVector to file. Using a container reference. /// Write a \ref DOFVector to file. Using a container reference.
inline inline
void writeFile(DOFVector<double> &values, void writeFile(DOFVector<double> &values,
std::string filename, std::string filename,
bool writeParallel = true) Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
)
{ {
writeFile(&values, filename, writeParallel); writeFile(&values, filename, format, highPrecision, writeParallel);
} }
/// Write a vector of \ref DOFVector to file. /// Write a vector of \ref DOFVector to file.
void writeFile(std::vector<DOFVector<double>*> &values, void writeFile(std::vector<DOFVector<double>*> &values,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
/// Write a \ref WorldVector of \ref DOFVector to file. /// Write a \ref WorldVector of \ref DOFVector to file.
void writeFile(WorldVector<DOFVector<double>*> &values, void writeFile(WorldVector<DOFVector<double>*> &values,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
/// Write a \ref DOFVector <WorldVector> to file, by converting /// Write a \ref DOFVector <WorldVector> to file, by converting
/// to a \ref WorldVector of \ref DOFVector and calling the appropriate /// to a \ref WorldVector of \ref DOFVector and calling the appropriate
/// method above. Using a container pointer. /// method above. Using a container pointer.
void writeFile(DOFVector<WorldVector<double> > *values, void writeFile(DOFVector<WorldVector<double> > *values,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
/// Write a \ref DOFVector <WorldVector> to file, by converting /// Write a \ref DOFVector <WorldVector> to file, by converting
/// to a \ref WorldVector of \ref DOFVector and calling the appropriate /// to a \ref WorldVector of \ref DOFVector and calling the appropriate
...@@ -86,29 +105,41 @@ namespace AMDiS { namespace io { ...@@ -86,29 +105,41 @@ namespace AMDiS { namespace io {
inline inline
void writeFile(DOFVector<WorldVector<double> > &values, void writeFile(DOFVector<WorldVector<double> > &values,
std::string filename, std::string filename,
bool writeParallel = true) Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
)
{ {
writeFile(&values, filename, writeParallel); writeFile(&values, filename, format, highPrecision, writeParallel);
} }
/// Write a \ref SystemVector to file. Using a container pointer. /// Write a \ref SystemVector to file. Using a container pointer.
void writeFile(SystemVector *values, void writeFile(SystemVector *values,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
/// Write a \ref SystemVector to file. Using a container reference. /// Write a \ref SystemVector to file. Using a container reference.
inline inline
void writeFile(SystemVector &values, void writeFile(SystemVector &values,
std::string filename, std::string filename,
bool writeParallel = true) Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
)
{ {
writeFile(&values, filename, writeParallel); writeFile(&values, filename, format, highPrecision, writeParallel);
} }
/// Write a vector of \ref DataCollector to file. /// Write a vector of \ref DataCollector to file.
void writeFile(std::vector<DataCollector<>*> &dcList, void writeFile(std::vector<DataCollector<>*> &dcList,
std::string filename, std::string filename,
bool writeParallel = true); Vtuformat format = ASCII,
bool highPrecision = false,
bool writeParallel = true
);
} // end namespace VtkWriter } // end namespace VtkWriter
} } // end namespace io, AMDiS } } // end namespace io, AMDiS
......