From 56e5eaa9c72e0054bd8dd8023241ed46b441af0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Dagand?= Date: Wed, 13 May 2026 16:23:59 +0200 Subject: [PATCH 1/2] Add a new BasicTri class which is a simplified version of a facet with less data --- src/CMakeLists.txt | 6 +++--- src/basicTri.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/basicTri.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 977cb04..7d7a768 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,9 +3,9 @@ SET(HEADERS config.h node.h expression_parser.h mesh.h electrostatSolver.h facette.h linear_algebra.h log-stats.h tags.h chronometer.h element.h) SET(SOURCES settings.cpp time_integration.cpp solver.cpp electrostatSolver.cpp - spinAccumulationSolver.cpp read.cpp save.cpp linear_algebra.cpp recentering.cpp tetra.cpp - energy.cpp facette.cpp expression_parser.cpp chronometer.cpp - tags.cpp mesh.cpp) + spinAccumulationSolver.cpp read.cpp save.cpp linear_algebra.cpp recentering.cpp + tetra.cpp energy.cpp facette.cpp expression_parser.cpp chronometer.cpp + basicTri.cpp tags.cpp mesh.cpp) configure_file(config.h.in ./config.h) diff --git a/src/basicTri.cpp b/src/basicTri.cpp new file mode 100644 index 0000000..f7523a4 --- /dev/null +++ b/src/basicTri.cpp @@ -0,0 +1,47 @@ +#include "facette.h" + +/** \class BasicTri +BasicTri is a simplified version of the class Fac which contains only +the nodes, the surface region and the region. +It is used when checking the validity of the mesh is needed but +not all the facet elements are needed. +*/ +class BasicTri + { +public: + /** Constructor using the indices vector and the region. sRegion is false by default. */ + inline BasicTri(const std::vector &inds, const int idReg, const bool surface = false) + : nodesInd({inds[0], inds[1], inds[2]}), idRegion(idReg), isSurfaceElement(surface) + { std::sort(nodesInd.begin(), nodesInd.end()); } + + /** Constructor used to copy a surface region facette */ + explicit BasicTri(const Facette::Fac & fac, const bool surface = true) + : nodesInd({fac.ind[0], fac.ind[1], fac.ind[2]}), idRegion(fac.idxPrm), isSurfaceElement(surface) + { std::sort(nodesInd.begin(), nodesInd.end()); } + + /** Compares the node indices in order */ + bool operator<(const BasicTri & o) const + { return this->nodesInd < o.nodesInd; } + + /** Returns true if all the nodes of the same indices are the same */ + bool operator==(const BasicTri & o) const + { + return (this->nodesInd[0] == o.nodesInd[0]) + && (this->nodesInd[1] == o.nodesInd[1]) + && (this->nodesInd[2] == o.nodesInd[2]); + } + + /** Returns true if the region is the same */ + inline bool sameVRegion(const BasicTri & tri) const + { return this->idRegion == tri.idRegion; } + + /** The 3 node indices composing the triangle */ + std::array nodesInd; + + /** index of the region of the triangle */ + int idRegion; + + /** If the triangle is in a surface region */ + bool isSurfaceElement; + + }; // class BasicTri \ No newline at end of file From 76066be339a4bba921132c9485e09d5585b1acda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Dagand?= Date: Wed, 13 May 2026 16:40:27 +0200 Subject: [PATCH 2/2] Add a fonction which filters some wrong mesh generation --- src/mesh.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mesh.h | 13 ++++++++ 2 files changed, 106 insertions(+) diff --git a/src/mesh.cpp b/src/mesh.cpp index b6aa8a5..6eef187 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1,5 +1,6 @@ #include "mesh.h" #include "meshUtils.h" +#include "basicTri.cpp" #include using namespace Mesh; @@ -160,6 +161,98 @@ void mesh::sortNodes(Nodes::index long_axis) }); } +void mesh::checkTriangles() + { + std::vector allTriCtnr; + const int tetraN = 4; + // Put all triangles into allTriCtnr after doing the conversion + std::for_each(tet.begin(), tet.end(), // For each tetrahedron + [this, &allTriCtnr](const Tetra::Tet &tetrahedron) + { + for (int i = 0; i < tetraN; i++) // For each 4 facets + { + BasicTri curTri({tetrahedron.ind[i], tetrahedron.ind[(i+1) % tetraN], + tetrahedron.ind[(i+2) % tetraN]}, + tetrahedron.idxPrm); + allTriCtnr.push_back(curTri); + } + }); + std::for_each(fac.begin(), fac.end(), [this, &allTriCtnr](const Facette::Fac &curFac) + { // For each surface element + allTriCtnr.push_back(BasicTri(curFac)); + }); + + if (allTriCtnr.empty()) + { + std::cout << "Error: not a single triangle is present in the mesh\n"; + exit(1); + } + else + { + std::sort(allTriCtnr.begin(), allTriCtnr.end()); + BasicTri *prevTri = &allTriCtnr[0]; + std::pair pairIdCurVolRegs(-1, -1); + int idCurSurfReg = -1; + int nbTotTri = 1; + int nbSurfReg = prevTri->isSurfaceElement; + + for (size_t i = 1; i < allTriCtnr.size(); i++) + { // For each triangle + if (!(allTriCtnr[i] == *prevTri)) + { // If the triangle changes + analyzeTriangle(nbTotTri, nbSurfReg, pairIdCurVolRegs, idCurSurfReg); + nbTotTri = 0; + nbSurfReg = 0; + idCurSurfReg = -1; + pairIdCurVolRegs.first = -1; + pairIdCurVolRegs.second = -1; + } + + if (allTriCtnr[i].isSurfaceElement) + { + idCurSurfReg = allTriCtnr[i].idRegion; + nbSurfReg++; + } + else + { + if (pairIdCurVolRegs.first == -1) + { pairIdCurVolRegs.first = allTriCtnr[i].idRegion; } + else + { pairIdCurVolRegs.second = allTriCtnr[i].idRegion; } + } + nbTotTri++; + prevTri = &allTriCtnr[i]; + } + } + } + +void mesh::analyzeTriangle(const int nbTotTri, const int nbSurfReg, + const std::pair &pairIdVolRegs, const int idSurfReg) + { + if (nbSurfReg > 1) + { + std::cout << "Error: wrong mesh generation. A triangle which belongs to " + "multiple surface regions has been found\n"; + exit(1); + } + else if (nbTotTri > 3 || (nbTotTri == 3 && nbSurfReg == 0)) + { + std::cout << "Error: wrong mesh generation. Three " + "identical triangles have been found\n"; + if (nbSurfReg == 1) + { + std::cout << "In surface region " << idSurfReg << "\n"; + } + exit(1); + } + else if (nbTotTri == 3 && nbSurfReg == 1 && pairIdVolRegs.first == pairIdVolRegs.second) + { + std::cout << "Error: wrong mesh generation. An internal triangle belonging " + "to the surface region " << idSurfReg << " has been found\n"; + exit(1); + } + } + double mesh::surface(std::vector &facIndices) { double S(0); diff --git a/src/mesh.h b/src/mesh.h index 914b06a..897aec0 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -118,6 +118,7 @@ class mesh } }); + checkTriangles(); for(unsigned int i=0;i &pairIdVolRegs, const int idSurfReg); + /** returns the surface defined by the set of facets of indices in facIndices * each elementary surface triangle defined by points p0,p1,p2 is computed using * norm(cross(p0p1,p0p2))/2, it is always positive */