diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt index 2d8b5b56fe5cbdcc193a3322504eb9188eba55c8..f84d8b57ee37048ae7de35c18126e437e982d227 100644 --- a/AMDiS/CMakeLists.txt +++ b/AMDiS/CMakeLists.txt @@ -163,6 +163,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc ${SOURCE_DIR}/io/ArhReader.cc ${SOURCE_DIR}/io/detail/ArhReader.cc ${SOURCE_DIR}/io/Arh2Reader.cc + ${SOURCE_DIR}/io/Arh2Writer.cc ${SOURCE_DIR}/io/detail/Arh2Reader.cc ${SOURCE_DIR}/io/detail/ArhWriter.cc ${SOURCE_DIR}/io/detail/Arh2Writer.cc diff --git a/AMDiS/src/io/Arh2Writer.cc b/AMDiS/src/io/Arh2Writer.cc new file mode 100644 index 0000000000000000000000000000000000000000..2e97864246402a2865baadaf32d413b369bd44b4 --- /dev/null +++ b/AMDiS/src/io/Arh2Writer.cc @@ -0,0 +1,108 @@ +/****************************************************************************** + * + * 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 "Arh2Writer.h" +#include "Mesh.h" +#include "MeshStructure.h" +#include "parallel/StdMpi.h" + +namespace AMDiS { namespace io { + + using namespace std; + using namespace AMDiS::Parallel; + + namespace Arh2Writer + { + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + void writeMetaData(Mesh *mesh, string metaFilename) + { + FUNCNAME("Arh2Writer::writeMetaData()"); + + int mpiSize = MPI::COMM_WORLD.Get_size(); + vector > > overallData; + std::set > data; + + // Calculate local data + + MeshStructure elementStructure; + int macroElIndex = -1; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + if (elInfo->getLevel() == 0) { + if (macroElIndex != -1) { + elementStructure.commit(); + + data.insert(make_pair(macroElIndex, elementStructure.getNumElements())); + } + elementStructure.clear(); + + macroElIndex = elInfo->getElement()->getIndex(); + } + elementStructure.insertElement(elInfo->getElement()->isLeaf()); + elInfo = stack.traverseNext(elInfo); + } + + TEST_EXIT_DBG(macroElIndex != -1)("Should not happen!\n"); + elementStructure.commit(); + data.insert(make_pair(macroElIndex, elementStructure.getNumElements())); + + // Collect data from other processors + + StdMpi > > stdMpi(MPI::COMM_WORLD); + + if(MPI::COMM_WORLD.Get_rank() == 0) { + for(int rank = 1; rank < mpiSize; rank++) + stdMpi.recv(rank); + } else { + stdMpi.send(0, data); + } + + stdMpi.startCommunication(); + + if(MPI::COMM_WORLD.Get_rank() == 0) { + overallData.push_back(data); + + for(int rank = 1; rank < mpiSize; rank++) { + std::set >& recvData = stdMpi.getRecvData(rank); + overallData.push_back(recvData); + } + + // Write to meta file + + ofstream file; + file.open(metaFilename.c_str()); + file << "METAARH\n"; + file << "" << "\n"; + file << mpiSize << "\n"; + for (int i = 0; i < mpiSize; i++) { + file << i << " " << overallData[i].size() << "\n"; + for (std::set >::iterator it = overallData[i].begin(); it != overallData[i].end(); ++it) + file << it->first << " " << it->second << "\n"; + } + file.close(); + } + } +#endif + + } +} } \ No newline at end of file diff --git a/AMDiS/src/io/Arh2Writer.h b/AMDiS/src/io/Arh2Writer.h index f4fc263469656f86db7c2fa2b1188f9a6fb06ea7..4eab6f3005f62acc5c7efcd2c431ad0fac01bb51 100644 --- a/AMDiS/src/io/Arh2Writer.h +++ b/AMDiS/src/io/Arh2Writer.h @@ -97,7 +97,11 @@ namespace AMDiS { namespace io { std::vector*> vecs; detail::write(filename, mesh, vecs, writeParallel); } - + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + void writeMetaData(Mesh *mesh, std::string filename); +#endif + } // end namespace Arh2Writer } } // end namespace io, AMDiS diff --git a/AMDiS/src/parallel/StdMpi.cc b/AMDiS/src/parallel/StdMpi.cc index 00f31d8508200523e1eefe63ac0d5707088ffe3e..5d2f7ae68d9f8f54585c494442b8e27071c8eec3 100644 --- a/AMDiS/src/parallel/StdMpi.cc +++ b/AMDiS/src/parallel/StdMpi.cc @@ -29,6 +29,7 @@ namespace AMDiS { namespace Parallel { MPI_Datatype StdMpiHelper >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_INT; + MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_UNSIGNED_LONG_LONG; @@ -157,7 +158,35 @@ namespace AMDiS { namespace Parallel { counter, bufSize); } - + // T = std::set > > + + int StdMpiHelper > >::getBufferSize(std::set > &data) + { + return data.size() * 2; + } + + void StdMpiHelper > >::createBuffer(std::set > &data, + int *buf) + { + int i = 0; + + for(std::set >::iterator it = data.begin(); it != data.end(); ++it) { + buf[i++] = it->first; + buf[i++] = it->second; + } + } + + void StdMpiHelper > >::makeFromBuffer(std::set > &data, + int *buf, + int bufSize) + { + data.clear(); + + for (int i = 0; i < bufSize; i += 2) + data.insert(std::make_pair(buf[i], buf[i + 1])); + } + + // T = vector diff --git a/AMDiS/src/parallel/StdMpi.h b/AMDiS/src/parallel/StdMpi.h index aab4b7f2903b75b0e934f2ba0ee9f4a8e080fd9f..ae1c51d6c68bd9041e595151e1dea3765618e9e4 100644 --- a/AMDiS/src/parallel/StdMpi.h +++ b/AMDiS/src/parallel/StdMpi.h @@ -107,6 +107,20 @@ namespace AMDiS { namespace Parallel { static void makeFromBuffer(std::vector > &data, int *buf, int bufSize); }; + + template<> + struct StdMpiHelper > > { + static MPI_Datatype mpiDataType; + + typedef int cppDataType; + + static int getBufferSize(std::set > &data); + + static void createBuffer(std::set > &data, int *buf); + + static void makeFromBuffer(std::set > &data, + int *buf, int bufSize); + }; template<>