From 0d2ad4af41efd7d2d22d92b2ad91823f9c790f4c Mon Sep 17 00:00:00 2001 From: artem karapetyan Date: Sat, 4 Dec 2021 01:38:23 +0300 Subject: [PATCH] add files --- AneuMeshLoader.cpp | 51 +++++++++++++ AneuMeshLoader.h | 14 ++++ Exception.h | 31 ++++++++ MeshLoader.cpp | 173 +++++++++++++++++++++++++++++++++++++++++++++ MeshLoader.h | 39 ++++++++++ Structure.cpp | 45 ++++++++++++ Structure.h | 59 ++++++++++++++++ main.cpp | 47 ++++++++++++ 8 files changed, 459 insertions(+) create mode 100644 AneuMeshLoader.cpp create mode 100644 AneuMeshLoader.h create mode 100644 Exception.h create mode 100644 MeshLoader.cpp create mode 100644 MeshLoader.h create mode 100644 Structure.cpp create mode 100644 Structure.h create mode 100644 main.cpp diff --git a/AneuMeshLoader.cpp b/AneuMeshLoader.cpp new file mode 100644 index 0000000..54ef3be --- /dev/null +++ b/AneuMeshLoader.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "AneuMeshLoader.h" +#include "Exception.h" + + +void AneuMeshLoader::loadMesh(const string& filename) { + std::ifstream file(filename); + if (!file) { + throw Wrong_file_format(); + } + cout << "file " << filename << " has opened" << endl; + + int cnt, dim; + file >> cnt >> dim; + nodes.reserve(cnt); + for (size_t i = 1; i <= cnt; i++) { + size_t id = i; + std::vector coord(dim); + for (size_t j = 1; j <= dim; j++) { + file >> coord[j - 1]; + } + nodes.emplace_back(id, coord, true); + } + file >> cnt >> dim; + for (int i = 1; i <= cnt; i++) { + size_t id = i; + std::vector coord(dim); + size_t materialId; + file >> materialId; + for (int j = 1; j <= dim; ++j) { + file >> coord[j - 1]; + } + finiteElements.emplace_back(id, materialId, coord); + } + + file >> cnt >> dim; + for (int i = 1; i <= cnt; i++) { + size_t id = i; + std::vector coord(dim); + size_t materialId; + file >> materialId; + for (int j = 1; j <= dim; j++) { + file >> coord[j - 1]; + } + boundaryFiniteElements.emplace_back(id, materialId, coord); + } + file.close(); + std::cout << ".aneu file downloaded" << std::endl; +} diff --git a/AneuMeshLoader.h b/AneuMeshLoader.h new file mode 100644 index 0000000..4971ad2 --- /dev/null +++ b/AneuMeshLoader.h @@ -0,0 +1,14 @@ +#pragma once +#include + +#include "MeshLoader.h" +#include "Structure.h" + +using std::cin; +using std::cout; +using std::endl; + +class AneuMeshLoader : public MeshLoader { +public: + void loadMesh(const string&) override; +}; \ No newline at end of file diff --git a/Exception.h b/Exception.h new file mode 100644 index 0000000..f829a69 --- /dev/null +++ b/Exception.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +class File_not_found : public std::exception { + std::string err; +public: + File_not_found() { + err.assign("Error : unable to open file"); + } + explicit File_not_found(const std::string& file) { + err.assign("Error: Unable to open " + file + " file"); + } + const char* what() const noexcept override { + return err.c_str(); + } +}; + +class Wrong_file_format : public std::exception { + std::string err; +public: + Wrong_file_format() { + err.assign("Error : inappropriate file format"); + } + explicit Wrong_file_format(const std::string& file_format) { + err.assign("Error : Format " + file_format + " is unsuitable"); + } + const char* what() const noexcept override { + return err.c_str(); + } +}; diff --git a/MeshLoader.cpp b/MeshLoader.cpp new file mode 100644 index 0000000..740a81c --- /dev/null +++ b/MeshLoader.cpp @@ -0,0 +1,173 @@ +#include "MeshLoader.h" + +std::vector& MeshLoader::GetNodes() { + return nodes; +} + +std::vector& MeshLoader::GetFE() { + return finiteElements; +} + +std::vector& MeshLoader::GetBFE() { + return boundaryFiniteElements; +} + +std::vector MeshLoader::findFE(size_t id_1, size_t id_2, size_t id_3) { + std::vector res; + auto iter = finiteElements.begin(); + auto end_iter = finiteElements.end(); + + while (iter != end_iter) { + iter = std::find_if(iter, end_iter, + [id_1, id_2, id_3](const FiniteElement& elem) { + return std::find(elem.material.begin(), elem.material.end(), id_1) != elem.material.end() + && std::find(elem.material.begin(), elem.material.end(), id_2) != elem.material.end() + && std::find(elem.material.begin(), elem.material.end(), id_3) != elem.material.end(); + }); + if (iter != end_iter) { + res.push_back(iter->ID); + iter++; + } + } + return res; +} + +std::vector MeshLoader::findEdge(size_t id_1, size_t id_2) { + std::vector res; + auto iter = finiteElements.begin(); + auto end_iter = finiteElements.end(); + + while (iter != end_iter) { + iter = std::find_if(iter, end_iter, [id_1, id_2](FiniteElement& elem) { + return std::find(elem.material.begin(), elem.material.end(), id_1) != elem.material.end() + && std::find(elem.material.begin(), elem.material.end(), id_2) != elem.material.end(); + }); + if (iter != end_iter) { + res.push_back(*iter); + iter++; + } + } + return res; +} + +std::vector MeshLoader::vertex_node_by_id(size_t id) { + std::set res; + auto iter = boundaryFiniteElements.begin(); + while (iter != boundaryFiniteElements.end()) { + iter = std::find_if(iter, boundaryFiniteElements.end(), [id](const BoundaryFiniteElement& s) { return s.ID_surface == id; }); + if (iter != boundaryFiniteElements.end()) + { + for (const auto& elem : iter->node_boundary) { + res.insert(get_node_by_id(id)); + } + ++iter; + } + } + return std::vector(res.begin(), res.end()); +} + +std::vector MeshLoader::get_material_id(size_t id) { + std::list res; + auto elem_by_material = nodes.begin(); + auto last_elem = nodes.end(); + while (elem_by_material != last_elem) { + + elem_by_material = std::find_if(elem_by_material, last_elem, [id](const Node& v) { return v.ID_node == id; }); + + if (elem_by_material != last_elem) { + res.push_back(*elem_by_material); + ++elem_by_material; + } + } + return std::vector(res.begin(), res.end()); + +} + +std::vector> MeshLoader::get_close_nodes() { + std::vector> res(nodes.size()); + for (const auto& iter_FiniteElement : boundaryFiniteElements) + { + for (auto& iter_nodes : iter_FiniteElement.node_boundary) + { + res[iter_nodes - 1].insert(iter_FiniteElement.node_boundary.begin(), iter_FiniteElement.node_boundary.end()); + res[iter_nodes - 1].erase(iter_nodes); + } + } + return res; +} + +std::vector MeshLoader::get_BoundaryFinite_id(size_t id) { + std::list res; + auto surface_by_ID = boundaryFiniteElements.begin(); + auto last_elem = boundaryFiniteElements.end(); + while (surface_by_ID != last_elem) { + surface_by_ID = std::find_if(surface_by_ID, last_elem, [id](const BoundaryFiniteElement& v) { return v.ID_surface == id; }); + if (surface_by_ID != last_elem) { + res.push_back(*surface_by_ID); + ++surface_by_ID; + } + } + return std::vector(res.begin(), res.end()); + +} + +Node MeshLoader::get_node(size_t id) { + nodes.at(id); +} + +Node& MeshLoader::get_node_by_id(size_t id) { + return nodes[id]; +} + +void MeshLoader::Print() { + cout << &GetNodes() << endl << &GetFE() << endl << &GetBFE << endl; +} + +void MeshLoader::insert_node() { + std::unordered_set edge; + for (auto& elem : boundaryFiniteElements) + { + std::vector iter(elem.ID_boundary); + for (auto i = iter.begin(); i != iter.end(); i++) + { + for (auto j = i + 1; j != iter.end(); j++) + { + Edge current_edge(*i, *j); + auto find_edge = edge.find(current_edge); + if (find_edge == edge.end()) { + Node left_node = get_node_by_id(elem.node_boundary[*i]); + Node right_node = get_node_by_id(elem.node_boundary[*j]); + std::vector x = { (left_node.coord[0] + right_node.coord[0]) / 2, + (left_node.coord[0] + right_node.coord[0]) / 2, + (left_node.coord[0] + right_node.coord[0]) / 2 }; + Node center_node(nodes.size() + 1, x, false); + current_edge.self_id = nodes.size() + 1; + edge.insert(current_edge); + nodes.push_back(std::move(center_node)); + elem.node_boundary.emplace_back(current_edge.self_id); + } + else { + elem.node_boundary.emplace_back(find_edge->self_id); + } + + } + } + } + for (auto& it : boundaryFiniteElements) + { + std::vector current_iter(it.node_boundary); + for (auto i = current_iter.begin(); i != current_iter.end() - 1; i++) + { + for (auto j = i + 1; j != current_iter.end(); j++) + { + Edge search_edge(*i, *j); + auto search_point = edge.find(search_edge); + if (search_point != edge.end()) + { + it.node_boundary.emplace_back(search_point->self_id); + } + } + } + } +} + diff --git a/MeshLoader.h b/MeshLoader.h new file mode 100644 index 0000000..f4ddbde --- /dev/null +++ b/MeshLoader.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include +#include +#include + +#include "Structure.h" + +using std::cin; +using std::cout; +using std::endl; +using std::string; + +class MeshLoader { +protected: + std::vector nodes; + std::vector finiteElements; + std::vector boundaryFiniteElements; +public: + virtual void loadMesh(const string&) = 0; + virtual ~MeshLoader() = default; + + std::vector& GetNodes(); + std::vector& GetFE(); + std::vector& GetBFE(); + std::vector findFE(size_t, size_t, size_t); + std::vector findEdge(size_t, size_t); + std::vector vertex_node_by_id(size_t); + std::vector> get_close_nodes(); + std::vector get_material_id(size_t); + std::vector get_BoundaryFinite_id(size_t); + Node get_node(size_t); + Node& get_node_by_id(size_t); + + void Print(); + void insert_node(); + +}; diff --git a/Structure.cpp b/Structure.cpp new file mode 100644 index 0000000..d6ea493 --- /dev/null +++ b/Structure.cpp @@ -0,0 +1,45 @@ +#include "Structure.h" + +std::ostream& operator << (std::ostream& out, const Node& elem) { + out << elem.ID_node << " | "; + for (auto& tmp : elem.coord) + out << tmp << " "; + out << " | " << elem.flag << " | " << std::endl; + return out; +} + +std::ostream& operator<<(std::ostream& out, const FiniteElement& elem) { + out << elem.ID << " | " << elem.ID_material << " | "; + for (auto& tmp : elem.material) + out << tmp << " "; + out << " | " << std::endl; + return out; +} + +std::ostream& operator<< (std::ostream& out, const BoundaryFiniteElement& elem) { + out << elem.ID_boundary << " | " << elem.ID_surface << " | "; + for (auto& tmp : elem.node_boundary) + out << tmp << " "; + out << " | " << std::endl; + return out; +} + +bool Edge::operator == (const Edge& p) const { + return (head_id == p.head_id && tail_id == p.tail_id) || + (head_id == p.tail_id && tail_id == p.head_id); +} + + + +void HashEdge::hash_combine(size_t& seed, const size_t& val) const { + seed ^= std::hash()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +size_t HashEdge::operator()(const Edge& p) const { + size_t seed = 0; + hash_combine(seed, p.head_id); + hash_combine(seed, p.tail_id); + hash_combine(seed, p.self_id); + + return seed; +} \ No newline at end of file diff --git a/Structure.h b/Structure.h new file mode 100644 index 0000000..142d01b --- /dev/null +++ b/Structure.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include + +struct Node { + size_t ID_node; + std::vector coord; + bool flag; + + Node(size_t p_ID_node, std::vector p_coord, bool p_flag) : + ID_node(p_ID_node), + coord(std::move(p_coord)), + flag(p_flag) {}; + friend std::ostream& operator << (std::ostream& out, const Node& elem); + +}; + +struct FiniteElement { + size_t ID, ID_material; + std::vector material; + + FiniteElement(size_t p_ID, size_t p_ID_material, std::vector p_materual) : + ID(p_ID), + ID_material(p_ID), + material(std::move(p_materual)) {}; + + friend std::ostream& operator << (std::ostream& out, const FiniteElement& elem); +}; + +struct BoundaryFiniteElement { + size_t ID_boundary, ID_surface; + std::vector node_boundary; + + BoundaryFiniteElement(size_t p_ID_boundary, size_t p_ID_surface, std::vectorp_node_boundary) : + ID_boundary(p_ID_boundary), + ID_surface(p_ID_surface), + node_boundary(std::move(p_node_boundary)) {}; + + friend std::ostream& operator << (std::ostream& out, const BoundaryFiniteElement& elem); +}; + +struct Edge { + size_t head_id; + size_t tail_id; + size_t self_id; + Edge() = default; + Edge(size_t p_head_id, size_t p_tail_id) : + head_id(p_head_id), + tail_id(p_tail_id) {}; + + bool operator == (const Edge& p) const; +}; + +struct HashEdge { + void hash_combine(size_t& seed, const size_t& val) const; + std::size_t operator() (const Edge& p) const; + +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a4cb99f --- /dev/null +++ b/main.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +#include "AneuMeshLoader.h" + +int main() { + const std::string name = "myfile"; + std::vector node; + MeshLoader* load = new AneuMeshLoader; + std::vector elem; + std::vector FEelem; + std::vector> close; + std::vector surface; + + load->loadMesh(name); + std::cout << "TEST" << std::endl; + + std::cout << "find finite element" << std::endl; + elem = load->findFE(3, 2, 2); + std::cout << elem << std::endl; + elem.clear(); + + std::cout << "findEdge" << std::endl; + FEelem = load->findEdge(1, 2); + for (const auto& x : FEelem) + std::cout << x << std::endl; + FEelem.clear(); + + std::cout << "get vertex node by id" << std::endl; + node = load->vertex_node_by_id(1); + std::cout << node << std::endl; + node.clear(); + + std::cout << "get boundary finite id" << std::endl; + surface = load->get_BoundaryFinite_id(1); + std::cout << surface << std::endl; + surface.clear(); + + std::cout << "Insert nodes" << std::endl; + load->insert_node(); + load->Print(); + delete(load); + return 0; +} -- GitLab