#ifndef TOPOLOGY #define TOPOLOGY /**************************************************************************/ /* File: topology.hh */ /* Author: Joachim Schoeberl */ /* Date: 27. Apr. 01 */ /**************************************************************************/ /* Mesh topology (Elements, Faces, Edges, Vertices */ namespace netgen { typedef int T_EDGE; typedef int T_FACE; class MeshTopology { const Mesh * mesh; bool buildvertex2element; bool buildedges; bool buildfaces; bool build_parent_edges = 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; Array> edge2vert; Array> face2vert; NgArray> edges; NgArray> faces; NgArray> surfedges; NgArray segedges; NgArray surffaces; NgArray surf2volelement; NgArray face2surfel; Array edge2segment; Table vert2element; Table vert2surfelement; Table vert2segment; Table vert2pointelement; int timestamp; public: int GetNSurfedges() const {return surfedges.Size();} MeshTopology () = default; MeshTopology (MeshTopology && top) = default; MeshTopology (const Mesh & amesh); ~MeshTopology (); MeshTopology & operator= (MeshTopology && top) = default; void SetBuildVertex2Element (bool bv2e) { buildvertex2element = bv2e; } void SetBuildEdges (bool be) { buildedges = be; } void SetBuildFaces (bool bf) { buildfaces = bf; } void SetBuildParentEdges (bool bh) { build_parent_edges = bh; } void SetBuildParentFaces (bool bh) { build_parent_faces = bh; } void EnableTable (string name, bool set); static void EnableTableStatic (string name, bool set); bool HasEdges () const { return buildedges; } bool HasFaces () const { return buildfaces; } bool HasParentEdges () const { return build_parent_edges; } void Update(NgTaskManager tm = &DummyTaskManager, NgTracer tracer = &DummyTracer); bool NeedsUpdate() const; int GetNEdges () const { return edge2vert.Size(); } int GetNFaces () const { return face2vert.Size(); } 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); DLL_HEADER 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 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; // orient = segedges.Get(segnr).orient; orient = GetSegmentEdgeOrientation(segnr); } */ [[deprecated("use GetEdges (ElementIndex) -> FlatArray")]] void GetElementEdges (int elnr, NgArray & edges) const; [[deprecated("use GetFaces (ElementIndex) -> FlatArray")]] void GetElementFaces (int elnr, NgArray & faces) const; void GetElementFaces (int elnr, NgArray & faces, bool withorientation) const; // definition in meshclass.hpp inline FlatArray GetEdges (ElementIndex elnr) const; inline FlatArray GetFaces (ElementIndex elnr) const; // [[deprecated("use GetElementEdge instead")]] void GetElementEdgeOrientations (int elnr, NgArray & eorient) const; // [[deprecated("use GetElementEdge instead")]] void GetElementFaceOrientations (int elnr, NgArray & forient) const; [[deprecated("use GetEdges (ElementIndex) -> FlatArray")]] int GetElementEdges (int elnr, int * edges, int * orient) const; // [[deprecated("use GetFaces (ElementIndex) -> FlatArray")]] 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 DLL_HEADER void GetFaceVertices (int fnr, NgArray & vertices) const; DLL_HEADER void GetFaceVertices (int fnr, int * vertices) const; [[deprecated("use GetEdgeVertices -> tupe(v0,v1) instead")]] DLL_HEADER void GetEdgeVertices (int enr, int & v1, int & v2) const; [[deprecated("use GetEdgeVertices -> tupe(v0,v1) instead")]] DLL_HEADER void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const; 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]; } DLL_HEADER void GetFaceEdges (int fnr, NgArray & edges, bool withorientation = false) const; ELEMENT_TYPE GetFaceType (int fnr) const // { return (face2vert.Get(fnr)[3] == 0) ? TRIG : QUAD; } { return (face2vert[fnr-1][3] == 0) ? TRIG : QUAD; } void GetSurfaceElementEdges (int elnr, NgArray & edges) const; int GetSurfaceElementFace (int elnr) const; [[deprecated("orientation is outdated")]] void GetSurfaceElementEdgeOrientations (int elnr, NgArray & eorient) const; // [[deprecated("orientation is outdated")]] int GetSurfaceElementFaceOrientation (int elnr) const; [[deprecated("use GetEdge -> FlatArray instead")]] void GetEdges (SurfaceElementIndex elnr, NgArray & edges) const; inline FlatArray GetEdges (SurfaceElementIndex elnr) const; // { return FlatArray(GetNEdges ( (*mesh)[elnr].GetType()), &surfedges[elnr][0]); } int GetFace (SurfaceElementIndex elnr) const { return surffaces[elnr]; } int GetSurfaceElementEdges (int elnr, int * edges, int * orient) const; 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]; } const T_FACE * GetElementFacesPtr (int elnr) const { return &faces[elnr][0]; } const T_FACE * GetSurfaceElementFacesPtr (int selnr) const { return &surffaces[selnr]; } 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]; } SegmentIndex GetSegmentOfEdge(int edgenr) const { return edge2segment[edgenr-1]; } [[deprecated("use GetVertexElements -> FlatArray instead")]] void GetVertexElements (int vnr, Array & elements) const; FlatArray GetVertexElements (PointIndex vnr) const { return vert2element[vnr]; } [[deprecated("use GetVertexSurfaceElements -> FlatArray instead")]] void GetVertexSurfaceElements( int vnr, Array& elements ) const; const auto & GetVertexSurfaceElements( ) const { return vert2surfelement; } FlatArray GetVertexSurfaceElements(PointIndex vnr) const { return vert2surfelement[vnr]; } FlatArray GetVertexSegments (PointIndex vnr) const { return vert2segment[vnr]; } FlatArray GetVertexPointElements (PointIndex vnr) const { return vert2pointelement[vnr]; } DLL_HEADER int GetVerticesEdge ( int v1, int v2) const; void GetSegmentVolumeElements ( int segnr, NgArray & els ) const; void GetSegmentSurfaceElements ( int segnr, NgArray & els ) const; // Call this before Update() to discard old edges void ClearEdges() { edge2vert.SetSize0(); } private: Array>> parent_edges; void BuildParentEdges (); Array>> parent_faces; void BuildParentFaces (); public: auto GetParentEdges (int enr) const { return parent_edges[enr]; } auto GetParentFaces (int fnr) const { return parent_faces[fnr]; } }; inline short int MeshTopology :: GetNVertices (ELEMENT_TYPE et) { 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: case PYRAMID13: return 5; case PRISM: case PRISM12: case PRISM15: return 6; case HEX: case HEX20: return 8; // default: // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; } return 0; } inline short int MeshTopology :: GetNPoints (ELEMENT_TYPE et) { switch (et) { case SEGMENT: return 2; case SEGMENT3: return 3; case TRIG: return 3; case TRIG6: return 6; case QUAD: case QUAD6: return 4; case QUAD8: return 8; case TET: return 4; case TET10: return 10; case PYRAMID: return 5; case PYRAMID13: return 13; case PRISM: return 6; case PRISM12: return 12; case PRISM15: return 15; case HEX: return 8; case HEX20: return 20; // default: // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; } return 0; } inline short int MeshTopology :: GetNEdges (ELEMENT_TYPE et) { __assume(et >= SEGMENT && et <= PYRAMID13); 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: case PYRAMID13: return 8; case PRISM: case PRISM12: case PRISM15: return 9; case HEX: case HEX20: return 12; default: return 0; // default: // cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl; } // return 0; } inline short int MeshTopology :: GetNFaces (ELEMENT_TYPE et) { __assume(et >= SEGMENT && et <= PYRAMID13); 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: case PYRAMID13: return 5; case PRISM: case PRISM12: case PRISM15: return 5; case HEX: case HEX20: return 6; default: return -99; // default: // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; } } const ELEMENT_EDGE * MeshTopology :: GetEdges1 (ELEMENT_TYPE et) { static ELEMENT_EDGE segm_edges[1] = { { 1, 2 }}; static ELEMENT_EDGE trig_edges[3] = { { 3, 1 }, { 2, 3 }, { 1, 2 }}; static ELEMENT_EDGE quad_edges[4] = { { 1, 2 }, { 3, 4 }, { 4, 1 }, { 2, 3 }}; static ELEMENT_EDGE tet_edges[6] = { { 4, 1 }, { 4, 2 }, { 4, 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 }}; static ELEMENT_EDGE prism_edges[9] = { { 3, 1 }, { 1, 2 }, { 3, 2 }, { 6, 4 }, { 4, 5 }, { 6, 5 }, { 3, 6 }, { 1, 4 }, { 2, 5 }}; static ELEMENT_EDGE pyramid_edges[8] = { { 1, 2 }, { 2, 3 }, { 1, 4 }, { 4, 3 }, { 1, 5 }, { 2, 5 }, { 3, 5 }, { 4, 5 }}; static ELEMENT_EDGE hex_edges[12] = { { 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: case PYRAMID13: return pyramid_edges; case PRISM: case PRISM12: case PRISM15: return prism_edges; case HEX: case HEX20: return hex_edges; // default: // cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; } 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 }, }; 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: case PYRAMID13: return pyramid_edges; case PRISM: case PRISM12: case PRISM15: return prism_edges; case HEX: case HEX20: return hex_edges; // default: // cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; } return 0; } FlatArray 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 }; } inline const ELEMENT_FACE * MeshTopology :: GetFaces1 (ELEMENT_TYPE et) { static const ELEMENT_FACE trig_faces[1] = { { 1, 2, 3, 0 } }; static const ELEMENT_FACE quad_faces[1] = { { 1, 2, 3, 4 } }; static const ELEMENT_FACE tet_faces[4] = { { 4, 2, 3, 0 }, { 4, 3, 1, 0 }, { 4, 1, 2, 0 }, { 1, 3, 2, 0 } }; static const ELEMENT_FACE prism_faces[5] = { { 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] = { { 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] = { { 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: case PRISM15: return prism_faces; case PYRAMID: case PYRAMID13: return pyramid_faces; case SEGMENT: case SEGMENT3: case HEX: case HEX20: return hex_faces; // default: // cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; } return 0; } 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: case PRISM15: return prism_faces; case PYRAMID: case PYRAMID13: return pyramid_faces; case SEGMENT: case SEGMENT3: case HEX: case HEX20: return hex_faces; // default: // cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; } return 0; } } #endif