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 cellVertViewType>
65 Orientation::getCellVertexMap(
typename cellVertViewType::non_const_value_type *subCellVerts,
66 ordinal_type &numVerts,
67 const shards::CellTopology cellTopo,
68 const cellVertViewType cellVertices,
69 const ordinal_type subCellDim,
70 const ordinal_type subCellOrd) {
71 static_assert(Kokkos::Impl::MemorySpaceAccess
72 <Kokkos::HostSpace,
typename cellVertViewType::device_type::memory_space>::accessible,
73 "host space cannot access cellVertViewType");
77 subCellVerts[0] = cellVertices(subCellOrd);
81 numVerts = cellTopo.getVertexCount(subCellDim, subCellOrd);
82 for (ordinal_type i=0;i<numVerts;++i)
83 subCellVerts[i] = cellVertices(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::getOrientation): " \
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 cellVertViewType>
157 Orientation::getOrientation(
const shards::CellTopology cellTopo,
158 const cellVertViewType cellVertices,
160 static_assert(Kokkos::Impl::MemorySpaceAccess
161 <Kokkos::HostSpace,
typename cellVertViewType::device_type::memory_space>::accessible,
162 "host space cannot access cellVertViewType");
165 auto dim = cellTopo.getDimension();
166 const ordinal_type nedge = (isSide && dim==1) ? 1 : cellTopo.getEdgeCount();
169 typename cellVertViewType::non_const_value_type vertsSubCell[2];
170 ordinal_type orts[12], nvertSubCell;
171 for (ordinal_type i=0;i<nedge;++i) {
172 Orientation::getCellVertexMap(vertsSubCell,
177 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
181 const ordinal_type nface = (isSide && dim==2) ? 1 : cellTopo.getFaceCount();
183 typename cellVertViewType::non_const_value_type vertsSubCell[4];
184 ordinal_type orts[6], nvertSubCell;
185 for (ordinal_type i=0;i<nface;++i) {
186 Orientation::getCellVertexMap(vertsSubCell,
191 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
201 const ordinal_type subcellOrd,
202 const shards::CellTopology cellTopo) {
203 ordinal_type r_val = -1;
205 const auto cellBaseKey = cellTopo.getBaseKey();
206 if (cellBaseKey == shards::Hexahedron<>::key) {
207 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 6) &&
208 !(subsubcellOrd < 4),
210 "subcell and subsubcell information are not correct" );
211 const int quad_to_hex_edges[6][4] = { { 0, 9, 4, 8 },
217 r_val = quad_to_hex_edges[subcellOrd][subsubcellOrd];
218 }
else if (cellBaseKey == shards::Tetrahedron<>::key) {
219 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 4) &&
220 !(subsubcellOrd < 3),
222 "subcell and subsubcell information are not correct" );
223 const ordinal_type tri_to_tet_edges[4][3] = { { 0, 4, 3 },
227 r_val = tri_to_tet_edges[subcellOrd][subsubcellOrd];
229 INTREPID2_TEST_FOR_EXCEPTION(
true, std::logic_error,
230 "cellTopo is not supported: try TET and HEX" );
235 KOKKOS_INLINE_FUNCTION
237 : _edgeOrt(0), _faceOrt(0) {}
239 KOKKOS_INLINE_FUNCTION
242 return (_edgeOrt == 0 && _faceOrt == 0);
245 KOKKOS_INLINE_FUNCTION
248#ifdef HAVE_INTREPID2_DEBUG
249 INTREPID2_TEST_FOR_ABORT( !((numEdge == 1) || (3 <= numEdge && numEdge <= 12 )),
250 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
254 for (ordinal_type i=0;i<numEdge;++i)
255 _edgeOrt |= (edgeOrt[i] & 1) << i;
258 KOKKOS_INLINE_FUNCTION
261#ifdef HAVE_INTREPID2_DEBUG
262 INTREPID2_TEST_FOR_ABORT( !((numEdge == 1) || (3 <= numEdge && numEdge <= 12 )),
263 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
266 for (ordinal_type i=0;i<numEdge;++i)
267 edgeOrt[i] = (_edgeOrt & (1 << i)) >> i;
270 KOKKOS_INLINE_FUNCTION
273#ifdef HAVE_INTREPID2_DEBUG
274 INTREPID2_TEST_FOR_ABORT( !((numFace == 1) || (4 <= numFace && numFace <= 6 )),
275 ">>> ERROR (Intrepid::Orientation::setFaceOrientation): "
279 for (ordinal_type i=0;i<numFace;++i) {
280 const ordinal_type s = i*3;
281 _faceOrt |= (faceOrt[i] & 7) << s;
285 KOKKOS_INLINE_FUNCTION
288#ifdef HAVE_INTREPID2_DEBUG
289 INTREPID2_TEST_FOR_ABORT( !((numFace == 1) || (4 <= numFace && numFace <= 6 )),
290 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): "
293 for (ordinal_type i=0;i<numFace;++i) {
294 const ordinal_type s = i*3;
295 faceOrt[i] = (_faceOrt & (7 << s)) >> s;
300 return "Orientation{ face: " + std::to_string(_faceOrt) +
"; edge: " + std::to_string(_edgeOrt) +
" }";
Orientation encoding and decoding.
KOKKOS_INLINE_FUNCTION void getFaceOrientation(ordinal_type *faceOrt, const ordinal_type numFace) const
KOKKOS_INLINE_FUNCTION void setFaceOrientation(const ordinal_type numFace, const ordinal_type faceOrt[])
std::string to_string() const
KOKKOS_INLINE_FUNCTION void getEdgeOrientation(ordinal_type *edgeOrt, const ordinal_type numEdge) const
KOKKOS_INLINE_FUNCTION Orientation()
static ordinal_type getEdgeOrdinalOfFace(const ordinal_type subsubcellOrd, const ordinal_type subcellOrd, const shards::CellTopology cellTopo)
KOKKOS_INLINE_FUNCTION void setEdgeOrientation(const ordinal_type numEdge, const ordinal_type edgeOrt[])
KOKKOS_INLINE_FUNCTION bool isAlignedToReference() const