From 362adc0288e3a889e6a5af18cc4de9b8b47b4073 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 18 May 2018 18:10:34 +0200 Subject: [PATCH] Set of improvements - GmshReader: - now knows about vertices - '"' are filtered from physical names - uses RefId to store entity lists - RefId: simple definition of references. only ref<->name association - EntityListManager: begining of entity sets handling --- src/mesh/Connectivity2D.hpp | 206 +++++--- src/mesh/GmshReader.cpp | 966 +++++++++++++++++++----------------- src/mesh/GmshReader.hpp | 158 ++++-- src/mesh/RefId.hpp | 69 +++ 4 files changed, 811 insertions(+), 588 deletions(-) create mode 100644 src/mesh/RefId.hpp diff --git a/src/mesh/Connectivity2D.hpp b/src/mesh/Connectivity2D.hpp index 47d19c024..1603b386c 100644 --- a/src/mesh/Connectivity2D.hpp +++ b/src/mesh/Connectivity2D.hpp @@ -9,15 +9,86 @@ #include <map> #include <algorithm> +#include <RefId.hpp> + +class EntityListManager +{ + public: + typedef Kokkos::View<const unsigned int*> CellIdArray; + typedef Kokkos::View<const unsigned int*> FaceIdArray; + typedef Kokkos::View<const unsigned int*> EdgeIdArray; + typedef Kokkos::View<const unsigned int*> NodeIdArray; + + typedef std::map<RefId, CellIdArray> CellIdArraySet; + typedef std::map<RefId, FaceIdArray> FaceIdArraySet; + typedef std::map<RefId, EdgeIdArray> EdgeIdArraySet; + typedef std::map<RefId, NodeIdArray> NodeIdArraySet; + + private: + CellIdArraySet m_cell_id_array_set; + FaceIdArraySet m_face_id_array_set; + EdgeIdArraySet m_edge_id_array_set; + NodeIdArraySet m_node_id_array_set; + + public: + + void addCellIdArray(const RefId& set_id, const CellIdArray& cell_id_array) + { + m_cell_id_array_set.insert(std::make_pair(set_id, cell_id_array)); + } + + void addFaceIdArray(const RefId& set_id, const FaceIdArray& face_id_array) + { + m_face_id_array_set.insert(std::make_pair(set_id, face_id_array)); + } + + void addEdgeIdArray(const RefId& set_id, const EdgeIdArray& edge_id_array) + { + m_edge_id_array_set.insert(std::make_pair(set_id, edge_id_array)); + } + + void addNodeIdArray(const RefId& set_id, const NodeIdArray& node_id_array) + { + m_node_id_array_set.insert(std::make_pair(set_id, node_id_array)); + } + + const CellIdArraySet& getCellIdArraySet() const + { + return m_cell_id_array_set; + } + + const FaceIdArraySet& getFaceIdArraySet() const + { + return m_face_id_array_set; + } + + const EdgeIdArraySet& getEdgeIdArraySet() const + { + return m_edge_id_array_set; + } + + const NodeIdArraySet& getNodeIdArraySet() const + { + return m_node_id_array_set; + } + + EntityListManager& operator=(const EntityListManager&) = delete; + EntityListManager() = default; + EntityListManager(const EntityListManager&) = delete; + ~EntityListManager() = default; +}; + class Connectivity2D { public: static constexpr size_t dimension = 2; typedef std::pair<unsigned int, Kokkos::View<const unsigned int*>> FacesBoundary; - typedef std::pair<unsigned int, Kokkos::View<const unsigned int*>> NodesBoundary; + typedef std::pair<RefId, Kokkos::View<const unsigned int*>> NodesBoundary; typedef std::vector<FacesBoundary> FacesBoundaryList; typedef std::vector<NodesBoundary> NodesBoundaryList; + + EntityListManager m_entity_list_manager; private: const size_t m_number_of_cells; size_t m_number_of_faces; @@ -33,7 +104,7 @@ private: Kokkos::View<unsigned short*> m_node_nb_cells; Kokkos::View<unsigned int**> m_node_cells; Kokkos::View<unsigned short**> m_node_cell_local_node; - + Kokkos::View<unsigned short*> m_face_nb_cells; Kokkos::View<unsigned int**> m_face_cells; Kokkos::View<unsigned short**> m_face_cell_local_face; @@ -56,8 +127,8 @@ private: bool operator<(const Face& f) const { return ((m_node0_id<f.m_node0_id) or - ((m_node0_id == f.m_node0_id) and - (m_node1_id<f.m_node1_id))); + ((m_node0_id == f.m_node0_id) and + (m_node1_id<f.m_node1_id))); } KOKKOS_INLINE_FUNCTION @@ -74,9 +145,9 @@ private: KOKKOS_INLINE_FUNCTION Face(unsigned int node0_id, - unsigned int node1_id) - : m_node0_id(node0_id), - m_node1_id(node1_id) + unsigned int node1_id) + : m_node0_id(node0_id), + m_node1_id(node1_id) { ; } @@ -93,19 +164,19 @@ private: for (unsigned int j=0; j<m_number_of_cells; ++j) { const unsigned short cell_nb_nodes = m_cell_nb_nodes[j]; for (unsigned short r=0; r<cell_nb_nodes; ++r) { - unsigned int node0_id = m_cell_nodes(j,r); - unsigned int node1_id = m_cell_nodes(j,(r+1)%cell_nb_nodes); - if (node1_id<node0_id) { - std::swap(node0_id, node1_id); - } - face_cells_map[Face(node0_id, node1_id)].push_back(std::make_pair(j, r)); + unsigned int node0_id = m_cell_nodes(j,r); + unsigned int node1_id = m_cell_nodes(j,(r+1)%cell_nb_nodes); + if (node1_id<node0_id) { + std::swap(node0_id, node1_id); + } + face_cells_map[Face(node0_id, node1_id)].push_back(std::make_pair(j, r)); } } m_number_of_faces = face_cells_map.size(); Kokkos::View<unsigned short*> face_nb_nodes("face_nb_nodes", m_number_of_faces); Kokkos::parallel_for(m_number_of_faces, KOKKOS_LAMBDA(const unsigned int& l) { - face_nb_nodes[l] = 2; + face_nb_nodes[l] = 2; }); m_face_nb_nodes = face_nb_nodes; @@ -113,10 +184,10 @@ private: { int l=0; for (const auto& face_cells_vector : face_cells_map) { - const Face& face = face_cells_vector.first; - face_nodes(l,0) = face.m_node0_id; - face_nodes(l,1) = face.m_node1_id; - ++l; + const Face& face = face_cells_vector.first; + face_nodes(l,0) = face.m_node0_id; + face_nodes(l,1) = face.m_node1_id; + ++l; } } m_face_nodes = face_nodes; @@ -125,9 +196,9 @@ private: { int l=0; for (const auto& face_cells_vector : face_cells_map) { - const auto& cells_vector = face_cells_vector.second; - face_nb_cells[l] = cells_vector.size(); - ++l; + const auto& cells_vector = face_cells_vector.second; + face_nb_cells[l] = cells_vector.size(); + ++l; } } m_face_nb_cells = face_nb_cells; @@ -136,12 +207,12 @@ private: { int l=0; for (const auto& face_cells_vector : face_cells_map) { - const auto& cells_vector = face_cells_vector.second; - for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { - unsigned int cell_number = cells_vector[lj].first; - face_cells(l,lj) = cell_number; - } - ++l; + const auto& cells_vector = face_cells_vector.second; + for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { + unsigned int cell_number = cells_vector[lj].first; + face_cells(l,lj) = cell_number; + } + ++l; } } m_face_cells = face_cells; @@ -152,35 +223,34 @@ private: { int l=0; for (const auto& face_cells_vector : face_cells_map) { - const auto& cells_vector = face_cells_vector.second; - for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { - unsigned int cell_number = cells_vector[lj].first; - unsigned short cell_local_face = cells_vector[lj].second; - cell_faces(cell_number,cell_local_face) = l; - } - ++l; + const auto& cells_vector = face_cells_vector.second; + for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { + unsigned int cell_number = cells_vector[lj].first; + unsigned short cell_local_face = cells_vector[lj].second; + cell_faces(cell_number,cell_local_face) = l; + } + ++l; } } m_cell_faces = cell_faces; Kokkos::View<unsigned short**> face_cell_local_face("face_cell_local_face", - m_number_of_faces, m_max_nb_node_per_cell); + m_number_of_faces, m_max_nb_node_per_cell); { int l=0; for (const auto& face_cells_vector : face_cells_map) { - const auto& cells_vector = face_cells_vector.second; - for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { - unsigned short cell_local_face = cells_vector[lj].second; - face_cell_local_face(l,lj) = cell_local_face; - } - ++l; + const auto& cells_vector = face_cells_vector.second; + for (unsigned short lj=0; lj<cells_vector.size(); ++lj) { + unsigned short cell_local_face = cells_vector[lj].second; + face_cell_local_face(l,lj) = cell_local_face; + } + ++l; } } m_face_cell_local_face = face_cell_local_face; } - -public: + public: const size_t& numberOfNodes() const { return m_number_of_nodes; @@ -200,7 +270,7 @@ public: { return m_max_nb_node_per_cell; } - + const Kokkos::View<const unsigned int**> cellNodes() const { return m_cell_nodes; @@ -262,7 +332,7 @@ public: } unsigned int getFaceNumber(const unsigned int node0_id, - const unsigned int node1_id) const + const unsigned int node1_id) const { #warning rewrite const unsigned int n0_id = std::min(node0_id, node1_id); @@ -270,7 +340,7 @@ public: // worst code ever for (unsigned int l=0; l<m_number_of_faces; ++l) { if ((m_face_nodes(l,0) == n0_id) and (m_face_nodes(l,1) == n1_id)) { - return l; + return l; } } std::cerr << "Face not found!\n"; @@ -278,27 +348,17 @@ public: return 0; } - size_t numberOfFaceBoundaries() const + EntityListManager& entityListManager() { - return m_faces_boundary_list.size(); + return m_entity_list_manager; } - const FacesBoundary& facesBoundary(const size_t& i) const + const EntityListManager& entityListManager() const { - return m_faces_boundary_list[i]; - } - - void addFaceBoundary(const unsigned int& ref, - const std::vector<unsigned int>& face_id_vector) - { - Kokkos::View<unsigned int*> faces_boundary("faces_boundary", face_id_vector.size()); - Kokkos::parallel_for(face_id_vector.size(), KOKKOS_LAMBDA(const int& l) { - faces_boundary[l] = face_id_vector[l]; - }); - m_faces_boundary_list.push_back(std::make_pair(ref, faces_boundary)); + return m_entity_list_manager; } - size_t numberOfNodeBoundaries() const +size_t numberOfNodeBoundaries() const { return m_nodes_boundary_list.size(); } @@ -308,8 +368,8 @@ public: return m_nodes_boundary_list[i]; } - void addNodeBoundary(const unsigned int& ref, - const Kokkos::View<const unsigned int*> nodes_boundary) + void addNodeBoundary(const RefId& ref, + const Kokkos::View<const unsigned int*> nodes_boundary) { m_nodes_boundary_list.push_back(std::make_pair(ref, nodes_boundary)); } @@ -317,7 +377,7 @@ public: Connectivity2D(const Connectivity2D&) = delete; Connectivity2D(const Kokkos::View<const unsigned short*> cell_nb_nodes, - const Kokkos::View<const unsigned int**> cell_nodes) + const Kokkos::View<const unsigned int**> cell_nodes) : m_number_of_cells (cell_nodes.extent(0)), m_cell_nb_nodes(cell_nb_nodes), m_cell_nodes (cell_nodes) @@ -325,21 +385,21 @@ public: { Kokkos::View<double*> inv_cell_nb_nodes("inv_cell_nb_nodes", m_number_of_cells); Kokkos::parallel_for(m_number_of_cells, KOKKOS_LAMBDA(const int&j){ - inv_cell_nb_nodes[j] = 1./m_cell_nb_nodes[j]; - }); + inv_cell_nb_nodes[j] = 1./m_cell_nb_nodes[j]; + }); m_inv_cell_nb_nodes = inv_cell_nb_nodes; } assert(m_number_of_cells>0); ConnectivityUtils utils; utils.computeNodeCellConnectivity(m_cell_nodes, - m_cell_nb_nodes, - m_number_of_cells, - m_max_nb_node_per_cell, - m_number_of_nodes, - m_node_nb_cells, - m_node_cells, - m_node_cell_local_node); + m_cell_nb_nodes, + m_number_of_cells, + m_max_nb_node_per_cell, + m_number_of_nodes, + m_node_nb_cells, + m_node_cells, + m_node_cell_local_node); this->_computeFaceCellConnectivities(); //this->_computeNodeFaceConnectivities(); diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp index ba398607b..53c704e13 100644 --- a/src/mesh/GmshReader.cpp +++ b/src/mesh/GmshReader.cpp @@ -9,8 +9,9 @@ #include <Connectivity2D.hpp> #include <Mesh.hpp> #include <map> +#include <regex> -template<typename T> +template<typename T> inline std::string stringify(const T & t) { std::ostringstream oss; @@ -18,7 +19,7 @@ inline std::string stringify(const T & t) return oss.str(); } -template<> +template<> inline std::string stringify<std::string>(const std::string& t) { return t; @@ -26,7 +27,7 @@ inline std::string stringify<std::string>(const std::string& t) class ErrorHandler { -public: + public: enum Type { asked, /**< execution request by the user*/ compilation, /**< syntax error in a language */ @@ -34,49 +35,49 @@ public: unexpected /**< Unexpected execution error */ }; -private: + private: const std::string __filename; /**< The source file name where the error occured */ const size_t __lineNumber; /**< The line number where exception was raised */ const std::string __errorMessage; /**< The reporting message */ const Type __type; /**< the type of the error */ -public: - /** + public: + /** * Prints the error message - * + * */ virtual void writeErrorMessage(); - /** + /** * The copy constructor - * + * * @param e an handled error */ ErrorHandler(const ErrorHandler& e) - : __filename(e.__filename), - __lineNumber(e.__lineNumber), - __errorMessage(e.__errorMessage), - __type(e.__type) + : __filename(e.__filename), + __lineNumber(e.__lineNumber), + __errorMessage(e.__errorMessage), + __type(e.__type) { ; } - /** + /** * Constructor - * + * * @param filename the source file name * @param lineNumber the source line * @param errorMessage the reported message * @param type the type of the error */ ErrorHandler(const std::string& filename, - const size_t& lineNumber, - const std::string& errorMessage, - const Type& type); + const size_t& lineNumber, + const std::string& errorMessage, + const Type& type); - /** + /** * The destructor - * + * */ virtual ~ErrorHandler() { @@ -86,205 +87,205 @@ public: void ErrorHandler::writeErrorMessage() { switch(__type) { - case asked: { - std::cerr << "\nremark: exit command explicitly called\n"; - } - case normal: { - std::cerr << '\n' << __filename << ':' << __lineNumber - << ":remark: emitted the following message\n"; - std::cerr << "error: " << __errorMessage << '\n'; - break; - } - case compilation: { - std::cerr << "\nline " << __lineNumber << ':' << __errorMessage << '\n'; - break; - } - case unexpected: { - std::cerr << '\n' << __filename << ':' << __lineNumber << ":\n" << __errorMessage << '\n'; - std::cerr << "\nUNEXPECTED ERROR: this should not occure, please report it\n"; - std::cerr << "\nBUG REPORT: Please send bug reports to:\n" - << " ff3d-dev@nongnu.org or freefem@ann.jussieu.fr\n" - << "or better, use the Bug Tracking System:\n" - << " http://savannah.nongnu.org/bugs/?group=ff3d\n"; - break; - } - default: { - std::cerr << __filename << ':' << __lineNumber << ": " << __errorMessage << '\n'; - std::cerr << __FILE__ << ':' << __LINE__ << ":remark: error type not implemented!\n"; - } + case asked: { + std::cerr << "\nremark: exit command explicitly called\n"; + } + case normal: { + std::cerr << '\n' << __filename << ':' << __lineNumber + << ":remark: emitted the following message\n"; + std::cerr << "error: " << __errorMessage << '\n'; + break; + } + case compilation: { + std::cerr << "\nline " << __lineNumber << ':' << __errorMessage << '\n'; + break; + } + case unexpected: { + std::cerr << '\n' << __filename << ':' << __lineNumber << ":\n" << __errorMessage << '\n'; + std::cerr << "\nUNEXPECTED ERROR: this should not occure, please report it\n"; + std::cerr << "\nBUG REPORT: Please send bug reports to:\n" + << " ff3d-dev@nongnu.org or freefem@ann.jussieu.fr\n" + << "or better, use the Bug Tracking System:\n" + << " http://savannah.nongnu.org/bugs/?group=ff3d\n"; + break; + } + default: { + std::cerr << __filename << ':' << __lineNumber << ": " << __errorMessage << '\n'; + std::cerr << __FILE__ << ':' << __LINE__ << ":remark: error type not implemented!\n"; + } } } ErrorHandler:: ErrorHandler(const std::string& filename, - const size_t& lineNumber, - const std::string& errorMessage, - const Type& type) - : __filename(filename), - __lineNumber(lineNumber), - __errorMessage(errorMessage), - __type(type) + const size_t& lineNumber, + const std::string& errorMessage, + const Type& type) + : __filename(filename), + __lineNumber(lineNumber), + __errorMessage(errorMessage), + __type(type) { ; } GmshReader::GmshReader(const std::string& filename) - : m_filename(filename) + : m_filename(filename) { try { - m_fin.open(m_filename); - if (not m_fin) { - std::cerr << "cannot read file '" << m_filename << "'\n"; - std::exit(0); - } - - // gmsh 2.2 format keywords - __keywordList["$MeshFormat"] = MESHFORMAT; - __keywordList["$EndMeshFormat"] = ENDMESHFORMAT; - __keywordList["$Nodes"] = NODES; - __keywordList["$EndNodes"] = ENDNODES; - __keywordList["$Elements"] = ELEMENTS; - __keywordList["$EndElements"] = ENDELEMENTS; - __keywordList["$PhysicalNames"] = PHYSICALNAMES; - __keywordList["$EndPhysicalNames"] = ENDPHYSICALNAMES; - - __numberOfPrimitiveNodes.resize(16); - __numberOfPrimitiveNodes[ 0] = 2; // edge - __numberOfPrimitiveNodes[ 1] = 3; // triangle - __numberOfPrimitiveNodes[ 2] = 4; // quadrangle - __numberOfPrimitiveNodes[ 3] = 4; // Tetrahedron - __numberOfPrimitiveNodes[ 4] = 8; // Hexaredron - __numberOfPrimitiveNodes[ 5] = 6; // Prism - __numberOfPrimitiveNodes[ 6] = 5; // Pyramid - __numberOfPrimitiveNodes[ 7] = 3; // second order edge - __numberOfPrimitiveNodes[ 8] = 6; // second order triangle - __numberOfPrimitiveNodes[ 9] = 9; // second order quadrangle - __numberOfPrimitiveNodes[10] = 10; // second order tetrahedron - __numberOfPrimitiveNodes[11] = 27; // second order hexahedron - __numberOfPrimitiveNodes[12] = 18; // second order prism - __numberOfPrimitiveNodes[13] = 14; // second order pyramid - __numberOfPrimitiveNodes[14] = 1; // point - - __primitivesNames[0] = "edges"; - __supportedPrimitives[0] = true; - __primitivesNames[1] = "triangles"; - __supportedPrimitives[1] = true; - __primitivesNames[2] = "quadrangles"; - __supportedPrimitives[2] = true; - __primitivesNames[3] = "tetrahedra"; - __supportedPrimitives[3] = true; - __primitivesNames[4] = "hexahedra"; - __supportedPrimitives[4] = true; - __primitivesNames[5] = "prisms"; - __supportedPrimitives[5] = false; - __primitivesNames[6] = "pyramids"; - __supportedPrimitives[6] = false; - __primitivesNames[7] = "second order edges"; - __supportedPrimitives[7] = false; - __primitivesNames[8] = "second order triangles"; - __supportedPrimitives[8] = false; - __primitivesNames[9] = "second order quadrangles"; - __supportedPrimitives[9] = false; - __primitivesNames[10] = "second order tetrahedra"; - __supportedPrimitives[10]= false; - __primitivesNames[11] = "second order hexahedra"; - __supportedPrimitives[11]= false; - __primitivesNames[12] = "second order prisms"; - __supportedPrimitives[12]= false; - __primitivesNames[13] = "second order pyramids"; - __supportedPrimitives[13]= false; - __primitivesNames[14] = "point"; - __supportedPrimitives[14]= false; - - std::cout << "Reading file '" << m_filename << "'\n"; - - // Getting vertices list - GmshReader::Keyword kw = this->__nextKeyword(); - switch(kw.second) { - // case NOD: { - // this->__readGmsh1(); - // break; - // } - case MESHFORMAT: { - double fileVersion = this->_getReal(); - if (fileVersion != 2.2) { - throw ErrorHandler(__FILE__,__LINE__, - "Cannot read Gmsh format '"+stringify(fileVersion)+"'", - ErrorHandler::normal); - } - int fileType = this->_getInteger(); - __binary = (fileType == 1); - if ((fileType < 0) or (fileType > 1)) { - throw ErrorHandler(__FILE__,__LINE__, - "Cannot read Gmsh file type '"+stringify(fileType)+"'", - ErrorHandler::normal); - } - - int dataSize = this->_getInteger(); - if (dataSize != sizeof(double)) { - throw ErrorHandler(__FILE__,__LINE__, - "Data size not supported '"+stringify(dataSize)+"'", - ErrorHandler::normal); - } - - if (__binary) { -// int one=0; - -// fseek(__ifh,1L,SEEK_CUR); -// fread(reinterpret_cast<char*>(&one),sizeof(int),1,__ifh); - -// if (one == 1) { -// __convertEndian = false; -// } else { -// invertEndianess(one); - -// if (one == 1) { -// __convertEndian = true; -// } else { -// throw ErrorHandler(__FILE__,__LINE__, -// "Cannot determine endianess", -// ErrorHandler::normal); -// } -// } - -// std::cout << "- Binary format: "; -// #ifdef WORDS_BIGENDIAN -// if (not __convertEndian) { -// std::cout << "big endian\n"; -// } else { -// std::cout << "little endian\n"; -// } -// #else // WORDS_BIGENDIAN -// if (not __convertEndian) { -// std::cout << "little endian\n"; -// } else { -// std::cout << "big endian\n"; -// } -// #endif // WORDS_BIGENDIAN - } - - kw = this->__nextKeyword(); - if (kw.second != ENDMESHFORMAT) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': expecting $EndMeshFormat, '"+kw.first+"' was found", - ErrorHandler::normal); + m_fin.open(m_filename); + if (not m_fin) { + std::cerr << "cannot read file '" << m_filename << "'\n"; + std::exit(0); + } + + // gmsh 2.2 format keywords + __keywordList["$MeshFormat"] = MESHFORMAT; + __keywordList["$EndMeshFormat"] = ENDMESHFORMAT; + __keywordList["$Nodes"] = NODES; + __keywordList["$EndNodes"] = ENDNODES; + __keywordList["$Elements"] = ELEMENTS; + __keywordList["$EndElements"] = ENDELEMENTS; + __keywordList["$PhysicalNames"] = PHYSICALNAMES; + __keywordList["$EndPhysicalNames"] = ENDPHYSICALNAMES; + + __numberOfPrimitiveNodes.resize(16); + __numberOfPrimitiveNodes[ 0] = 2; // edge + __numberOfPrimitiveNodes[ 1] = 3; // triangle + __numberOfPrimitiveNodes[ 2] = 4; // quadrangle + __numberOfPrimitiveNodes[ 3] = 4; // Tetrahedron + __numberOfPrimitiveNodes[ 4] = 8; // Hexaredron + __numberOfPrimitiveNodes[ 5] = 6; // Prism + __numberOfPrimitiveNodes[ 6] = 5; // Pyramid + __numberOfPrimitiveNodes[ 7] = 3; // second order edge + __numberOfPrimitiveNodes[ 8] = 6; // second order triangle + __numberOfPrimitiveNodes[ 9] = 9; // second order quadrangle + __numberOfPrimitiveNodes[10] = 10; // second order tetrahedron + __numberOfPrimitiveNodes[11] = 27; // second order hexahedron + __numberOfPrimitiveNodes[12] = 18; // second order prism + __numberOfPrimitiveNodes[13] = 14; // second order pyramid + __numberOfPrimitiveNodes[14] = 1; // point + + __primitivesNames[0] = "edges"; + __supportedPrimitives[0] = true; + __primitivesNames[1] = "triangles"; + __supportedPrimitives[1] = true; + __primitivesNames[2] = "quadrangles"; + __supportedPrimitives[2] = true; + __primitivesNames[3] = "tetrahedra"; + __supportedPrimitives[3] = true; + __primitivesNames[4] = "hexahedra"; + __supportedPrimitives[4] = true; + __primitivesNames[5] = "prisms"; + __supportedPrimitives[5] = false; + __primitivesNames[6] = "pyramids"; + __supportedPrimitives[6] = false; + __primitivesNames[7] = "second order edges"; + __supportedPrimitives[7] = false; + __primitivesNames[8] = "second order triangles"; + __supportedPrimitives[8] = false; + __primitivesNames[9] = "second order quadrangles"; + __supportedPrimitives[9] = false; + __primitivesNames[10] = "second order tetrahedra"; + __supportedPrimitives[10]= false; + __primitivesNames[11] = "second order hexahedra"; + __supportedPrimitives[11]= false; + __primitivesNames[12] = "second order prisms"; + __supportedPrimitives[12]= false; + __primitivesNames[13] = "second order pyramids"; + __supportedPrimitives[13]= false; + __primitivesNames[14] = "point"; + __supportedPrimitives[14]= true; + + std::cout << "Reading file '" << m_filename << "'\n"; + + // Getting vertices list + GmshReader::Keyword kw = this->__nextKeyword(); + switch(kw.second) { + // case NOD: { + // this->__readGmsh1(); + // break; + // } + case MESHFORMAT: { + double fileVersion = this->_getReal(); + if (fileVersion != 2.2) { + throw ErrorHandler(__FILE__,__LINE__, + "Cannot read Gmsh format '"+stringify(fileVersion)+"'", + ErrorHandler::normal); + } + int fileType = this->_getInteger(); + __binary = (fileType == 1); + if ((fileType < 0) or (fileType > 1)) { + throw ErrorHandler(__FILE__,__LINE__, + "Cannot read Gmsh file type '"+stringify(fileType)+"'", + ErrorHandler::normal); + } + + int dataSize = this->_getInteger(); + if (dataSize != sizeof(double)) { + throw ErrorHandler(__FILE__,__LINE__, + "Data size not supported '"+stringify(dataSize)+"'", + ErrorHandler::normal); + } + + if (__binary) { + // int one=0; + + // fseek(__ifh,1L,SEEK_CUR); + // fread(reinterpret_cast<char*>(&one),sizeof(int),1,__ifh); + + // if (one == 1) { + // __convertEndian = false; + // } else { + // invertEndianess(one); + + // if (one == 1) { + // __convertEndian = true; + // } else { + // throw ErrorHandler(__FILE__,__LINE__, + // "Cannot determine endianess", + // ErrorHandler::normal); + // } + // } + + // std::cout << "- Binary format: "; + // #ifdef WORDS_BIGENDIAN + // if (not __convertEndian) { + // std::cout << "big endian\n"; + // } else { + // std::cout << "little endian\n"; + // } + // #else // WORDS_BIGENDIAN + // if (not __convertEndian) { + // std::cout << "little endian\n"; + // } else { + // std::cout << "big endian\n"; + // } + // #endif // WORDS_BIGENDIAN + } + + kw = this->__nextKeyword(); + if (kw.second != ENDMESHFORMAT) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': expecting $EndMeshFormat, '"+kw.first+"' was found", + ErrorHandler::normal); + } + + this->__readGmshFormat2_2(); + + break; + } + default: { + throw ErrorHandler(__FILE__,__LINE__, + "cannot determine format version of '"+m_filename+"'", + ErrorHandler::normal); + } } - this->__readGmshFormat2_2(); - - break; - } - default: { - throw ErrorHandler(__FILE__,__LINE__, - "cannot determine format version of '"+m_filename+"'", - ErrorHandler::normal); - } - } - - this->__proceedData(); - // this->__createMesh(); + this->__proceedData(); + // this->__createMesh(); } catch(ErrorHandler e) { e.writeErrorMessage(); @@ -298,14 +299,14 @@ void GmshReader::__readVertices() std::cout << "- Number Of Vertices: " << numberOfVerices << '\n'; if (numberOfVerices<0) { throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+this->m_filename - +"': number of vertices is negative", - ErrorHandler::normal); + "reading file '"+this->m_filename + +"': number of vertices is negative", + ErrorHandler::normal); } __verticesNumbers.resize(numberOfVerices); __vertices = Kokkos::View<R3*>("vertices",numberOfVerices); - + if (not __binary) { for (int i=0; i<numberOfVerices; ++i) { __verticesNumbers[i] = this->_getInteger(); @@ -313,7 +314,7 @@ void GmshReader::__readVertices() const double y = this->_getReal(); const double z = this->_getReal(); __vertices[i] = TinyVector<3, double>(x,y,z); - } + } } else { // fseek(m_fin.file()__ifh,1L,SEEK_CUR); // for (int i=0; i<numberOfVerices; ++i) { @@ -394,9 +395,9 @@ GmshReader::__readElements2_2() std::cout << "- Number Of Elements: " << numberOfElements << '\n'; if (numberOfElements<0) { throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': number of elements is negative", - ErrorHandler::normal); + "reading file '"+m_filename + +"': number of elements is negative", + ErrorHandler::normal); } __elementType.resize(numberOfElements); @@ -409,22 +410,22 @@ GmshReader::__readElements2_2() const int elementType = this->_getInteger()-1; if ((elementType < 0) or (elementType > 14)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': unknown element type '"+stringify(elementType)+"'", - ErrorHandler::normal); + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': unknown element type '"+stringify(elementType)+"'", + ErrorHandler::normal); } __elementType[i] = elementType; const int numberOfTags = this->_getInteger(); __references[i] = this->_getInteger(); // physical reference for (int tag=1; tag<numberOfTags; ++tag) { - this->_getInteger(); // drops remaining tags + this->_getInteger(); // drops remaining tags } const int numberOfVertices = __numberOfPrimitiveNodes[elementType]; __elementVertices[i].resize(numberOfVertices); for (int j=0; j<numberOfVertices; ++j) { - __elementVertices[i][j] = this->_getInteger(); + __elementVertices[i][j] = this->_getInteger(); } } } else { @@ -502,7 +503,19 @@ __readPhysicalNames2_2() const int physical_number = this->_getInteger(); std::string physical_name; m_fin >> physical_name; - std::cout << "- " << rang::style::bold << physical_name << " <-> " << physical_number << " for dimension " << physical_dimension << rang::style::reset << " [IGNORED]\n"; + physical_name = std::regex_replace(physical_name, std::regex("(\")"), ""); + std::cout << "- " << rang::style::bold << physical_name + << " <-> " << physical_number << " for dimension " + << physical_dimension << rang::style::reset + << " [" << rang::fg::yellow << "IGNORED" << rang::style::reset << "]\n"; + PhysicalRefId physical_ref_id(physical_dimension, RefId(physical_number, physical_name)); + auto searched_physical_ref_id = m_physical_ref_map.find(physical_number); + if (searched_physical_ref_id != m_physical_ref_map.end()) { + std::cerr << "Physical reference id '" << physical_ref_id + << "' already defined as '" << searched_physical_ref_id->second << "'!"; + std::exit(0); + } + m_physical_ref_map[physical_number] = physical_ref_id; } } @@ -521,76 +534,74 @@ GmshReader::__proceedData() for (size_t i=0; i<elementNumber.dimension(); ++i) { if (elementNumber[i]>0) { std::cout << " - Number of " - << __primitivesNames[i] - << ": " << elementNumber[i]; + << __primitivesNames[i] + << ": " << elementNumber[i]; if (not(__supportedPrimitives[i])) { - std::cout << " [IGNORED]"; + std::cout << " [" << rang::fg::yellow << "IGNORED" << rang::style::reset << "]"; } else { - std::cout << " references: "; - for(std::set<size_t>::const_iterator iref - = elementReferences[i].begin(); - iref != elementReferences[i].end(); ++iref) { - if (iref != elementReferences[i].begin()) std::cout << ','; - std::cout << *iref; - } - - switch (i) { - // Supported entities - case 0: { // edges - __edges - = Kokkos::View<Edge*>("edges", - elementNumber[i]); - __edges_ref.resize(elementNumber[i]); - break; - } - case 1: { // triangles - __triangles - = Kokkos::View<Triangle*>("triangles", - elementNumber[i]); - __triangles_ref.resize(elementNumber[i]); - break; - } - case 2: { // quadrangles - __quadrangles - = Kokkos::View<Quadrangle*>("quadrangles", - elementNumber[i]); - __quadrangles_ref.resize(elementNumber[i]); - break; - } - case 3: { // tetrahedra - __tetrahedra - = Kokkos::View<Tetrahedron*>("tetrahedra", - elementNumber[i]); - __tetrahedra_ref.resize(elementNumber[i]); - break; - } - case 4: {// hexahedra - __hexahedra - = Kokkos::View<Hexahedron*>("hexahedra", - elementNumber[i]); - __hexahedra_ref.resize(elementNumber[i]); - } - // Ignored entities - case 14: {// point - break; - } - // Unsupported entities - case 5: // prism - case 6: // pyramid - case 7: // second order edge - case 8: // second order triangle - case 9: // second order quadrangle - case 10: // second order tetrahedron - case 11: // second order hexahedron - case 12: // second order prism - case 13: // second order pyramid - default: { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': ff3d cannot read this kind of element", - ErrorHandler::normal); - } - } + std::cout << " references: "; + for(std::set<size_t>::const_iterator iref + = elementReferences[i].begin(); + iref != elementReferences[i].end(); ++iref) { + if (iref != elementReferences[i].begin()) std::cout << ','; + std::cout << *iref; + } + + switch (i) { + // Supported entities + case 0: { // edges + __edges = Kokkos::View<Edge*>("edges", + elementNumber[i]); + __edges_ref.resize(elementNumber[i]); + break; + } + case 1: { // triangles + __triangles = Kokkos::View<Triangle*>("triangles", + elementNumber[i]); + __triangles_ref.resize(elementNumber[i]); + break; + } + case 2: { // quadrangles + __quadrangles = Kokkos::View<Quadrangle*>("quadrangles", + elementNumber[i]); + __quadrangles_ref.resize(elementNumber[i]); + break; + } + case 3: { // tetrahedra + __tetrahedra = Kokkos::View<Tetrahedron*>("tetrahedra", + elementNumber[i]); + __tetrahedra_ref.resize(elementNumber[i]); + break; + } + case 4: {// hexahedra + __hexahedra = Kokkos::View<Hexahedron*>("hexahedra", + elementNumber[i]); + __hexahedra_ref.resize(elementNumber[i]); + } + // Ignored entities + case 14: {// point + __points = Kokkos::View<Point*>("points", + elementNumber[i]); + __points_ref.resize(elementNumber[i]); + break; + } + // Unsupported entities + case 5: // prism + case 6: // pyramid + case 7: // second order edge + case 8: // second order triangle + case 9: // second order quadrangle + case 10: // second order tetrahedron + case 11: // second order hexahedron + case 12: // second order prism + case 13: // second order pyramid + default: { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': ff3d cannot read this kind of element", + ErrorHandler::normal); + } + } } std::cout << '\n'; } @@ -607,16 +618,16 @@ GmshReader::__proceedData() if (minNumber<0) { throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': ff3d does not implement negative vertices number", - ErrorHandler::normal); + "reading file '"+m_filename + +"': ff3d does not implement negative vertices number", + ErrorHandler::normal); } - // A value of -1 means that the vertex is unknown + // A value of -1 means that the vertex is unknown __verticesCorrepondance.resize(maxNumber+1,-1); for (size_t i=0; i<__verticesNumbers.size(); ++i) { - + __verticesCorrepondance[__verticesNumbers[i]] = i; } @@ -628,125 +639,130 @@ GmshReader::__proceedData() std::vector<int>& elementVertices = __elementVertices[i]; switch (__elementType[i]) { // Supported entities - case 0: { // edge - int& edgeNumber = elementNumber[0]; - const int a = __verticesCorrepondance[elementVertices[0]]; - const int b = __verticesCorrepondance[elementVertices[1]]; - if ((a<0) or (b<0)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': error reading element "+stringify(i) - +" [bad vertices definition]", - ErrorHandler::normal); + case 0: { // edge + int& edgeNumber = elementNumber[0]; + const int a = __verticesCorrepondance[elementVertices[0]]; + const int b = __verticesCorrepondance[elementVertices[1]]; + if ((a<0) or (b<0)) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': error reading element "+stringify(i) + +" [bad vertices definition]", + ErrorHandler::normal); + } + __edges[edgeNumber] + = Edge(a, b); + __edges_ref[edgeNumber] = __references[i]; + edgeNumber++; // one more edge + break; } - __edges[edgeNumber] - = Edge(a, b); - __edges_ref[edgeNumber] = __references[i]; - edgeNumber++; // one more edge - break; - } - case 1: { // triangles - int& triangleNumber = elementNumber[1]; - - const int a = __verticesCorrepondance[elementVertices[0]]; - const int b = __verticesCorrepondance[elementVertices[1]]; - const int c = __verticesCorrepondance[elementVertices[2]]; - if ((a<0) or (b<0) or (c<0)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': error reading element "+stringify(i) - +" [bad vertices definition]", - ErrorHandler::normal); + case 1: { // triangles + int& triangleNumber = elementNumber[1]; + + const int a = __verticesCorrepondance[elementVertices[0]]; + const int b = __verticesCorrepondance[elementVertices[1]]; + const int c = __verticesCorrepondance[elementVertices[2]]; + if ((a<0) or (b<0) or (c<0)) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': error reading element "+stringify(i) + +" [bad vertices definition]", + ErrorHandler::normal); + } + __triangles[triangleNumber] + = Triangle(a, b, c); + __triangles_ref[triangleNumber] = __references[i]; + triangleNumber++; // one more triangle + break; } - __triangles[triangleNumber] - = Triangle(a, b, c); - __triangles_ref[triangleNumber] = __references[i]; - triangleNumber++; // one more triangle - break; - } - case 2: { // quadrangle - int& quadrilateralNumber = elementNumber[2]; - - const int a = __verticesCorrepondance[elementVertices[0]]; - const int b = __verticesCorrepondance[elementVertices[1]]; - const int c = __verticesCorrepondance[elementVertices[2]]; - const int d = __verticesCorrepondance[elementVertices[3]]; - if ((a<0) or (b<0) or (c<0) or (d<0)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': error reading element "+stringify(i) - +" [bad vertices definition]", - ErrorHandler::normal); + case 2: { // quadrangle + int& quadrilateralNumber = elementNumber[2]; + + const int a = __verticesCorrepondance[elementVertices[0]]; + const int b = __verticesCorrepondance[elementVertices[1]]; + const int c = __verticesCorrepondance[elementVertices[2]]; + const int d = __verticesCorrepondance[elementVertices[3]]; + if ((a<0) or (b<0) or (c<0) or (d<0)) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': error reading element "+stringify(i) + +" [bad vertices definition]", + ErrorHandler::normal); + } + __quadrangles[quadrilateralNumber] = Quadrangle(a,b,c,d); + __quadrangles_ref[quadrilateralNumber] = __references[i]; + quadrilateralNumber++; // one more quadrangle + break; } - __quadrangles[quadrilateralNumber] = Quadrangle(a,b,c,d); - __quadrangles_ref[quadrilateralNumber] = __references[i]; - quadrilateralNumber++; // one more quadrangle - break; - } - case 3: { // tetrahedra - int& tetrahedronNumber = elementNumber[3]; - - const int a = __verticesCorrepondance[elementVertices[0]]; - const int b = __verticesCorrepondance[elementVertices[1]]; - const int c = __verticesCorrepondance[elementVertices[2]]; - const int d = __verticesCorrepondance[elementVertices[3]]; - if ((a<0) or (b<0) or (c<0) or (d<0)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': error reading element "+stringify(i) - +" [bad vertices definition]", - ErrorHandler::normal); + case 3: { // tetrahedra + int& tetrahedronNumber = elementNumber[3]; + + const int a = __verticesCorrepondance[elementVertices[0]]; + const int b = __verticesCorrepondance[elementVertices[1]]; + const int c = __verticesCorrepondance[elementVertices[2]]; + const int d = __verticesCorrepondance[elementVertices[3]]; + if ((a<0) or (b<0) or (c<0) or (d<0)) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': error reading element "+stringify(i) + +" [bad vertices definition]", + ErrorHandler::normal); + } + __tetrahedra[tetrahedronNumber] = Tetrahedron(a, b, c, d); + __tetrahedra_ref[tetrahedronNumber] = __references[i]; + tetrahedronNumber++; // one more tetrahedron + break; } - __tetrahedra[tetrahedronNumber] = Tetrahedron(a, b, c, d); - __tetrahedra_ref[tetrahedronNumber] = __references[i]; - tetrahedronNumber++; // one more tetrahedron - break; - } - case 4: { // hexaredron - int& hexahedronNumber = elementNumber[4]; - - const int a = __verticesCorrepondance[elementVertices[0]]; - const int b = __verticesCorrepondance[elementVertices[1]]; - const int c = __verticesCorrepondance[elementVertices[2]]; - const int d = __verticesCorrepondance[elementVertices[3]]; - const int e = __verticesCorrepondance[elementVertices[4]]; - const int f = __verticesCorrepondance[elementVertices[5]]; - const int g = __verticesCorrepondance[elementVertices[6]]; - const int h = __verticesCorrepondance[elementVertices[7]]; - if ((a<0) or (b<0) or (c<0) or (d<0) or (e<0) or (f<0) or (g<0) or (h<0)) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': error reading element "+stringify(i) - +" [bad vertices definition]", - ErrorHandler::normal); + case 4: { // hexaredron + int& hexahedronNumber = elementNumber[4]; + + const int a = __verticesCorrepondance[elementVertices[0]]; + const int b = __verticesCorrepondance[elementVertices[1]]; + const int c = __verticesCorrepondance[elementVertices[2]]; + const int d = __verticesCorrepondance[elementVertices[3]]; + const int e = __verticesCorrepondance[elementVertices[4]]; + const int f = __verticesCorrepondance[elementVertices[5]]; + const int g = __verticesCorrepondance[elementVertices[6]]; + const int h = __verticesCorrepondance[elementVertices[7]]; + if ((a<0) or (b<0) or (c<0) or (d<0) or (e<0) or (f<0) or (g<0) or (h<0)) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': error reading element "+stringify(i) + +" [bad vertices definition]", + ErrorHandler::normal); + } + __hexahedra[hexahedronNumber] + = Hexahedron(a, b, c, d, + e, f, g, h); + __hexahedra_ref[hexahedronNumber] = __references[i]; + hexahedronNumber++; // one more hexahedron + break; + } + // Unsupported entities + case 14:{// point + int& point_number = elementNumber[14]; + const int a = __verticesCorrepondance[elementVertices[0]]; + __points[point_number] = a; + __points_ref[point_number] = __references[i]; + point_number++; + break; + } + case 5: // prism + case 6: // pyramid + case 7: // second order edge + case 8: // second order triangle + case 9: // second order quadrangle + case 10: // second order tetrahedron + case 11: // second order hexahedron + case 12: // second order prism + case 13:{// second order pyramid + } + default: { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': ff3d cannot read this kind of element", + ErrorHandler::normal); } - __hexahedra[hexahedronNumber] - = Hexahedron(a, b, c, d, - e, f, g, h); - __hexahedra_ref[hexahedronNumber] = __references[i]; - hexahedronNumber++; // one more hexahedron - break; - } - // Unsupported entities - case 14:{// point - break; - } - case 5: // prism - case 6: // pyramid - case 7: // second order edge - case 8: // second order triangle - case 9: // second order quadrangle - case 10: // second order tetrahedron - case 11: // second order hexahedron - case 12: // second order prism - case 13:{// second order pyramid - } - default: { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': ff3d cannot read this kind of element", - ErrorHandler::normal); - } } } @@ -790,7 +806,7 @@ GmshReader::__proceedData() cell_nodes(j,1) = __triangles[j][1]; cell_nodes(j,2) = __triangles[j][2]; } - + const size_t nb_quadrangles = __quadrangles.extent(0); for (size_t j=0; j<nb_quadrangles; ++j) { const size_t jq = j+nb_triangles; @@ -812,43 +828,63 @@ GmshReader::__proceedData() std::map<unsigned int, std::vector<unsigned int>> ref_faces_map; for (unsigned int e=0; e<__edges.extent(0); ++e) { const unsigned int edge_number = connectivity.getFaceNumber(__edges[e][0], __edges[e][1]); - const unsigned int ref = __edges_ref[e]; + const unsigned int& ref = __edges_ref[e]; ref_faces_map[ref].push_back(edge_number); } for (const auto& ref_face_list : ref_faces_map) { - connectivity.addFaceBoundary(ref_face_list.first, - ref_face_list.second); + Kokkos::View<unsigned int*> face_list("face_list", ref_face_list.second.size()); + for (size_t j=0; j<ref_face_list.second.size(); ++j) { + face_list[j]=ref_face_list.second[j]; + } + const PhysicalRefId& physical_ref_id = m_physical_ref_map.at(ref_face_list.first); + connectivity.entityListManager().addFaceIdArray(physical_ref_id.refId(), face_list); } const Kokkos::View<const unsigned int**> face_nodes = connectivity.faceNodes(); - for (size_t i=0; i<connectivity.numberOfFaceBoundaries(); ++i) { - const Connectivity2D::FacesBoundary& faces_boundary - = connectivity.facesBoundary(i); + std::cout << rang::fgB::red << "Creating nodes from faces for BC should not change connectivity definition" << rang::style::reset << '\n'; + + const EntityListManager& entity_list_manager = connectivity.entityListManager(); + for (const auto& id_face_array : entity_list_manager.getFaceIdArraySet()) { + const RefId& ref = id_face_array.first; + const auto& face_ids = id_face_array.second; - const unsigned int ref = faces_boundary.first; std::set<unsigned int> node_id_set; - const Kokkos::View<const unsigned int*> face_ids - = faces_boundary.second; - + for (unsigned int l=0; l<face_ids.extent(0); ++l) { - for (unsigned short r=0; r<2; ++r) { - node_id_set.insert(face_nodes(face_ids[l],r)); - } + for (unsigned short r=0; r<2; ++r) { + node_id_set.insert(face_nodes(face_ids[l],r)); + } } Kokkos::View<unsigned int*> node_id_list("node_ids", node_id_set.size()); { - int r=0; - for (auto node_id : node_id_set) { - node_id_list[r] = node_id; - ++r; - } + int r=0; + for (auto node_id : node_id_set) { + node_id_list[r] = node_id; + ++r; + } } connectivity.addNodeBoundary(ref, node_id_list); } + std::map<unsigned int, std::vector<unsigned int>> ref_points_map; + for (unsigned int r=0; r<__points.extent(0); ++r) { + const unsigned int point_number = __points[r]; + const unsigned int& ref = __points_ref[r]; + ref_points_map[ref].push_back(point_number); + } + + for (const auto& ref_point_list : ref_points_map) { + Kokkos::View<unsigned int*> point_list("point_list", ref_point_list.second.size()); + for (size_t j=0; j<ref_point_list.second.size(); ++j) { + point_list[j]=ref_point_list.second[j]; + } + const PhysicalRefId& physical_ref_id = m_physical_ref_map.at(ref_point_list.first); + connectivity.entityListManager().addNodeIdArray(physical_ref_id.refId(), point_list); + } + typedef Mesh<Connectivity2D> MeshType; typedef TinyVector<2, double> Rd; @@ -913,9 +949,9 @@ GmshReader::__nextKeyword() } throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': unknown keyword '"+aKeyword+"'", - ErrorHandler::normal); + "reading file '"+m_filename + +"': unknown keyword '"+aKeyword+"'", + ErrorHandler::normal); kw.first = aKeyword; kw.second = Unknown; @@ -930,47 +966,47 @@ __readGmshFormat2_2() while (kw.second != EndOfFile) { kw = this->__nextKeyword(); switch (kw.second) { - case NODES: { - this->__readVertices(); - if (this->__nextKeyword().second != ENDNODES) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': expecting $EndNodes, '"+kw.first+"' was found", - ErrorHandler::normal); + case NODES: { + this->__readVertices(); + if (this->__nextKeyword().second != ENDNODES) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': expecting $EndNodes, '"+kw.first+"' was found", + ErrorHandler::normal); + } + break; } - break; - } - case ELEMENTS: { - this->__readElements2_2(); - kw = this->__nextKeyword(); - if (kw.second != ENDELEMENTS) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': expecting $EndElements, '"+kw.first+"' was found", - ErrorHandler::normal); + case ELEMENTS: { + this->__readElements2_2(); + kw = this->__nextKeyword(); + if (kw.second != ENDELEMENTS) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': expecting $EndElements, '"+kw.first+"' was found", + ErrorHandler::normal); + } + break; } - break; - } - case PHYSICALNAMES: { - this->__readPhysicalNames2_2(); - if (this->__nextKeyword().second != ENDPHYSICALNAMES) { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': expecting $EndNodes, '"+kw.first+"' was found", - ErrorHandler::normal); + case PHYSICALNAMES: { + this->__readPhysicalNames2_2(); + if (this->__nextKeyword().second != ENDPHYSICALNAMES) { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': expecting $EndNodes, '"+kw.first+"' was found", + ErrorHandler::normal); + } + break; } - break; - } - case EndOfFile: { - break; - } - default: { - throw ErrorHandler(__FILE__,__LINE__, - "reading file '"+m_filename - +"': unexpected '"+kw.first+"'", - ErrorHandler::normal); - } + case EndOfFile: { + break; + } + default: { + throw ErrorHandler(__FILE__,__LINE__, + "reading file '"+m_filename + +"': unexpected '"+kw.first+"'", + ErrorHandler::normal); + } } } } diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp index fb41a5c35..f02cfa16f 100644 --- a/src/mesh/GmshReader.hpp +++ b/src/mesh/GmshReader.hpp @@ -1,42 +1,79 @@ #ifndef GMSH_READER_HPP #define GMSH_READER_HPP -#include <string> -#include <array> -#include <vector> -#include <map> -#include <fstream> #include <Kokkos_Core.hpp> #include <TinyVector.hpp> #include <Connectivity2D.hpp> #include <Mesh.hpp> +#include <RefId.hpp> + +#include <string> +#include <array> +#include <vector> +#include <map> +#include <fstream> + class GmshReader { public: typedef TinyVector<3, double> R3; -private: - std::ifstream m_fin; - const std::string m_filename; - - int _getInteger() - { - int i; - m_fin >> i; - return std::move(i); - } - - double _getReal() + class PhysicalRefId { - double d; - m_fin >> d; + private: + int m_dimension; + RefId m_ref_id; + + public: + friend std::ostream& operator<<(std::ostream& os, + const PhysicalRefId& physical_ref_id) + { + os << physical_ref_id.m_ref_id << "[dimension " << physical_ref_id.m_dimension << "]"; + return os; + } + + bool operator<(const PhysicalRefId& physical_ref_id) const + { + return m_ref_id.tagNumber()<physical_ref_id.m_ref_id.tagNumber(); + } + + bool operator==(const PhysicalRefId& physical_ref_id) const + { + return m_ref_id.tagNumber()==physical_ref_id.m_ref_id.tagNumber(); + } + + const int& dimension() const + { + return m_dimension; + } + + const RefId& refId() const + { + return m_ref_id; + } + + PhysicalRefId& operator=(const PhysicalRefId&) = default; + PhysicalRefId& operator=(PhysicalRefId&&) =default; + PhysicalRefId(const int& dimension, + const RefId& ref_id) + : m_dimension(dimension), + m_ref_id(ref_id) + { + ; + } + PhysicalRefId() = default; + PhysicalRefId(const PhysicalRefId&) = default; + PhysicalRefId(PhysicalRefId&&) = default; + ~PhysicalRefId() = default; + }; - return std::move(d); - } +private: + std::ifstream m_fin; + const std::string m_filename; - /** + /** * Gmsh format provides a numbered, none ordrered and none dense * vertices list, this stores the number of read vertices. */ @@ -44,6 +81,9 @@ private: Kokkos::View<R3*> __vertices; + typedef unsigned int Point; + Kokkos::View<Point*> __points; + std::vector<int> __points_ref; typedef TinyVector<2,unsigned int> Edge; Kokkos::View<Edge*> __edges; std::vector<int> __edges_ref; @@ -60,63 +100,81 @@ private: Kokkos::View<Hexahedron*> __hexahedra; std::vector<int> __hexahedra_ref; - /** + /** * Gmsh format provides a numbered, none ordrered and none dense * vertices list, this provides vertices renumbering correspondance */ std::vector<int> __verticesCorrepondance; - /** + /** * elements types */ std::vector<short> __elementType; - /** + /** * References */ std::vector<int> __references; - /** + /** * References */ std::vector<std::vector<int> > __elementVertices; - /** + /** * Stores the number of nodes associated to each primitive - * + * */ std::vector<int> __numberOfPrimitiveNodes; - /** + /** * Array of boolean describing gmsh supported primitives by ff3d - * + * */ std::array<bool, 15> __supportedPrimitives; - /** + /** * Primitives names according to there number - * + * */ std::map<int, std::string> __primitivesNames; bool __binary; /**< true if binary format */ bool __convertEndian; /**< true if needs to adapt endianess */ - /** - * Adapts gmsh data to ff3d's structures - * + std::map<unsigned int, PhysicalRefId> m_physical_ref_map; + + int _getInteger() + { + int i; + m_fin >> i; + + return std::move(i); + } + + double _getReal() + { + double d; + m_fin >> d; + + return std::move(d); + } + + /** + * Adapts gmsh data to ff3d's structures + * */ void __proceedData(); - /** + /** * Reads data in format 2.2 - * + * */ void __readGmshFormat2_2(); /** * List of allowed keyword in mesh file - * + * */ enum KeywordType { // gmsh 2.2 @@ -135,7 +193,7 @@ private: /** * List of known keywords - * + * */ typedef std::map<std::string, int> KeywordList; @@ -143,44 +201,44 @@ private: /** * Type for keyword - * + * */ typedef std::pair<std::string, int> Keyword; - /** + /** * Skips next comments if exists - * + * */ void __skipComments(); - /** + /** * Reads the next keyword and returns its token - * + * * @return KeywordToken */ Keyword __nextKeyword(); - /** + /** * get list of vertices - * + * */ void __getVertices(); /** * Read list of vertices - * + * */ void __readVertices(); /** * Read all elements in format 2.0 - * + * */ void __readElements2_2(); /** * Reads physical names - * + * */ void __readPhysicalNames2_2(); @@ -195,7 +253,7 @@ public: GmshReader(const std::string& filename); ~GmshReader() = default; - + }; #endif // GMSH_READER_HPP diff --git a/src/mesh/RefId.hpp b/src/mesh/RefId.hpp new file mode 100644 index 000000000..775b1a713 --- /dev/null +++ b/src/mesh/RefId.hpp @@ -0,0 +1,69 @@ +#ifndef REF_ID_HPP +#define REF_ID_HPP + +#include <string> +#include <iostream> + +class RefId +{ + private: + unsigned int m_tag_number; + std::string m_tag_name; + + public: + friend std::ostream& operator<<(std::ostream& os, const RefId& ref_id) + { + if (ref_id.m_tag_name.size()>0) { + os << ref_id.m_tag_name << '(' << ref_id.m_tag_number << ')'; + } else { + os << ref_id.m_tag_number; + } + return os; + } + + bool operator==(const RefId& ref_id) const + { + return ((m_tag_number==ref_id.m_tag_number) and + (m_tag_name==ref_id.m_tag_name)); + } + + bool operator<(const RefId& ref_id) const + { + return ((m_tag_number<ref_id.m_tag_number) or + ((m_tag_number==ref_id.m_tag_number) and + (m_tag_name<ref_id.m_tag_name))); + } + + const unsigned int& tagNumber() const + { + return m_tag_number; + } + + const std::string& tagName() const + { + return m_tag_name; + } + + RefId& operator=(const RefId&) = default; + RefId& operator=(RefId&&) = default; + RefId() = default; + RefId(const RefId&) = default; + RefId(RefId&&) = default; + explicit RefId(const unsigned int& tag_number, + const std::string& tag_name) + : m_tag_number(tag_number), + m_tag_name(tag_name) + { + ; + } + + explicit RefId(const unsigned int& tag_number) + : m_tag_number(tag_number) + { + ; + } + + ~RefId() = default; +}; + +#endif // REF_ID_HPP -- GitLab