From 0c8df54a5c4b632d7954afdb9bfe1c895faeae0e Mon Sep 17 00:00:00 2001 From: Dmitrii Yakovlev Date: Sun, 30 Oct 2022 21:21:02 +0300 Subject: [PATCH] #commit4 --- AneuMeshLoader.cpp | 109 ++++++++++++++++++++------------------------- AneuMeshLoader.h | 3 +- Exception.h | 28 ++++++++++++ MeshLoader.cpp | 104 +++++++++++++++++++++++++----------------- MeshLoader.h | 19 ++++---- StructDataType.cpp | 26 ++++++++--- StructDataType.h | 18 ++++++-- main.cpp | 49 ++++++++++++++++++-- out | 8 ++++ 9 files changed, 241 insertions(+), 123 deletions(-) create mode 100644 Exception.h create mode 100644 out diff --git a/AneuMeshLoader.cpp b/AneuMeshLoader.cpp index 8d15ced..9787b0d 100644 --- a/AneuMeshLoader.cpp +++ b/AneuMeshLoader.cpp @@ -1,64 +1,53 @@ -#include "AneuMeshLoader.h" + #include "AneuMeshLoader.h" #include - -void AneuMeshLoader::loadMesh(const std::string& _filename) { - std::ifstream input(_filename); - if (!input) { - - } - int dimension, count; - input >> count; - input >> dimension; - Nodes.reserve(count); - for (int i = 1; i <= count; ++i) { - Node temp_node; - temp_node.coordinate.reserve(dimension); - temp_node.NodeID = i; - temp_node.bundle = true; - double cord; - for (int j = 0; j < dimension; j++) - { - input >> cord; - temp_node.coordinate.push_back(cord); - } - Nodes.push_back(std::move(temp_node)); - } - - input >> count >> dimension; - element.reserve(count); - int id = 0; - for (int i = 0; i < count; ++i) { - FiniteElement tmp{}; - int nodeId; - input >> tmp.GeometryAreaID; - for (int j = 0; j < dimension; ++j) { - input >> nodeId; - tmp.NodeID.push_back(nodeId); - } - ++id; - tmp.FiniteElementID = id; - element.push_back(std::move(tmp)); - } - - input >> count >> dimension; - element.reserve(count); - for (int i = 0; i < count; ++i) { - FiniteElement tmp{}; - int nodeId; - input >> tmp.GeometryAreaID; - for (int j = 0; j < dimension; ++j) { - input >> nodeId; - tmp.NodeID.push_back(nodeId); - } - ++id; - tmp.FiniteElementID = id; - element.push_back(std::move(tmp)); - } -}; - - - - +#include + +void AneuMeshLoader::loadMesh(const std::string& fileName, const std::string& format) { + std::ifstream file(fileName + format); + if (!file.is_open()) { + std::ifstream file2(fileName + format); + file2.is_open() ? throw WrongFileFormat() : throw FileNotFound(); + } + int count, dimension; + file >> count >> dimension; + Nodes.reserve(count); + for (int i = 0; i < count; ++i) { + Node temp; + file >> temp.coordinate[0] >> temp.coordinate[1] >> temp.coordinate[2]; + temp.ID = i+1; + temp.bundle = false; + Nodes.push_back(temp); + } + + file >> count >> dimension; + Element.reserve(count); + for (int i = 0; i < count; ++i) { + FiniteElement temp; + int IDNode; + file >> temp.GeometryAreaID; + for (int j = 0; j < dimension; ++j) { + file >> IDNode; + temp.NodeID.push_back(IDNode); + } + temp.FiniteElementID = i; + Element.push_back(std::move(temp)); + } + + file >> count >> dimension; + Boundelement.reserve(count); + for (int i = 0; i < count; ++i) { + FiniteElement temp; + int IDNode; + file >> temp.GeometryAreaID; + for (int j = 0; j < dimension; ++j) { + file >> IDNode; + temp.NodeID.push_back(IDNode); + } + temp.FiniteElementID = i; + Boundelement.push_back(std::move(temp)); + } + file.close(); +} diff --git a/AneuMeshLoader.h b/AneuMeshLoader.h index de4ffeb..94f230c 100644 --- a/AneuMeshLoader.h +++ b/AneuMeshLoader.h @@ -1,13 +1,14 @@ #pragma once #include "MeshLoader.h" #include "StructDataType.h" +#include "Exception.h" #include #include class AneuMeshLoader: public MeshLoader { private: public: - void loadMesh(const std::string&) override; + void loadMesh(const std::string&, const std::string&) override; }; diff --git a/Exception.h b/Exception.h new file mode 100644 index 0000000..8e8d97c --- /dev/null +++ b/Exception.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include + +class FileNotFound : public std::exception +{ + std::string err; +public: + FileNotFound() { + err.assign("File wasn't found!"); + } + + const char* what() const noexcept override { + return err.c_str(); + } +}; + +class WrongFileFormat : public std::exception +{ + std::string err; +public: + WrongFileFormat() { + err.assign("Wrong format!"); + } + const char* what() const noexcept override { + return err.c_str(); + } +}; diff --git a/MeshLoader.cpp b/MeshLoader.cpp index 380ffe0..1f2cfb5 100644 --- a/MeshLoader.cpp +++ b/MeshLoader.cpp @@ -1,9 +1,11 @@ #include #include #include +#include #include "MeshLoader.h" #include "Hash.h" - +#include +#include //!!! Задание на защиту (не удалять). //!!! Реализовать на основе std::ranges @@ -18,28 +20,31 @@ const std::vector& MeshLoader::getNodes() { } const std::vector& MeshLoader::getFiniteElement() { - return element; + return Element; } const std::vector& MeshLoader::getBoundElement() { - return boundelement; + return Boundelement; } std::vector MeshLoader::getFiniteElementID(int _id1, int _id2, int _id3) { std::vector res; - auto po = [&_id1, &_id2, &_id3, &res](const FiniteElement& elem) { - - //!!! Используйте для проверки принадлежности std::any_of - - 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())) { + + auto po = [&_id1, &_id2, &_id3, &res](const FiniteElement& elem) { + //!!! Используйте для проверки принадлежности std::any_of + //Поправил + if ((std::any_of(elem.NodeID.begin(), elem.NodeID.end(), + [&_id1](const int&id) {return id==_id1;})) && + (std::any_of(elem.NodeID.begin(), elem.NodeID.end(), + [&_id2](const int& id) {return id == _id2; })) && + (std::any_of(elem.NodeID.begin(), elem.NodeID.end(), + [&_id3](const int& id) {return id == _id3; }))) { res.push_back(elem.FiniteElementID); } }; - std::for_each(element.begin(), element.end(),po); + std::for_each(Element.begin(), Element.end(),po); return res; } @@ -48,37 +53,41 @@ std::vector MeshLoader::getFiniteElementEdge(int _id1, int _id2) { auto po = [&_id1, &_id2, &res](const FiniteElement& elem) { //!!! Используйте для проверки принадлежности std::any_of - - 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())) { + // Поправил + if ((std::any_of(elem.NodeID.begin(), elem.NodeID.end(), + [&_id1](const int& id) {return id == _id1; })) && + (std::any_of(elem.NodeID.begin(), elem.NodeID.end(), + [&_id2](const int& id) {return id == _id2; }))) { res.push_back(elem.FiniteElementID); } }; - std::for_each(element.begin(), element.end(),po); + std::for_each(Element.begin(), Element.end(),po); return res; } -std::vector MeshLoader::getNodesId(int _id) { //!!! Не понятно, что делает метод? Что за id ?? - std::vector res; - auto cur = element.begin(); +std::vector MeshLoader::getNodesByBorderID(int _id) { //!!! Не понятно, что делает метод? Что за id ?? + std::set res; + auto cur = Boundelement.begin(); - auto po = [_id](const FiniteElement& elem) { - return elem.GeometryAreaID == _id; - }; - while (cur != element.end()) { - cur = std::find_if(cur, element.end(), po); - if (cur != element.end()) { - for (auto node : cur->NodeID) { - Node nodeId = Nodes[node]; //!!! Получить узел по ID? чтобы получить ID узла? + while (cur != Boundelement.end()) { + cur = std::find_if(cur, Boundelement.end(), [_id](const FiniteElement& elem) { + return elem.GeometryAreaID == _id; + } + ); + if (cur != Boundelement.end()) { + for (const auto &nod : cur->NodeID) { + Node nodeId = Nodes[nod-1]; //!!! Получить узел по ID? чтобы получить ID узла? + // Поправил - нужно получить узлы принадлежащие указанной поверхности - res.push_back(nodeId.NodeID); //!!! Кто сказал, что не будет дубликатов в результате? Неверно выбран контейнер + res.insert(nodeId); //!!! Кто сказал, что не будет дубликатов в результате? Неверно выбран контейнер + //Исправил } ++cur; } } - return std::vector(res.begin(), res.end()); + return std::vector(res.begin(), res.end()); } std::vector MeshLoader::getFiniteElementIdSurface(int _id) { @@ -89,7 +98,7 @@ std::vector MeshLoader::getFiniteElementIdSurface(int _id) { } }; - std::for_each(element.begin(), element.end(), po); + std::for_each(Element.begin(), Element.end(), po); return res; } @@ -101,30 +110,30 @@ std::vector MeshLoader::getFiniteElementIDVol(int _id) { } }; - std::for_each(element.begin(), element.end(), po); + std::for_each(Boundelement.begin(), Boundelement.end(), po); return res; } -void MeshLoader::printNode() { //!!! Давайте адекватные имена. Узел или узлы печатаются? - std::cout << Nodes; +void MeshLoader::printNodes(const std::vector& nodes) { //!!! Давайте адекватные имена. Узел или узлы печатаются? + std::cout << nodes; } -void MeshLoader::printFiniteElement() { - std::cout << element; +void MeshLoader::printFiniteElements(const std::vector& elem) { + std::cout << elem; } void MeshLoader::insertNodeMid() { std::unordered_set edge; - for (auto& elem : element) { + 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); + curEdge.updMid(newNode.ID); Nodes.push_back(newNode); - elem.NodeID.push_back(newNode.NodeID); + elem.NodeID.push_back(newNode.ID); } else { elem.NodeID.push_back(curEdge.midNode); @@ -132,7 +141,7 @@ void MeshLoader::insertNodeMid() { } } } - for (auto& belem : boundelement) { + for (auto& belem : Boundelement) { std::vector bfeNodesId = belem.NodeID; for (auto first = 0; first < 3; ++first) { for (auto sec = first + 1; sec < 3; ++sec) { @@ -147,7 +156,7 @@ void MeshLoader::insertNodeMid() { } -std::vector MeshLoader::getMiddleEdge(const Edge& edge) { +std::array 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)) + @@ -162,13 +171,13 @@ Node MeshLoader::getMiddleNode(const Edge& edge) { return newNode; } -std::vector MeshLoader::getCoordinate(int id) { +std::array 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 (const auto& elem : Boundelement) { for (auto nodeId : elem.NodeID) for (auto anthNodeId : elem.NodeID) if (nodeId != anthNodeId) @@ -177,6 +186,19 @@ std::vector> MeshLoader::createNeighborsVector() { return neighbors; } +// Задание на защиту +double GetDistance(const Node& n,const Node& node) { + return sqrt(pow(n.coordinate[0] - node.coordinate[0],2) + pow(n.coordinate[1]-node.coordinate[1],2) + pow(n.coordinate[2] - node.coordinate[2],2)); +} + +void MeshLoader::SortedByDistance(std::vector& nod,const Node& n) { + std::ranges::sort(nod, std::less{}, + [&](const Node& a) { + return GetDistance(a,n); + }); + + +} diff --git a/MeshLoader.h b/MeshLoader.h index ee8e42e..709ce10 100644 --- a/MeshLoader.h +++ b/MeshLoader.h @@ -3,19 +3,20 @@ #include #include #include +#include #include "StructDataType.h" class MeshLoader { private: Node getMiddleNode(const Edge&); - std::vector getMiddleEdge(const Edge&); - std::vector getCoordinate(int); + std::array getMiddleEdge(const Edge&); + std::array getCoordinate(int); protected: std::vector Nodes; - std::vector element; - std::vector boundelement; + std::vector Element; + std::vector Boundelement; public: - virtual void loadMesh(const std::string&) = 0; + virtual void loadMesh(const std::string&, const std::string&) = 0; virtual ~MeshLoader() = default; const std::vector& getNodes(); @@ -24,17 +25,19 @@ public: std::vector getFiniteElementID(int, int, int); std::vector getFiniteElementEdge(int, int); - std::vector getNodesId(int); + std::vector getNodesByBorderID(int); std::vector getFiniteElementIdSurface(int); std::vector getFiniteElementIDVol(int); - void printNode(); + static void printNodes(const std::vector&); - void printFiniteElement(); + static void printFiniteElements(const std::vector&); void insertNodeMid(); + void SortedByDistance(std::vector&,const Node&); + std::vector> createNeighborsVector(); diff --git a/StructDataType.cpp b/StructDataType.cpp index afa6609..f36324f 100644 --- a/StructDataType.cpp +++ b/StructDataType.cpp @@ -1,22 +1,29 @@ #include "StructDataType.h" +Node::Node(int nId, const std::array& nCoords, bool nVertex): + ID(nId), coordinate(nCoords), bundle(nVertex) {} + std::ostream& operator<<(std::ostream& out, const Node& _node) { - out << _node.NodeID << " "; - for (auto cord : _node.coordinate) { - out << cord << " "; - }; - out << "Bundle:" << _node.bundle; + out << _node.ID << " "; + out << _node.coordinate[0] << " " << _node.coordinate[1] << " " << _node.coordinate[2]; + out << " " << _node.bundle; out << std::endl; return out; } std::ostream& operator<<(std::ostream& out, const std::vector& _node) { - for (auto node : _node) + for (const auto& node : _node) out << node; return out; +}; + +bool Node::operator<(const Node& node) const { + return ID < node.ID; } + + std::ostream& operator<<(std::ostream& out, const FiniteElement& _finiteel) { out << _finiteel.FiniteElementID << " "; out << _finiteel.GeometryAreaID << " "; @@ -33,6 +40,13 @@ std::ostream& operator<<(std::ostream& out, const std::vector& _f return out; } + + + + + + + Edge::Edge(int firstNodeId, int secNodeId) : edgeNodes({ firstNodeId, secNodeId }) {} diff --git a/StructDataType.h b/StructDataType.h index 1203c97..87b09c4 100644 --- a/StructDataType.h +++ b/StructDataType.h @@ -1,14 +1,25 @@ #pragma once #include #include - +#include struct Node { - int NodeID; - std::vector coordinate; + int ID; + static constexpr int dim = 3; + std::array coordinate; bool bundle; + Node() = default; + Node(int, const std::array&, bool); + friend std::ostream& operator<<(std::ostream&, const Node&); friend std::ostream& operator<<(std::ostream&, const std::vector&); + + bool operator<(const Node& node) const; + + + + + }; struct FiniteElement { @@ -18,6 +29,7 @@ struct FiniteElement { friend std::ostream& operator<<(std::ostream&, const FiniteElement&); friend std::ostream& operator<<(std::ostream&, const std::vector&); + }; struct Edge { diff --git a/main.cpp b/main.cpp index 4700796..cad0486 100644 --- a/main.cpp +++ b/main.cpp @@ -1,13 +1,54 @@ +#include +#include +#include #include +#include +#include +#include + #include "MeshLoader.h" #include "AneuMeshLoader.h" -int main() { +using namespace std; +int main() { MeshLoader* l = new AneuMeshLoader(); //!!! Отлично. Где delete? - l->loadMesh("a.aneu"); - l->printNode(); - l->printFiniteElement(); + try { + l->loadMesh("a", ".aneu"); + } + catch (std::exception& er) { + std::cerr << er.what() << std::endl; + delete l; + return 0; + } + + l->printNodes(l->getNodes()); + l->printFiniteElements(l->getFiniteElement()); + l->printFiniteElements(l->getBoundElement()); + + std::cout << "ID Finite elements by nodes" << std::endl; + auto finelem = l->getFiniteElementID(4,1,2); + for (int elem : finelem) { + std::cout << elem << " "; + } + std::cout << std::endl << "-----------------------------------" << std::endl; + + // Задание на защиту + auto N = l->getNodes(); + auto n = l->getNodesByBorderID(3); + Node N1(1, {2,2,2},0); + l->SortedByDistance(n,N1); + + std::ofstream fout("out", std::ios::app); + + auto res1 = n | std::ranges::views::drop(10) + | std::ranges::views::take(10); + + std::ranges::copy(res1, std::ostream_iterator(fout, "\n")); + + std::cout << n; + std::cout << "-------------------------------------" << std::endl; + delete l; return 0; } \ No newline at end of file diff --git a/out b/out new file mode 100644 index 0000000..d128afd --- /dev/null +++ b/out @@ -0,0 +1,8 @@ +8 1 1 1 0 + +6 0 1 1 0 + +7 1 1 0 0 + +4 0 1 0 0 + -- GitLab