/****************************************************************************** * * AMDiS - Adaptive multidimensional simulations * * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis * * Authors: * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * * This file is part of AMDiS * * See also license.opensource.txt in the distribution. * ******************************************************************************/ #include #include #include #include "Arh2Reader.h" #include "detail/Arh2Reader.h" #include #include #include namespace AMDiS { namespace io { namespace Arh2Reader { using namespace std; void readByName(string filename, DOFVector& vec, bool writeParallel, int nProcs) { readByName(filename, &vec, writeParallel, nProcs); } void readByName(string filename, DOFVector* vec, bool writeParallel, int nProcs) { vector*> vecs(0); vecs.push_back(vec); detail::readFile(filename, nullptr, vecs, writeParallel, nProcs, true); } void readByName(string filename, vector*> vecs, bool writeParallel, int nProcs) { detail::readFile(filename, nullptr, vecs, writeParallel, nProcs, true); } void readByName(string filename, SystemVector *sysVec, bool writeParallel, int nProcs) { vector*> vecs(0); for(int i = 0 ; i < sysVec->getSize(); i++) { vecs.push_back(sysVec->getDOFVector(i)); } detail::readFile(filename, nullptr, vecs, writeParallel, nProcs, true); } void readFile(string filename, SystemVector *sysVec, bool writeParallel, int nProcs) { vector*> vecs(0); for(int i = 0 ; i < sysVec->getSize(); i++) { vecs.push_back(sysVec->getDOFVector(i)); } detail::readFile(filename, nullptr, vecs, writeParallel, nProcs); } void readFile(string filename, DOFVector* vec0, DOFVector* vec1, DOFVector* vec2, bool writeParallel, int nProcs) { vector*> vecs(0); if(vec0 || vec1 || vec2) vecs.push_back(vec0); if(vec1 || vec2) vecs.push_back(vec1); if(vec2) vecs.push_back(vec2); detail::readFile(filename, nullptr, vecs, writeParallel, nProcs); } void readFile(string filename, vector*> vecs, bool writeParallel, int nProcs) { detail::readFile(filename, nullptr, vecs, writeParallel, nProcs); } void readFile(string filename, Mesh* mesh, bool writeParallel, int nProcs) { vector*> vecs(0); detail::readFile(filename, mesh, vecs, writeParallel, nProcs); } int readNumOfValueVectors(string filename, bool writeParallel) { FUNCNAME("Arh2Reader::readNumOfValueVectors"); ifstream file; 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); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS filename = name + "-p" + lexical_cast(MPI::COMM_WORLD.Get_rank()) + "-.arh"; #endif } file.open(filename.c_str(), ios::in | ios::binary); TEST_EXIT(file.is_open()) ("Cannot open file %s\n", filename.c_str()); uint32_t nValueVectors = 0; detail::firstRead(file); long pos = file.tellg(); file.seekg(pos + 16); file.read(reinterpret_cast(&nValueVectors), 4); file.close(); return nValueVectors; } int readHeaderSize(string filename, bool writeParallel) { FUNCNAME("Arh2Reader::readHeaderSize"); ifstream file; 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); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS filename = name + "-p" + lexical_cast(MPI::COMM_WORLD.Get_rank()) + "-.arh"; #endif } file.open(filename.c_str(), ios::in | ios::binary); TEST_EXIT(file.is_open()) ("Cannot open file %s\n", filename.c_str()); uint32_t headerLen = 0; detail::firstRead(file); file.read(reinterpret_cast(&headerLen), 4); file.close(); return headerLen; } bool isReadable(string filename, bool writeParallel) { FUNCNAME("Arh2Reader::isReadable"); ifstream file; 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); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS filename = name + "-p" + lexical_cast(MPI::COMM_WORLD.Get_rank()) + "-.arh"; #endif } file.open(filename.c_str(), ios::in | ios::binary); TEST_EXIT(file.is_open()) ("Cannot open file %s\n", filename.c_str()); string typeId(4, ' '); uint8_t major = 0, minor = 0; file.read(const_cast(typeId.data()), 4); file.read(reinterpret_cast(&major), 1); file.read(reinterpret_cast(&minor), 1); file.close(); return (typeId == "arh2" && major == MAJOR && minor <= MINOR) ? true : false; } void readMeta(string filename, DOFVector* vec0, DOFVector* vec1, DOFVector* vec2) { vector*> vecs; if (vec0) vecs.push_back(vec0); if (vec1) vecs.push_back(vec1); if (vec2) vecs.push_back(vec2); readMeta(filename, vecs); } void readMeta(string filename, vector*> vecs) { FUNCNAME("Arh2Reader::readMeta()"); Mesh* mesh = nullptr; for (size_t i = 0; i < vecs.size(); i++) { if(vecs[i]) { if(!mesh) mesh = vecs[i]->getFeSpace()->getMesh(); else TEST_EXIT(mesh == vecs[i]->getFeSpace()->getMesh()) ("The mesh of the DOFVectors should be the same for Reader because in one file there is only one mesh.\n"); } } if(!mesh) { WARNING("You haven't specified the target.\n"); return; } // === Read the meta arh file. === string arhPrefix = ""; map elInRank; map elCodeSize; int nProc = readMetaData(filename, elInRank, elCodeSize, arhPrefix); // === Check which arh files must be read by current rank. === // Set of all file indices which should be read to restore all macro elements. std::set readArhFiles; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL); while (elInfo) { int macroElIndex = elInfo->getElement()->getIndex(); TEST_EXIT(elInRank.count(macroElIndex))("Should not happen!\n"); readArhFiles.insert(elInRank[macroElIndex]); elInfo = stack.traverseNext(elInfo); } // === Read the individual arh files. === boost::filesystem::path p(filename.c_str()); boost::filesystem::path directory = p.parent_path(); for (std::set::iterator it = readArhFiles.begin(); it != readArhFiles.end(); ++it) { string arhFilename = directory.string() + "/" + arhPrefix; if (nProc == 1) arhFilename += ".arh"; else arhFilename += "-p" + boost::lexical_cast(*it) + "-.arh"; MSG("ARH2 file read from: %s\n", arhFilename.c_str()); detail::read(arhFilename, mesh, vecs); } } int readMetaData(string filename, map &elInRank, map &elCodeSize, string &arhPrefix) { FUNCNAME("Arh2Reader::readMetaData()"); ifstream file; file.open(filename.c_str()); TEST_EXIT(file.is_open()) ("Cannot open arh meta file \"%s\"\n", filename.c_str()); string readStr = ""; file >> readStr; arhPrefix = ""; file >> arhPrefix; int nProc; file >> nProc; // Maps to each macro element index the arh file index it is stored in. for (int i = 0; i < nProc; i++) { int tmp; file >> tmp; TEST_EXIT(tmp == i)("Should not happen!\n"); int nMacroEl; file >> nMacroEl; for (int j = 0; j < nMacroEl; j++) { int elIndex, codeSize; file >> elIndex; file >> codeSize; elInRank[elIndex] = i; elCodeSize[elIndex] = codeSize; } } file.close(); return nProc; } int readMetaData(string filename) { FUNCNAME("Arh2Reader::readMetaData()"); ifstream file; file.open(filename.c_str()); TEST_EXIT(file.is_open()) ("Cannot open arh meta file \"%s\"\n", filename.c_str()); string readStr = ""; file >> readStr; file >> readStr; int nProc; file >> nProc; file.close(); return nProc; } int readMetaFromArh(std::string filename, std::map &elInRank, std::map &elCodeSize){ #ifdef HAVE_PARALLEL_DOMAIN_AMDIS int nProcs = MPI::COMM_WORLD.Get_size(); #else int nProcs = -1; #endif // check for consistency // That is, if there are no more or less files as nProcs int i = 0; for (; i < nProcs + 1; i++) { string fn = filename + "-p" + boost::lexical_cast(i) + "-.arh"; if(!boost::filesystem::exists(fn)) break; } TEST_EXIT(i == nProcs) ("Number of arh files doesn't match number of processors \n"); // data format: (rank ; (elIndex; elCodeSize) ) vector > > data(nProcs); //collect data for (int i = 0; i < nProcs; i++) { string fn = filename + "-p" + boost::lexical_cast(i) + "-.arh"; detail::readMetaFromSgArh(fn, i, data); } //make elInRank and elCodeSize-Map for (int i = 0; i < nProcs; i++) { for (std::set >::iterator it = data[i].begin(); it != data[i].end(); ++it){ elInRank[it->first]=i; elCodeSize[it->first]=it->second; } } return nProcs; } } // end namespace Arh2Reader } } // end namespace io, AMDiS