// ============================================================================ // == == // == Amdis - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == TU Dresden == // == == // == Institut für Wissenschaftliches Rechnen == // == Zellescher Weg 12-14 == // == 01069 Dresden == // == germany == // == == // ============================================================================ // == == // == https://gforge.zih.tu-dresden.de/projects/amdis/ == // == == // ============================================================================ /** \file MeshStructure.h */ #ifndef AMDIS_MESH_STRUCTURE_H #define AMDIS_MESH_STRUCTURE_H #include #include "AMDiS_fwd.h" #include "Global.h" #include "parallel/InteriorBoundary.h" namespace AMDiS { class MeshStructure { public: MeshStructure() : currentIndex(0), currentCode(0), pos(0), currentElement(0), nElements(0), debugMode(false) {} void clear(); /// Creates a mesh structure code from a mesh object by traversing it in preorder. void init(Mesh *mesh); void init(BoundaryObject &bound); void init(const std::vector& initCode, int n) { code = initCode; nElements = n; reset(); } /** \brief * Sets all position counters, that are used to traverse the code, to the starting * position. The code itself is not changed. */ void reset(); /// Returns whether the code is empty or not. inline bool empty() { return (nElements == 0); } inline void commit() { if (pos > 0) code.push_back(currentCode); reset(); } bool skipBranch(MeshStructure *insert = NULL); ElInfo *skipBranch(ElInfo *elInfo, TraverseStack *stack); bool nextElement(MeshStructure *insert = NULL); inline bool isLeafElement() { return (currentCode & 1) == 0; } /** \brief * Merges a mesh structure code with its own mesh structure code. The result * overwrites the own mesh structure code. */ void merge(MeshStructure *struc) { MeshStructure temp(*this); merge(&temp, struc, this); } /** \brief * Fits a given mesh to the mesh structure code. * * \param debugMode In debugMode, the whole mesh is fitted to the mesh structure * code. Otherwise, the mesh is fitted only on the partition * of the current process. */ void fitMeshToStructure(Mesh *mesh, RefinementManager *manager, bool checkPartition = false, bool debugMode = false); /// Prints the mesh structure code. void print() { FUNCNAME("MeshStructure::print()"); std::stringstream oss; if (empty()) { oss << "-" << std::endl; } else { reset(); bool cont = true; while (cont) { if (isLeafElement()) oss << "0"; else oss << "1"; cont = nextElement(); } } MSG("Mesh structure code: %s\n", oss.str().c_str()); } /// Returns the mesh structure code. inline const std::vector& getCode() { return code; } inline int getNumElements() { return nElements; } inline int getCurrentElement() { return currentElement; } void setDebugMode(bool b) { debugMode = b; } /// Returns true, if the given mesh structure code is equal to this one. bool compare(MeshStructure &other); protected: /// Insert a new element to the structure code. Is used by the init function. void insertElement(bool isLeaf); void addAlongSide(Element *el, GeoIndex subObj, int ithObj, int elType, bool reverseOrder); /// Merges two mesh structure codes to one structure code. void merge(MeshStructure *structure1, MeshStructure *structure2, MeshStructure *result); protected: /// Mesh structure code. std::vector code; int currentIndex; unsigned long int currentCode; int pos; int currentElement; int nElements; /// If true, some output is printed to screen during mesh structure code generation. bool debugMode; static const int unsignedLongSize; }; } #endif