// // Software License for AMDiS // // Copyright (c) 2010 Dresden University of Technology // All rights reserved. // Authors: Simon Vey, Thomas Witkowski et al. // // This file is part of AMDiS // // See also license.opensource.txt in the distribution. #include #include #include #include #include "ElementFileWriter.h" #include "BasisFunction.h" #include "Parameters.h" #include "Traverse.h" #include "AdaptInfo.h" namespace AMDiS { using namespace std; ElementFileWriter::ElementFileWriter(string name_, Mesh *mesh_, map &mapvec) : name(name_), amdisMeshDatExt(".elem.mesh"), vtkExt(".vtu"), writeAMDiSFormat(0), writeVtkFormat(0), appendIndex(0), indexLength(5), indexDecimals(3), tsModulo(1), timestepNumber(-1), mesh(mesh_), vec(mapvec) { if (name != "") { Parameters::get(name + "->output->filename", filename); Parameters::get(name + "->output->AMDiS format", writeAMDiSFormat); Parameters::get(name + "->output->AMDiS mesh-dat ext", amdisMeshDatExt); Parameters::get(name + "->output->ParaView format", writeVtkFormat); Parameters::get(name + "->output->append index", appendIndex); Parameters::get(name + "->output->index length", indexLength); Parameters::get(name + "->output->index decimals", indexDecimals); Parameters::get(name + "->output->write every i-th timestep", 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; 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 (writeAMDiSFormat) { TEST_EXIT(mesh)("no mesh\n"); writeMeshDatValues(const_cast((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((fn + vtkExt).c_str())); MSG("VTK file written to %s\n", (fn + vtkExt).c_str()); } } void ElementFileWriter::writeFile(map &vec, Mesh *mesh, string filename, int level) { ElementFileWriter efw("", mesh, vec); efw.writeVtkValues(filename, level); } void ElementFileWriter::writeMeshDatValues(string filename, double time) { FUNCNAME("ElementFileWriter::writeMeshDatValues()"); boost::iostreams::filtering_ostream file; { //boost::iostreams seems not to truncate the file ofstream swapfile(filename.c_str(), ios::out | ios::trunc); TEST_EXIT(swapfile.is_open()) ("Cannot open file %s for writing!\n", name.c_str()); swapfile.close(); } file.push(boost::iostreams::file_descriptor_sink(filename, ios::trunc)); int dim = mesh->getDim(); double val; // === Write header. === file << "mesh name: " << mesh->getName().c_str() << "\n\n"; file << "time: " << time << "\n\n"; file << "DIM: " << dim << "\n"; file << "DIM_OF_WORLD: " << Global::getGeo(WORLD) << "\n\n"; file << "number of vertices: " << (dim+1)*mesh->getNumberOfLeaves() << "\n"; file << "number of elements: " << mesh->getNumberOfLeaves() << "\n\n"; // === Write vertex coordinates (every vertex for every element). === file << "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) { file << elInfo->getCoord(i)[j] << " "; } file << "\n"; } elInfo = stack.traverseNext(elInfo); } // === Write elements. === int numLeaves = mesh->getNumberOfLeaves(); int vertCntr = 0; file << "\n"; file << "element vertices:\n"; for (int i = 0; i < numLeaves; ++i) { for (int j = 0; j <= dim; ++j) { file << vertCntr << " "; ++vertCntr; } file << "\n"; } // === Write values. === // Write values header. file << "\n"; file << "number of values: 1\n\n"; file << "value description: " << name.c_str() << "\n"; file << "number of interpolation points: 0" << "\n"; file << "type: scalar" << "\n"; file << "interpolation type: lagrange" << "\n"; file << "interpolation degree: 1" << "\n"; file << "end of description: " << name.c_str() << "\n\n"; // Write values. file << "vertex values: " << name.c_str() << "\n"; file.setf(ios::scientific,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) { file << val << "\n"; } elInfo = stack.traverseNext(elInfo); } // end of: mesh traverse // Write values trailor. file << "\n"; file << "interpolation values: " << name.c_str() << "\n\n\n"; file << "element interpolation points: " << name.c_str() << "\n"; } void ElementFileWriter::writeVtkValues(string filename, int level) { FUNCNAME("ElementFileWriter::writeVtkValues()"); boost::iostreams::filtering_ostream file; { //boost::iostreams seems not to truncate the file ofstream swapfile(filename.c_str(), ios::out | ios::trunc); TEST_EXIT(swapfile.is_open()) ("Cannot open file %s for writing!\n", name.c_str()); swapfile.close(); } file.push(boost::iostreams::file_descriptor_sink(filename, ios::trunc)); int dim = mesh->getDim(); int dimOfWorld = Global::getGeo(WORLD); int vertices = mesh->getGeo(VERTEX); int nElements = mesh->getNumberOfLeaves(); Flag traverseFlag = level == -1 ? Mesh::CALL_LEAF_EL : Mesh::CALL_EL_LEVEL; if (level != -1) { nElements = 0; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, level, Mesh::CALL_EL_LEVEL); while (elInfo) { nElements++; elInfo = stack.traverseNext(elInfo); } } file << "\n"; file << "\n"; file << " \n"; file << " \n"; file << " \n"; file << " \n"; // === Write vertex coordinates (every vertex for every element). === TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, level, traverseFlag | 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++) file << elInfo->getCoord(i)[j] << " "; for (int j = dimOfWorld; j < 3; j++) file << "0.0"; file << "\n"; } elInfo = stack.traverseNext(elInfo); } file << " \n"; file << " \n"; file << " \n"; file << " \n"; for (int i = 0; i < nElements; i++) file << " " << (i + 1) * vertices << "\n"; file << " \n"; file << " \n"; for (int i = 0; i < nElements; i++) { switch (vertices) { case 2: file << " 3\n"; break; case 3: file << " 5\n"; break; case 4: file << " 10\n"; break; default: break; } } file << " \n"; file << " \n"; int vertCntr = 0; for (int i = 0; i < nElements; ++i) { for (int j = 0; j <= dim; ++j) { file << vertCntr << " "; ++vertCntr; } file << "\n"; } file << " \n"; file << " \n"; file << " \n"; file << " \n"; file.setf(ios::scientific,ios::floatfield); elInfo = stack.traverseFirst(mesh, level, traverseFlag | Mesh::FILL_COORDS); int vc = 0; while (elInfo) { // Get element value. double val = vec[elInfo->getElement()->getIndex()]; // Write value for each vertex of each element. for (int i = 0; i <= dim; i++) file << (fabs(val) < 1e-40 ? 0.0 : val) << "\n"; vc++; elInfo = stack.traverseNext(elInfo); } file << " \n"; file << " \n"; file << " \n"; file << " \n"; file << "\n"; } }