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

@ -783,6 +783,12 @@ namespace ngcore
pos = nextpos;
}
}
void DeleteData()
{
hash = T_HASH(invalid);
used = 0;
}
class Iterator
{

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 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.
@ -1593,6 +1597,13 @@ inline size_t HashValue (INDEX_2 i2, size_t size) { return (113*size_t(i2[0])+si
pos = nextpos;
}
}
void DeleteData()
{
for (auto & v : hash)
SetInvalid(v);
used = 0;
}
class Iterator
{

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
{
Ng_Node<1> node;
node.vertices.ptr = mesh->GetTopology().GetEdgeVerticesPtr(nr);
node.vertices.ptr = (const int*)mesh->GetTopology().GetEdgeVerticesPtr(nr);
return node;
}
template <> NGX_INLINE DLL_HEADER const Ng_Node<2> Ngx_Mesh :: GetNode<2> (int nr) const
{
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.surface_el = mesh->GetTopology().GetFace2SurfaceElement (nr+1)-1;
return node;

View File

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

View File

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

View File

@ -15,36 +15,9 @@
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_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
{
@ -56,16 +29,15 @@ class MeshTopology
bool build_parent_faces = false; // may be changed to default = false
static bool static_buildedges, static_buildfaces, static_buildvertex2element;
NgArray<INDEX_2> edge2vert;
NgArray<INDEX_4> face2vert;
/*
NgArray<T_EDGE[12]> edges;
NgArray<T_FACE[6]> faces;
NgArray<T_EDGE[4]> surfedges;
*/
NgArray<FixArray<T_EDGE,12>> edges;
NgArray<FixArray<T_FACE,6>> faces;
NgArray<FixArray<T_EDGE,4>> surfedges;
// NgArray<INDEX_2> edge2vert;
// NgArray<INDEX_4> face2vert;
// should be that:
NgArray<std::array<PointIndex,2>> edge2vert;
NgArray<std::array<PointIndex,4>> face2vert;
NgArray<std::array<T_EDGE,12>> edges;
NgArray<std::array<T_FACE,6>> faces;
NgArray<std::array<T_EDGE,4>> surfedges;
NgArray<T_EDGE> segedges;
NgArray<T_FACE> surffaces;
@ -114,12 +86,16 @@ public:
static const Point3d * GetVertices (ELEMENT_TYPE et);
inline static const ELEMENT_EDGE * GetEdges1 (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 * GetFaces0 (ELEMENT_TYPE et);
[[deprecated("use GetEdge(SegmentIndex) instead")]]
int GetSegmentEdge (int segnr) const { return segedges[segnr-1]+1; }
int GetEdge (SegmentIndex segnr) const { return segedges[segnr]; }
[[deprecated("use GetEdge(SegmentIndex) instead")]]
void GetSegmentEdge (int segnr, int & enr, int & orient) const
{
enr = segedges.Get(segnr)+1;
@ -129,16 +105,24 @@ public:
void GetElementEdges (int elnr, NgArray<int> & edges) const;
void GetElementFaces (int elnr, NgArray<int> & faces, bool withorientation = false) const;
[[deprecated("use GetElementEdge instead")]]
void GetElementEdgeOrientations (int elnr, NgArray<int> & eorient) const;
[[deprecated("use GetElementEdge instead")]]
void GetElementFaceOrientations (int elnr, NgArray<int> & forient) const;
int GetElementEdges (int elnr, int * edges, 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
[[deprecated("use GetElementEdge instead")]]
int GetElementFaceOrientation (int elnr, int locfacenr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSurfaceElementEdgeOrientation (int elnr, int locedgenr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSurfaceElementFaceOrientation2 (int elnr) const; // old style
[[deprecated("use GetElementEdge instead")]]
int GetSegmentEdgeOrientation (int elnr) const; // old style
@ -146,8 +130,9 @@ public:
void GetFaceVertices (int fnr, int * vertices) const;
void GetEdgeVertices (int enr, int & v1, int & v2) const;
void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const;
const int * GetEdgeVerticesPtr (int enr) const { return &edge2vert[enr][0]; }
const int * GetFaceVerticesPtr (int fnr) const { return &face2vert[fnr][0]; }
auto GetEdgeVertices (int enr) const { return tuple(edge2vert[enr][0], edge2vert[enr][1]); }
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;
ELEMENT_TYPE GetFaceType (int fnr) const
@ -157,7 +142,13 @@ public:
int GetSurfaceElementFace (int elnr) const;
void GetSurfaceElementEdgeOrientations (int elnr, NgArray<int> & eorient) const;
int GetSurfaceElementFaceOrientation (int elnr) const;
[[deprecated("use GetEdge -> FlatArray instead")]]
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
{ return surffaces[elnr]; }
@ -180,13 +171,17 @@ public:
int GetFace2SurfaceElement (int fnr) const { return face2surfel[fnr-1]; }
SegmentIndex GetSegmentOfEdge(int edgenr) const { return edge2segment[edgenr-1]; }
[[deprecated("use GetVertexElements -> FlatArray instead")]]
void GetVertexElements (int vnr, Array<ElementIndex> & elements) const;
FlatArray<ElementIndex> GetVertexElements (int vnr) const
{ return vert2element[vnr]; }
[[deprecated("use GetVertexSurfaceElements -> FlatArray instead")]]
void GetVertexSurfaceElements( int vnr, Array<SurfaceElementIndex>& elements ) const;
const auto & GetVertexSurfaceElements( ) const { return vert2surfelement; }
FlatArray<SurfaceElementIndex> GetVertexSurfaceElements(PointIndex vnr) const
{ 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 };
}