From f22a7a2a65e53d8e731337c9f35f30fcf0afbf60 Mon Sep 17 00:00:00 2001 From: Nikita Borodin Date: Tue, 19 Oct 2021 15:51:55 +0300 Subject: [PATCH] Commit 19.10.21 --- AneuMeshLoader.cpp | 28 +- AneuMeshLoader.h | 3 +- DataStructures.cpp | 56 +--- DataStructures.h | 108 ++----- Main.cpp | 89 +++--- MeshLoader.cpp | 563 +++++++++---------------------------- MeshLoader.h | 77 ++--- NeuMeshLoader.cpp | 39 ++- NeuMeshLoader.h | 3 +- lab1-finite-element-method | 2 +- 10 files changed, 251 insertions(+), 717 deletions(-) diff --git a/AneuMeshLoader.cpp b/AneuMeshLoader.cpp index b81275b..1630d60 100644 --- a/AneuMeshLoader.cpp +++ b/AneuMeshLoader.cpp @@ -1,5 +1,4 @@ #include "AneuMeshLoader.h" -#include "Exceptions.h" #include #include @@ -8,30 +7,25 @@ void AneuMeshLoader::LoadMesh(const std::string& filename) { std::ifstream input(filename); if (!input) { - throw NoFileFoundException(filename); + //throw } - else std::cout << "File \"" << filename << "\" was succesfully opened" << std::endl; + else std::cout << "File \"" << filename << "\" was succesfully opened"; int dimension, amount; input >> amount >> dimension; - for (int i = 1; i <= amount; ++i) -{ + nodes.reserve(amount); + for (int i = 1; i <= amount; ++i) { Node temp_node; temp_node.nodeID = i; input >> temp_node.x >> temp_node.y >> temp_node.z; temp_node.vertex = true; -<<<<<<< HEAD - nodes.insert(std::move(temp_node));// -======= - nodes.push_back(temp_node); //!!! std::move не помешает ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 + nodes.push_back(temp_node); } input >> amount >> dimension; - - for (int i = 1; i <= amount; ++i) - { + elements.reserve(amount); + for (int i = 1; i <= amount; ++i) { FiniteElement temp_element; temp_element.elementID = i; input >> temp_element.materialID; @@ -41,10 +35,11 @@ void AneuMeshLoader::LoadMesh(const std::string& filename) { input >> temp_id; temp_element.nodesID.push_back(temp_id); } - elements.insert(std::move(temp_element)); + elements.push_back(std::move(temp_element)); } input >> amount >> dimension; + surfaces.reserve(amount); for (int i = 1; i <= amount; ++i) { BoundaryFiniteElement temp_surface; temp_surface.surfaceID = i; @@ -60,10 +55,9 @@ void AneuMeshLoader::LoadMesh(const std::string& filename) { temp_surface.nodesID[2]); temp_surface.elementID = temp_elements[0].elementID; temp_surface.materialID = temp_elements[0].materialID; - boundaryFEs.insert(std::move(temp_surface)); + surfaces.push_back(std::move(temp_surface)); } - input.close(); - + input.close(); std::cout << "All data was loaded, closing the file..." << std::endl; } diff --git a/AneuMeshLoader.h b/AneuMeshLoader.h index 880ec55..9fd065d 100644 --- a/AneuMeshLoader.h +++ b/AneuMeshLoader.h @@ -5,8 +5,7 @@ #include "MeshLoader.h" -class AneuMeshLoader : public MeshLoader -{ +class AneuMeshLoader : public MeshLoader { public: void LoadMesh(const std::string&) override; }; \ No newline at end of file diff --git a/DataStructures.cpp b/DataStructures.cpp index 6d8e364..43886fd 100644 --- a/DataStructures.cpp +++ b/DataStructures.cpp @@ -1,17 +1,14 @@ #include "DataStructures.h" #include -#include -std::ostream& operator<<(std::ostream& out_stream, const Node& node_) -{ +std::ostream& operator<<(std::ostream& out_stream, const Node& node_) { out_stream << std::setw(4) << node_.nodeID << " |" << std::right << std::setw(11) << node_.x << std::setw(11) << node_.y << std::setw(11) << node_.z << " | " << node_.vertex << "\n"; return out_stream; } -std::ostream& operator<<(std::ostream& out_stream, const std::set& nodes_) -{ +std::ostream& operator<<(std::ostream& out_stream, const std::vector& nodes_) { out_stream << nodes_.size() << (nodes_.size() > 1 ? " Nodes:\n" : " Node:\n") << " ID" << std::setw(10) << "X" << std::setw(11) << "Y" << std::setw(11) << "Z" << std::setw(14) << "Vertex\n"; for (const auto& it : nodes_) @@ -19,17 +16,7 @@ std::ostream& operator<<(std::ostream& out_stream, const std::set& nodes_) return out_stream; } -std::ostream& operator<<(std::ostream& out_stream, const std::vector& nodes_) -{ - out_stream << nodes_.size() << (nodes_.size() > 1 ? " Nodes:\n" : " Node:\n") << " ID" - << std::setw(10) << "X" << std::setw(11) << "Y" << std::setw(11) << "Z" << std::setw(14) << "Vertex\n"; - for (const auto& it : nodes_) - out_stream << it; - return out_stream; -} - -std::ostream& operator<<(std::ostream& out_stream, const FiniteElement& element_) -{ +std::ostream& operator<<(std::ostream& out_stream, const FiniteElement& element_) { out_stream << std::setw(4) << element_.elementID << " |" << std::setw(11) << element_.materialID << " |"; for (const auto& nodes_ID_it : element_.nodesID) @@ -38,8 +25,7 @@ std::ostream& operator<<(std::ostream& out_stream, const FiniteElement& element_ return out_stream; } -std::ostream& operator<<(std::ostream& out_stream, const std::set& elements_) -{ +std::ostream& operator<<(std::ostream& out_stream, const std::vector& elements_) { int elements_size = elements_.size(); out_stream << elements_size << (elements_size > 1 ? " Elements:\n" : " Element:\n") << " ID" << std::setw(15) << "Material_ID" << std::setw(15) << "Nodes ID\n"; @@ -48,18 +34,7 @@ std::ostream& operator<<(std::ostream& out_stream, const std::set return out_stream; } -std::ostream& operator<<(std::ostream& out_stream, const std::vector& elements_) -{ - int elements_size = elements_.size(); - out_stream << elements_size << (elements_size > 1 ? " Elements:\n" : " Element:\n") - << " ID" << std::setw(15) << "Material_ID" << std::setw(15) << "Nodes ID\n"; - for (const auto& it : elements_) - out_stream << it; - return out_stream; -} - -std::ostream& operator<<(std::ostream& out_stream, const BoundaryFiniteElement& surface_) -{ +std::ostream& operator<<(std::ostream& out_stream, const BoundaryFiniteElement& surface_) { out_stream << std::setw(9) << surface_.surfaceID << " |" << std::setw(9) << surface_.boundaryID << " |"; for (const auto& nodes_ID_it : surface_.nodesID) @@ -68,22 +43,11 @@ std::ostream& operator<<(std::ostream& out_stream, const BoundaryFiniteElement& return out_stream; } -std::ostream& operator<<(std::ostream& out_stream, const std::multiset& boundaryFEs_) -{ - int boundaryFEs_size = boundaryFEs_.size(); - out_stream << boundaryFEs_size << (boundaryFEs_size > 1 ? " boundaryFEs:\n" : " Surface:\n") +std::ostream& operator<<(std::ostream& out_stream, const std::vector& surfaces_) { + int surfaces_size = surfaces_.size(); + out_stream << surfaces_size << (surfaces_size > 1 ? " Surfaces:\n" : " Surface:\n") << "Surface_ID" << std::setw(11) << "Border_ID" << std::setw(14) << "Nodes ID\n"; - for (const auto& it : boundaryFEs_) + for (const auto& it : surfaces_) out_stream << it; return out_stream; -} - -std::ostream& operator<<(std::ostream& out_stream, const std::vector& boundaryFEs_) -{ - int boundaryFEs_size = boundaryFEs_.size(); - out_stream << boundaryFEs_size << (boundaryFEs_size > 1 ? " boundaryFEs:\n" : " Surface:\n") - << "Surface_ID" << std::setw(11) << "Border_ID" << std::setw(14) << "Nodes ID\n"; - for (const auto& it : boundaryFEs_) - out_stream << it; - return out_stream; -} +} \ No newline at end of file diff --git a/DataStructures.h b/DataStructures.h index ba871fa..d36f1ed 100644 --- a/DataStructures.h +++ b/DataStructures.h @@ -2,119 +2,43 @@ #include #include -#include -#include - -typedef struct Node -{ +typedef struct Node { int nodeID = 0; double x = 0, y = 0, z = 0; bool vertex = 0; - Node() = default; - Node(int ID_, double x_, double y_, double z_, bool vertex_) : - nodeID(ID_), x(x_), y(y_), z(z_), vertex(vertex_) {} + /*Node() = default; + Node(int, double, double, double, bool);*/ friend std::ostream& operator<<(std::ostream&, const Node&); - friend std::ostream& operator<<(std::ostream&, const std::set&); friend std::ostream& operator<<(std::ostream&, const std::vector&); - - bool operator<(const Node& p_node) const - { - return nodeID < p_node.nodeID; - } - - bool operator==(const Node& p_node) const - { - if (nodeID == p_node.nodeID && x == p_node.x && y == p_node.y && - z == p_node.z && vertex == p_node.vertex) - return true; - else return false; - }; }Node; -typedef struct FiniteElement -{ +typedef struct FiniteElement { int elementID = 0; int materialID = 0; std::vector nodesID; friend std::ostream& operator<<(std::ostream&, const FiniteElement&); - friend std::ostream& operator<<(std::ostream&, const std::set&); - friend std::ostream& operator<<(std::ostream&, const std::vector&); - - bool operator<(const FiniteElement& p_node) const - { - return elementID < p_node.elementID; - } - + friend std::ostream& operator<<(std::ostream&, const std::vector&); + // }FiniteElement; -typedef struct BoundaryFiniteElement : public FiniteElement // boundaryFEs (1 ) -{// - int boundaryID = 0;// - int surfaceID = 0;//id +typedef struct BoundaryFiniteElement : public FiniteElement { + int boundaryID = 0; + int surfaceID = 0; friend std::ostream& operator<<(std::ostream&, const BoundaryFiniteElement&); - friend std::ostream& operator<<(std::ostream&, const std::multiset&); friend std::ostream& operator<<(std::ostream&, const std::vector&); - - bool operator==(const BoundaryFiniteElement& p_node) const - { - return boundaryID == p_node.boundaryID; - } - - bool operator<(const BoundaryFiniteElement& p_node) const - { - return boundaryID < p_node.boundaryID; - } }BoundaryFiniteElement; -typedef struct Edge // -{ - int first_node_id; - int last_node_id; - int center_id; - - Edge() = default; - Edge(int id1, int id2, int id3) : - first_node_id(id1), last_node_id(id2), center_id(id3) {} - - friend inline bool operator==(const Edge& left_edge, const Edge& right_edge) - { - if (right_edge.first_node_id == left_edge.first_node_id && right_edge.last_node_id == left_edge.last_node_id) - return true; - else if (right_edge.first_node_id == left_edge.last_node_id && right_edge.last_node_id == left_edge.first_node_id) - return true; - else return false; - } - - bool operator<(const Edge& right_edge) const - { - return center_id < right_edge.center_id; - } - void updateCenter(int id_) - { - center_id = id_; - } -}Edge; +typedef struct Edge { + int ID_1; + int ID_2; + int center_ID; + //bool operator==(const Edge&) const; + //bool operator<(const Edge&) const; -namespace std -{ - template<> - class hash - { - public: - size_t operator()(const Edge& s) const - { - std::size_t seed = 0; - boost::hash_combine(seed, s.first_node_id); - boost::hash_combine(seed, s.center_id); - boost::hash_combine(seed, s.last_node_id); - - return seed; - } - }; -} \ No newline at end of file +}Edge; \ No newline at end of file diff --git a/Main.cpp b/Main.cpp index e6e23ce..475977b 100644 --- a/Main.cpp +++ b/Main.cpp @@ -2,57 +2,42 @@ #include #include #include -#include + #include "NeuMeshLoader.h" #include "MeshLoader.h" #include "AneuMeshLoader.h" -<<<<<<< HEAD -MeshLoader* File_Format_Checker(const std::string& cfile)// , file -======= -std::string FILEPATH = "C:\\cube.aneu"; //!!! Не нужно создавать глобальные переменные. + +//std::string FILEPATH = R"(C:\Users\Bychin\Documents\_Projects\ClionProjects\laboratory_work_1_2\a-neu-files\cube.neu)"; +std::string FILEPATH = "../LR1_sem3/cube.neu"; -MeshLoader* File_Format_Checker(std::string& file) //!!! Строки передаются по ссылке на константу ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 -{ - std::string file = cfile; - while (file.back() == ' ') +MeshLoader* File_Format_Checker(std::string& file) { // deletes all whitespaces, checks correct format + while (file.back() == ' ') // and call suitable loader file.pop_back(); MeshLoader* mesh_pointer = nullptr; // check .aneu std::size_t found = file.rfind(".aneu"); - if (found != std::string::npos && file.length() - found == 5) - { + if (found != std::string::npos && file.length() - found == 5) { std::cout << "File-format-checker was passed." << std::endl; - //dynamic_cast(mesh_pointer); + dynamic_cast(mesh_pointer); mesh_pointer = new AneuMeshLoader; return mesh_pointer; } // check .neu found = file.rfind(".neu"); - if (found != std::string::npos && file.length() - found == 4) - { + if (found != std::string::npos && file.length() - found == 4) { std::cout << "File-format-checker was passed." << std::endl; -<<<<<<< HEAD - //dynamic_cast(mesh_pointer); - mesh_pointer = new NeuMeshLoader;//smart -======= - - dynamic_cast(mesh_pointer); //!!! Эта строка с какой целью приведена? Она ничего не делает. - - mesh_pointer = new NeuMeshLoader; //!!! Не нашел delete ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 + dynamic_cast(mesh_pointer); + mesh_pointer = new NeuMeshLoader; return mesh_pointer; } - else - { + else { std::cout << "Warning! File-format-checker was not passed!" << std::endl; - return 0; //std::size_t dot = file.rfind('.'); /*if (dot == std::string::npos) throw BadFileFormatException(); @@ -60,21 +45,20 @@ MeshLoader* File_Format_Checker(std::string& file) //!!! Строки перед }; } -void Mesh_Loader_Demo(MeshLoader* loader_, const std::string& filepath_) -{ +void Mesh_Loader_Demo(MeshLoader* loader_, const std::string& filepath_) { loader_->LoadMesh(filepath_); loader_->Print_Data(); std::vector elements_vector; std::vector nodes_vector; - std::map> neighbours; - std::vector boundaryFEs_vector; + std::vector> neighbours; + std::vector surfaces_vector; std::cout << "Result of Get_Elements_by_ID(2, 4, 8) function:\n"; elements_vector = loader_->getElementsByID(2, 4, 8); std::cout << elements_vector; elements_vector.clear(); - std::cout << "\nResult of Get_Elements_by_edge(2, 8) function:\n"; + /*std::cout << "\nResult of Get_Elements_by_edge(2, 8) function:\n"; elements_vector = loader_->getElementsByEdge(2, 8); std::cout << elements_vector; elements_vector.clear(); @@ -89,45 +73,36 @@ void Mesh_Loader_Demo(MeshLoader* loader_, const std::string& filepath_) std::cout << elements_vector; elements_vector.clear(); - std::cout << "\nResult of Get_boundaryFEs_by_Surface_ID(1) function:\n"; - boundaryFEs_vector = loader_->getsboundaryFEsByBoundary(1); - std::cout << boundaryFEs_vector; - boundaryFEs_vector.clear(); + std::cout << "\nResult of Get_Surfaces_by_Surface_ID(1) function:\n"; + surfaces_vector = loader_->getsSurfacesByBoundary(1); + std::cout << surfaces_vector; + surfaces_vector.clear(); - auto N = loader_->getNodes(); std::cout << "\nResult of Get_Nodes_Neighbors() function:\n"; - for (const auto& i : N) - { - std::cout << "For node with ID "<< i.nodeID << " : " << std::endl; - neighbours = loader_->getNodeNeighbours(); - for (int j = 1; j < neighbours.size(); ++j) - std::cout << "Neighbors for Node with ID = " << neighbours[j] << std::endl; - } + neighbours = loader_->getNodeNeighbours(); + for (int i = 1; i < neighbours.size(); ++i) + std::cout << "Neighbors for Node with ID = " << i << "\n" << neighbours[i]; neighbours.clear(); - std::cout << "\nResult of insertCenterNode() function:\n"; - loader_->insertCenterNode(); - loader_->Print_Data(); + /*std::cout << "\nResult of Transform_Elements_to_Quadratic() function:\n"; + loader_->Transform_Elements_to_Quadratic(); + loader_->Print_Data();*/ } -struct fixed_tolower : std::unary_function -{ - char operator()(char c) const - { +struct fixed_tolower : std::unary_function { // as a struct for a better chance of inlining + char operator()(char c) const { return tolower((unsigned char)c); } }; -int main(int argc, char* argv[]) -{ - std::string filepath = "C:\\cube.aneu"; +int main(int argc, char* argv[]) { + std::string filepath = FILEPATH; if (argc == 1) std::cout << "No arguments were added, using standard file PATH..." << std::endl; else if (argc > 2) std::cout << "There must be one or none arguments! Set file path to default..." << std::endl; - else - { + else { std::cout << "Set file path to \"" << argv[1] << "\"..." << std::endl; filepath = argv[1]; std::transform(filepath.begin(), filepath.end(), filepath.begin(), fixed_tolower()); // .aneu = .ANEU = .AnEu = etc @@ -135,6 +110,6 @@ int main(int argc, char* argv[]) MeshLoader* loader = File_Format_Checker(filepath); Mesh_Loader_Demo(loader, filepath); - delete loader; + return 0; } \ No newline at end of file diff --git a/MeshLoader.cpp b/MeshLoader.cpp index 299f29c..92cc0f0 100644 --- a/MeshLoader.cpp +++ b/MeshLoader.cpp @@ -1,440 +1,141 @@ -#include -#include -#include +#include +#include +#include #include -#include -#include "MeshLoader.h" - -std::set MeshLoader::getNodes() -{ - return nodes; -} - -std::set MeshLoader::getFiniteElements() -{ - return elements; -} - -std::multiset MeshLoader::getBoundaryFiniteElements() -{ - return boundaryFEs; -} - - - -std::vector MeshLoader::getElementsByID(const int id1, const int id2, const int id3) //возможность нескольких узлов - контейнер -{ -<<<<<<< HEAD - /*std::vector result; -======= - //!!! Реализаци должна быть на основе алгоритмов - - std::vector result; ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - auto current_iter = elements.begin(); - auto last_iter = elements.end(); - FiniteElement current_element; - while (current_iter != last_iter) - { -<<<<<<< HEAD - current_iter = std::find_if(current_iter, last_iter, [id1, id2, id3, ¤t_element]() { -======= - current_iter = std::find_if(current_iter, last_iter, [id1, id2, id3](FiniteElement current_element) {//!!! Копирование current_element на каждой итерации ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id3) != current_element.nodesID.end(); }); - if (current_iter != last_iter) - { - result.push_back(*current_iter); - ++current_iter; - } - } - return result;*/ - std::vector result; - auto current_iter = elements.begin(); - while (current_iter != elements.end()) - { - auto it = std::find_if(current_iter, elements.end(), [id1, id2, id3](const FiniteElement& current_element) { - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id3) != current_element.nodesID.end(); }); - result.push_back(*it); - } - // при true вставляет, при false не вставляет - return result;//O(n) -} - -std::vector MeshLoader::getElementsByEdge(const int id1, const int id2) //возможность нескольких КЭ -{ -<<<<<<< HEAD - /*std::vector result; -======= - //!!! Реализаци должна быть на основе алгоритмов - - std::vector result; ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - auto current_iter = elements.begin(); - auto last_iter = elements.end(); - FiniteElement current_element; - while (current_iter != last_iter) - { -<<<<<<< HEAD - current_iter = std::find_if(current_iter, last_iter, [id1, id2, ¤t_element]() { -======= - current_iter = std::find_if(current_iter, last_iter, [id1, id2](FiniteElement current_element) { //!!! Копирование current_element на каждой итерации ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end(); }); - if (current_iter != last_iter) - { - result.push_back(*current_iter); - ++current_iter; - } - } - return result;*/ - std::vector result; - std::copy_if(elements.begin(), elements.end(), std::back_inserter(result), [id1, id2](const FiniteElement& current_element) { - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() - && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end(); }); - return result; - //O(n) -} - -std::vector MeshLoader::getElementsByOneID(const int id1) -{ -<<<<<<< HEAD - /*std::vector result; -======= - //!!! Реализаци должна быть на основе алгоритмов - - std::vector result; ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - auto current_iter = elements.begin(); - auto last_iter = elements.end(); - FiniteElement current_element; - while (current_iter != last_iter) - { -<<<<<<< HEAD - current_iter = std::find_if(current_iter, last_iter, [id1,¤t_element]() { -======= - current_iter = std::find_if(current_iter, last_iter, [id1](FiniteElement current_element) {//!!! Копирование current_element на каждой итерации ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end(); }); - if (current_iter != last_iter) - { - result.push_back(*current_iter); - ++current_iter; - } - } - return result;*/ - std::vector result; - std::copy_if(elements.begin(), elements.end(), std::back_inserter(result), [id1](const FiniteElement& current_element) { - return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end(); }); - return result; - //O(n) -} -std::vector MeshLoader::getNodesByBoundary(int boundaryID) -{ -<<<<<<< HEAD - /*std::set result;//оператор == определён - std::for_each(boundaryFEs.begin(), boundaryFEs.end(), [&](const BoundaryFiniteElement& current_element) { - if (current_element.boundaryID == boundaryID) -======= - std::set result; - auto current_iter = surfaces.begin(); - auto last_iter = surfaces.end(); - - //!!! Реализаци должна быть на основе алгоритмов - - while (current_iter != last_iter) - { - current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) {//!!! Копирование current_element на каждой итерации - return current_element.boundaryID == boundaryID; }); - if (current_iter != last_iter) ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - { - std::for_each(current_element.nodesID.begin(), current_element.nodesID.end(), [&]() { - auto node_by_ID = std::find_if(nodes.begin(), nodes.end(), [¤t_element](Node n) { return n.nodeID == current_element; }); - result.insert(*node_by_ID); - }); - std::copy_if(nodes.begin(), nodes.end(), std::inserter(result, result.begin()), [](Node n) { - - }); - /*for (const auto& it : current_element.nodesID) - { - auto node_by_ID = std::find_if(nodes.begin(), nodes.end(), [it](Node n) { return n.nodeID == it; }); //!!! Копирование n на каждой итерации - result.insert(*node_by_ID); - } - }; - });*/ - std::vector result; - std::vector final_result; - BoundaryFiniteElement tmp; - tmp.boundaryID == boundaryID; - typedef std::multiset::iterator It; - std::pair range = boundaryFEs.equal_range(tmp); - if (*(range.first) == tmp) - { - std::copy(range.first, range.second, std::back_inserter(result)); - } - for_each(result.begin(), result.end(), [&](const BoundaryFiniteElement& elem) { - for (int i = 0; i < 3; ++i) - { - Node nmp; - nmp.nodeID = elem.nodesID[i]; - auto nodeIter = nodes.find(nmp); - final_result.push_back(*nodeIter); - } - });//O(log(n)) - return final_result; -} - -std::vector MeshLoader::getElementsByBoundary(int surfaceID) -{ -<<<<<<< HEAD - /*std::set result; - auto current_iter = boundaryFEs.begin(); - auto last_iter = boundaryFEs.end(); -======= - //!!! Реализаци должна быть на основе алгоритмов - - std::set result; - auto current_iter = surfaces.begin(); - auto last_iter = surfaces.end(); ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - while (current_iter != last_iter) - { - current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) {//!!! Копирование current_element на каждой итерации - return current_element.boundaryID == boundaryID; }); - if (current_iter != last_iter) - { - auto element_by_ID = std::find_if(elements.begin(), elements.end(), [current_iter](FiniteElement n) {//!!! Копирование n на каждой итерации - return n.elementID == current_iter->elementID; }); - result.insert(*element_by_ID); - ++current_iter; - } - }*/ - std::vector result;//vector? - std::copy_if(boundaryFEs.begin(), boundaryFEs.end(), std::back_inserter(result), [surfaceID](const BoundaryFiniteElement& current_element) { - return surfaceID == current_element.surfaceID; - }); - return result;//O(n) -} +#include "MeshLoader.h" -std::vector MeshLoader::getsboundaryFEsByBoundary(int boundaryID)//что поменять? -{ -<<<<<<< HEAD - /*std::vector result; - auto current_iter = boundaryFEs.begin(); - auto last_iter = boundaryFEs.end(); - std::copy_if(boundaryFEs.begin(), boundaryFEs.end(), std::back_inserter(result), [boundaryID](const BoundaryFiniteElement& current_element) { - return current_element.boundaryID == boundaryID; - }); - { - current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) { - return current_element.boundaryID == boundaryID; }); - if (current_iter != last_iter) - { - result.push_back(*current_iter); - ++current_iter; - } - } - return result;*/ - /*std::vector result; - auto current_iter = boundaryFEs.begin(); - auto last_iter = boundaryFEs.end(); -======= - //!!! Реализаци должна быть на основе алгоритмов - - std::vector result; - auto current_iter = surfaces.begin(); - auto last_iter = surfaces.end(); ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - while (current_iter != last_iter) - { - current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) {//!!! Копирование current_element на каждой итерации - return current_element.boundaryID == boundaryID; }); - if (current_iter != last_iter) - { - result.push_back(*current_iter); - ++current_iter; - } - } - return result;*/ - std::vector result;//vector? - BoundaryFiniteElement tmp; - tmp.boundaryID == boundaryID; - typedef std::multiset::iterator It; - std::pair range = boundaryFEs.equal_range(tmp); - if (*(range.first) == tmp) - { - std::copy(range.first, range.second, std::back_inserter(result)); - } - return result;//O(log(n)) +std::vector& MeshLoader::getNodes() { + return nodes; +} + +std::vector& MeshLoader::getFiniteElements() { + return elements; +} + +std::vector& MeshLoader::getBoundaryFiniteElements() { + return surfaces; +} + +std::vector MeshLoader::getElementsByID(const int id1, const int id2, const int id3) { + std::vector result; + auto current_iter = elements.begin(); + auto last_iter = elements.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [id1, id2, id3](FiniteElement current_element) { + return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() + && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end() + && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id3) != current_element.nodesID.end(); }); + if (current_iter != last_iter) { + result.push_back(*current_iter); + ++current_iter; + } + } + return result; +} + +std::vector MeshLoader::getElementsByEdge(const int id1, const int id2) { + std::vector result; + auto current_iter = elements.begin(); + auto last_iter = elements.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [id1, id2](FiniteElement current_element) { + return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end() + && std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id2) != current_element.nodesID.end(); }); + if (current_iter != last_iter) { + result.push_back(*current_iter); + ++current_iter; + } + } + return result; +} + +std::vector MeshLoader::getElementsByOneID(const int id1) { + std::vector result; + auto current_iter = elements.begin(); + auto last_iter = elements.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [id1](FiniteElement current_element) { + return std::find(current_element.nodesID.begin(), current_element.nodesID.end(), id1) != current_element.nodesID.end(); }); + if (current_iter != last_iter) { + result.push_back(*current_iter); + ++current_iter; + } + } + return result; +} + +std::vector MeshLoader::getNodesByBoundary(int boundaryID) { + std::set result; + auto current_iter = surfaces.begin(); + auto last_iter = surfaces.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) { + return current_element.boundaryID == boundaryID; }); + if (current_iter != last_iter) { + for (const auto& it : current_iter->nodesID) { + auto node_by_ID = std::find_if(nodes.begin(), nodes.end(), [it](Node n) { return n.nodeID == it; }); + result.insert(*node_by_ID); + } + ++current_iter; + } + } + return std::vector(result.begin(), result.end()); +} + +std::vector MeshLoader::getElementsByBoundary(int boundaryID) { + std::set result; + auto current_iter = surfaces.begin(); + auto last_iter = surfaces.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) { + return current_element.boundaryID == boundaryID; }); + if (current_iter != last_iter) { + auto element_by_ID = std::find_if(elements.begin(), elements.end(), [current_iter](FiniteElement n) { + return n.elementID == current_iter->elementID; }); + result.insert(*element_by_ID); + ++current_iter; + } + } + return std::vector(result.begin(), result.end()); +} + +std::vector MeshLoader::getsSurfacesByBoundary(int boundaryID) { + std::vector result; + auto current_iter = surfaces.begin(); + auto last_iter = surfaces.end(); + while (current_iter != last_iter) { + current_iter = std::find_if(current_iter, last_iter, [boundaryID](BoundaryFiniteElement current_element) { + return current_element.boundaryID == boundaryID; }); + if (current_iter != last_iter) { + result.push_back(*current_iter); + ++current_iter; + } + } + return result; } void MeshLoader::insertCenterNode() { - auto edges = deleteEdgesDublicates(); - for (auto it = elements.begin(); it != elements.end(); it++) - { -<<<<<<< HEAD - std::vector current_nodes(it->nodesID); - for (auto i = current_nodes.begin(); i < current_nodes.end(); ++i) - for (auto j = i + 1; j < current_nodes.end(); ++j) - { - Edge current_edge(*i, *j, 0); - auto founded_edge = edges.find(current_edge); -======= - std::vector current_nodes(it.nodesID); - for (auto i = current_nodes.begin(); i < current_nodes.end() - 1; ++i) //!!! Зачем нужен -1? - for (auto j = i + 1; j < current_nodes.end(); ++j) - { - Edge current_edge(*i, *j, 0); - auto founded_edge = std::find(edges.cbegin(), edges.cend(), current_edge); //!!! Потеряны преимущества контейнера - сложность O(n) ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - if (founded_edge == edges.cend()) { - Node left_node = *getNodeByID(*i); - Node right_node = *getNodeByID(*j); - int center_id_ = getLastNodeID() + 1; - Node center_node(center_id_, (left_node.x + right_node.x) / 2, - (left_node.y + right_node.y) / 2, (left_node.z + right_node.z) / 2, false); - - current_edge.updateCenter(center_id_); - nodes.insert(center_node); - edges.insert(current_edge); - auto tmp = *it; - elements.erase(*it); - tmp.nodesID.push_back(center_id_);//добавил существующий узел в элемент - elements.insert(std::move(tmp));// - } - //!!! А если ребро было обработано, то в элемент не нужно существующий узел добавить? - } - } - for (auto& it : boundaryFEs) - { - std::vector current_nodes(it.nodesID); - for (auto i = current_nodes.begin(); i < current_nodes.end() - 1; ++i) - for (auto j = i + 1; j < current_nodes.end(); ++j) - { - Edge current_edge(*i, *j, 0); -<<<<<<< HEAD - auto founded_edge = edges.find(current_edge); -======= - auto founded_edge = std::find(edges.cbegin(), edges.cend(), current_edge); //!!! Потеряны преимущества контейнера - сложность O(n) ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - if (founded_edge != edges.cend()) - { - auto tmp = it; - elements.erase(it); - tmp.nodesID.push_back(founded_edge->center_id); - elements.insert(std::move(tmp)); - } - } - } } - - -Node* MeshLoader::getNodeByID(int id) -{ -<<<<<<< HEAD - Node tmp; - tmp.nodeID = id; - nodes.find(tmp); - return 0;//O(log(n)) -======= - for (auto& cur : nodes) //!!! Потеряны преимущества контейнера - сложность O(n) - if (cur.nodeID == id) - return &cur; - return 0; ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 -} - -int MeshLoader::getLastNodeID() -{ - return nodes.rbegin()->nodeID; -} - - - -<<<<<<< HEAD -std::map> MeshLoader::getNodeNeighbours() -======= -std::vector MeshLoader::getNodeNeighbours(int p_nodeID) //!!! Соседи должны создаваться для всех узлов ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 -{ - std::map> result_out; - std::for_each(nodes.begin(), nodes.end(), [&](const Node& current_node) { - std::set result_in; - std::vector element_vec = getElementsByOneID(current_node.nodeID); - std::vector NodeNeighbors; - - std::for_each(element_vec.begin(), element_vec.end(), [&result_in](const FiniteElement& current_elem) { - result_in.insert(current_elem.nodesID.begin(), current_elem.nodesID.end()); - }); - - result_in.erase(current_node.nodeID); - - std::for_each(result_in.begin(), result_in.end(), [&](int curr_nodeID) { - NodeNeighbors.push_back(*getNodeByID(curr_nodeID)); - }); - result_out.emplace(current_node.nodeID, NodeNeighbors); - }); - return result_out; -} - - -void MeshLoader::Print_Data() -{ - - std::cout << getNodes() << std::endl - << getFiniteElements() << std::endl - << getBoundaryFiniteElements() << std::endl; -} - -std::unordered_set > MeshLoader::deleteEdgesDublicates() -{ -<<<<<<< HEAD -======= - //!!! Что тут проиходит? Как в неупорядоченном контейнере можно что-то сортировать? - - std::unordered_set > edges; ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 - std::unordered_set > result; - auto current_iter = edges.begin(); - auto last_iter = edges.end(); - for (auto& i : edges) - { - for (auto it=++current_iter; it != edges.end(); (it->first_node_id == i.last_node_id && it->last_node_id == i.first_node_id) ? it = edges.erase(it) : ++it) - { - result.insert(*it); - } - } - return result; -} -<<<<<<< HEAD -======= -void MeshLoader::sortEdges(std::vector& p_vector) { - //!!! Непонятный метод - - std::vector copy_vec; - std::copy(p_vector.begin(), p_vector.end(), copy_vec.begin()); - auto first_iter = p_vector.begin(); - auto last_iter = p_vector.end(); - auto last_iter2 = p_vector.rbegin(); - auto first_iter2 = p_vector.rend(); - - - - for (auto i = first_iter; i != last_iter; ++i) { - for (auto j = first_iter2; j != last_iter2; ++j) { - p_vector.erase(remove_if(copy_vec.begin(), copy_vec.end(), - [i, j]() {return (i->first_node_id == j->last_node_id && i->last_node_id == j->first_node_id); })); - } - } - -} ->>>>>>> 1b434108a50987c6f13bfeed8c9b8da456e45fa7 +/*std::vector> MeshLoader::getNodeNeighbours() { + std::set result_in; + std::vector> result_out; + for (const auto& i : nodes) { + for (const auto& j : getElementsByOneID(i.nodeID)) { + for (auto k : j.nodesID) { + auto node_by_ID = std::find_if(nodes.begin(), nodes.end(), [k](Node n) { return n.nodeID == k; }); + result_in.insert(*node_by_ID); + } + } + result_out.push_back(std::vector(result_in.begin(), result_in.end())); + } + return result_out; +}*/ + +void MeshLoader::Print_Data() { + std::cout << getNodes() << std::endl + << getFiniteElements() << std::endl + << getBoundaryFiniteElements() << std::endl; +} \ No newline at end of file diff --git a/MeshLoader.h b/MeshLoader.h index 5d5ba07..b0e326e 100644 --- a/MeshLoader.h +++ b/MeshLoader.h @@ -3,66 +3,47 @@ #include #include #include -#include -#include + #include "DataStructures.h" -#include -class MeshLoader -{ +class MeshLoader { protected: - std::set nodes; - std::set elements; - std::multiset boundaryFEs; - - std::unordered_set> edges; + std::vector nodes; + std::vector elements; + std::vector surfaces; public: - virtual void LoadMesh(const std::string&) = 0; - virtual ~MeshLoader() = default; - - // , STL- , - std::set getNodes(); - std::set getFiniteElements(); - std::multiset getBoundaryFiniteElements(); - - // , ID - std::vector getElementsByID(int, int, int); - - // , , ID - std::vector getElementsByEdge(int, int); - - // , ID - std::vector getNodesByBoundary(int); - - // , ID - std::vector getElementsByBoundary(int); + virtual void LoadMesh(const std::string&) = 0; + virtual ~MeshLoader() = default; - // , ID - std::vector getsboundaryFEsByBoundary(int); + // , STL- , + std::vector& getNodes(); + std::vector& getFiniteElements(); + std::vector& getBoundaryFiniteElements(); - // , - void insertCenterNode(); + // , ID + std::vector getElementsByID(int, int, int); - // , , n - n - std::map> getNodeNeighbours(); + // , , ID + std::vector getElementsByEdge(int, int); - // , Node, FiniteElement BoundaryFiniteElement - void Print_Data(); + // , ID + std::vector getElementsByOneID(int); - // , ID - std::vector getElementsByOneID(int); + // , ID + std::vector getNodesByBoundary(int); - - + // , ID + std::vector getElementsByBoundary(int); - //, ID - int getLastNodeID(); + // , ID + std::vector getsSurfacesByBoundary(int); - //, ID - Node* getNodeByID(int id); + // , + void insertCenterNode(); - + // , , n - n + std::vector> getNodeNeighbours(); - std::unordered_set> deleteEdgesDublicates(); - void sortEdges(std::vector&); + // , Node, FiniteElement BoundaryFiniteElement + void Print_Data(); }; \ No newline at end of file diff --git a/NeuMeshLoader.cpp b/NeuMeshLoader.cpp index a3bf133..f8bdc42 100644 --- a/NeuMeshLoader.cpp +++ b/NeuMeshLoader.cpp @@ -1,62 +1,59 @@ #include #include #include -#include "Exceptions.h" + #include "NeuMeshLoader.h" -void NeuMeshLoader::LoadMesh(const std::string& filename) -{ +void NeuMeshLoader::LoadMesh(const std::string& filename) { std::ifstream input(filename); - if (!input) - { - throw NoFileFoundException(filename); + if (!input) { + //throw } - else std::cout << "File \"" << filename << "\" was succesfully opened" << std::endl; + else std::cout << "File \"" << filename << "\" was succesfully opened"; int dimension, amount; input >> amount; - - for (int i = 1; i <= amount; ++i) - { + nodes.reserve(amount); + for (int i = 1; i <= amount; ++i) { Node temp_node; temp_node.nodeID = i; input >> temp_node.x >> temp_node.y >> temp_node.z; temp_node.vertex = true; - nodes.insert(temp_node); + nodes.push_back(temp_node); } input >> amount; + // some manipulations to find out dimension should be added dimension = 4; - for (int i = 1; i <= amount; ++i) - { + elements.reserve(amount); + for (int i = 1; i <= amount; ++i) { FiniteElement temp_element; temp_element.elementID = i; input >> temp_element.materialID; temp_element.nodesID.reserve(dimension); int temp_id; - for (int j = 0; j < dimension; ++j) - { + for (int j = 0; j < dimension; ++j) { input >> temp_id; temp_element.nodesID.push_back(temp_id); } - elements.insert(std::move(temp_element)); + elements.push_back(std::move(temp_element)); } input >> amount; + // some manipulations to find out dimension should be added dimension = 3; - for (int i = 1; i <= amount; ++i) - { + surfaces.reserve(amount); + for (int i = 1; i <= amount; ++i) { BoundaryFiniteElement temp_surface; temp_surface.surfaceID = i; input >> temp_surface.boundaryID; temp_surface.nodesID.reserve(dimension); int temp_id; - for (int j = 0; j < dimension; ++j) - { + for (int j = 0; j < dimension; ++j) { input >> temp_id; temp_surface.nodesID.push_back(temp_id); } @@ -65,7 +62,7 @@ void NeuMeshLoader::LoadMesh(const std::string& filename) temp_surface.nodesID[2]); temp_surface.elementID = temp_elements[0].elementID; temp_surface.materialID = temp_elements[0].materialID; - boundaryFEs.insert(std::move(temp_surface)); + surfaces.push_back(std::move(temp_surface)); } input.close(); diff --git a/NeuMeshLoader.h b/NeuMeshLoader.h index 24576cd..71cde50 100644 --- a/NeuMeshLoader.h +++ b/NeuMeshLoader.h @@ -6,8 +6,7 @@ #include "MeshLoader.h" -class NeuMeshLoader : public MeshLoader -{ +class NeuMeshLoader : public MeshLoader { public: void LoadMesh(const std::string&) override; }; diff --git a/lab1-finite-element-method b/lab1-finite-element-method index 1b43410..4fc3b4e 160000 --- a/lab1-finite-element-method +++ b/lab1-finite-element-method @@ -1 +1 @@ -Subproject commit 1b434108a50987c6f13bfeed8c9b8da456e45fa7 +Subproject commit 4fc3b4eff60f8a00a7ba4666bd753401a0ba9f6d -- GitLab