1 // Copyright (c) 2017-2021, Lawrence Livermore National Security, LLC and
2 // other Axom Project Developers. See the top-level LICENSE file for details.
3 //
4 // SPDX-License-Identifier: (BSD-3-Clause)
5 
6 #ifndef MINT_CELLTYPES_HPP_
7 #define MINT_CELLTYPES_HPP_
8 
9 #include "axom/mint/config.hpp"
10 
11 namespace axom
12 {
13 namespace mint
14 {
15 static constexpr int MAX_CELL_NODES = 27;
16 static constexpr int MAX_CELL_FACES = 6;
17 static constexpr int MAX_FACE_NODES = 9;
18 static constexpr int MAX_ALL_FACES_NODES = MAX_CELL_FACES * MAX_FACE_NODES;
19 
20 /*!
21  * \brief Enumerates all cell types supported by Mint
22  */
23 enum class CellType : signed char
24 {
25   UNDEFINED_CELL = -1,  ///< UNDEFINED
26 
27   VERTEX,   ///< VERTEX
28   SEGMENT,  ///< LINE_SEGMENT
29 
30   TRIANGLE,  ///< LINEAR_TRIANGLE
31   QUAD,      ///< LINEAR_QUAD
32   TET,       ///< LINEAR_TET
33   HEX,       ///< LINEAR_HEX
34   PRISM,     ///< LINEAR_PRISM
35   PYRAMID,   ///< LINEAR_PYRAMID
36 
37   QUAD9,  ///< QUADRATIC QUAD
38   HEX27,  ///< QUADRATIC HEX
39 
40   NUM_CELL_TYPES  ///<  total number of cell types
41 };
42 
43 constexpr CellType UNDEFINED_CELL = CellType::UNDEFINED_CELL;
44 constexpr CellType VERTEX = CellType::VERTEX;
45 constexpr CellType SEGMENT = CellType::SEGMENT;
46 constexpr CellType TRIANGLE = CellType::TRIANGLE;
47 constexpr CellType QUAD = CellType::QUAD;
48 constexpr CellType TET = CellType::TET;
49 constexpr CellType HEX = CellType::HEX;
50 constexpr CellType PRISM = CellType::PRISM;
51 constexpr CellType PYRAMID = CellType::PYRAMID;
52 constexpr CellType QUAD9 = CellType::QUAD9;
53 constexpr CellType HEX27 = CellType::HEX27;
54 constexpr int NUM_CELL_TYPES = static_cast<int>(CellType::NUM_CELL_TYPES);
55 
56 /*!
57  * \def REGISTER_CELL_INFO( MINT_CELL_TYPE, MINT_NAME, BP_NAME, VTK_TYPE,
58  *                          N_NODES, N_FACES, N_FACE_NODES, FACE_CELL_TYPES,
59  *                          FACE_NODES )
60  *
61  * \brief Convenience macro used to register information about a cell type.
62  *
63  * \param MINT_CELL_TYPE the mint cell type, e.g., mint::QUAD, mint::HEX, etc.
64  * \param MINT_NAME the associated mint name for the cell type.
65  * \param BP_NAME the associated name in the mesh blueprint.
66  * \param VTK_TYPE the corresponding VTK type.
67  * \param N_NODES the number of nodes that the cell has.
68  * \param N_FACES the number of faces that the cell has.
69  * \param N_FACE_NODES an array; the number of nodes that each face has.
70  * \param FACE_CELL_TYPES an array; the VTK type of each face.
71  * \param FACE_NODES an array; the node offsets specifying each face
72  *        (CCW, so normal points out).
73  */
74 #define REGISTER_CELL_INFO(MINT_CELL_TYPE,                        \
75                            MINT_NAME,                             \
76                            BP_NAME,                               \
77                            VTK_TYPE,                              \
78                            N_NODES,                               \
79                            N_FACES,                               \
80                            N_FACE_NODES,                          \
81                            FACE_CELL_TYPES,                       \
82                            FACE_NODES)                            \
83   namespace internal                                              \
84   {                                                               \
85   static const CellInfo MINT_CELL_TYPE##_INFO = {MINT_CELL_TYPE,  \
86                                                  MINT_NAME,       \
87                                                  BP_NAME,         \
88                                                  VTK_TYPE,        \
89                                                  N_NODES,         \
90                                                  N_FACES,         \
91                                                  N_FACE_NODES,    \
92                                                  FACE_CELL_TYPES, \
93                                                  FACE_NODES};     \
94   }
95 
96 /*!
97  * \def CELL_INFO( MINT_CELL_TYPE )
98  *
99  * \brief Convenience macro used to access a registered CellInfo struct for
100  *  the specified mint cell type.
101  *
102  * \param MINT_CELL_TYPE the mint cell type, e.g., mint::QUAD, mint::HEX, etc.
103  */
104 #define CELL_INFO(MINT_CELL_TYPE) internal::MINT_CELL_TYPE##_INFO
105 
106 /*!
107  * \struct CellInfo
108  *
109  * \brief Holds information associated with a given cell type.
110  */
111 typedef struct
112 {
113   CellType cell_type;         /*!< cell type, e.g. mint::QUAD, mint::HEX */
114   const char* name;           /*!< the name associated with the cell */
115   const char* blueprint_name; /*!< corresponding mesh blueprint name */
116   int vtk_type;               /*!< corresponding vtk_type */
117   int num_nodes;              /*!< number of nodes for the given cell */
118   int num_faces;              /*!< number of faces for the given cell */
119   int face_nodecount[MAX_CELL_FACES]; /*!< number of nodes for each of cell's faces */
120   CellType face_types[MAX_CELL_FACES]; /*!< face type, e.g. mint::SEGMENT, mint::QUAD */
121   IndexType face_nodes[MAX_ALL_FACES_NODES]; /*!< nodes for each of cell's faces */
122 } CellInfo;
123 
124 // This construct lets us pass literal arrays to function-like macros.
125 // AR stands for ARray.
126 #define AR(...) __VA_ARGS__
127 
128 // Cell Info registration
129 REGISTER_CELL_INFO(VERTEX,
130                    "VERTEX",
131                    "point",
132                    1,
133                    1,
134                    0,
135                    AR({0}),
136                    AR({UNDEFINED_CELL}),
137                    AR({0}));
138 
139 REGISTER_CELL_INFO(SEGMENT,
140                    "SEGMENT",
141                    "line",
142                    3,
143                    2,
144                    0,
145                    AR({0}),
146                    AR({UNDEFINED_CELL}),
147                    AR({
148                      0,  // face 0
149                      1   // face 1
150                    }));
151 
152 REGISTER_CELL_INFO(TRIANGLE,
153                    "TRIANGLE",
154                    "tri",
155                    5,
156                    3,
157                    3,
158                    AR({2, 2, 2}),
159                    AR({SEGMENT, SEGMENT, SEGMENT}),
160                    AR({
161                      0,
162                      1,  // face 0
163                      1,
164                      2,  // face 1
165                      2,
166                      0  // face 2
167                    }));
168 
169 REGISTER_CELL_INFO(QUAD,
170                    "QUAD",
171                    "quad",
172                    9,
173                    4,
174                    4,
175                    AR({2, 2, 2, 2}),
176                    AR({SEGMENT, SEGMENT, SEGMENT, SEGMENT}),
177                    AR({
178                      0,
179                      1,  // face 0
180                      1,
181                      2,  // face 1
182                      2,
183                      3,  // face 2
184                      3,
185                      0  // face 3
186                    }));
187 
188 REGISTER_CELL_INFO(TET,
189                    "TET",
190                    "tet",
191                    10,
192                    4,
193                    4,
194                    AR({3, 3, 3, 3}),
195                    AR({TRIANGLE, TRIANGLE, TRIANGLE, TRIANGLE}),
196                    AR({
197                      0,
198                      2,
199                      1,  // face 0
200                      0,
201                      3,
202                      2,  // face 1
203                      0,
204                      1,
205                      3,  // face 2
206                      1,
207                      2,
208                      3  // face 3
209                    }));
210 
211 REGISTER_CELL_INFO(HEX,
212                    "HEX",
213                    "hex",
214                    12,
215                    8,
216                    6,
217                    AR({4, 4, 4, 4, 4, 4}),
218                    AR({QUAD, QUAD, QUAD, QUAD, QUAD, QUAD}),
219                    AR({
220                      0, 3, 2, 1,  // face 0
221                      1, 2, 6, 5,  // face 1
222                      1, 5, 4, 0,  // face 2
223                      0, 4, 7, 3,  // face 3
224                      7, 6, 2, 3,  // face 4
225                      4, 5, 6, 7   // face 5
226                    }));
227 
228 REGISTER_CELL_INFO(PRISM,
229                    "PRISM",
230                    "prism-no-bp",
231                    13,
232                    6,
233                    5,
234                    AR({3, 4, 4, 4, 3}),
235                    AR({TRIANGLE, QUAD, QUAD, QUAD, TRIANGLE}),
236                    AR({
237                      0,
238                      1,
239                      2,  // face 0
240                      0,
241                      2,
242                      5,
243                      3,  // face 1
244                      0,
245                      3,
246                      4,
247                      1,  // face 2
248                      1,
249                      4,
250                      5,
251                      2,  // face 3
252                      3,
253                      5,
254                      4  // face 4
255                    }));
256 
257 REGISTER_CELL_INFO(PYRAMID,
258                    "PYRAMID",
259                    "pyramid-no-bp",
260                    14,
261                    5,
262                    5,
263                    AR({4, 3, 3, 3, 3}),
264                    AR({QUAD, TRIANGLE, TRIANGLE, TRIANGLE, TRIANGLE}),
265                    AR({
266                      0,
267                      3,
268                      2,
269                      1,  // face 0
270                      0,
271                      1,
272                      4,  // face 1
273                      1,
274                      2,
275                      4,  // face 2
276                      2,
277                      3,
278                      4,  // face 3
279                      3,
280                      0,
281                      4  // face 4
282                    }));
283 
284 REGISTER_CELL_INFO(QUAD9,
285                    "QUAD9",
286                    "quad9-no-bp",
287                    28,
288                    9,
289                    4,
290                    AR({2, 2, 2, 2}),
291                    AR({SEGMENT, SEGMENT, SEGMENT, SEGMENT}),
292                    AR({
293                      0,
294                      1,  // face 0
295                      1,
296                      2,  // face 1
297                      2,
298                      3,  // face 2
299                      3,
300                      0  // face 3
301                    }));
302 
303 REGISTER_CELL_INFO(HEX27,
304                    "HEX27",
305                    "hex27-no-bp",
306                    29,
307                    27,
308                    6,
309                    AR({9, 9, 9, 9, 9, 9}),
310                    AR({QUAD9, QUAD9, QUAD9, QUAD9, QUAD9, QUAD9}),
311                    AR({
312                      0, 3, 2, 1, 11, 10, 9,  8,  24,  // face 0
313                      1, 2, 6, 5, 9,  18, 13, 17, 21,  // face 1
314                      1, 5, 4, 0, 17, 12, 16, 8,  22,  // face 2
315                      0, 4, 7, 3, 16, 15, 19, 11, 20,  // face 3
316                      7, 6, 2, 3, 14, 18, 10, 19, 23,  // face 4
317                      4, 5, 6, 7, 12, 13, 14, 15, 25   // face 5
318                    }));
319 
320 /*!
321  * \brief Array of CellInfo corresponding to each cell type
322  * \note The order at which CellInfo for each type is added has to match
323  *  the order of the cell types in the CellTypes enum above.
324  */
325 static const CellInfo cell_info[NUM_CELL_TYPES] = {CELL_INFO(VERTEX),
326                                                    CELL_INFO(SEGMENT),
327                                                    CELL_INFO(TRIANGLE),
328                                                    CELL_INFO(QUAD),
329                                                    CELL_INFO(TET),
330                                                    CELL_INFO(HEX),
331                                                    CELL_INFO(PRISM),
332                                                    CELL_INFO(PYRAMID),
333                                                    CELL_INFO(QUAD9),
334                                                    CELL_INFO(HEX27)};
335 
336 /*!
337  * \brief Return the underlying integer associated with the given CellType.
338  *
339  * \param [in] type the CellType in question.
340  */
cellTypeToInt(CellType type)341 inline constexpr int cellTypeToInt(CellType type)
342 {
343   return static_cast<int>(type);
344 }
345 
346 /*!
347  * \brief Return the CellInfo struct associated with the given type.
348  *
349  * \param [in] type the CellType in question.
350  */
getCellInfo(CellType type)351 inline constexpr const CellInfo& getCellInfo(CellType type)
352 {
353   return cell_info[cellTypeToInt(type)];
354 }
355 
356 } /* namespace mint */
357 } /* namespace axom */
358 
359 #endif /* MINT_CellTypes_HPP_ */
360