Intrepid2
Intrepid2_OrientationDef.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Intrepid2 Package
4//
5// Copyright 2007 NTESS and the Intrepid2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10
15#ifndef __INTREPID2_ORIENTATION_DEF_HPP__
16#define __INTREPID2_ORIENTATION_DEF_HPP__
17
18// disable clang warnings
19#if defined (__clang__) && !defined (__INTEL_COMPILER)
20#pragma clang system_header
21#endif
22
23namespace Intrepid2 {
24
25 // ------------------------------------------------------------------------------------
26 // Orientation
27 //
28 //
29 template<typename cellVertViewType>
30 inline
31 void
32 Orientation::getCellVertexMap(typename cellVertViewType::non_const_value_type *subCellVerts,
33 ordinal_type &numVerts,
34 const shards::CellTopology cellTopo,
35 const cellVertViewType cellVertices,
36 const ordinal_type subCellDim,
37 const ordinal_type subCellOrd) {
38 static_assert(Kokkos::Impl::MemorySpaceAccess
39 <Kokkos::HostSpace,typename cellVertViewType::device_type::memory_space>::accessible,
40 "host space cannot access cellVertViewType");
41 switch (subCellDim) {
42 case 0: {
43 numVerts = 1;
44 subCellVerts[0] = cellVertices(subCellOrd);
45 break;
46 }
47 default: {
48 numVerts = cellTopo.getVertexCount(subCellDim, subCellOrd);
49 for (ordinal_type i=0;i<numVerts;++i)
50 subCellVerts[i] = cellVertices(cellTopo.getNodeMap(subCellDim, subCellOrd, i));
51 break;
52 }
53 }
54 }
55
56 template<typename subCellVertType>
57 inline
58 ordinal_type
59 Orientation::getOrientation(const subCellVertType subCellVerts[],
60 const ordinal_type numVerts) {
61 ordinal_type ort = 0;
62
63#ifdef HAVE_INTREPID2_DEBUG
64 for(ordinal_type i=0;i<numVerts-1;++i)
65 for(ordinal_type j=i+1;j<numVerts;++j)
66 INTREPID2_TEST_FOR_ABORT( ( subCellVerts[i] == subCellVerts[j] ),
67 ">>> ERROR (Intrepid::Orientation::getOrientation): " \
68 "Invalid subCellVerts, some vertex ids are repeated");
69#endif
70
71 ordinal_type rotation = 0; // find smallest vertex id
72 for (ordinal_type i=1;i<numVerts;++i)
73 rotation = (subCellVerts[i] < subCellVerts[rotation]) ? i : rotation;
74
75 switch (numVerts) {
76 case 2: {// edge
77 ort = rotation;
78 break;
79 }
80 case 3: {
81 const ordinal_type axes[][2] = { {1,2}, {2,0}, {0,1} };
82 const ordinal_type flip = (subCellVerts[axes[rotation][0]] > subCellVerts[axes[rotation][1]]);
83
84 ort = flip*3 + rotation;
85 break;
86 }
87 case 4: {
88 const ordinal_type axes[][2] = { {1,3}, {2,0}, {3,1}, {0,2} };
89 const ordinal_type flip = (subCellVerts[axes[rotation][0]] > subCellVerts[axes[rotation][1]]);
90
91 ort = flip*4 + rotation;
92 break;
93 }
94 default: {
95 INTREPID2_TEST_FOR_ABORT( true,
96 ">>> ERROR (Intrepid::Orientation::getOrientation): " \
97 "Invalid numVerts (2 (edge),3 (triangle) and 4 (quadrilateral) are allowed)");
98 break;
99 }
100 }
101 return ort;
102 }
103
104 template<typename cellVertViewType>
105 inline
106 Orientation
107 Orientation::getOrientation(const shards::CellTopology cellTopo,
108 const cellVertViewType cellVertices,
109 bool isSide) {
110 static_assert(Kokkos::Impl::MemorySpaceAccess
111 <Kokkos::HostSpace,typename cellVertViewType::device_type::memory_space>::accessible,
112 "host space cannot access cellVertViewType");
113
114 Orientation ort;
115 auto dim = cellTopo.getDimension();
116 const ordinal_type nedge = (isSide && dim==1) ? 1 : cellTopo.getEdgeCount();
117
118 if (nedge > 0) {
119 typename cellVertViewType::non_const_value_type vertsSubCell[2];
120 ordinal_type orts[12], nvertSubCell;
121 for (ordinal_type i=0;i<nedge;++i) {
122 Orientation::getCellVertexMap(vertsSubCell,
123 nvertSubCell,
124 cellTopo,
125 cellVertices,
126 1, i);
127 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
128 }
129 ort.setEdgeOrientation(nedge, orts);
130 }
131 const ordinal_type nface = (isSide && dim==2) ? 1 : cellTopo.getFaceCount();
132 if (nface > 0) {
133 typename cellVertViewType::non_const_value_type vertsSubCell[4];
134 ordinal_type orts[6], nvertSubCell;
135 for (ordinal_type i=0;i<nface;++i) {
136 Orientation::getCellVertexMap(vertsSubCell,
137 nvertSubCell,
138 cellTopo,
139 cellVertices,
140 2, i);
141 orts[i] = Orientation::getOrientation(vertsSubCell, nvertSubCell);
142 }
143 ort.setFaceOrientation(nface, orts);
144 }
145 return ort;
146 }
147
148 inline
149 ordinal_type
150 Orientation::getEdgeOrdinalOfFace(const ordinal_type subsubcellOrd,
151 const ordinal_type subcellOrd,
152 const shards::CellTopology cellTopo) {
153 ordinal_type r_val = -1;
154
155 const auto cellBaseKey = cellTopo.getBaseKey();
156 if (cellBaseKey == shards::Hexahedron<>::key) {
157 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 6) &&
158 !(subsubcellOrd < 4),
159 std::logic_error,
160 "subcell and subsubcell information are not correct" );
161 const int quad_to_hex_edges[6][4] = { { 0, 9, 4, 8 },
162 { 1,10, 5, 9 },
163 { 2,11, 6,10 },
164 { 8, 7,11, 3 },
165 { 3, 2, 1, 0 },
166 { 4, 5, 6, 7 } };
167 r_val = quad_to_hex_edges[subcellOrd][subsubcellOrd];
168 } else if (cellBaseKey == shards::Tetrahedron<>::key) {
169 INTREPID2_TEST_FOR_EXCEPTION( !(subcellOrd < 4) &&
170 !(subsubcellOrd < 3),
171 std::logic_error,
172 "subcell and subsubcell information are not correct" );
173 const ordinal_type tri_to_tet_edges[4][3] = { { 0, 4, 3 },
174 { 1, 5, 4 },
175 { 3, 5, 2 },
176 { 2, 1, 0 } };
177 r_val = tri_to_tet_edges[subcellOrd][subsubcellOrd];
178 } else {
179 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
180 "cellTopo is not supported: try TET and HEX" );
181 }
182 return r_val;
183 }
184
185 KOKKOS_INLINE_FUNCTION
187 : _edgeOrt(0), _faceOrt(0) {}
188
189 KOKKOS_INLINE_FUNCTION
190 bool
192 return (_edgeOrt == 0 && _faceOrt == 0);
193 }
194
195 KOKKOS_INLINE_FUNCTION
196 void
197 Orientation::setEdgeOrientation(const ordinal_type numEdge, const ordinal_type edgeOrt[]) {
198#ifdef HAVE_INTREPID2_DEBUG
199 INTREPID2_TEST_FOR_ABORT( !((numEdge == 1) || (3 <= numEdge && numEdge <= 12 )),
200 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
201 "Invalid numEdge");
202#endif
203 _edgeOrt = 0;
204 for (ordinal_type i=0;i<numEdge;++i)
205 _edgeOrt |= (edgeOrt[i] & 1) << i;
206 }
207
208 KOKKOS_INLINE_FUNCTION
209 void
210 Orientation::getEdgeOrientation(ordinal_type *edgeOrt, const ordinal_type numEdge) const {
211#ifdef HAVE_INTREPID2_DEBUG
212 INTREPID2_TEST_FOR_ABORT( !((numEdge == 1) || (3 <= numEdge && numEdge <= 12 )),
213 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): " \
214 "Invalid numEdge");
215#endif
216 for (ordinal_type i=0;i<numEdge;++i)
217 edgeOrt[i] = (_edgeOrt & (1 << i)) >> i;
218 }
219
220 KOKKOS_INLINE_FUNCTION
221 void
222 Orientation::setFaceOrientation(const ordinal_type numFace, const ordinal_type faceOrt[]) {
223#ifdef HAVE_INTREPID2_DEBUG
224 INTREPID2_TEST_FOR_ABORT( !((numFace == 1) || (4 <= numFace && numFace <= 6 )),
225 ">>> ERROR (Intrepid::Orientation::setFaceOrientation): "
226 "Invalid numFace");
227#endif
228 _faceOrt = 0;
229 for (ordinal_type i=0;i<numFace;++i) {
230 const ordinal_type s = i*3;
231 _faceOrt |= (faceOrt[i] & 7) << s;
232 }
233 }
234
235 KOKKOS_INLINE_FUNCTION
236 void
237 Orientation::getFaceOrientation(ordinal_type *faceOrt, const ordinal_type numFace) const {
238#ifdef HAVE_INTREPID2_DEBUG
239 INTREPID2_TEST_FOR_ABORT( !((numFace == 1) || (4 <= numFace && numFace <= 6 )),
240 ">>> ERROR (Intrepid::Orientation::setEdgeOrientation): "
241 "Invalid numFace");
242#endif
243 for (ordinal_type i=0;i<numFace;++i) {
244 const ordinal_type s = i*3;
245 faceOrt[i] = (_faceOrt & (7 << s)) >> s;
246 }
247 }
248
249 inline std::string Orientation::to_string() const {
250 return "Orientation{ face: " + std::to_string(_faceOrt) + "; edge: " + std::to_string(_edgeOrt) + " }";
251 }
252}
253
254#endif
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[])
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