diff --git a/Hash.h b/Hash.h new file mode 100644 index 0000000000000000000000000000000000000000..bb6b4601b9ccf42a448638a3aef523fbf52c6323 --- /dev/null +++ b/Hash.h @@ -0,0 +1,37 @@ +#pragma once + +#include "StructDataType.h" + +template +inline void hashCombine(std::size_t& seed, const T& val) { + seed ^= std::hash()(val) + 0x9e3379b9 + (seed << 6) + (seed >> 2); +} + +template +inline void hashVal(std::size_t& seed, const T& val) { + hashCombine(seed, val); +} + +template +inline void hashVal(std::size_t& seed, const T& val, const Types &...args) { + hashCombine(seed, val); + hashVal(seed, args...); +} + +template +inline std::size_t hashVal(const Types &...args) { + std::size_t seed = 0; + hashVal(seed, args...); + return seed; +} + +struct hash { + size_t operator()(const Edge& edge) const { + if (edge.edgeNodes.first <= edge.edgeNodes.second) { + return hashVal(edge.edgeNodes.first, edge.edgeNodes.second); + } + else { + return hashVal(edge.edgeNodes.second, edge.edgeNodes.first); + } + } +}; diff --git a/MeshLoader.cpp b/MeshLoader.cpp index 9483dda8ecda9ae853bb56b0be412184a2f8ab00..a392c44e8528c9ea30f5d67be40858710075246f 100644 --- a/MeshLoader.cpp +++ b/MeshLoader.cpp @@ -1,7 +1,8 @@ #include #include +#include #include "MeshLoader.h" - +#include "Hash.h" const std::vector& MeshLoader::getNodes() { return Nodes; @@ -11,14 +12,17 @@ const std::vector& MeshLoader::getFiniteElement() { return element; } +const std::vector& MeshLoader::getBoundElement() { + return boundelement; +} + std::vector MeshLoader::getFiniteElementID(int _id1, int _id2, int _id3) { std::vector res; auto po = [&_id1, &_id2, &_id3, &res](const FiniteElement& elem) { if ((std::find(elem.NodeID.begin(), elem.NodeID.end(), _id1) != elem.NodeID.end()) && (std::find(elem.NodeID.begin(), elem.NodeID.end(), _id2) != elem.NodeID.end()) && - (std::find(elem.NodeID.begin(), elem.NodeID.end(), _id3) != elem.NodeID.end()) && - elem.NodeID.size() == 3) { + (std::find(elem.NodeID.begin(), elem.NodeID.end(), _id3) != elem.NodeID.end())) { res.push_back(elem.FiniteElementID); } }; @@ -31,8 +35,7 @@ std::vector MeshLoader::getFiniteElementEdge(int _id1, int _id2) { std::vector res; auto po = [&_id1, &_id2, &res](const FiniteElement& elem) { if ((std::find(elem.NodeID.begin(), elem.NodeID.end(), _id1) != elem.NodeID.end()) && - (std::find(elem.NodeID.begin(), elem.NodeID.end(), _id2) != elem.NodeID.end()) && - elem.NodeID.size() == 3) { + (std::find(elem.NodeID.begin(), elem.NodeID.end(), _id2) != elem.NodeID.end())) { res.push_back(elem.FiniteElementID); } }; @@ -46,7 +49,7 @@ std::vector MeshLoader::getNodesId(int _id) { auto cur = element.begin(); auto po = [_id](const FiniteElement& elem) { - return elem.GeometryAreaID == _id && elem.NodeID.size() == 3; + return elem.GeometryAreaID == _id; }; while (cur != element.end()) { @@ -65,7 +68,7 @@ std::vector MeshLoader::getNodesId(int _id) { std::vector MeshLoader::getFiniteElementIdSurface(int _id) { std::vector res; auto po = [&_id, &res](const FiniteElement& elem) { - if (elem.GeometryAreaID == _id && elem.NodeID.size() == 3) { + if (elem.GeometryAreaID == _id) { res.push_back(elem.FiniteElementID); } }; @@ -77,7 +80,7 @@ std::vector MeshLoader::getFiniteElementIdSurface(int _id) { std::vector MeshLoader::getFiniteElementIDVol(int _id) { std::vector res; auto po = [&_id, &res](const FiniteElement& elem) { - if (elem.GeometryAreaID == _id && elem.NodeID.size() == 4) { + if (elem.GeometryAreaID == _id) { res.push_back(elem.FiniteElementID); } }; @@ -94,6 +97,72 @@ void MeshLoader::printFiniteElement() { std::cout << element; } +void MeshLoader::insertNodeMid() { + std::unordered_set edge; + for (auto& elem : element) { + std::vector ElemNideID = elem.NodeID; + for (int first = 0; first < 4; ++first) { + for (auto sec = first + 1; sec < 4; ++sec) { + Edge curEdge(ElemNideID[first], ElemNideID[sec]); + if (edge.insert(curEdge).second) { + Node newNode = getMiddleNode(curEdge); + curEdge.updMid(newNode.NodeID); + Nodes.push_back(newNode); + elem.NodeID.push_back(newNode.NodeID); + } + else { + elem.NodeID.push_back(curEdge.midNode); + } + } + } + } + for (auto& belem : boundelement) { + std::vector bfeNodesId = belem.NodeID; + for (auto first = 0; first < 3; ++first) { + for (auto sec = first + 1; sec < 3; ++sec) { + auto curEdgeIter = edge.find({ bfeNodesId[first], bfeNodesId[sec]}); + if (curEdgeIter == edge.end()) { + curEdgeIter = edge.find({ bfeNodesId[sec], bfeNodesId[first]}); + } + belem.NodeID.push_back(curEdgeIter->midNode); + } + } + } +} + + +std::vector MeshLoader::getMiddleEdge(const Edge& edge) { + double MiddleX = ((Nodes.at(edge.edgeNodes.first - 1).coordinate.at(0)) + + (Nodes.at(edge.edgeNodes.second - 1).coordinate.at(0))) / 2; + double MiddleY = ((Nodes.at(edge.edgeNodes.first - 1).coordinate.at(1)) + + (Nodes.at(edge.edgeNodes.second - 1).coordinate.at(1))) / 2; + double MiddleZ = ((Nodes.at(edge.edgeNodes.first - 1).coordinate.at(2)) + + (Nodes.at(edge.edgeNodes.second - 1).coordinate.at(2))) / 2; + return { MiddleX, MiddleY, MiddleZ }; +} + +Node MeshLoader::getMiddleNode(const Edge& edge) { + Node newNode(Nodes.size() + 1, getMiddleEdge(edge), false); + return newNode; +} + +std::vector MeshLoader::getCoordinate(int id) { + return Nodes.at(id).coordinate; +} + +std::vector> MeshLoader::createNeighborsVector() { + std::vector> neighbors(Nodes.size() + 1); + for (const auto& elem : boundelement) { + for (auto nodeId : elem.NodeID) + for (auto anthNodeId : elem.NodeID) + if (nodeId != anthNodeId) + neighbors[nodeId].insert(anthNodeId); + } + + return neighbors; +} + + diff --git a/MeshLoader.h b/MeshLoader.h index 5852cc7f33e8ad65f993fdd2546452411a2cdd3d..ee8e42e0c25813ef966ed38fc27662f5c5ecc3e8 100644 --- a/MeshLoader.h +++ b/MeshLoader.h @@ -2,33 +2,42 @@ #include #include #include +#include #include "StructDataType.h" class MeshLoader { +private: + Node getMiddleNode(const Edge&); + std::vector getMiddleEdge(const Edge&); + std::vector getCoordinate(int); protected: std::vector Nodes; std::vector element; + std::vector boundelement; public: virtual void loadMesh(const std::string&) = 0; + virtual ~MeshLoader() = default; const std::vector& getNodes(); - const std::vector& getFiniteElement(); + const std::vector& getBoundElement(); std::vector getFiniteElementID(int, int, int); - std::vector getFiniteElementEdge(int, int); - std::vector getNodesId(int); std::vector getFiniteElementIdSurface(int); - std::vector getFiniteElementIDVol(int); void printNode(); void printFiniteElement(); + void insertNodeMid(); + + std::vector> createNeighborsVector(); + + diff --git a/StructDataType.cpp b/StructDataType.cpp index c2984494dc781312f895a5d08fe9511665a6dda3..afa66098b89c427a448d29914ba687bb0182f70c 100644 --- a/StructDataType.cpp +++ b/StructDataType.cpp @@ -33,3 +33,36 @@ std::ostream& operator<<(std::ostream& out, const std::vector& _f return out; } +Edge::Edge(int firstNodeId, int secNodeId) + : edgeNodes({ firstNodeId, secNodeId }) {} + +void Edge::updMid(int midN) { + midNode = midN; +} + +Edge& Edge::operator=(const Edge& edge) { + if (this != &edge) { + this->edgeNodes = edge.edgeNodes; + this->midNode = edge.midNode; + } + return *this; +} + +bool Edge::operator==(const Edge& edge) const { + return (edgeNodes.first == edge.edgeNodes.first) && + (edgeNodes.second == edge.edgeNodes.second); +} + +std::istream& operator>>(std::istream& in, Edge& edge) { + in >> edge.edgeNodes.first + >> edge.edgeNodes.second; + return in; +} + +std::ostream& operator<<(std::ostream& out, Edge& edge) { + out << edge.edgeNodes.first << ", " + << edge.edgeNodes.second << std::endl; + return out; +} + + diff --git a/StructDataType.h b/StructDataType.h index 354d0c5954b411f8b4eb418e77e118f3292182eb..1203c971e2b1faa42ee651450925c094f75d88aa 100644 --- a/StructDataType.h +++ b/StructDataType.h @@ -18,4 +18,16 @@ struct FiniteElement { friend std::ostream& operator<<(std::ostream&, const FiniteElement&); friend std::ostream& operator<<(std::ostream&, const std::vector&); -}; \ No newline at end of file +}; + +struct Edge { + std::pair edgeNodes; + int midNode = -1; + Edge() = default; + Edge(int, int); + void updMid(int); + Edge& operator=(const Edge&); + bool operator==(const Edge&) const; + friend std::istream& operator>>(std::istream&, Edge&); + friend std::ostream& operator<<(std::ostream&, Edge&); +};