#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(); } }