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 
23 namespace 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
KOKKOS_INLINE_FUNCTION void getFaceOrientation(ordinal_type *faceOrt, const ordinal_type numFace) const
KOKKOS_INLINE_FUNCTION void setEdgeOrientation(const ordinal_type numEdge, const ordinal_type edgeOrt[])
Orientation encoding and decoding.
KOKKOS_INLINE_FUNCTION bool isAlignedToReference() const
KOKKOS_INLINE_FUNCTION void setFaceOrientation(const ordinal_type numFace, const ordinal_type faceOrt[])
static ordinal_type getEdgeOrdinalOfFace(const ordinal_type subsubcellOrd, const ordinal_type subcellOrd, const shards::CellTopology cellTopo)
KOKKOS_INLINE_FUNCTION void getEdgeOrientation(ordinal_type *edgeOrt, const ordinal_type numEdge) const
KOKKOS_INLINE_FUNCTION Orientation()