48 #ifndef __INTREPID2_ORIENTATION_DEF_HPP__ 49 #define __INTREPID2_ORIENTATION_DEF_HPP__ 52 #if defined (__clang__) && !defined (__INTEL_COMPILER) 53 #pragma clang system_header 62 template<
typename elemNodeViewType>
65 Orientation::getElementNodeMap(
typename elemNodeViewType::non_const_value_type *subCellVerts,
66 ordinal_type &numVerts,
67 const shards::CellTopology cellTopo,
68 const elemNodeViewType elemNodes,
69 const ordinal_type subCellDim,
70 const ordinal_type subCellOrd) {
71 static_assert(Kokkos::Impl::MemorySpaceAccess
72 <Kokkos::HostSpace,
typename elemNodeViewType::device_type::memory_space>::accessible,
73 "host space cannot access elemNodeViewType");
77 subCellVerts[0] = elemNodes(subCellOrd);
81 numVerts = cellTopo.getVertexCount(subCellDim, subCellOrd);
82 for (ordinal_type i=0;i<numVerts;++i)
83 subCellVerts[i] = elemNodes(cellTopo.getNodeMap(subCellDim, subCellOrd, i));
89 template<
typename subCellVertType>
92 Orientation::getOrientation(
const subCellVertType subCellVerts[],
93 const ordinal_type numVerts) {
97 #ifdef HAVE_INTREPID2_DEBUG 98 INTREPID2_TEST_FOR_ABORT( ( subCellVerts[0] == subCellVerts[1] ),
99 ">>> ERROR (Intrepid::Orientation::getOrientation): " \
100 "Invalid subCellVerts, same vertex ids are repeated");
102 ort = (subCellVerts[0] > subCellVerts[1]);
106 #ifdef HAVE_INTREPID2_DEBUG 107 INTREPID2_TEST_FOR_ABORT( ( subCellVerts[0] == subCellVerts[1] ||
108 subCellVerts[0] == subCellVerts[2] ||
109 subCellVerts[1] == subCellVerts[2] ),
110 ">>> ERROR (Intrepid::Orientation::getOrientation): " \
111 "Invalid subCellVerts, same vertex ids are repeated");
113 ordinal_type rotation = 0;
114 for (ordinal_type i=1;i<3;++i)
115 rotation = ( subCellVerts[i] < subCellVerts[rotation] ? i : rotation );
117 const ordinal_type axes[][2] = { {1,2}, {2,0}, {0,1} };
118 const ordinal_type flip = (subCellVerts[axes[rotation][0]] > subCellVerts[axes[rotation][1]]);
120 ort = flip*3 + rotation;
124 #ifdef HAVE_INTREPID2_DEBUG 125 INTREPID2_TEST_FOR_ABORT( ( subCellVerts[0] == subCellVerts[1] ||
126 subCellVerts[0] == subCellVerts[2] ||
127 subCellVerts[0] == subCellVerts[3] ||
128 subCellVerts[1] == subCellVerts[2] ||
129 subCellVerts[1] == subCellVerts[3] ||
130 subCellVerts[2] == subCellVerts[3] ),
131 ">>> ERROR (Intrepid::Orientation::getGlobalVertexNodes): " \
132 "Invalid subCellVerts, same vertex ids are repeated");
134 ordinal_type rotation = 0;
135 for (ordinal_type i=1;i<4;++i)
136 rotation = ( subCellVerts[i] < subCellVerts[rotation] ? i : rotation );
138 const ordinal_type axes[][2] = { {1,3}, {2,0}, {3,1}, {0,2} };
139 const ordinal_type flip = (subCellVerts[axes[rotation][0]] > subCellVerts[axes[rotation][1]]);
141 ort = flip*4 + rotation;
145 INTREPID2_TEST_FOR_ABORT(
true,
146 ">>> ERROR (Intrepid::Orientation::getOrientation): " \
147 "Invalid numVerts (2 (edge),3 (triangle) and 4 (quadrilateral) are allowed)");
154 template<
typename elemNodeViewType>
157 Orientation::getOrientation(
const shards::CellTopology cellTopo,
158 const elemNodeViewType elemNodes) {
159 static_assert(Kokkos::Impl::MemorySpaceAccess
160 <Kokkos::HostSpace,
typename elemNodeViewType::device_type::memory_space>::accessible,
161 "host space cannot access elemNodeViewType");
164 const ordinal_type nedge = cellTopo.getEdgeCount();
167 typename elemNodeViewType::non_const_value_type vertsSubCell[2];
168 ordinal_type orts[12], nvertSubCell;
169 for (ordinal_type i=0;i<nedge;++i) {
170 Orientation::getElementNodeMap(vertsSubCell,
175 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
177 ort.setEdgeOrientation(nedge, orts);
179 const ordinal_type nface = cellTopo.getFaceCount();
181 typename elemNodeViewType::non_const_value_type vertsSubCell[4];
182 ordinal_type orts[6], nvertSubCell;
183 for (ordinal_type i=0;i<nface;++i) {
184 Orientation::getElementNodeMap(vertsSubCell,
189 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
191 ort.setFaceOrientation(nface, orts);
198 Orientation::getEdgeOrdinalOfFace(
const ordinal_type subsubcellOrd,
199 const ordinal_type subcellOrd,
200 const shards::CellTopology cellTopo) {
201 ordinal_type r_val = -1;
203 const auto cellBaseKey = cellTopo.getBaseKey();
204 if (cellBaseKey == shards::Hexahedron<>::key) {
205 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 6) &&
206 !(subsubcellOrd < 4),
208 "subcell and subsubcell information are not correct" );
209 const int quad_to_hex_edges[6][4] = { { 0, 9, 4, 8 },
215 r_val = quad_to_hex_edges[subcellOrd][subsubcellOrd];
216 }
else if (cellBaseKey == shards::Tetrahedron<>::key) {
217 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 4) &&
218 !(subsubcellOrd < 3),
220 "subcell and subsubcell information are not correct" );
221 const ordinal_type tri_to_tet_edges[4][3] = { { 0, 4, 3 },
225 r_val = tri_to_tet_edges[subcellOrd][subsubcellOrd];
227 INTREPID2_TEST_FOR_EXCEPTION(
true, std::logic_error,
228 "cellTopo is not supported: try TET and HEX" );
462 KOKKOS_INLINE_FUNCTION
463 Orientation::Orientation()
464 : _edgeOrt(0), _faceOrt(0) {}
466 KOKKOS_INLINE_FUNCTION
468 Orientation::isAlignedToReference()
const {
469 return (_edgeOrt == 0 && _faceOrt == 0);
472 KOKKOS_INLINE_FUNCTION
474 Orientation::setEdgeOrientation(
const ordinal_type numEdge,
const ordinal_type edgeOrt[]) {
475 #ifdef HAVE_INTREPID2_DEBUG 476 INTREPID2_TEST_FOR_ABORT( !( 3 <= numEdge && numEdge <= 12 ),
477 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
478 "Invalid numEdge (3--12)");
481 for (ordinal_type i=0;i<numEdge;++i)
482 _edgeOrt |= (edgeOrt[i] & 1) << i;
485 KOKKOS_INLINE_FUNCTION
487 Orientation::getEdgeOrientation(ordinal_type *edgeOrt,
const ordinal_type numEdge)
const {
488 #ifdef HAVE_INTREPID2_DEBUG 489 INTREPID2_TEST_FOR_ABORT( !( 3 <= numEdge && numEdge <= 12 ),
490 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
491 "Invalid numEdge (3--12)");
493 for (ordinal_type i=0;i<numEdge;++i)
494 edgeOrt[i] = (_edgeOrt & (1 << i)) >> i;
497 KOKKOS_INLINE_FUNCTION
499 Orientation::setFaceOrientation(
const ordinal_type numFace,
const ordinal_type faceOrt[]) {
500 #ifdef HAVE_INTREPID2_DEBUG 501 INTREPID2_TEST_FOR_ABORT( !( 4 <= numFace && numFace <= 6 ),
502 ">>> ERROR (Intrepid::Orientation::setFaceOrientation): " 503 "Invalid numFace (4--6)");
506 for (ordinal_type i=0;i<numFace;++i) {
507 const ordinal_type s = i*3;
508 _faceOrt |= (faceOrt[i] & 7) << s;
512 KOKKOS_INLINE_FUNCTION
514 Orientation::getFaceOrientation(ordinal_type *faceOrt,
const ordinal_type numFace)
const {
515 #ifdef HAVE_INTREPID2_DEBUG 516 INTREPID2_TEST_FOR_ABORT( !( 4 <= numFace && numFace <= 6 ),
517 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " 518 "Invalid numFace (4--6)");
520 for (ordinal_type i=0;i<numFace;++i) {
521 const ordinal_type s = i*3;
522 faceOrt[i] = (_faceOrt & (7 << s)) >> s;
526 inline std::string Orientation::to_string()
const {
527 return "Orientation{ face: " + std::to_string(_faceOrt) +
"; edge: " + std::to_string(_edgeOrt) +
" }";