netgen/libsrc/meshing/topology.hpp

734 lines
15 KiB
C++
Raw Normal View History

2009-01-13 04:40:13 +05:00
#ifndef TOPOLOGY
#define TOPOLOGY
/**************************************************************************/
/* File: topology.hh */
/* Author: Joachim Schoeberl */
/* Date: 27. Apr. 01 */
/**************************************************************************/
/*
Mesh topology
(Elements, Faces, Edges, Vertices
*/
2016-01-07 17:37:48 +05:00
namespace netgen
{
2014-01-07 16:42:39 +06:00
struct T_EDGE
{
// int orient:1;
int nr; // 0-based
2014-01-07 16:42:39 +06:00
};
struct T_FACE
{
// int forient:3;
int fnr; // 0-based
2014-01-07 16:42:39 +06:00
};
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]; }
};
2014-01-07 16:42:39 +06:00
2009-01-13 04:40:13 +05:00
class MeshTopology
{
const Mesh * mesh;
2009-01-13 04:40:13 +05:00
bool buildedges;
bool buildfaces;
2013-04-03 02:29:53 +06:00
Array<INDEX_2> edge2vert;
Array<INDEX_4> face2vert;
/*
2014-01-07 16:42:39 +06:00
Array<T_EDGE[12]> edges;
Array<T_FACE[6]> faces;
Array<T_EDGE[4]> surfedges;
*/
Array<FixArray<T_EDGE,12>> edges;
Array<FixArray<T_FACE,6>> faces;
Array<FixArray<T_EDGE,4>> surfedges;
2014-01-07 16:42:39 +06:00
Array<T_EDGE> segedges;
Array<T_FACE> surffaces;
2013-04-03 02:29:53 +06:00
Array<INDEX_2> surf2volelement;
Array<int> face2surfel;
TABLE<ElementIndex,PointIndex::BASE> vert2element;
TABLE<SurfaceElementIndex,PointIndex::BASE> vert2surfelement;
TABLE<SegmentIndex,PointIndex::BASE> vert2segment;
TABLE<int,PointIndex::BASE> vert2pointelement;
2009-01-13 04:40:13 +05:00
int timestamp;
public:
int GetNSurfedges() const {return surfedges.Size();}
MeshTopology () = default;
MeshTopology (const MeshTopology & top) = default;
MeshTopology (MeshTopology && top) = default;
2009-01-13 04:40:13 +05:00
MeshTopology (const Mesh & amesh);
~MeshTopology ();
MeshTopology & operator= (const MeshTopology & top) = default;
MeshTopology & operator= (MeshTopology && top) = default;
2009-01-13 04:40:13 +05:00
void SetBuildEdges (bool be)
{ buildedges = be; }
void SetBuildFaces (bool bf)
{ buildfaces = bf; }
bool HasEdges () const
{ return buildedges; }
bool HasFaces () const
{ return buildfaces; }
2018-01-04 15:48:45 +05:00
void Update(TaskManager tm = &DummyTaskManager, Tracer tracer = &DummyTracer);
2009-01-13 04:40:13 +05:00
2009-11-01 02:03:52 +05:00
int GetNEdges () const { return edge2vert.Size(); }
int GetNFaces () const { return face2vert.Size(); }
2009-01-13 04:40:13 +05:00
2016-01-07 17:37:48 +05:00
static inline short int GetNVertices (ELEMENT_TYPE et);
static inline short int GetNPoints (ELEMENT_TYPE et);
static inline short int GetNEdges (ELEMENT_TYPE et);
static inline short int GetNFaces (ELEMENT_TYPE et);
2009-01-13 04:40:13 +05:00
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 const ELEMENT_FACE * GetFaces1 (ELEMENT_TYPE et);
inline static const ELEMENT_FACE * GetFaces0 (ELEMENT_TYPE et);
2009-01-13 04:40:13 +05:00
2014-01-07 16:42:39 +06:00
int GetSegmentEdge (int segnr) const { return segedges[segnr-1].nr+1; }
int GetEdge (SegmentIndex segnr) const { return segedges[segnr].nr; }
2009-01-13 04:40:13 +05:00
void GetSegmentEdge (int segnr, int & enr, int & orient) const
{
2014-01-07 16:42:39 +06:00
enr = segedges.Get(segnr).nr+1;
// orient = segedges.Get(segnr).orient;
orient = GetSegmentEdgeOrientation(segnr);
2009-01-13 04:40:13 +05:00
}
2009-01-25 17:35:25 +05:00
void GetElementEdges (int elnr, Array<int> & edges) const;
void GetElementFaces (int elnr, Array<int> & faces, bool withorientation = false) const;
void GetElementEdgeOrientations (int elnr, Array<int> & eorient) const;
void GetElementFaceOrientations (int elnr, Array<int> & forient) const;
2009-01-13 04:40:13 +05:00
int GetElementEdges (int elnr, int * edges, int * orient) const;
int GetElementFaces (int elnr, int * faces, int * orient) const;
int GetElementEdgeOrientation (int elnr, int locedgenr) const; // old style
int GetElementFaceOrientation (int elnr, int locfacenr) const; // old style
int GetSurfaceElementEdgeOrientation (int elnr, int locedgenr) const; // old style
int GetSurfaceElementFaceOrientation2 (int elnr) const; // old style
int GetSegmentEdgeOrientation (int elnr) const; // old style
2009-01-25 17:35:25 +05:00
void GetFaceVertices (int fnr, Array<int> & vertices) const;
2009-01-13 04:40:13 +05:00
void GetFaceVertices (int fnr, int * vertices) const;
2009-07-20 14:36:36 +06:00
void GetEdgeVertices (int enr, int & v1, int & v2) const;
2012-08-20 20:10:23 +06:00
void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const;
2009-07-20 14:36:36 +06:00
const int * GetEdgeVerticesPtr (int enr) const { return &edge2vert[enr][0]; }
2010-05-17 15:00:30 +06:00
const int * GetFaceVerticesPtr (int fnr) const { return &face2vert[fnr][0]; }
2009-01-25 17:35:25 +05:00
void GetFaceEdges (int fnr, Array<int> & edges, bool withorientation = false) const;
2009-01-13 04:40:13 +05:00
2017-02-16 02:30:48 +05:00
ELEMENT_TYPE GetFaceType (int fnr) const
{ return (face2vert.Get(fnr)[3] == 0) ? TRIG : QUAD; }
2009-01-13 04:40:13 +05:00
2009-01-25 17:35:25 +05:00
void GetSurfaceElementEdges (int elnr, Array<int> & edges) const;
2009-01-13 04:40:13 +05:00
int GetSurfaceElementFace (int elnr) const;
2009-01-25 17:35:25 +05:00
void GetSurfaceElementEdgeOrientations (int elnr, Array<int> & eorient) const;
2009-01-13 04:40:13 +05:00
int GetSurfaceElementFaceOrientation (int elnr) const;
2012-08-20 20:10:23 +06:00
void GetEdges (SurfaceElementIndex elnr, Array<int> & edges) const;
2017-02-16 02:30:48 +05:00
int GetFace (SurfaceElementIndex elnr) const
{ return surffaces[elnr].fnr; }
2009-01-13 04:40:13 +05:00
int GetSurfaceElementEdges (int elnr, int * edges, int * orient) const;
2014-01-07 16:42:39 +06:00
const T_EDGE * GetElementEdgesPtr (int elnr) const { return &edges[elnr][0]; }
const T_EDGE * GetSurfaceElementEdgesPtr (int selnr) const { return &surfedges[selnr][0]; }
const T_EDGE * GetSegmentElementEdgesPtr (int selnr) const { return &segedges[selnr]; }
2009-07-13 19:03:01 +06:00
2014-01-07 16:42:39 +06:00
const T_FACE * GetElementFacesPtr (int elnr) const { return &faces[elnr][0]; }
const T_FACE * GetSurfaceElementFacesPtr (int selnr) const { return &surffaces[selnr]; }
2009-07-13 19:03:01 +06:00
2009-01-13 04:40:13 +05:00
void GetSurface2VolumeElement (int selnr, int & elnr1, int & elnr2) const
{
elnr1 = surf2volelement.Get(selnr)[0];
elnr2 = surf2volelement.Get(selnr)[1];
}
int GetFace2SurfaceElement (int fnr) const { return face2surfel[fnr-1]; }
2012-08-20 20:10:23 +06:00
void GetVertexElements (int vnr, Array<ElementIndex> & elements) const;
2016-03-23 12:17:45 +05:00
FlatArray<ElementIndex> GetVertexElements (int vnr) const
{ return vert2element[vnr]; }
2009-01-13 04:40:13 +05:00
void GetVertexSurfaceElements( int vnr, Array<SurfaceElementIndex>& elements ) const;
2016-03-23 12:17:45 +05:00
FlatArray<SurfaceElementIndex> GetVertexSurfaceElements (int vnr) const
{ return vert2surfelement[vnr]; }
2009-01-13 04:40:13 +05:00
2016-03-23 12:17:45 +05:00
FlatArray<SegmentIndex> GetVertexSegments (int vnr) const
{ return vert2segment[vnr]; }
2016-08-17 17:51:02 +05:00
FlatArray<int> GetVertexPointElements (int vnr) const
{ return vert2pointelement[vnr]; }
2009-01-13 04:40:13 +05:00
int GetVerticesEdge ( int v1, int v2) const;
void GetSegmentVolumeElements ( int segnr, Array<ElementIndex> & els ) const;
void GetSegmentSurfaceElements ( int segnr, Array<SurfaceElementIndex> & els ) const;
2009-01-13 04:40:13 +05:00
};
2016-01-07 17:37:48 +05:00
inline short int MeshTopology :: GetNVertices (ELEMENT_TYPE et)
2009-07-13 19:03:01 +06:00
{
switch (et)
{
case SEGMENT:
case SEGMENT3:
return 2;
case TRIG:
case TRIG6:
return 3;
case QUAD:
case QUAD6:
case QUAD8:
return 4;
case TET:
case TET10:
return 4;
case PYRAMID:
return 5;
case PRISM:
case PRISM12:
return 6;
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
2009-07-13 19:03:01 +06:00
return 8;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl;
2009-07-13 19:03:01 +06:00
}
return 0;
}
2016-01-07 17:37:48 +05:00
inline short int MeshTopology :: GetNPoints (ELEMENT_TYPE et)
2009-07-13 19:03:01 +06:00
{
switch (et)
{
case SEGMENT:
return 2;
case SEGMENT3:
return 3;
case TRIG:
return 3;
case TRIG6:
return 6;
case QUAD:
case QUAD6:
return 4;
2019-01-18 02:08:35 +05:00
case QUAD8:
return 8;
2009-07-13 19:03:01 +06:00
case TET:
return 4;
case TET10:
return 10;
case PYRAMID:
return 5;
case PRISM:
case PRISM12:
return 6;
case HEX:
return 8;
2019-01-18 02:08:35 +05:00
case HEX20:
return 20;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl;
2009-07-13 19:03:01 +06:00
}
return 0;
}
2016-01-07 17:37:48 +05:00
inline short int MeshTopology :: GetNEdges (ELEMENT_TYPE et)
2009-07-13 19:03:01 +06:00
{
2016-01-07 17:37:48 +05:00
__assume(et >= SEGMENT && et <= HEX);
2009-07-13 19:03:01 +06:00
switch (et)
{
case SEGMENT:
case SEGMENT3:
return 1;
case TRIG:
case TRIG6:
return 3;
case QUAD:
case QUAD6:
case QUAD8:
return 4;
case TET:
case TET10:
return 6;
case PYRAMID:
return 8;
case PRISM:
case PRISM12:
return 9;
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
2009-07-13 19:03:01 +06:00
return 12;
2016-01-07 17:37:48 +05:00
default:
return 0;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl;
2009-07-13 19:03:01 +06:00
}
2016-01-07 17:37:48 +05:00
// return 0;
2009-07-13 19:03:01 +06:00
}
2016-01-07 17:37:48 +05:00
inline short int MeshTopology :: GetNFaces (ELEMENT_TYPE et)
2009-07-13 19:03:01 +06:00
{
2016-01-07 17:37:48 +05:00
__assume(et >= SEGMENT && et <= HEX);
2009-07-13 19:03:01 +06:00
switch (et)
{
case SEGMENT:
case SEGMENT3:
return 0;
case TRIG:
case TRIG6:
return 1;
case QUAD:
case QUAD6:
case QUAD8:
return 1;
case TET:
case TET10:
return 4;
case PYRAMID:
return 5;
case PRISM:
case PRISM12:
return 5;
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
2009-07-13 19:03:01 +06:00
return 6;
2016-01-07 17:37:48 +05:00
default:
return -99;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl;
2009-07-13 19:03:01 +06:00
}
}
2009-01-13 04:40:13 +05:00
const ELEMENT_EDGE * MeshTopology :: GetEdges1 (ELEMENT_TYPE et)
2009-01-13 04:40:13 +05:00
{
static ELEMENT_EDGE segm_edges[1] =
2009-01-13 04:40:13 +05:00
{ { 1, 2 }};
static ELEMENT_EDGE trig_edges[3] =
2009-01-13 04:40:13 +05:00
{ { 3, 1 },
{ 2, 3 },
{ 1, 2 }};
static ELEMENT_EDGE quad_edges[4] =
2009-01-13 04:40:13 +05:00
{ { 1, 2 },
{ 3, 4 },
{ 4, 1 },
{ 2, 3 }};
static ELEMENT_EDGE tet_edges[6] =
2009-01-13 04:40:13 +05:00
{ { 4, 1 },
{ 4, 2 },
{ 4, 3 },
{ 1, 2 },
{ 1, 3 },
{ 2, 3 }};
static ELEMENT_EDGE prism_edges[9] =
2009-01-13 04:40:13 +05:00
{ { 3, 1 },
{ 1, 2 },
{ 3, 2 },
{ 6, 4 },
{ 4, 5 },
{ 6, 5 },
{ 3, 6 },
{ 1, 4 },
{ 2, 5 }};
static ELEMENT_EDGE pyramid_edges[8] =
2009-01-13 04:40:13 +05:00
{ { 1, 2 },
{ 2, 3 },
{ 1, 4 },
{ 4, 3 },
{ 1, 5 },
{ 2, 5 },
{ 3, 5 },
{ 4, 5 }};
static ELEMENT_EDGE hex_edges[12] =
2009-01-13 04:40:13 +05:00
{
{ 1, 2 },
{ 3, 4 },
{ 4, 1 },
{ 2, 3 },
{ 5, 6 },
{ 7, 8 },
{ 8, 5 },
{ 6, 7 },
{ 1, 5 },
{ 2, 6 },
{ 3, 7 },
{ 4, 8 },
};
switch (et)
{
case SEGMENT:
case SEGMENT3:
return segm_edges;
case TRIG:
case TRIG6:
return trig_edges;
case QUAD:
case QUAD6:
case QUAD8:
return quad_edges;
case TET:
case TET10:
return tet_edges;
case PYRAMID:
return pyramid_edges;
case PRISM:
case PRISM12:
return prism_edges;
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
2009-01-13 04:40:13 +05:00
return hex_edges;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetEdges, illegal element type " << et << endl;
2009-01-13 04:40:13 +05:00
}
return 0;
}
const ELEMENT_EDGE * MeshTopology :: GetEdges0 (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 },
};
2019-01-18 02:08:35 +05:00
switch (et)
{
case SEGMENT:
case SEGMENT3:
return segm_edges;
case TRIG:
case TRIG6:
return trig_edges;
case QUAD:
case QUAD6:
case QUAD8:
return quad_edges;
case TET:
case TET10:
return tet_edges;
case PYRAMID:
return pyramid_edges;
case PRISM:
case PRISM12:
return prism_edges;
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
return hex_edges;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetEdges, illegal element type " << et << endl;
}
return 0;
}
2014-01-07 16:42:39 +06:00
inline const ELEMENT_FACE * MeshTopology :: GetFaces1 (ELEMENT_TYPE et)
2009-01-13 04:40:13 +05:00
{
static const ELEMENT_FACE trig_faces[1] =
2009-01-13 04:40:13 +05:00
{ { 1, 2, 3, 0 } };
static const ELEMENT_FACE quad_faces[1] =
2009-01-13 04:40:13 +05:00
{ { 1, 2, 3, 4 } };
static const ELEMENT_FACE tet_faces[4] =
2009-01-13 04:40:13 +05:00
{ { 4, 2, 3, 0 },
{ 4, 3, 1, 0 },
{ 4, 1, 2, 0 },
{ 1, 3, 2, 0 } };
static const ELEMENT_FACE prism_faces[5] =
2009-01-13 04:40:13 +05:00
{
{ 1, 3, 2, 0 },
{ 4, 5, 6, 0 },
{ 3, 1, 4, 6 },
{ 1, 2, 5, 4 },
{ 2, 3, 6, 5 }
};
static const ELEMENT_FACE pyramid_faces[5] =
2009-01-13 04:40:13 +05:00
{
{ 1, 2, 5, 0 },
{ 2, 3, 5, 0 },
{ 3, 4, 5, 0 },
{ 4, 1, 5, 0 },
{ 1, 4, 3, 2 }
};
static const ELEMENT_FACE hex_faces[6] =
2009-01-13 04:40:13 +05:00
{
{ 1, 4, 3, 2 },
{ 5, 6, 7, 8 },
{ 1, 2, 6, 5 },
{ 2, 3, 7, 6 },
{ 3, 4, 8, 7 },
{ 4, 1, 5, 8 }
};
switch (et)
{
case TRIG:
case TRIG6:
return trig_faces;
case QUAD:
case QUAD6:
case QUAD8:
return quad_faces;
case TET:
case TET10:
return tet_faces;
case PRISM:
case PRISM12:
return prism_faces;
case PYRAMID:
return pyramid_faces;
case SEGMENT:
case SEGMENT3:
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
2009-01-13 04:40:13 +05:00
return hex_faces;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetVertices, illegal element type " << et << endl;
2009-01-13 04:40:13 +05:00
}
return 0;
}
2014-01-07 16:42:39 +06:00
inline const ELEMENT_FACE * MeshTopology :: GetFaces0 (ELEMENT_TYPE et)
{
static const ELEMENT_FACE trig_faces[1] =
{ { 0, 1, 2, -1 } };
static const ELEMENT_FACE quad_faces[1] =
{ { 0, 1, 2, 3 } };
static const ELEMENT_FACE tet_faces[4] =
{ { 3, 1, 2, -1 },
{ 3, 2, 0, -1 },
{ 3, 0, 1, -1 },
{ 0, 2, 1, -1 } };
static const ELEMENT_FACE prism_faces[5] =
{
{ 0, 2, 1, -1 },
{ 3, 4, 5, -1 },
{ 2, 0, 3, 5 },
{ 0, 1, 4, 3 },
{ 1, 2, 5, 4 }
};
static const ELEMENT_FACE pyramid_faces[5] =
{
{ 0, 1, 4, -1 },
{ 1, 2, 4, -1 },
{ 2, 3, 4, -1 },
{ 3, 0, 4, -1 },
{ 0, 3, 2, 1 }
};
static const ELEMENT_FACE hex_faces[6] =
{
{ 0, 3, 2, 1 },
{ 4, 5, 6, 7 },
{ 0, 1, 5, 4 },
{ 1, 2, 6, 5 },
{ 2, 3, 7, 6 },
{ 3, 0, 4, 7 }
};
switch (et)
{
case TRIG:
case TRIG6:
return trig_faces;
case QUAD:
case QUAD6:
case QUAD8:
return quad_faces;
case TET:
case TET10:
return tet_faces;
case PRISM:
case PRISM12:
return prism_faces;
case PYRAMID:
return pyramid_faces;
case SEGMENT:
case SEGMENT3:
case HEX:
2019-01-18 02:08:35 +05:00
case HEX20:
return hex_faces;
2014-01-07 16:42:39 +06:00
// default:
// cerr << "Ng_ME_GetVertices, illegal element type " << et << endl;
}
return 0;
}
2016-01-07 17:37:48 +05:00
}
2009-01-13 04:40:13 +05:00
#endif