Skip to content
Snippets Groups Projects
Commit 22cbefcb authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

handle degenerate case when the same element touches both sides of the same...

handle degenerate case when the same element touches both sides of the same crack with different nodes
parent cf6db03e
No related branches found
No related tags found
No related merge requests found
...@@ -31,6 +31,7 @@ gmsh.model.addPhysicalGroup(1, new_lines, 101) ...@@ -31,6 +31,7 @@ gmsh.model.addPhysicalGroup(1, new_lines, 101)
gmsh.model.mesh.generate(2) gmsh.model.mesh.generate(2)
gmsh.plugin.setNumber("Crack", "PhysicalGroup", 101) gmsh.plugin.setNumber("Crack", "PhysicalGroup", 101)
# gmsh.plugin.setNumber("Crack", "DebugView", 1)
gmsh.plugin.run("Crack") gmsh.plugin.run("Crack")
# save all the elements in the mesh (even those that do not belong to any # save all the elements in the mesh (even those that do not belong to any
......
...@@ -28,6 +28,7 @@ gmsh.model.mesh.generate(3) ...@@ -28,6 +28,7 @@ gmsh.model.mesh.generate(3)
# "crack" the mesh by duplicating the elements and nodes on the small surface # "crack" the mesh by duplicating the elements and nodes on the small surface
gmsh.plugin.setNumber("Crack", "Dimension", 2) gmsh.plugin.setNumber("Crack", "Dimension", 2)
gmsh.plugin.setNumber("Crack", "PhysicalGroup", phys) gmsh.plugin.setNumber("Crack", "PhysicalGroup", phys)
#gmsh.plugin.setNumber("Crack", "DebugView", 1)
gmsh.plugin.run("Crack") gmsh.plugin.run("Crack")
# save all the elements in the mesh (even those that do not belong to any # save all the elements in the mesh (even those that do not belong to any
......
...@@ -211,8 +211,11 @@ PView *GMSH_CrackPlugin::execute(PView *view) ...@@ -211,8 +211,11 @@ PView *GMSH_CrackPlugin::execute(PView *view)
for(auto it = bndVertices.begin(); it != bndVertices.end(); it++) for(auto it = bndVertices.begin(); it != bndVertices.end(); it++)
crackVertices.erase(*it); crackVertices.erase(*it);
// compute elements on one side of the crack // compute elements on the positive side of the crack, and keep track of each
std::set<MElement *> oneside; // node in the element that leads to categorizing the element on this side
// (this allows to handle the degenerate case where the same element touches
// the same crack on both sides, with different nodes - cf. #1750)
std::map<MElement *, std::vector<std::size_t> > oneside;
std::vector<GEntity *> allentities; std::vector<GEntity *> allentities;
m->getEntities(allentities); m->getEntities(allentities);
for(std::size_t ent = 0; ent < allentities.size(); ent++) { for(std::size_t ent = 0; ent < allentities.size(); ent++) {
...@@ -229,7 +232,6 @@ PView *GMSH_CrackPlugin::execute(PView *view) ...@@ -229,7 +232,6 @@ PView *GMSH_CrackPlugin::execute(PView *view)
// connected crack elements, we consider the element lies on the // connected crack elements, we consider the element lies on the
// "positive side" of the crack // "positive side" of the crack
SPoint3 b = e->barycenter(); SPoint3 b = e->barycenter();
bool found = false;
for(auto ce : it->second) { for(auto ce : it->second) {
SVector3 dv = SVector3(b, ce->barycenter()); SVector3 dv = SVector3(b, ce->barycenter());
SVector3 n; SVector3 n;
...@@ -238,20 +240,24 @@ PView *GMSH_CrackPlugin::execute(PView *view) ...@@ -238,20 +240,24 @@ PView *GMSH_CrackPlugin::execute(PView *view)
else else
n = ce->getFace(0).normal(); n = ce->getFace(0).normal();
if(dot(n, dv) < 0) { if(dot(n, dv) < 0) {
oneside.insert(e); auto it2 = oneside.find(e);
found = true; if(it2 == oneside.end())
break; oneside[e] = {j};
else {
if(std::find(it2->second.begin(), it2->second.end(), j) ==
it2->second.end())
it2->second.push_back(j);
}
} }
} }
if(found) break; // we're done for the element
} }
} }
} }
if(debug) { if(debug) {
std::map<int, std::vector<double> > d; std::map<int, std::vector<double> > d;
for(auto e : oneside) d[e->getNum()] = {(double)e->getNum()}; for(auto e : oneside) d[e.first->getNum()] = {(double)e.first->getNum()};
view = new PView("Elements on one side of crack", "ElementData", view = new PView("Elements on positive side of crack", "ElementData",
GModel::current(), d); GModel::current(), d);
} }
...@@ -316,14 +322,16 @@ PView *GMSH_CrackPlugin::execute(PView *view) ...@@ -316,14 +322,16 @@ PView *GMSH_CrackPlugin::execute(PView *view)
// replace vertices in elements on one side of the crack // replace vertices in elements on one side of the crack
for(auto it = oneside.begin(); it != oneside.end(); it++) { for(auto it = oneside.begin(); it != oneside.end(); it++) {
MElement *e = *it; MElement *e = it->first;
for(std::size_t i = 0; i < e->getNumVertices(); i++) { for(auto i : it->second) {
if(vxv.count(e->getVertex(i))) e->setVertex(i, vxv[e->getVertex(i)]); MVertex *v = e->getVertex(i);
if(vxv.count(v))
e->setVertex(i, vxv[v]);
else
Msg::Warning("Mesh node %lu not found in cracked nodes", v->getNum());
} }
} }
// m->pruneMeshVertexAssociations();
CTX::instance()->mesh.changed = ENT_ALL; CTX::instance()->mesh.changed = ENT_ALL;
return view; return view;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment