From d11eeb722973f639a7982fc1bfe68856d24bb6fc Mon Sep 17 00:00:00 2001 From: Khapisov Malik Date: Sun, 14 Nov 2021 21:53:52 +0300 Subject: [PATCH] Fixing volume and volume_range --- ...nt of a finite element mesh loader.vcxproj | 1 + .../MeshLoader.cpp | 67 +++++++------------ .../MeshLoader.h | 5 +- 3 files changed, 28 insertions(+), 45 deletions(-) diff --git a/Development of a finite element mesh loader/Development of a finite element mesh loader.vcxproj b/Development of a finite element mesh loader/Development of a finite element mesh loader.vcxproj index f1c3e8a..53b0d5d 100644 --- a/Development of a finite element mesh loader/Development of a finite element mesh loader.vcxproj +++ b/Development of a finite element mesh loader/Development of a finite element mesh loader.vcxproj @@ -118,6 +118,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + stdcpplatest Console diff --git a/Development of a finite element mesh loader/MeshLoader.cpp b/Development of a finite element mesh loader/MeshLoader.cpp index c5a6e07..7d4686e 100644 --- a/Development of a finite element mesh loader/MeshLoader.cpp +++ b/Development of a finite element mesh loader/MeshLoader.cpp @@ -3,8 +3,13 @@ #include #include #include -#include -#include + +std::ostream& operator << (std::ostream& out, const std::vector& cont) { + for (size_t i : std::ranges::views::iota(size_t(0), cont.size())) + out << cont[i] << " "; + out << std::endl; + return out; +} std::vector MeshLoader::finite_elements_ID(int ID1, int ID2, int ID3) { std::vector result; @@ -199,70 +204,46 @@ std::vector> MeshLoader::near_nodes() { return result; } -double MeshLoader::volume(int ID1, int ID2, int ID3, int ID4) { - Node A = get_node(ID1); - Node B = get_node(ID2); - Node C = get_node(ID3); - Node D = get_node(ID4); +double MeshLoader::volume(const FiniteElement& elem) { + if (elem.nodes_ID.size() < 4) + return 0.0; + + Node A = get_node(elem.nodes_ID[0]); + Node B = get_node(elem.nodes_ID[1]); + Node C = get_node(elem.nodes_ID[2]); + Node D = get_node(elem.nodes_ID[3]); double A1 = (B.cd[0] - A.cd[0]) * ((C.cd[1] - A.cd[1]) * (D.cd[2] - A.cd[2]) - (C.cd[2] - A.cd[2]) * (D.cd[1] - A.cd[1])); double A2 = -(B.cd[1] - A.cd[1]) * ((C.cd[0] - A.cd[0]) * (D.cd[2] - A.cd[2]) - (D.cd[0] - A.cd[0]) * (C.cd[2] - A.cd[2])); double A3 = (B.cd[2] - A.cd[2]) * ((C.cd[0] - A.cd[0]) * (D.cd[1] - A.cd[1]) - (D.cd[0] - A.cd[0]) * (C.cd[1] - A.cd[1])); return (A1 + A2 + A3) / 6.0; } -struct Tetrahedron { - int ID1, ID2, ID3, ID4; - - Tetrahedron() : ID1(0), ID2(0), ID3(0), ID4(0) {} - Tetrahedron(int ID1, int ID2, int ID3, int ID4) : ID1(ID1), ID2(ID2), ID3(ID3), ID4(ID4) {} - - friend std::ostream& operator << (std::ostream& out, const Tetrahedron& ABCD) { - out << ABCD.ID1 << " " << ABCD.ID2 << " " << ABCD.ID3 << " " << ABCD.ID4 << std::endl; - return out; - } -}; - void MeshLoader::volume_range(int m_ID, double a, double b, const std::string& filepath) { - + //!!! Что-то слишком сложно и не понятно. std::ranges позволяют выполнить задание по сути в одну строку, //!!! составив pipeline. Нужно сделать контейнер самих КЭ (не ID) по полученному котейнеру из ID и далее для него использовать //!!! std::ranges::views::transform, std::ranges::views::filter и std::ranges::copy (исправлено) - + std::vector elements = finite_elements_material(m_ID); if (elements.empty()) return; - - std::vector tetrahedrons; std::ofstream file(filepath + ".txt"); - - //!!! Я никак не могу поянять, зачем нужны эти циклы? - //!!! Есть метод, который возвращает ID КЭ в данной области. - //!!! Нужно по этим ID создать контейнер самих КЭ и его обработать. - for (int i : std::ranges::views::iota(size_t(0), elements.size())) { - for (int j : std::ranges::views::iota(size_t(0), elements.size())) { - for (int k : std::ranges::views::iota(size_t(0), elements.size())) { - for (int l : std::ranges::views::iota(size_t(0), elements.size())) - tetrahedrons.push_back(Tetrahedron(elements[i].nodes_ID[0], elements[j].nodes_ID[0], elements[k].nodes_ID[0], elements[l].nodes_ID[0])); - } - } - } std::ranges::copy( - tetrahedrons | + elements | std::ranges::views::filter( - [&](const Tetrahedron& ABCD) { - double t = volume(ABCD.ID1, ABCD.ID2, ABCD.ID3, ABCD.ID4); - return t - a > 0.00001 && b - t > 0.00001; + [&](const FiniteElement& elem) { + double V = volume(elem); + return V - a > std::numeric_limits::epsilon() && b - V > std::numeric_limits::epsilon(); }) | std::ranges::views::transform( - [](const Tetrahedron& ABCD) { - return ABCD; //!!! Тетраэдр преобразуется в тетраэдр? Должны его узлы возвращаться. И должен быть перегружен << для vector из ID + [](const FiniteElement& elem) { + return elem.nodes_ID; }), - std::ostream_iterator(file)); - + std::ostream_iterator>(file)); } diff --git a/Development of a finite element mesh loader/MeshLoader.h b/Development of a finite element mesh loader/MeshLoader.h index b2a5eb5..e1cb079 100644 --- a/Development of a finite element mesh loader/MeshLoader.h +++ b/Development of a finite element mesh loader/MeshLoader.h @@ -2,6 +2,7 @@ #include "Types.h" #include #include +#include class MeshLoader { protected: @@ -11,13 +12,13 @@ protected: private: Node get_node(int ID) { - return nodes.at(ID); + return nodes[ID]; } int last_nodes() { return nodes.rbegin()->ID; } - double volume(int ID1, int ID2, int ID3, int ID4); // + double volume(const FiniteElement&); // public: virtual void loadmesh(const std::string&, const std::string&, const std::string&) = 0; -- GitLab