-
Thomas Witkowski authoredThomas Witkowski authored
ElementFileWriter.cc 11.07 KiB
#include "ElementFileWriter.h"
#include "BasisFunction.h"
#include "Parameters.h"
#include "Traverse.h"
#include "AdaptInfo.h"
namespace AMDiS {
ElementFileWriter::ElementFileWriter(std::string name_,
const FiniteElemSpace *feSpace_,
std::map<int, double> &mapvec)
: name(name_),
tecplotExt(".plt"),
amdisMeshDatExt(".elem.mesh"),
vtkExt(".vtu"),
writeTecPlotFormat(0),
writeAMDiSFormat(0),
writeVtkFormat(0),
appendIndex(0),
indexLength(5),
indexDecimals(3),
tsModulo(1),
timestepNumber(-1),
mesh(feSpace_->getMesh()),
feSpace(feSpace_),
vec(mapvec)
{
if (name != "") {
GET_PARAMETER(0, name + "->output->filename", &filename);
GET_PARAMETER(0, name + "->output->TecPlot format", "%d", &writeTecPlotFormat);
GET_PARAMETER(0, name + "->output->TecPlot ext", &tecplotExt);
GET_PARAMETER(0, name + "->output->AMDiS format", "%d", &writeAMDiSFormat);
GET_PARAMETER(0, name + "->output->AMDiS mesh-dat ext", &amdisMeshDatExt);
GET_PARAMETER(0, name + "->output->ParaView format", "%d", &writeVtkFormat);
GET_PARAMETER(0, name + "->output->append index", "%d", &appendIndex);
GET_PARAMETER(0, name + "->output->index length", "%d", &indexLength);
GET_PARAMETER(0, name + "->output->index decimals", "%d", &indexDecimals);
GET_PARAMETER(0, name + "->output->write every i-th timestep", "%d", &tsModulo);
}
}
void ElementFileWriter::writeFiles(AdaptInfo *adaptInfo, bool force,
int level, Flag traverseFlag,
bool (*writeElem)(ElInfo*))
{
FUNCNAME("ElementFileWriter::writeFiles()");
timestepNumber++;
timestepNumber %= tsModulo;
if ((timestepNumber != 0) && !force)
return;
std::string fn = filename;
if (appendIndex) {
TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
char formatStr[9];
sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
char timeStr[20];
sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);
fn += timeStr;
}
if (writeTecPlotFormat) {
TEST_EXIT(mesh)("no mesh\n");
writeTecPlotValues(const_cast<char*>((fn + tecplotExt).c_str()));
MSG("TecPlot file written to %s\n", (fn + tecplotExt).c_str());
}
if (writeAMDiSFormat) {
TEST_EXIT(mesh)("no mesh\n");
writeMeshDatValues(const_cast<char*>( (fn + amdisMeshDatExt).c_str()),
adaptInfo ? adaptInfo->getTime() : 0.0);
MSG("MeshDat file written to %s\n", (fn + amdisMeshDatExt).c_str());
}
if (writeVtkFormat) {
TEST_EXIT(mesh)("no mesh\n");
writeVtkValues(const_cast<char*>( (fn + vtkExt).c_str()));
MSG("VTK file written to %s\n", (fn + vtkExt).c_str());
}
}
void ElementFileWriter::writeFile(std::map<int, double> &vec,
const FiniteElemSpace *feSpace,
std::string filename)
{
ElementFileWriter efw("", feSpace, vec);
efw.writeVtkValues(filename);
}
void ElementFileWriter::writeTecPlotValues(std::string filename)
{
FUNCNAME("ElementFileWriter::writeTecPlotValues()");
std::ofstream fout(filename.c_str());
TEST_EXIT(fout)("Could not open file %s !\n", filename.c_str());
fout.setf(std::ios::scientific,std::ios::floatfield);
int dim = mesh->getDim();
double val;
// === Write header. ===
fout << "TITLE = \"" << name.c_str() << "\"\n";
fout << "VARIABLES = ";
switch (dim) {
case 2: fout << "\"x\",\"y\"";
break;
case 3: fout << "\"x\",\"y\",\"z\"";
break;
default: ERROR_EXIT("illegal dimension !\n");
break;
}
fout << ",\"" << name.c_str() << "\"\n";
fout << "ZONE T=\"" << name.c_str() << "\""
<< ", N=" << 3*mesh->getNumberOfLeaves()
<< ", E=" << mesh->getNumberOfLeaves()
<< ", F=FEPOINT, ";
switch (dim) {
case 2: fout << "ET=TRIANGLE\n\n";
break;
case 3: fout << "ET=TETRAHEDRON\n\n";
break;
default: ERROR_EXIT("illegal dimension !\n");
break;
}
// === Write vertex coordinates and values (for each element !). ===
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh,
-1,
Mesh::CALL_LEAF_EL |
Mesh::FILL_COORDS);
while (elInfo) {
// Get element value.
val = vec[elInfo->getElement()->getIndex()];
// Write coordinates of all element vertices and element value.
for (int i = 0; i <= dim; ++i) {
for (int j = 0; j < dim; ++j)
fout << elInfo->getCoord(i)[j] << " ";
fout << val << "\n";
}
elInfo = stack.traverseNext(elInfo);
} // end of: mesh traverse
// === Write elements. ===
int numLeaves = mesh->getNumberOfLeaves();
int vertCntr = 0;
fout << "\n";
for (int i = 0; i<numLeaves; ++i) {
for (int j = 0; j<=dim; ++j) {
++vertCntr;
fout << vertCntr << " ";
}
fout << "\n";
}
fout.close();
}
void ElementFileWriter::writeMeshDatValues(std::string filename, double time)
{
FUNCNAME("ElementFileWriter::writeMeshDatValues()");
std::ofstream fout(filename.c_str());
TEST_EXIT(fout)("Could not open file %s !\n", filename.c_str());
int dim = mesh->getDim();
double val;
// === Write header. ===
fout << "mesh name: " << mesh->getName().c_str() << "\n\n";
fout << "time: " << time << "\n\n";
fout << "DIM: " << dim << "\n";
fout << "DIM_OF_WORLD: " << Global::getGeo(WORLD) << "\n\n";
fout << "number of vertices: " << (dim+1)*mesh->getNumberOfLeaves() << "\n";
fout << "number of elements: " << mesh->getNumberOfLeaves() << "\n\n";
// === Write vertex coordinates (every vertex for every element). ===
fout << "vertex coordinates:\n";
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh,
-1,
Mesh::CALL_LEAF_EL |
Mesh::FILL_COORDS);
while (elInfo) {
// Write coordinates of all element vertices.
for (int i = 0; i <= dim; ++i) {
for (int j = 0; j < dim; ++j) {
fout << elInfo->getCoord(i)[j] << " ";
}
fout << "\n";
}
elInfo = stack.traverseNext(elInfo);
}
// === Write elements. ===
int numLeaves = mesh->getNumberOfLeaves();
int vertCntr = 0;
fout << "\n";
fout << "element vertices:\n";
for (int i = 0; i < numLeaves; ++i) {
for (int j = 0; j <= dim; ++j) {
fout << vertCntr << " ";
++vertCntr;
}
fout << "\n";
}
// === Write values. ===
// Write values header.
fout << "\n";
fout << "number of values: 1\n\n";
fout << "value description: " << name.c_str() << "\n";
fout << "number of interpolation points: 0" << "\n";
fout << "type: scalar" << "\n";
fout << "interpolation type: lagrange" << "\n";
fout << "interpolation degree: 1" << "\n";
fout << "end of description: " << name.c_str() << "\n\n";
// Write values.
fout << "vertex values: " << name.c_str() << "\n";
fout.setf(std::ios::scientific,std::ios::floatfield);
elInfo = stack.traverseFirst(mesh,
-1,
Mesh::CALL_LEAF_EL);
while (elInfo) {
// Get element value.
val = vec[elInfo->getElement()->getIndex()];
// Write value for each vertex of each element.
for (int i = 0; i <= dim; ++i) {
fout << val << "\n";
}
elInfo = stack.traverseNext(elInfo);
} // end of: mesh traverse
// Write values trailor.
fout << "\n";
fout << "interpolation values: " << name.c_str() << "\n\n\n";
fout << "element interpolation points: " << name.c_str() << "\n";
fout.close();
}
void ElementFileWriter::writeVtkValues(std::string filename)
{
FUNCNAME("ElementFileWriter::writeVtkValues()");
std::ofstream fout(filename.c_str());
TEST_EXIT(fout)("Could not open file %s !\n", filename.c_str());
int dim = mesh->getDim();
int dimOfWorld = Global::getGeo(WORLD);
int vertices = mesh->getGeo(VERTEX);
int nElements = mesh->getNumberOfLeaves();
double val;
fout << "<?xml version=\"1.0\"?>" << std::endl;
fout << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
fout << " <UnstructuredGrid>" << std::endl;
fout << " <Piece NumberOfPoints=\"" << (dim + 1) * nElements
<< "\" NumberOfCells=\"" << nElements << "\">" << std::endl;
fout << " <Points>" << std::endl;
fout << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
// === Write vertex coordinates (every vertex for every element). ===
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh,
-1,
Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
while (elInfo) {
// Write coordinates of all element vertices.
for (int i = 0; i <= dim; i++) {
for (int j = 0; j < dimOfWorld; j++)
fout << elInfo->getCoord(i)[j] << " ";
for (int j = dimOfWorld; j < 3; j++)
fout << "0.0";
fout << "\n";
}
elInfo = stack.traverseNext(elInfo);
}
fout << " </DataArray>" << std::endl;
fout << " </Points>" << std::endl;
fout << " <Cells>" << std::endl;
fout << " <DataArray type=\"Int32\" Name=\"offsets\">" << std::endl;
for (int i = 0; i < nElements; i++)
fout << " " << (i + 1) * vertices << std::endl;
fout << " </DataArray>" << std::endl;
fout << " <DataArray type=\"UInt8\" Name=\"types\">" << std::endl;
for (int i = 0; i < nElements; i++) {
switch (vertices) {
case 2:
fout << " 3" << std::endl;
break;
case 3:
fout << " 5" << std::endl;
break;
case 4:
fout << " 10" << std::endl;
break;
default:
break;
}
}
fout << " </DataArray>" << std::endl;
fout << " <DataArray type=\"Int32\" Name=\"connectivity\">" << std::endl;
int vertCntr = 0;
for (int i = 0; i < nElements; ++i) {
for (int j = 0; j <= dim; ++j) {
fout << vertCntr << " ";
++vertCntr;
}
fout << std::endl;
}
fout << " </DataArray>" << std::endl;
fout << " </Cells>" << std::endl;
fout << " <PointData>" << std::endl;
fout << " <DataArray type=\"Float32\" Name=\"value\" format=\"ascii\">" << std::endl;
fout.setf(std::ios::scientific,std::ios::floatfield);
elInfo = stack.traverseFirst(mesh,
-1,
Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
int vc = 0;
while (elInfo) {
// Get element value.
val = vec[elInfo->getElement()->getIndex()];
// Write value for each vertex of each element.
for (int i = 0; i <= dim; i++) {
fout << (fabs(val) < 1e-40 ? 0.0 : val) << "\n";
}
vc++;
elInfo = stack.traverseNext(elInfo);
}
fout << " </DataArray>" << std::endl;
fout << " </PointData>" << std::endl;
fout << " </Piece>" << std::endl;
fout << " </UnstructuredGrid>" << std::endl;
fout << "</VTKFile>" << std::endl;
fout.close();
}
}