some modernization of Topology

This commit is contained in:
Joachim Schoeberl 2022-04-21 11:37:30 +02:00
parent 480aa843c5
commit 6fd99a5a29
6 changed files with 230 additions and 140 deletions

View File

@ -784,6 +784,12 @@ namespace ngcore
} }
} }
void DeleteData()
{
hash = T_HASH(invalid);
used = 0;
}
class Iterator class Iterator
{ {
const ClosedHashTable & tab; const ClosedHashTable & tab;

View File

@ -1390,6 +1390,10 @@ inline void SetInvalid (INDEX_2 & i2) { i2[0] = -1; }
inline bool IsInvalid (INDEX_2 i2) { return i2[0] == -1; } inline bool IsInvalid (INDEX_2 i2) { return i2[0] == -1; }
inline size_t HashValue (INDEX_2 i2, size_t size) { return (113*size_t(i2[0])+size_t(i2[1])) % size; } inline size_t HashValue (INDEX_2 i2, size_t size) { return (113*size_t(i2[0])+size_t(i2[1])) % size; }
inline void SetInvalid (INDEX_3 & i3) { i3[0] = -1; }
inline bool IsInvalid (INDEX_3 i3) { return i3[0] == -1; }
inline size_t HashValue (INDEX_3 i3, size_t size) { return (i3[0]+15*size_t(i3[1])+41*size_t(i3[2])) % size; }
/** /**
A closed hash-table. A closed hash-table.
@ -1594,6 +1598,13 @@ inline size_t HashValue (INDEX_2 i2, size_t size) { return (113*size_t(i2[0])+si
} }
} }
void DeleteData()
{
for (auto & v : hash)
SetInvalid(v);
used = 0;
}
class Iterator class Iterator
{ {
const ClosedHashTable & tab; const ClosedHashTable & tab;

View File

@ -296,14 +296,14 @@ template <> NGX_INLINE DLL_HEADER const Ng_Node<0> Ngx_Mesh :: GetNode<0> (int v
template <> NGX_INLINE DLL_HEADER const Ng_Node<1> Ngx_Mesh :: GetNode<1> (int nr) const template <> NGX_INLINE DLL_HEADER const Ng_Node<1> Ngx_Mesh :: GetNode<1> (int nr) const
{ {
Ng_Node<1> node; Ng_Node<1> node;
node.vertices.ptr = mesh->GetTopology().GetEdgeVerticesPtr(nr); node.vertices.ptr = (const int*)mesh->GetTopology().GetEdgeVerticesPtr(nr);
return node; return node;
} }
template <> NGX_INLINE DLL_HEADER const Ng_Node<2> Ngx_Mesh :: GetNode<2> (int nr) const template <> NGX_INLINE DLL_HEADER const Ng_Node<2> Ngx_Mesh :: GetNode<2> (int nr) const
{ {
Ng_Node<2> node; Ng_Node<2> node;
node.vertices.ptr = mesh->GetTopology().GetFaceVerticesPtr(nr); node.vertices.ptr = (const int*)mesh->GetTopology().GetFaceVerticesPtr(nr);
node.vertices.nv = (node.vertices.ptr[3] == 0) ? 3 : 4; node.vertices.nv = (node.vertices.ptr[3] == 0) ? 3 : 4;
node.surface_el = mesh->GetTopology().GetFace2SurfaceElement (nr+1)-1; node.surface_el = mesh->GetTopology().GetFace2SurfaceElement (nr+1)-1;
return node; return node;

View File

@ -623,7 +623,8 @@ namespace netgen
if (mesh.GetDimension() == 3) if (mesh.GetDimension() == 3)
for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++)
{ {
top.GetEdges (i, edgenrs); // top.GetEdges (i, edgenrs);
auto edgenrs = top.GetEdges (i);
for (int j = 0; j < edgenrs.Size(); j++) for (int j = 0; j < edgenrs.Size(); j++)
edgeorder[edgenrs[j]] = aorder; edgeorder[edgenrs[j]] = aorder;
faceorder[top.GetFace (i)] = aorder; faceorder[top.GetFace (i)] = aorder;
@ -722,7 +723,8 @@ namespace netgen
if (working) if (working)
for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++)
{ {
top.GetEdges (i, edgenrs); // top.GetEdges (i, edgenrs);
auto edgenrs = top.GetEdges(i);
const Element2d & el = mesh[i]; const Element2d & el = mesh[i];
const ELEMENT_EDGE * edges = MeshTopology::GetEdges0 (el.GetType()); const ELEMENT_EDGE * edges = MeshTopology::GetEdges0 (el.GetType());
@ -1381,7 +1383,7 @@ namespace netgen
if (info.order > 1) if (info.order > 1)
{ {
const MeshTopology & top = mesh.GetTopology(); const MeshTopology & top = mesh.GetTopology();
info.edgenr = top.GetSegmentEdge (elnr+1)-1; info.edgenr = top.GetEdge (elnr);
info.ndof += edgeorder[info.edgenr]-1; info.ndof += edgeorder[info.edgenr]-1;
} }
@ -1459,7 +1461,7 @@ namespace netgen
if (info.order > 1) if (info.order > 1)
{ {
const MeshTopology & top = mesh.GetTopology(); const MeshTopology & top = mesh.GetTopology();
info.edgenr = top.GetSegmentEdge (elnr+1)-1; info.edgenr = top.GetEdge (elnr);
info.ndof += edgeorder[info.edgenr]-1; info.ndof += edgeorder[info.edgenr]-1;
} }

View File

@ -100,18 +100,16 @@ namespace netgen
{ {
const Element & el = mesh[elnr]; const Element & el = mesh[elnr];
int neledges = MeshTopology::GetNEdges (el.GetType()); auto eledges = MeshTopology::GetEdges (el.GetType());
const ELEMENT_EDGE * eledges = MeshTopology::GetEdges0 (el.GetType()); for (int k = 0; k < eledges.Size(); k++)
for (int k = 0; k < neledges; k++)
{ {
INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]);
// edge.Sort();
int edgedir = (edge.I1() > edge.I2()); int edgedir = (edge.I1() > edge.I2());
if (edgedir) swap (edge.I1(), edge.I2()); if (edgedir) swap (edge.I1(), edge.I2());
if (edge.I1() != v) continue; if (edge.I1() != v) continue;
func (edge, elnr, k, 3, edgedir); func (edge, elnr, k, 3);
} }
} }
@ -119,19 +117,17 @@ namespace netgen
{ {
const Element2d & el = mesh[elnr]; const Element2d & el = mesh[elnr];
int neledges = MeshTopology::GetNEdges (el.GetType()); auto eledges = MeshTopology::GetEdges (el.GetType());
const ELEMENT_EDGE * eledges = MeshTopology::GetEdges0 (el.GetType()); for (int k = 0; k < eledges.Size(); k++)
for (int k = 0; k < neledges; k++)
{ {
INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]);
// edge.Sort();
int edgedir = (edge.I1() > edge.I2()); int edgedir = (edge.I1() > edge.I2());
if (edgedir) swap (edge.I1(), edge.I2()); if (edgedir) swap (edge.I1(), edge.I2());
if (edge.I1() != v) continue; if (edge.I1() != v) continue;
func (edge, elnr, k, 2, edgedir); func (edge, elnr, k, 2);
} }
} }
@ -145,7 +141,7 @@ namespace netgen
edge.Sort(); edge.Sort();
if (edge.I1() != v) continue; if (edge.I1() != v) continue;
func (edge, elnr, 0, 1, edgedir); func (edge, elnr, 0, 1);
} }
} }
@ -177,7 +173,7 @@ namespace netgen
if (face.I1() != v) continue; if (face.I1() != v) continue;
func (face, elnr, j, true, facedir); func (face, elnr, j, true);
} }
/* /*
if (pass == 1) if (pass == 1)
@ -227,7 +223,7 @@ namespace netgen
if (face4.I1() != v) continue; if (face4.I1() != v) continue;
func(face4, elnr, j, true, facedir); func(face4, elnr, j, true);
/* /*
INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); INDEX_3 face(face4.I1(), face4.I2(), face4.I3());
@ -291,7 +287,7 @@ namespace netgen
if (face.I1() != v) continue; if (face.I1() != v) continue;
func(face, elnr, 0, false, facedir); func(face, elnr, 0, false);
/* /*
if (vert2face.Used (face)) if (vert2face.Used (face))
facenum = vert2face.Get(face); facenum = vert2face.Get(face);
@ -344,7 +340,7 @@ namespace netgen
} }
if (face4.I1() != v) continue; if (face4.I1() != v) continue;
func(face4, elnr, 0, false, facedir); func(face4, elnr, 0, false);
/* /*
INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); INDEX_3 face(face4.I1(), face4.I2(), face4.I3());
@ -403,7 +399,6 @@ namespace netgen
(*tracer) ("Topology::Update setup tables", false); (*tracer) ("Topology::Update setup tables", false);
NgArray<int,PointIndex::BASE> cnt(nv); NgArray<int,PointIndex::BASE> cnt(nv);
NgArray<int> vnums;
/* /*
generate: generate:
@ -516,7 +511,8 @@ namespace netgen
{ {
auto begin = r.First(); auto begin = r.First();
auto end = r.Next(); auto end = r.Next();
INDEX_CLOSED_HASHTABLE<int> v2eht(2*max_edge_on_vertex+10); // INDEX_CLOSED_HASHTABLE<int> v2eht(2*max_edge_on_vertex+10);
ngcore::ClosedHashTable<int, int> v2eht(2*max_edge_on_vertex+10);
for (PointIndex v = begin+PointIndex::BASE; for (PointIndex v = begin+PointIndex::BASE;
v < end+PointIndex::BASE; v++) v < end+PointIndex::BASE; v++)
{ {
@ -537,7 +533,7 @@ namespace netgen
} }
LoopOverEdges (*mesh, *this, v, LoopOverEdges (*mesh, *this, v,
[&] (INDEX_2 edge, int elnr, int loc_edge, int element_dim, int edgedir) [&] (INDEX_2 edge, int elnr, int loc_edge, int element_dim)
{ {
if (!v2eht.Used (edge.I2())) if (!v2eht.Used (edge.I2()))
{ {
@ -573,8 +569,9 @@ namespace netgen
{ {
auto begin = r.First(); auto begin = r.First();
auto end = r.Next(); auto end = r.Next();
INDEX_CLOSED_HASHTABLE<int> v2eht(2*max_edge_on_vertex+10); // INDEX_CLOSED_HASHTABLE<int> v2eht(2*max_edge_on_vertex+10);
NgArray<int> vertex2; ngcore::ClosedHashTable<int, int> v2eht(2*max_edge_on_vertex+10);
Array<int> vertex2;
for (PointIndex v = begin+PointIndex::BASE; for (PointIndex v = begin+PointIndex::BASE;
v < end+PointIndex::BASE; v++) v < end+PointIndex::BASE; v++)
{ {
@ -596,7 +593,7 @@ namespace netgen
} }
LoopOverEdges (*mesh, *this, v, LoopOverEdges (*mesh, *this, v,
[&](INDEX_2 edge, int elnr, int loc_edge, int element_dim, int edgedir) [&](INDEX_2 edge, int elnr, int loc_edge, int element_dim)
{ {
if (!v2eht.Used(edge.I2())) if (!v2eht.Used(edge.I2()))
{ {
@ -610,28 +607,26 @@ namespace netgen
for (int j = 0; j < vertex2.Size(); j++) for (int j = 0; j < vertex2.Size(); j++)
{ {
v2eht.Set (vertex2[j], ned); v2eht.Set (vertex2[j], ned);
edge2vert[ned] = INDEX_2 (v, vertex2[j]); // edge2vert[ned] = INDEX_2 (v, vertex2[j]);
edge2vert[ned] = { v, vertex2[j] };
ned++; ned++;
} }
LoopOverEdges (*mesh, *this, v, LoopOverEdges (*mesh, *this, v,
[&](INDEX_2 edge, int elnr, int loc_edge, int element_dim, int edgedir) [&](INDEX_2 edge, int elnr, int loc_edge, int element_dim)
{ {
int edgenum = v2eht.Get(edge.I2()); int edgenum = v2eht.Get(edge.I2());
switch (element_dim) switch (element_dim)
{ {
case 3: case 3:
edges[elnr][loc_edge] = edgenum; edges[elnr][loc_edge] = edgenum;
// edges[elnr][loc_edge].orient = edgedir;
break; break;
case 2: case 2:
surfedges[elnr][loc_edge] = edgenum; surfedges[elnr][loc_edge] = edgenum;
// surfedges[elnr][loc_edge].orient = edgedir;
break; break;
case 1: case 1:
segedges[elnr] = edgenum; segedges[elnr] = edgenum;
edge2segment[edgenum] = elnr; edge2segment[edgenum] = elnr;
// segedges[elnr].orient = edgedir;
break; break;
} }
}); });
@ -1022,7 +1017,8 @@ namespace netgen
{ {
auto begin = r.First(); auto begin = r.First();
auto end = r.Next(); auto end = r.Next();
INDEX_3_CLOSED_HASHTABLE<int> vert2face(2*max_face_on_vertex+10); // INDEX_3_CLOSED_HASHTABLE<int> vert2face(2*max_face_on_vertex+10);
ClosedHashTable<INDEX_3, int> vert2face(2*max_face_on_vertex+10);
for (PointIndex v = begin+PointIndex::BASE; for (PointIndex v = begin+PointIndex::BASE;
v < end+PointIndex::BASE; v++) v < end+PointIndex::BASE; v++)
{ {
@ -1031,9 +1027,9 @@ namespace netgen
for (int j = 0; j < vert2oldface[v].Size(); j++) for (int j = 0; j < vert2oldface[v].Size(); j++)
{ {
int fnr = vert2oldface[v][j]; int fnr = vert2oldface[v][j];
INDEX_3 face (face2vert[fnr].I1(), INDEX_3 face (face2vert[fnr][0],
face2vert[fnr].I2(), face2vert[fnr][1],
face2vert[fnr].I3()); face2vert[fnr][2]);
vert2face.Set (face, 33); // something vert2face.Set (face, 33); // something
} }
int cnti = 0; int cnti = 0;
@ -1052,9 +1048,9 @@ namespace netgen
} }
} }
LoopOverFaces (*mesh, *this, v, LoopOverFaces (*mesh, *this, v,
[&] (INDEX_4 i4, int elnr, int j, bool volume, int facedir) [&] (INDEX_4 i4, int elnr, int j, bool volume)
{ {
INDEX_3 face(i4.I1(), i4.I2(), i4.I3()); INDEX_3 face(i4[0], i4[1], i4[2]);
if (!vert2face.Used (face)) if (!vert2face.Used (face))
{ {
cnti++; cnti++;
@ -1086,7 +1082,8 @@ namespace netgen
{ {
auto begin = r.First(); auto begin = r.First();
auto end = r.Next(); auto end = r.Next();
INDEX_3_CLOSED_HASHTABLE<int> vert2face(2*max_face_on_vertex+10); // INDEX_3_CLOSED_HASHTABLE<int> vert2face(2*max_face_on_vertex+10);
ClosedHashTable<INDEX_3, int> vert2face(2*max_face_on_vertex+10);
for (PointIndex v = begin+PointIndex::BASE; for (PointIndex v = begin+PointIndex::BASE;
v < end+PointIndex::BASE; v++) v < end+PointIndex::BASE; v++)
{ {
@ -1097,9 +1094,9 @@ namespace netgen
for (int j = 0; j < vert2oldface[v].Size(); j++) for (int j = 0; j < vert2oldface[v].Size(); j++)
{ {
int fnr = vert2oldface[v][j]; int fnr = vert2oldface[v][j];
INDEX_3 face (face2vert[fnr].I1(), INDEX_3 face (face2vert[fnr][0],
face2vert[fnr].I2(), face2vert[fnr][1],
face2vert[fnr].I3()); face2vert[fnr][2]);
vert2face.Set (face, fnr); vert2face.Set (face, fnr);
} }
@ -1112,8 +1109,8 @@ namespace netgen
face.Sort(); face.Sort();
if (!vert2face.Used(face)) if (!vert2face.Used(face))
{ {
INDEX_4 i4(face.I1(), face.I2(), face.I3(), 0); // INDEX_4 i4(face.I1(), face.I2(), face.I3(), 0);
face2vert[nfa] = i4; face2vert[nfa] = { face[0], face[1], face[2], 0 }; // i4;
vert2face.Set (face, nfa); vert2face.Set (face, nfa);
nfa++; nfa++;
// cout << "adding face " << i4 << endl; // cout << "adding face " << i4 << endl;
@ -1123,12 +1120,12 @@ namespace netgen
} }
LoopOverFaces (*mesh, *this, v, LoopOverFaces (*mesh, *this, v,
[&] (INDEX_4 i4, int elnr, int j, bool volume, int facedir) [&] (INDEX_4 i4, int elnr, int j, bool volume)
{ {
INDEX_3 face(i4.I1(), i4.I2(), i4.I3()); INDEX_3 face(i4.I1(), i4.I2(), i4.I3());
if (!vert2face.Used (face)) if (!vert2face.Used (face))
{ {
face2vert[nfa] = i4; face2vert[nfa] = { i4[0], i4[1], i4[2], i4[3] }; // i4;
vert2face.Set (face, nfa); vert2face.Set (face, nfa);
nfa++; nfa++;
} }
@ -1141,9 +1138,9 @@ namespace netgen
{ {
if (face2vert[j][0] == v) if (face2vert[j][0] == v)
{ {
INDEX_3 face (face2vert[j].I1(), INDEX_3 face (face2vert[j][0],
face2vert[j].I2(), face2vert[j][1],
face2vert[j].I3()); face2vert[j][2]);
vert2face.Set (face, j); vert2face.Set (face, j);
} }
else else
@ -1152,20 +1149,14 @@ namespace netgen
LoopOverFaces (*mesh, *this, v, LoopOverFaces (*mesh, *this, v,
[&] (INDEX_4 i4, int elnr, int j, bool volume, int facedir) [&] (INDEX_4 i4, int elnr, int j, bool volume)
{ {
INDEX_3 face(i4.I1(), i4.I2(), i4.I3()); INDEX_3 face(i4.I1(), i4.I2(), i4.I3());
int facenum = vert2face.Get(face); int facenum = vert2face.Get(face);
if (volume) if (volume)
{
faces[elnr][j] = facenum; faces[elnr][j] = facenum;
// faces[elnr][j].forient = facedir;
}
else else
{
surffaces[elnr] = facenum; surffaces[elnr] = facenum;
// surffaces[elnr].forient = facedir;
}
}); });
} }
}, TasksPerThread(4) ); }, TasksPerThread(4) );
@ -1528,14 +1519,19 @@ namespace netgen
#endif #endif
{ {
(*testout) << "illegal face : " << i << endl; (*testout) << "illegal face : " << i << endl;
(*testout) << "points = " << face2vert[i] << endl; (*testout) << "points = "
<< face2vert[i][0] << ","
<< face2vert[i][1] << ","
<< face2vert[i][2] << ","
<< face2vert[i][3]
<< endl;
(*testout) << "pos = "; (*testout) << "pos = ";
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
if (face2vert[i].I(j+1) >= 1) if (face2vert[i][j] >= 1)
(*testout) << (*mesh)[(PointIndex)face2vert[i].I(j+1)] << " "; (*testout) << (*mesh)[(PointIndex)face2vert[i][j]] << " ";
(*testout) << endl; (*testout) << endl;
FlatArray<ElementIndex> vertels = GetVertexElements (face2vert[i].I(1)); FlatArray<ElementIndex> vertels = GetVertexElements (face2vert[i][0]);
for (int k = 0; k < vertels.Size(); k++) for (int k = 0; k < vertels.Size(); k++)
{ {
int elfaces[10], orient[10]; int elfaces[10], orient[10];
@ -2165,6 +2161,12 @@ namespace netgen
eledges[i] = surfedges[elnr][i]; eledges[i] = surfedges[elnr][i];
} }
FlatArray<T_EDGE> MeshTopology :: GetEdges (SurfaceElementIndex elnr) const
{
return FlatArray<T_EDGE>(GetNEdges ( (*mesh)[elnr].GetType()), &surfedges[elnr][0]);
}
int MeshTopology :: GetSurfaceElementFace (int elnr) const int MeshTopology :: GetSurfaceElementFace (int elnr) const
{ {
return surffaces.Get(elnr)+1; return surffaces.Get(elnr)+1;
@ -2534,13 +2536,6 @@ namespace netgen
} }
} }
/*
ELEMENT_TYPE MeshTopology :: GetFaceType (int fnr) const
{
if (face2vert.Get(fnr)[3] == 0) return TRIG; else return QUAD;
}
*/
void MeshTopology :: GetVertexElements (int vnr, Array<ElementIndex> & elements) const void MeshTopology :: GetVertexElements (int vnr, Array<ElementIndex> & elements) const
{ {
@ -2548,29 +2543,6 @@ namespace netgen
elements = vert2element[vnr]; elements = vert2element[vnr];
} }
/*
NgFlatArray<ElementIndex> MeshTopology :: GetVertexElements (int vnr) const
{
if (vert2element)
return (*vert2element)[vnr];
return NgFlatArray<ElementIndex> (0,0);
}
NgFlatArray<SurfaceElementIndex> MeshTopology :: GetVertexSurfaceElements (int vnr) const
{
if (vert2surfelement)
return (*vert2surfelement)[vnr];
return NgFlatArray<SurfaceElementIndex> (0,0);
}
NgFlatArray<SegmentIndex> MeshTopology :: GetVertexSegments (int vnr) const
{
if (vert2segment)
return (*vert2segment)[vnr];
return NgFlatArray<SegmentIndex> (0,0);
}
*/
void MeshTopology :: GetVertexSurfaceElements( int vnr, void MeshTopology :: GetVertexSurfaceElements( int vnr,
Array<SurfaceElementIndex> & elements ) const Array<SurfaceElementIndex> & elements ) const
{ {
@ -2581,9 +2553,10 @@ namespace netgen
int MeshTopology :: GetVerticesEdge ( int v1, int v2 ) const int MeshTopology :: GetVerticesEdge ( int v1, int v2 ) const
{ {
Array<ElementIndex> elements_v1;
NgArray<int> elementedges; NgArray<int> elementedges;
GetVertexElements ( v1, elements_v1); // Array<ElementIndex> elements_v1;
// GetVertexElements ( v1, elements_v1);
auto elements_v1 = GetVertexElements ( v1 );
int edv1, edv2; int edv1, edv2;
for ( int i = 0; i < elements_v1.Size(); i++ ) for ( int i = 0; i < elements_v1.Size(); i++ )
@ -2605,8 +2578,12 @@ namespace netgen
void MeshTopology :: void MeshTopology ::
GetSegmentVolumeElements ( int segnr, NgArray<ElementIndex> & volels ) const GetSegmentVolumeElements ( int segnr, NgArray<ElementIndex> & volels ) const
{ {
/*
int v1, v2; int v1, v2;
GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); // GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 );
GetEdgeVertices ( GetEdge (segnr-1)+1, v1, v2 );
*/
auto [v1,v2] = GetEdgeVertices ( GetEdge (segnr-1) );
auto volels1 = GetVertexElements ( v1 ); auto volels1 = GetVertexElements ( v1 );
auto volels2 = GetVertexElements ( v2 ); auto volels2 = GetVertexElements ( v2 );
volels.SetSize(0); volels.SetSize(0);
@ -2620,7 +2597,8 @@ namespace netgen
GetSegmentSurfaceElements (int segnr, NgArray<SurfaceElementIndex> & els) const GetSegmentSurfaceElements (int segnr, NgArray<SurfaceElementIndex> & els) const
{ {
int v1, v2; int v1, v2;
GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); // GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 );
GetEdgeVertices ( GetEdge (segnr-1)+1, v1, v2 );
auto els1 = GetVertexSurfaceElements ( v1 ); auto els1 = GetVertexSurfaceElements ( v1 );
auto els2 = GetVertexSurfaceElements ( v2 ); auto els2 = GetVertexSurfaceElements ( v2 );
els.SetSize(0); els.SetSize(0);

View File

@ -15,37 +15,10 @@
namespace netgen namespace netgen
{ {
/*
struct T_EDGE
{
// int orient:1;
int nr; // 0-based
};
struct T_FACE
{
// int forient:3;
int fnr; // 0-based
};
*/
typedef int T_EDGE; typedef int T_EDGE;
typedef int T_FACE; typedef int T_FACE;
/*
template <typename T, int S>
struct FixArray
{
T vals[S];
T & operator[] (size_t i) { return vals[i]; }
T operator[] (size_t i) const { return vals[i]; }
};
*/
template <typename T, int S>
using FixArray = std::array<T,S>;
class MeshTopology class MeshTopology
{ {
const Mesh * mesh; const Mesh * mesh;
@ -56,16 +29,15 @@ class MeshTopology
bool build_parent_faces = false; // may be changed to default = false bool build_parent_faces = false; // may be changed to default = false
static bool static_buildedges, static_buildfaces, static_buildvertex2element; static bool static_buildedges, static_buildfaces, static_buildvertex2element;
NgArray<INDEX_2> edge2vert; // NgArray<INDEX_2> edge2vert;
NgArray<INDEX_4> face2vert; // NgArray<INDEX_4> face2vert;
/* // should be that:
NgArray<T_EDGE[12]> edges; NgArray<std::array<PointIndex,2>> edge2vert;
NgArray<T_FACE[6]> faces; NgArray<std::array<PointIndex,4>> face2vert;
NgArray<T_EDGE[4]> surfedges;
*/ NgArray<std::array<T_EDGE,12>> edges;
NgArray<FixArray<T_EDGE,12>> edges; NgArray<std::array<T_FACE,6>> faces;
NgArray<FixArray<T_FACE,6>> faces; NgArray<std::array<T_EDGE,4>> surfedges;
NgArray<FixArray<T_EDGE,4>> surfedges;
NgArray<T_EDGE> segedges; NgArray<T_EDGE> segedges;
NgArray<T_FACE> surffaces; NgArray<T_FACE> surffaces;
@ -114,12 +86,16 @@ public:
static const Point3d * GetVertices (ELEMENT_TYPE et); static const Point3d * GetVertices (ELEMENT_TYPE et);
inline static const ELEMENT_EDGE * GetEdges1 (ELEMENT_TYPE et); inline static const ELEMENT_EDGE * GetEdges1 (ELEMENT_TYPE et);
inline static const ELEMENT_EDGE * GetEdges0 (ELEMENT_TYPE et); inline static const ELEMENT_EDGE * GetEdges0 (ELEMENT_TYPE et);
inline static FlatArray<ELEMENT_EDGE> GetEdges (ELEMENT_TYPE et);
inline static const ELEMENT_FACE * GetFaces1 (ELEMENT_TYPE et); inline static const ELEMENT_FACE * GetFaces1 (ELEMENT_TYPE et);
inline static const ELEMENT_FACE * GetFaces0 (ELEMENT_TYPE et); inline static const ELEMENT_FACE * GetFaces0 (ELEMENT_TYPE et);
[[deprecated("use GetEdge(SegmentIndex) instead")]]
int GetSegmentEdge (int segnr) const { return segedges[segnr-1]+1; } int GetSegmentEdge (int segnr) const { return segedges[segnr-1]+1; }
int GetEdge (SegmentIndex segnr) const { return segedges[segnr]; } int GetEdge (SegmentIndex segnr) const { return segedges[segnr]; }
[[deprecated("use GetEdge(SegmentIndex) instead")]]
void GetSegmentEdge (int segnr, int & enr, int & orient) const void GetSegmentEdge (int segnr, int & enr, int & orient) const
{ {
enr = segedges.Get(segnr)+1; enr = segedges.Get(segnr)+1;
@ -129,16 +105,24 @@ public:
void GetElementEdges (int elnr, NgArray<int> & edges) const; void GetElementEdges (int elnr, NgArray<int> & edges) const;
void GetElementFaces (int elnr, NgArray<int> & faces, bool withorientation = false) const; void GetElementFaces (int elnr, NgArray<int> & faces, bool withorientation = false) const;
[[deprecated("use GetElementEdge instead")]]
void GetElementEdgeOrientations (int elnr, NgArray<int> & eorient) const; void GetElementEdgeOrientations (int elnr, NgArray<int> & eorient) const;
[[deprecated("use GetElementEdge instead")]]
void GetElementFaceOrientations (int elnr, NgArray<int> & forient) const; void GetElementFaceOrientations (int elnr, NgArray<int> & forient) const;
int GetElementEdges (int elnr, int * edges, int * orient) const; int GetElementEdges (int elnr, int * edges, int * orient) const;
int GetElementFaces (int elnr, int * faces, int * orient) const; int GetElementFaces (int elnr, int * faces, int * orient) const;
[[deprecated("use GetElementEdge instead")]]
int GetElementEdgeOrientation (int elnr, int locedgenr) const; // old style int GetElementEdgeOrientation (int elnr, int locedgenr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetElementFaceOrientation (int elnr, int locfacenr) const; // old style int GetElementFaceOrientation (int elnr, int locfacenr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSurfaceElementEdgeOrientation (int elnr, int locedgenr) const; // old style int GetSurfaceElementEdgeOrientation (int elnr, int locedgenr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSurfaceElementFaceOrientation2 (int elnr) const; // old style int GetSurfaceElementFaceOrientation2 (int elnr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSegmentEdgeOrientation (int elnr) const; // old style int GetSegmentEdgeOrientation (int elnr) const; // old style
@ -146,8 +130,9 @@ public:
void GetFaceVertices (int fnr, int * vertices) const; void GetFaceVertices (int fnr, int * vertices) const;
void GetEdgeVertices (int enr, int & v1, int & v2) const; void GetEdgeVertices (int enr, int & v1, int & v2) const;
void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const; void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const;
const int * GetEdgeVerticesPtr (int enr) const { return &edge2vert[enr][0]; } auto GetEdgeVertices (int enr) const { return tuple(edge2vert[enr][0], edge2vert[enr][1]); }
const int * GetFaceVerticesPtr (int fnr) const { return &face2vert[fnr][0]; } auto GetEdgeVerticesPtr (int enr) const { return &edge2vert[enr][0]; }
auto GetFaceVerticesPtr (int fnr) const { return &face2vert[fnr][0]; }
void GetFaceEdges (int fnr, NgArray<int> & edges, bool withorientation = false) const; void GetFaceEdges (int fnr, NgArray<int> & edges, bool withorientation = false) const;
ELEMENT_TYPE GetFaceType (int fnr) const ELEMENT_TYPE GetFaceType (int fnr) const
@ -157,7 +142,13 @@ public:
int GetSurfaceElementFace (int elnr) const; int GetSurfaceElementFace (int elnr) const;
void GetSurfaceElementEdgeOrientations (int elnr, NgArray<int> & eorient) const; void GetSurfaceElementEdgeOrientations (int elnr, NgArray<int> & eorient) const;
int GetSurfaceElementFaceOrientation (int elnr) const; int GetSurfaceElementFaceOrientation (int elnr) const;
[[deprecated("use GetEdge -> FlatArray instead")]]
void GetEdges (SurfaceElementIndex elnr, NgArray<int> & edges) const; void GetEdges (SurfaceElementIndex elnr, NgArray<int> & edges) const;
FlatArray<T_EDGE> GetEdges (SurfaceElementIndex elnr) const;
// { return FlatArray<T_EDGE>(GetNEdges ( (*mesh)[elnr].GetType()), &surfedges[elnr][0]); }
int GetFace (SurfaceElementIndex elnr) const int GetFace (SurfaceElementIndex elnr) const
{ return surffaces[elnr]; } { return surffaces[elnr]; }
@ -181,12 +172,16 @@ public:
SegmentIndex GetSegmentOfEdge(int edgenr) const { return edge2segment[edgenr-1]; } SegmentIndex GetSegmentOfEdge(int edgenr) const { return edge2segment[edgenr-1]; }
[[deprecated("use GetVertexElements -> FlatArray instead")]]
void GetVertexElements (int vnr, Array<ElementIndex> & elements) const; void GetVertexElements (int vnr, Array<ElementIndex> & elements) const;
FlatArray<ElementIndex> GetVertexElements (int vnr) const FlatArray<ElementIndex> GetVertexElements (int vnr) const
{ return vert2element[vnr]; } { return vert2element[vnr]; }
[[deprecated("use GetVertexSurfaceElements -> FlatArray instead")]]
void GetVertexSurfaceElements( int vnr, Array<SurfaceElementIndex>& elements ) const; void GetVertexSurfaceElements( int vnr, Array<SurfaceElementIndex>& elements ) const;
const auto & GetVertexSurfaceElements( ) const { return vert2surfelement; } const auto & GetVertexSurfaceElements( ) const { return vert2surfelement; }
FlatArray<SurfaceElementIndex> GetVertexSurfaceElements(PointIndex vnr) const FlatArray<SurfaceElementIndex> GetVertexSurfaceElements(PointIndex vnr) const
{ return vert2surfelement[vnr]; } { return vert2surfelement[vnr]; }
@ -606,6 +601,104 @@ const ELEMENT_EDGE * MeshTopology :: GetEdges0 (ELEMENT_TYPE et)
} }
FlatArray<ELEMENT_EDGE> MeshTopology :: GetEdges (ELEMENT_TYPE et)
{
static ELEMENT_EDGE segm_edges[1] =
{ { 0, 1 }};
static ELEMENT_EDGE trig_edges[3] =
{ { 2, 0 },
{ 1, 2 },
{ 0, 1 }};
static ELEMENT_EDGE quad_edges[4] =
{ { 0, 1 },
{ 2, 3 },
{ 3, 0 },
{ 1, 2 }};
static ELEMENT_EDGE tet_edges[6] =
{ { 3, 0 },
{ 3, 1 },
{ 3, 2 },
{ 0, 1 },
{ 0, 2 },
{ 1, 2 }};
static ELEMENT_EDGE prism_edges[9] =
{ { 2, 0 },
{ 0, 1 },
{ 2, 1 },
{ 5, 3 },
{ 3, 4 },
{ 5, 4 },
{ 2, 5 },
{ 0, 3 },
{ 1, 4 }};
static ELEMENT_EDGE pyramid_edges[8] =
{ { 0, 1 },
{ 1, 2 },
{ 0, 3 },
{ 3, 2 },
{ 0, 4 },
{ 1, 4 },
{ 2, 4 },
{ 3, 4 }};
static ELEMENT_EDGE hex_edges[12] =
{
{ 0, 1 },
{ 2, 3 },
{ 3, 0 },
{ 1, 2 },
{ 4, 5 },
{ 6, 7 },
{ 7, 4 },
{ 5, 6 },
{ 0, 4 },
{ 1, 5 },
{ 2, 6 },
{ 3, 7 },
};
switch (et)
{
case SEGMENT:
case SEGMENT3:
return { 1, segm_edges };
case TRIG:
case TRIG6:
return { 3, trig_edges };
case QUAD:
case QUAD6:
case QUAD8:
return { 4, quad_edges };
case TET:
case TET10:
return { 6, tet_edges };
case PYRAMID:
case PYRAMID13:
return { 8, pyramid_edges };
case PRISM:
case PRISM12:
case PRISM15:
return { 9, prism_edges };
case HEX:
case HEX20:
return { 12, hex_edges };
// default:
// cerr << "Ng_ME_GetEdges, illegal element type " << et << endl;
}
return { 0, nullptr };
}