diff --git a/MeshLoader.cpp b/MeshLoader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c4d3d2a55912e9613f6758a03b532beca2a2acd --- /dev/null +++ b/MeshLoader.cpp @@ -0,0 +1,272 @@ +#include "MeshLoader.h" + +void MeshLoader::add_node(const Node& a) +{ + node.push_back(a); +} + +void MeshLoader::add_Finite_Element(const Finite_element& a) +{ + FE.push_back(a); +} + +Node UI_to_N(uint16_t id, const MeshLoader& b) +{ + Node tmp; + for (int i = 0; i < b.node.size(); i++) + { + if (b.node[i].n_id == id) + tmp = b.node[i]; + break; + } + return tmp; +} + +uint16_t N_to_UI(const Node& a) +{ + return a.n_id; +} + +void MeshLoader::add_BFE(const Boundary_Finite_element& a) +{ + BFE.push_back(a); +} + +const vector& MeshLoader::getBoundary_Finite_Element() +{ + return BFE; +} + +const vector& MeshLoader::getFinite_Element() +{ + return FE; +} + +const vector& MeshLoader::get_nodes() +{ + return node; +} + +vector< Finite_element> MeshLoader::findFinite_Element(const uint16_t& a, const uint16_t& b, const uint16_t& c) +{ + vector buf; + vector::iterator x = FE.begin(); + while (x != FE.end()) + { + auto found = std::find_if(x, FE.end(), [a, b, c](const Finite_element& t) { + int d = 0; + for (int i = 0; i < 4; i++) + { + if ((t.nodes[i] == a) || (t.nodes[i] == b) || (t.nodes[i] == c)) + d++; + } + return d == 3; + }); + if (x != buf.end()) + { + buf.push_back(*x); + x++; + } + } + return buf; +} + +vector< Finite_element> MeshLoader::findFinite_Element(const uint16_t& a, const uint16_t& b) +{ + vector buf; + vector::iterator x = FE.begin(); + while (x != FE.end()) + { + auto found{ std::find_if(x,FE.end(),[a,b](const Finite_element& t) { + int d = 0; + for (int i = 0; i < 4; i++) + { + if ((t.nodes[i] == a) || (t.nodes[i] == b)) + d++; + } + return d == 2; + }) }; + if (found != FE.end()) + { + buf.push_back(*found); + x++; + } + + } + return buf; +} + +set MeshLoader::find_nodes(const uint16_t& gg_id) +{ + set buf; + for (int i = 0; i < BFE.size(); i++) + { + if(BFE[i].g_id==gg_id) + for (int j = 0; j < BFE[i].nodes.size(); j++) + { + buf.insert(UI_to_N(BFE[j].nodes[i],*this)); + } + } + return buf; +} + +vectorMeshLoader:: findFinite_Element(const uint16_t& id_materiala) +{ + vector buf; + for (int i = 0; i < FE.size(); i++) + { + if (FE[i].m_id == id_materiala) + buf.push_back(FE[i]); + } + return buf; +} + +vector MeshLoader::findBoundary_Finite_Element(const uint16_t& id_granitsi) +{ + vector buf; + for (int i = 0; i < BFE.size(); i++) + { + if (BFE[i].g_id == id_granitsi) + buf.push_back(BFE[i]); + } + return buf; +} + +map> MeshLoader::find_neighbors() +{ + map> buf; + + for (int i = 0; i < FE.size(); i++) + { + for (int j = 0; j < 4; i++) + { + for (int k = 0; k < 4; k++) + { + if (k != j) + buf[FE[i].nodes[j]].insert(FE[i].nodes[k]); + } + //!!! Короче и быстрее buf[узел i].insert(все соседи i-го узла) + /*if (buf.count(FE[i].nodes[j]) == 0) + { + for (int k = 0; k < 4; k++) + { + if(j!=k) + + } + } + else + { + for (int k = 0; k < 4; k++) + { + if(k!=j) + buf[FE[i].nodes[j]].insert(FE[i].nodes[k]); + } + }*/ + } + } + return buf; +} + +void MeshLoader::insertt() +{ + unordered_set hash; + for (int i = 0; i < FE.size(); i++) + { + for (int j = 0; j < 4; j++) + { + for (int k = 0; k < 4; k++) + { + if (j != k) + { + Edge buf(FE[i].nodes[j], FE[i].nodes[k]); + if (hash.find(buf) != hash.end()) + { + Node ins = mid_elem(FE[i].nodes[0], FE[i].nodes[j]); + node.push_back(ins); + FE[i].nodes.push_back(ins.n_id); + uint16_t o = FE[i].nodes[j]; + uint16_t t = FE[i].nodes[k]; + buf.nodes[2] = ins.n_id; + } + //!!! А если ребро захешировано в данный КЭ узел с существующем ID добавлять не надо? + //!!! Тип Ребро должен хранить ID ребра в середине, чтобы быстро к нему обратиться. + } + } + } + } + + for (auto& it : BFE) + { + Edge buff((it).nodes[0],it.nodes[1]); + buff = *(hash.find(buff));; //!!! Потеря производительности + it.nodes.push_back(buff.nodes[2]); + } +} + +Node MeshLoader::mid_elem(uint16_t c, uint16_t d) +{ + Node a = UI_to_N(c, *this); + Node b = UI_to_N(d, *this); + Node buf; + buf.x = (a.x + b.x) / 2; + buf.y = (a.y + b.y) / 2; + buf.z = (a.z + b.z) / 2; + buf.gr = true; + return buf; +} + +bool srav_node(const Node& a, const Node& b) +{ + return (a.n_id==b.n_id); +} + +bool operator ==(const Edge& a, const Edge& b) +{ + return(((a.nodes[0] == b.nodes[0]) && (a.nodes[1] == b.nodes[1])||((a.nodes[0] == b.nodes[1]) && (a.nodes[1] == b.nodes[0])))); +} + +/*Edge findEdge(uint16_t id1, uint16_t id2,const unordered_set& sett) +{ + Edge buf(id1, id2); + + //!!! Не понял, а зачем мы тогда unordered_set используем? Чтобы все ребра перебирать? + //!!! Потеряны все преимущества контейнера. + + unordered_set::iterator x = sett.begin(); + auto found = std::find_if(x, sett.end(), [id1, id2](const Edge& t) { + int d = 0; + for (int i = 0; i < 3; i++) + { + if ((t.nodes[i] == id1) || (t.nodes[i] == id2)) + d++; + } + return d == 2; + }); + return *found; +}*/ + + +vector MeshLoader::findBoundary_Finite_Element(uint16_t id1, uint16_t id2) +{ + vector buf; + vector::iterator it = BFE.begin(); + while (it != BFE.end()) + { + auto found = std::find_if(it, BFE.end(), [id1, id2](const Boundary_Finite_element& a) + { + int d = 0; + for (int i = 0; i < 4; i++) + { + if ((a.nodes[i] == id1) || (a.nodes[i] == id2)) + d++; + } + return d == 2; + }); + if (it != BFE.end()) + { + buf.push_back(*it); + it++; + } + } + return buf; +}