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.
80
81const char *const ShapeTypeMap[SIZE_ShapeType] = {
82 "NoGeomShapeType", "Point", "Segment", "Triangle",
83 "Quadrilateral", "Tetrahedron", "Pyramid", "Prism",
84 "Hexahedron", "NodalTri", "NodalTet", "NodalPrism"};
85
86// Hold the dimension of each of the types of shapes.
87constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType] = {
88 0, // Unknown
89 0, // ePoint
90 1, // eSegment
91 2, // eTriangle
92 2, // eQuadrilateral
93 3, // eTetrahedron
94 3, // ePyramid
95 3, // ePrism
96 3, // eHexahedron
97 2, // eNodalTtri
98 3, // eNodalTet
99 3, // eNodalPrism
100};
101
102namespace StdSegData
103{
104inline constexpr int getNumberOfCoefficients(int Na)
105{
106 return Na;
107}
108
109inline constexpr int getNumberOfBndCoefficients([[maybe_unused]] int Na)
110{
111 return 2;
112}
113} // namespace StdSegData
114
115// Dimensions of coefficients for each space
116namespace StdTriData
117{
118inline constexpr int getNumberOfCoefficients(int Na, int Nb)
119{
120 // Note these assertions have been set to > 0 because
121 // it can also be used to evaluate face expansion
122 // order
123 ASSERTL2(Na > 0, "Order in 'a' direction must be > 0.");
124 ASSERTL2(Nb > 0, "Order in 'b' direction must be > 0.");
125 ASSERTL1(Na <= Nb, "order in 'a' direction is higher "
126 "than order in 'b' direction");
127 return Na * (Na + 1) / 2 + Na * (Nb - Na);
128}
129
130inline constexpr int getNumberOfBndCoefficients(int Na, int Nb)
131{
132 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
133 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
134 ASSERTL1(Na <= Nb, "order in 'a' direction is higher "
135 "than order in 'b' direction");
136 return (Na - 1) + 2 * (Nb - 1);
137}
138} // namespace StdTriData
139
140// Dimensions of coefficients for each space
141namespace StdNodalTriData
142{
143inline constexpr int getNumberOfCoefficients(int Na, int Nb)
144{
145 ASSERTL1(Na == Nb, "order in 'a' direction needs to be the same as "
146 "b' direction for nodaltri");
147 return Na * (Nb + 1) / 2;
148}
149
150inline constexpr int getNumberOfBndCoefficients(int Na, int Nb)
151{
152 ASSERTL1(Na == Nb, "order in 'a' direction needs to be the same as "
153 "b' direction for nodaltri");
154 return (Na - 1) + 2 * (Nb - 1);
155}
156} // namespace StdNodalTriData
157
158namespace StdQuadData
159{
160inline constexpr int getNumberOfCoefficients(int Na, int Nb)
161{
162 // Note these assertions have been set to > 0 because
163 // it can also be used to evaluate face expansion
164 // order
165 ASSERTL2(Na > 0, "Order in 'a' direction must be > 0.");
166 ASSERTL2(Nb > 0, "Order in 'b' direction must be > 0.");
167 return Na * Nb;
168}
169
170inline constexpr int getNumberOfBndCoefficients(int Na, int Nb)
171{
172 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
173 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
174 return 2 * (Na - 1) + 2 * (Nb - 1);
175}
176} // namespace StdQuadData
177
178namespace StdHexData
179{
180inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
181{
182 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
183 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
184 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
185 return Na * Nb * Nc;
186}
187
188inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
189{
190 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
191 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
192 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
193 return 2 * Na * Nb + 2 * Na * Nc + 2 * Nb * Nc - 4 * (Na + Nb + Nc) + 8;
194}
195} // namespace StdHexData
196
197namespace StdTetData
198{
199/**
200 * Adds up the number of cells in a truncated Nc by Nc by Nc
201 * pyramid, where the longest Na rows and longest Nb columns are
202 * kept. Example: (Na, Nb, Nc) = (3, 4, 5); The number of
203 * coefficients is the sum of the elements of the following
204 * matrix:
205 *
206 * |5 4 3 2 0|
207 * |4 3 2 0 |
208 * |3 2 0 |
209 * |0 0 |
210 * |0 |
211 *
212 * Sum = 28 = number of tet coefficients.
213 */
214inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
215{
216 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
217 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
218 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
219 ASSERTL1(Na <= Nc, "order in 'a' direction is higher "
220 "than order in 'c' direction");
221 ASSERTL1(Nb <= Nc, "order in 'b' direction is higher "
222 "than order in 'c' direction");
223 int nCoef = Na * Nb * Nc - Na * Nc * (Na - 1) / 2 - Na * Nb * (Nb - 1) / 2 +
224 Na * (Na - 1) * (Na - 2) / 6;
225 return nCoef;
226}
227inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
228{
229 ASSERTL2(Na > 1, "Order in 'a' direction must be > 1.");
230 ASSERTL2(Nb > 1, "Order in 'b' direction must be > 1.");
231 ASSERTL2(Nc > 1, "Order in 'c' direction must be > 1.");
232 ASSERTL1(Na <= Nc, "order in 'a' direction is higher "
233 "than order in 'c' direction");
234 ASSERTL1(Nb <= Nc, "order in 'b' direction is higher "
235 "than order in 'c' direction");
236
237 int nCoef = Na * (Na + 1) / 2 + (Nb - Na) * Na // base
238 + Na * (Na + 1) / 2 + (Nc - Na) * Na // front
239 + 2 * (Nb * (Nb + 1) / 2 + (Nc - Nb) * Nb) // 2 other sides
240 - Na - 2 * Nb - 3 * Nc // less edges
241 + 4; // plus vertices
242
243 return nCoef;
244}
245} // namespace StdTetData
246
247namespace StdNodalTetData
248{
249/**
250 * Adds up the number of cells in a truncated Nc by Nc by Nc
251 * pyramid, where the longest Na rows and longest Nb columns are
252 * kept. Example: (Na, Nb, Nc) = (3, 4, 5); The number of
253 * coefficients is the sum of the elements of the following
254 * matrix:
255 *
256 * |5 4 3 2 0|
257 * |4 3 2 0 |
258 * |3 2 0 |
259 * |0 0 |
260 * |0 |
261 *
262 * Sum = 28 = number of tet coefficients.
263 */
264inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
265{
266 ASSERTL1(Na == Nb, "order in 'a' direction needs to be the same as "
267 "b' direction for nodaltet");
268 ASSERTL1(Nb == Nc, "order in 'a' direction needs to be the same as "
269 "c' direction for nodaltet");
270 return Na * (Nb + 1) * (Nc + 2) / 6;
271}
272
273inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
274{
275 ASSERTL1(Na == Nb, "order in 'a' direction needs to be the same as "
276 "b' direction for nodaltet");
277 ASSERTL1(Nb == Nc, "order in 'a' direction needs to be the same as "
278 "c' direction for nodaltet");
279 int nCoef = Na * (Na + 1) / 2 + (Nb - Na) * Na // base
280 + Na * (Na + 1) / 2 + (Nc - Na) * Na // front
281 + 2 * (Nb * (Nb + 1) / 2 + (Nc - Nb) * Nb) // 2 other sides
282 - Na - 2 * Nb - 3 * Nc // less edges
283 + 4; // plus vertices
284
285 return nCoef;
286}
287} // namespace StdNodalTetData
288
289namespace StdPyrData
290{
291inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
292{
293 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
294 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
295 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
296 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
297 "than order in 'c' direction.");
298 ASSERTL1(Nb <= Nc, "Order in 'b' direction is higher "
299 "than order in 'c' direction.");
300
301 // Count number of coefficients explicitly.
302 int nCoeff = 0;
303
304 // Count number of interior tet modes
305 for (int a = 0; a < Na; ++a)
306 {
307 for (int b = 0; b < Nb; ++b)
308 {
309 for (int c = 0; c < Nc - std::max(a, b); ++c)
310 {
311 ++nCoeff;
312 }
313 }
314 }
315 return nCoeff;
316}
317
318inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
319{
320 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
321 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
322 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
323 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
324 "than order in 'c' direction.");
325 ASSERTL1(Nb <= Nc, "Order in 'b' direction is higher "
326 "than order in 'c' direction.");
327
328 return Na * Nb // base
329 + 2 * (Na * (Na + 1) / 2 + (Nc - Na) * Na) // front and back
330 + 2 * (Nb * (Nb + 1) / 2 + (Nc - Nb) * Nb) // sides
331 - 2 * Na - 2 * Nb - 4 * Nc // less edges
332 + 5; // plus vertices
333}
334} // namespace StdPyrData
335
336namespace StdPrismData
337{
338inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
339{
340 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
341 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
342 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
343 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
344 "than order in 'c' direction.");
345
346 return Nb * StdTriData::getNumberOfCoefficients(Na, Nc);
347}
348
349inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
350{
351 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
352 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
353 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
354 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
355 "than order in 'c' direction.");
356
357 return Na * Nb + 2 * Nb * Nc // rect faces
358 + 2 * (Na * (Na + 1) / 2 + (Nc - Na) * Na) // tri faces
359 - 2 * Na - 3 * Nb - 4 * Nc // less edges
360 + 6; // plus vertices
361}
362} // namespace StdPrismData
363
364namespace StdNodalPrismData
365{
366inline constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
367{
368 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
369 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
370 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
371 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
372 "than order in 'c' direction.");
373
374 return Nb * StdTriData::getNumberOfCoefficients(Na, Nc);
375}
376
377inline constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
378{
379 ASSERTL1(Na > 1, "Order in 'a' direction must be > 1.");
380 ASSERTL1(Nb > 1, "Order in 'b' direction must be > 1.");
381 ASSERTL1(Nc > 1, "Order in 'c' direction must be > 1.");
382 ASSERTL1(Na <= Nc, "Order in 'a' direction is higher "
383 "than order in 'c' direction.");
384
385 return Na * Nb + 2 * Nb * Nc // rect faces
386 + 2 * (Na * (Na + 1) / 2 + (Nc - Na) * Na) // tri faces
387 - 2 * Na - 3 * Nb - 4 * Nc // less edges
388 + 6; // plus vertices
389}
390} // namespace StdNodalPrismData
391
392inline constexpr int GetNumberOfCoefficients(ShapeType shape,
393 std::vector<unsigned int> &modes,
394 int offset = 0)
395{
396 int returnval = 0;
397 switch (shape)
398 {
399 case eSegment:
400 returnval = modes[offset];
401 break;
402 case eTriangle:
403 returnval = StdTriData::getNumberOfCoefficients(modes[offset],
404 modes[offset + 1]);
405 break;
406 case eNodalTri:
408 modes[offset], modes[offset + 1]);
409 break;
410 case eQuadrilateral:
411 returnval = modes[offset] * modes[offset + 1];
412 break;
413 case eTetrahedron:
415 modes[offset], modes[offset + 1], modes[offset + 2]);
416 break;
417 case ePyramid:
419 modes[offset], modes[offset + 1], modes[offset + 2]);
420 break;
421 case ePrism:
423 modes[offset], modes[offset + 1], modes[offset + 2]);
424 break;
425 case eHexahedron:
426 returnval = modes[offset] * modes[offset + 1] * modes[offset + 2];
427 break;
428 default:
429 NEKERROR(ErrorUtil::efatal, "Unknown Shape Type");
430 break;
431 }
432
433 return returnval;
434}
435
436inline constexpr int GetNumberOfCoefficients(ShapeType shape, int na,
437 int nb = 0, int nc = 0)
438{
439 int returnval = 0;
440 switch (shape)
441 {
442 case eSegment:
443 returnval = na;
444 break;
445 case eTriangle:
446 returnval = StdTriData::getNumberOfCoefficients(na, nb);
447 break;
448 case eNodalTri:
450 break;
451 case eQuadrilateral:
452 returnval = na * nb;
453 break;
454 case eTetrahedron:
455 returnval = StdTetData::getNumberOfCoefficients(na, nb, nc);
456 break;
457 case eNodalTet:
458 returnval = StdNodalTetData::getNumberOfCoefficients(na, nb, nc);
459 break;
460 case ePyramid:
461 returnval = StdPyrData::getNumberOfCoefficients(na, nb, nc);
462 break;
463 case ePrism:
464 returnval = StdPrismData::getNumberOfCoefficients(na, nb, nc);
465 break;
466 case eNodalPrism:
467 returnval = StdNodalPrismData::getNumberOfCoefficients(na, nb, nc);
468 break;
469 case eHexahedron:
470 returnval = na * nb * nc;
471 break;
472 default:
473 NEKERROR(ErrorUtil::efatal, "Unknown Shape Type");
474 break;
475 }
476
477 return returnval;
478}
479} // namespace Nektar::LibUtilities
480
481#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...
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfCoefficients(int Na, int Nb)
constexpr int getNumberOfBndCoefficients(int Na, int Nb)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb)
constexpr int getNumberOfCoefficients(int Na, int Nb)
constexpr int getNumberOfBndCoefficients(int Na)
constexpr int getNumberOfCoefficients(int Na)
constexpr int getNumberOfCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
constexpr int getNumberOfBndCoefficients(int Na, int Nb)
constexpr int getNumberOfCoefficients(int Na, int Nb)
const char *const ShapeTypeMap[SIZE_ShapeType]
Definition ShapeType.hpp:81
constexpr int GetNumberOfCoefficients(ShapeType shape, std::vector< unsigned int > &modes, int offset=0)
constexpr unsigned int ShapeTypeDimMap[SIZE_ShapeType]
Definition ShapeType.hpp:87