Nektar++
Loading...
Searching...
No Matches
ShapeType.hpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: ShapeType.hpp
4//
5// For more information, please see: http://www.nektar.info/
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33////////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHAPE_TYPE_H
36#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHAPE_TYPE_H
37
38#include <algorithm>
39#include <vector>
40
42
43#ifdef min
44#undef min
45#endif
46
48{
49
50// Types of geometry types.
74
75const char *const ShapeTypeMap[SIZE_ShapeType] = {
76 "NoGeomShapeType", "Point", "Segment", "Triangle", "Quadrilateral",
77 "Tetrahedron", "Pyramid", "Prism", "Hexahedron",
78};
79
80// Hold the dimension of each of the types of shapes.
81constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType] = {
82 0, // Unknown
83 0, // ePoint
84 1, // eSegment
85 2, // eTriangle
86 2, // eQuadrilateral
87 3, // eTetrahedron
88 3, // ePyramid
89 3, // ePrism
90 3, // eHexahedron
91};
92
93namespace StdSegData
94{
95inline int getNumberOfCoefficients(int Na)
96{
97 return Na;
98}
99
100inline int getNumberOfBndCoefficients([[maybe_unused]] int Na)
101{
102 return 2;
103}
104} // namespace StdSegData
105
106// Dimensions of coefficients for each space
107namespace StdTriData
108{
109inline int getNumberOfCoefficients(int Na, int Nb)
110{
111 // Note these assertions have been set to > 0 because
112 // it can also be used to evaluate face expansion
113 // order
114 ASSERTL2(Na > 0, "Order in 'a' direction must be > 0.");
115 ASSERTL2(Nb > 0, "Order in 'b' direction must be > 0.");
116 ASSERTL1(Na <= Nb, "order in 'a' direction is higher "
117 "than order in 'b' direction");
118 return Na * (Na + 1) / 2 + Na * (Nb - Na);
119}
120
121inline int getNumberOfBndCoefficients(int Na, int Nb)
122{
123 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
124 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
125 ASSERTL1(Na <= Nb, "order in 'a' direction is higher "
126 "than order in 'b' direction");
127 return (Na - 1) + 2 * (Nb - 1);
128}
129} // namespace StdTriData
130
131namespace StdQuadData
132{
133inline int getNumberOfCoefficients(int Na, int Nb)
134{
135 // Note these assertions have been set to > 0 because
136 // it can also be used to evaluate face expansion
137 // order
138 ASSERTL2(Na > 0, "Order in 'a' direction must be > 0.");
139 ASSERTL2(Nb > 0, "Order in 'b' direction must be > 0.");
140 return Na * Nb;
141}
142
143inline int getNumberOfBndCoefficients(int Na, int Nb)
144{
145 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
146 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
147 return 2 * (Na - 1) + 2 * (Nb - 1);
148}
149} // namespace StdQuadData
150
151namespace StdHexData
152{
153inline int getNumberOfCoefficients(int Na, int Nb, int Nc)
154{
155 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
156 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
157 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
158 return Na * Nb * Nc;
159}
160
161inline int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
162{
163 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
164 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
165 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
166 return 2 * Na * Nb + 2 * Na * Nc + 2 * Nb * Nc - 4 * (Na + Nb + Nc) + 8;
167}
168} // namespace StdHexData
169
170namespace StdTetData
171{
172/**
173 * Adds up the number of cells in a truncated Nc by Nc by Nc
174 * pyramid, where the longest Na rows and longest Nb columns are
175 * kept. Example: (Na, Nb, Nc) = (3, 4, 5); The number of
176 * coefficients is the sum of the elements of the following
177 * matrix:
178 *
179 * |5 4 3 2 0|
180 * |4 3 2 0 |
181 * |3 2 0 |
182 * |0 0 |
183 * |0 |
184 *
185 * Sum = 28 = number of tet coefficients.
186 */
187inline int getNumberOfCoefficients(int Na, int Nb, int Nc)
188{
189 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
190 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
191 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
192 ASSERTL1(Na <= Nc, "order in 'a' direction is higher "
193 "than order in 'c' direction");
194 ASSERTL1(Nb <= Nc, "order in 'b' direction is higher "
195 "than order in 'c' direction");
196 int nCoef = Na * Nb * Nc - Na * Nc * (Na - 1) / 2 - Na * Nb * (Nb - 1) / 2 +
197 Na * (Na - 1) * (Na - 2) / 6;
198 return nCoef;
199}
200
201inline int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
202{
203 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
204 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
205 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
206 ASSERTL1(Na <= Nc, "order in 'a' direction is higher "
207 "than order in 'c' direction");
208 ASSERTL1(Nb <= Nc, "order in 'b' direction is higher "
209 "than order in 'c' direction");
210
211 int nCoef = Na * (Na + 1) / 2 + (Nb - Na) * Na // base
212 + Na * (Na + 1) / 2 + (Nc - Na) * Na // front
213 + 2 * (Nb * (Nb + 1) / 2 + (Nc - Nb) * Nb) // 2 other sides
214 - Na - 2 * Nb - 3 * Nc // less edges
215 + 4; // plus vertices
216
217 return nCoef;
218}
219} // namespace StdTetData
220
221namespace StdPyrData
222{
223inline int getNumberOfCoefficients(int Na, int Nb, int Nc)
224{
225 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
226 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
227 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
228 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
229 "than order in 'c' direction.");
230 ASSERTL1(Nb <= Nc, "Order in 'b' direction is higher "
231 "than order in 'c' direction.");
232
233 // Count number of coefficients explicitly.
234 int nCoeff = 0;
235
236 // Count number of interior tet modes
237 for (int a = 0; a < Na; ++a)
238 {
239 for (int b = 0; b < Nb; ++b)
240 {
241 for (int c = 0; c < Nc - std::max(a, b); ++c)
242 {
243 ++nCoeff;
244 }
245 }
246 }
247 return nCoeff;
248}
249
250inline int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
251{
252 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
253 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
254 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
255 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
256 "than order in 'c' direction.");
257 ASSERTL1(Nb <= Nc, "Order in 'b' direction is higher "
258 "than order in 'c' direction.");
259
260 return Na * Nb // base
261 + 2 * (Na * (Na + 1) / 2 + (Nc - Na) * Na) // front and back
262 + 2 * (Nb * (Nb + 1) / 2 + (Nc - Nb) * Nb) // sides
263 - 2 * Na - 2 * Nb - 4 * Nc // less edges
264 + 5; // plus vertices
265}
266} // namespace StdPyrData
267
268namespace StdPrismData
269{
270inline int getNumberOfCoefficients(int Na, int Nb, int Nc)
271{
272 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
273 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
274 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
275 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
276 "than order in 'c' direction.");
277
278 return Nb * StdTriData::getNumberOfCoefficients(Na, Nc);
279}
280
281inline int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
282{
283 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
284 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
285 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
286 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
287 "than order in 'c' direction.");
288
289 return Na * Nb + 2 * Nb * Nc // rect faces
290 + 2 * (Na * (Na + 1) / 2 + (Nc - Na) * Na) // tri faces
291 - 2 * Na - 3 * Nb - 4 * Nc // less edges
292 + 6; // plus vertices
293}
294} // namespace StdPrismData
295
297 std::vector<unsigned int> &modes,
298 int offset = 0)
299{
300 int returnval = 0;
301 switch (shape)
302 {
303 case eSegment:
304 returnval = modes[offset];
305 break;
306 case eTriangle:
307 returnval = StdTriData::getNumberOfCoefficients(modes[offset],
308 modes[offset + 1]);
309 break;
310 case eQuadrilateral:
311 returnval = modes[offset] * modes[offset + 1];
312 break;
313 case eTetrahedron:
315 modes[offset], modes[offset + 1], modes[offset + 2]);
316 break;
317 case ePyramid:
319 modes[offset], modes[offset + 1], modes[offset + 2]);
320 break;
321 case ePrism:
323 modes[offset], modes[offset + 1], modes[offset + 2]);
324 break;
325 case eHexahedron:
326 returnval = modes[offset] * modes[offset + 1] * modes[offset + 2];
327 break;
328 default:
329 NEKERROR(ErrorUtil::efatal, "Unknown Shape Type");
330 break;
331 }
332
333 return returnval;
334}
335
336inline int GetNumberOfCoefficients(ShapeType shape, int na, int nb = 0,
337 int nc = 0)
338{
339 int returnval = 0;
340 switch (shape)
341 {
342 case eSegment:
343 returnval = na;
344 break;
345 case eTriangle:
346 returnval = StdTriData::getNumberOfCoefficients(na, nb);
347 break;
348 case eQuadrilateral:
349 returnval = na * nb;
350 break;
351 case eTetrahedron:
352 returnval = StdTetData::getNumberOfCoefficients(na, nb, nc);
353 break;
354 case ePyramid:
355 returnval = StdPyrData::getNumberOfCoefficients(na, nb, nc);
356 break;
357 case ePrism:
358 returnval = StdPrismData::getNumberOfCoefficients(na, nb, nc);
359 break;
360 case eHexahedron:
361 returnval = na * nb * nc;
362 break;
363 default:
364 NEKERROR(ErrorUtil::efatal, "Unknown Shape Type");
365 break;
366 }
367
368 return returnval;
369}
370} // namespace Nektar::LibUtilities
371
372#endif
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfBndCoefficients(int Na, int Nb)
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfBndCoefficients(int Na, int Nb)
const char *const ShapeTypeMap[SIZE_ShapeType]
Definition ShapeType.hpp:75
int GetNumberOfCoefficients(ShapeType shape, std::vector< unsigned int > &modes, int offset=0)
constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType]
Definition ShapeType.hpp:81