Nektar++
NodalTetElec.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NodalTetElec.cpp
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: 3D Nodal Tet Electrostatic Point Definitions
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
38namespace Nektar
39{
40namespace LibUtilities
41{
43 PointsKey(0, eNodalTetElec), NodalTetElec::Create)};
44
45// ////////////////////////////////////////////////////////
46// Coordinate the nodal tetrahedron electrostatic points
47
49{
50 // Allocate the storage for points
52
53 size_t index = 0, isum = 0;
54 const size_t offset = 5; // offset to match Datafile
55 NekDouble b, c, d;
56 size_t numPoints = GetNumPoints();
57
58 // initialize values
59 for (size_t i = 0; i < numPoints - 2; ++i)
60 {
61 index += NodalTetElecNPTS[i];
62 }
63
64 for (size_t i = 0; i < NodalTetElecNPTS[numPoints - 2]; ++i, ++index)
65 {
66 // 1 Point Symmetry: aaaa
67 if (int(NodalTetElecData[index][0]))
68 {
69 b = NodalTetElecData[index][6];
70 c = NodalTetElecData[index][7];
71 d = NodalTetElecData[index][8];
72
73 m_points[0][isum] = 2.0 * b - 1.0;
74 m_points[1][isum] = 2.0 * c - 1.0;
75 m_points[2][isum] = 2.0 * d - 1.0;
76 isum++;
77 continue;
78 } // end symmetry 1
79
80 // 4 Point symmetry: aaab or abbb
81 if (int(NodalTetElecData[index][1]))
82 {
83 for (size_t j = 0; j < 4; ++j)
84 {
85 b = NodalTetElecData[index][offset + perm4_3d[j][1]];
86 c = NodalTetElecData[index][offset + perm4_3d[j][2]];
87 d = NodalTetElecData[index][offset + perm4_3d[j][3]];
88
89 m_points[0][isum] = 2.0 * b - 1.0;
90 m_points[1][isum] = 2.0 * c - 1.0;
91 m_points[2][isum] = 2.0 * d - 1.0;
92 isum++;
93 } // end j
94 continue;
95 } // end symmetry 4
96
97 // 6 Point symmetry: aabb
98 if (int(NodalTetElecData[index][2]))
99 {
100 for (size_t j = 0; j < 6; ++j)
101 {
102 b = NodalTetElecData[index][offset + perm6_3d[j][1]];
103 c = NodalTetElecData[index][offset + perm6_3d[j][2]];
104 d = NodalTetElecData[index][offset + perm6_3d[j][3]];
105
106 m_points[0][isum] = 2.0 * b - 1.0;
107 m_points[1][isum] = 2.0 * c - 1.0;
108 m_points[2][isum] = 2.0 * d - 1.0;
109 isum++;
110 } // end j
111 continue;
112 } // end symmetry6
113
114 // 12 Point symmetry: case aabc
115 if (int(NodalTetElecData[index][3]) == 1)
116 {
117 for (size_t j = 0; j < 12; ++j)
118 {
119 b = NodalTetElecData[index][offset + perm12A_3d[j][1]];
120 c = NodalTetElecData[index][offset + perm12A_3d[j][2]];
121 d = NodalTetElecData[index][offset + perm12A_3d[j][3]];
122
123 m_points[0][isum] = 2.0 * b - 1.0;
124 m_points[1][isum] = 2.0 * c - 1.0;
125 m_points[2][isum] = 2.0 * d - 1.0;
126 isum++;
127 } // end j
128 continue;
129 } // end symmetry 12 aabc
130
131 // 12 Point symmetry: case abcc
132 if (int(NodalTetElecData[index][3]) == 2)
133 {
134 for (size_t j = 0; j < 12; ++j)
135 {
136 b = NodalTetElecData[index][offset + perm12B_3d[j][1]];
137 c = NodalTetElecData[index][offset + perm12B_3d[j][2]];
138 d = NodalTetElecData[index][offset + perm12B_3d[j][3]];
139
140 m_points[0][isum] = 2.0 * b - 1.0;
141 m_points[1][isum] = 2.0 * c - 1.0;
142 m_points[2][isum] = 2.0 * d - 1.0;
143 isum++;
144 } // end j
145 continue;
146 } // end symmetry 12 abcc
147
148 // 12 Point symmetry: case abbc
149 if (int(NodalTetElecData[index][3]) == 3)
150 {
151 for (size_t j = 0; j < 12; ++j)
152 {
153 b = NodalTetElecData[index][offset + perm12C_3d[j][1]];
154 c = NodalTetElecData[index][offset + perm12C_3d[j][2]];
155 d = NodalTetElecData[index][offset + perm12C_3d[j][3]];
156
157 m_points[0][isum] = 2.0 * b - 1.0;
158 m_points[1][isum] = 2.0 * c - 1.0;
159 m_points[2][isum] = 2.0 * d - 1.0;
160 isum++;
161 } // end j
162 continue;
163 } // end symmetry 12 abbc
164
165 // 24 Point symmetry: case abcd
166 if (int(NodalTetElecData[index][4]))
167 {
168 for (size_t j = 0; j < 24; ++j)
169 {
170 b = NodalTetElecData[index][offset + perm24_3d[j][1]];
171 c = NodalTetElecData[index][offset + perm24_3d[j][2]];
172 d = NodalTetElecData[index][offset + perm24_3d[j][3]];
173
174 m_points[0][isum] = 2.0 * b - 1.0;
175 m_points[1][isum] = 2.0 * c - 1.0;
176 m_points[2][isum] = 2.0 * d - 1.0;
177 isum++;
178 } // end j
179 continue;
180 } // end symmetry24abcd
181
182 } // end npts
183
185
186 ASSERTL1((static_cast<size_t>(isum) == m_pointsKey.GetTotNumPoints()),
187 "sum not equal to npts");
188
190 numPoints - 1, m_points[0], m_points[1], m_points[2]);
191}
192
194{
195 // Allocate the storage for points
197
198 typedef DataType T;
199
200 // Solve the Vandermonde system of integrals for the weight vector
201 NekVector<T> w = m_util->GetWeights();
202 m_weights = Array<OneD, T>(w.GetRows(), w.GetPtr());
203}
204
205// ////////////////////////////////////////
206// CalculateInterpMatrix()
211
212{
214 xi[0] = xia;
215 xi[1] = yia;
216 xi[2] = zia;
217
218 std::shared_ptr<NekMatrix<NekDouble>> mat =
219 m_util->GetInterpolationMatrix(xi);
220 Vmath::Vcopy(mat->GetRows() * mat->GetColumns(), mat->GetRawPtr(), 1,
221 &interp[0], 1);
222}
223
225{
226 // Allocate the derivative matrix.
227 PointsBaseType::v_CalculateDerivMatrix();
228
229 m_derivmatrix[0] = m_util->GetDerivMatrix(0);
230 m_derivmatrix[1] = m_util->GetDerivMatrix(1);
231 m_derivmatrix[2] = m_util->GetDerivMatrix(2);
232}
233
234std::shared_ptr<PointsBaseType> NodalTetElec::Create(const PointsKey &key)
235{
236 std::shared_ptr<PointsBaseType> returnval(
238 returnval->Initialize();
239 return returnval;
240}
241
243{
244 size_t cnt;
245 size_t istart, iend;
246
247 const size_t nVerts = 4;
248 const size_t nEdgeInteriorPoints = GetNumPoints() - 2;
249 const size_t nFaceInteriorPoints =
250 (GetNumPoints() - 3) * (GetNumPoints() - 2) / 2;
251 // const size_t nBoundaryPoints = 4 + 6*nEdgeInteriorPoints +
252 // 4*nFaceInteriorPoints;
253 const size_t nAllPoints =
254 GetNumPoints() * (GetNumPoints() + 1) * (GetNumPoints() + 2) / 6;
255 if (nEdgeInteriorPoints == 0)
256 {
257 return;
258 }
259
260 // group all edge 1 points
261 istart = nVerts;
262 for (size_t i = cnt = istart; i < nAllPoints; i++)
263 {
264 if (fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol &&
265 fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol)
266 {
267 std::swap(m_points[0][cnt], m_points[0][i]);
268 std::swap(m_points[1][cnt], m_points[1][i]);
269 std::swap(m_points[2][cnt], m_points[2][i]);
270 cnt++;
271 }
272 }
273
274 // bubble sort edge 1 (counterclockwise numbering)
275 iend = istart + nEdgeInteriorPoints;
276 for (size_t i = istart; i < iend; i++)
277 {
278 for (size_t j = istart + 1; j < iend; j++)
279 {
280 if (m_points[0][j] < m_points[0][j - 1])
281 {
282 std::swap(m_points[0][j], m_points[0][j - 1]);
283 std::swap(m_points[1][j], m_points[1][j - 1]);
284 std::swap(m_points[2][j], m_points[2][j - 1]);
285 }
286 }
287 }
288
289 // group the points of edge 2 together;
290 istart = iend;
291 for (size_t i = cnt = istart; i < nAllPoints; i++)
292 {
293 if (fabs(m_points[1][i] + m_points[0][i]) < NekConstants::kNekZeroTol &&
294 fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol)
295 {
296 std::swap(m_points[0][cnt], m_points[0][i]);
297 std::swap(m_points[1][cnt], m_points[1][i]);
298 std::swap(m_points[2][cnt], m_points[2][i]);
299 cnt++;
300 }
301 }
302
303 // bubble sort edge 2 (counterclockwise numbering)
304 iend = istart + nEdgeInteriorPoints;
305 for (size_t i = istart; i < iend; i++)
306 {
307 for (size_t j = istart + 1; j < iend; j++)
308 {
309 if (m_points[1][j] < m_points[1][j - 1])
310 {
311 std::swap(m_points[0][j], m_points[0][j - 1]);
312 std::swap(m_points[1][j], m_points[1][j - 1]);
313 std::swap(m_points[2][j], m_points[2][j - 1]);
314 }
315 }
316 }
317
318 // group the points of edge 3 together;
319 istart = iend;
320 for (size_t i = cnt = istart; i < nAllPoints; i++)
321 {
322 if (fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol &&
323 fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol)
324 {
325 std::swap(m_points[0][cnt], m_points[0][i]);
326 std::swap(m_points[1][cnt], m_points[1][i]);
327 std::swap(m_points[2][cnt], m_points[2][i]);
328 cnt++;
329 }
330 }
331
332 // bubble sort edge 3 (counterclockwise numbering)
333 iend = istart + nEdgeInteriorPoints;
334 for (size_t i = istart; i < iend; i++)
335 {
336 for (size_t j = istart + 1; j < iend; j++)
337 {
338 if (m_points[1][j] > m_points[1][j - 1])
339 {
340 std::swap(m_points[0][j], m_points[0][j - 1]);
341 std::swap(m_points[1][j], m_points[1][j - 1]);
342 std::swap(m_points[2][j], m_points[2][j - 1]);
343 }
344 }
345 }
346
347 // group the points of edge 4 together;
348 istart = iend;
349 for (size_t i = cnt = istart; i < nAllPoints; i++)
350 {
351 if (fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol &&
352 fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol)
353 {
354 std::swap(m_points[0][cnt], m_points[0][i]);
355 std::swap(m_points[1][cnt], m_points[1][i]);
356 std::swap(m_points[2][cnt], m_points[2][i]);
357 cnt++;
358 }
359 }
360
361 // bubble sort edge 3 (counterclockwise numbering)
362 iend = istart + nEdgeInteriorPoints;
363 for (size_t i = istart; i < iend; i++)
364 {
365 for (size_t j = istart + 1; j < iend; j++)
366 {
367 if (m_points[2][j] < m_points[2][j - 1])
368 {
369 std::swap(m_points[0][j], m_points[0][j - 1]);
370 std::swap(m_points[1][j], m_points[1][j - 1]);
371 std::swap(m_points[2][j], m_points[2][j - 1]);
372 }
373 }
374 }
375
376 // group the points of edge 5 together;
377 istart = iend;
378 for (size_t i = cnt = istart; i < nAllPoints; i++)
379 {
380 if (fabs(m_points[0][i] + m_points[2][i]) < NekConstants::kNekZeroTol &&
381 fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol)
382 {
383 std::swap(m_points[0][cnt], m_points[0][i]);
384 std::swap(m_points[1][cnt], m_points[1][i]);
385 std::swap(m_points[2][cnt], m_points[2][i]);
386 cnt++;
387 }
388 }
389
390 // bubble sort edge 5 (counterclockwise numbering)
391 iend = istart + nEdgeInteriorPoints;
392 for (size_t i = istart; i < iend; i++)
393 {
394 for (size_t j = istart + 1; j < iend; j++)
395 {
396 if (m_points[2][j] < m_points[2][j - 1])
397 {
398 std::swap(m_points[0][j], m_points[0][j - 1]);
399 std::swap(m_points[1][j], m_points[1][j - 1]);
400 std::swap(m_points[2][j], m_points[2][j - 1]);
401 }
402 }
403 }
404
405 // group the points of edge 6 together;
406 istart = iend;
407 for (size_t i = cnt = istart; i < nAllPoints; i++)
408 {
409 if (fabs(m_points[1][i] + m_points[2][i]) < NekConstants::kNekZeroTol &&
410 fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol)
411 {
412 std::swap(m_points[0][cnt], m_points[0][i]);
413 std::swap(m_points[1][cnt], m_points[1][i]);
414 std::swap(m_points[2][cnt], m_points[2][i]);
415 cnt++;
416 }
417 }
418
419 // bubble sort edge 6 (counterclockwise numbering)
420 iend = istart + nEdgeInteriorPoints;
421 for (size_t i = istart; i < iend; i++)
422 {
423 for (size_t j = istart + 1; j < iend; j++)
424 {
425 if (m_points[2][j] < m_points[2][j - 1])
426 {
427 std::swap(m_points[0][j], m_points[0][j - 1]);
428 std::swap(m_points[1][j], m_points[1][j - 1]);
429 std::swap(m_points[2][j], m_points[2][j - 1]);
430 }
431 }
432 }
433
434 if (GetNumPoints() < 4)
435 {
436 // no face points
437 return;
438 }
439
440 // group the points of face 1 together;
441 istart = iend;
442 for (size_t i = cnt = istart; i < nAllPoints; i++)
443 {
444 if (fabs(m_points[2][i] + 1.0) < NekConstants::kNekZeroTol)
445 {
446 std::swap(m_points[0][cnt], m_points[0][i]);
447 std::swap(m_points[1][cnt], m_points[1][i]);
448 std::swap(m_points[2][cnt], m_points[2][i]);
449 cnt++;
450 }
451 }
452
453 // bubble sort face1 (tensor numbering)
454 iend = istart + nFaceInteriorPoints;
455 bool repeat = true;
456 while (repeat)
457 {
458 repeat = false;
459 for (size_t i = istart; i < iend - 1; i++)
460 {
461 if (m_points[1][i] > m_points[1][i + 1])
462 {
463 std::swap(m_points[0][i + 1], m_points[0][i]);
464 std::swap(m_points[1][i + 1], m_points[1][i]);
465 std::swap(m_points[2][i + 1], m_points[2][i]);
466 repeat = true;
467 }
468 }
469 }
470 size_t offset = 0;
471 size_t npl = GetNumPoints() - 3;
472 while (npl > 1)
473 {
474 repeat = true;
475 while (repeat)
476 {
477 repeat = false;
478 for (size_t i = offset + istart; i < offset + istart + npl - 1; i++)
479 {
480 if (m_points[0][i] > m_points[0][i + 1])
481 {
482 std::swap(m_points[0][i + 1], m_points[0][i]);
483 std::swap(m_points[1][i + 1], m_points[1][i]);
484 std::swap(m_points[2][i + 1], m_points[2][i]);
485 repeat = true;
486 }
487 }
488 }
489 offset += npl;
490 npl--;
491 }
492
493 // group the points of face 2 together;
494 istart = iend;
495 for (size_t i = cnt = istart; i < nAllPoints; i++)
496 {
497 if (fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol)
498 {
499 std::swap(m_points[0][cnt], m_points[0][i]);
500 std::swap(m_points[1][cnt], m_points[1][i]);
501 std::swap(m_points[2][cnt], m_points[2][i]);
502 cnt++;
503 }
504 }
505
506 // bubble sort face2 (tensor numbering)
507 iend = istart + nFaceInteriorPoints;
508 repeat = true;
509 while (repeat)
510 {
511 repeat = false;
512 for (size_t i = istart; i < iend - 1; i++)
513 {
514 if (m_points[2][i] > m_points[2][i + 1])
515 {
516 std::swap(m_points[0][i + 1], m_points[0][i]);
517 std::swap(m_points[1][i + 1], m_points[1][i]);
518 std::swap(m_points[2][i + 1], m_points[2][i]);
519 repeat = true;
520 }
521 }
522 }
523 offset = 0;
524 npl = GetNumPoints() - 3;
525 while (npl > 1)
526 {
527 repeat = true;
528 while (repeat)
529 {
530 repeat = false;
531 for (size_t i = offset + istart; i < offset + istart + npl - 1; i++)
532 {
533 if (m_points[0][i] > m_points[0][i + 1])
534 {
535 std::swap(m_points[0][i + 1], m_points[0][i]);
536 std::swap(m_points[1][i + 1], m_points[1][i]);
537 std::swap(m_points[2][i + 1], m_points[2][i]);
538 repeat = true;
539 }
540 }
541 }
542 offset += npl;
543 npl--;
544 }
545
546 // group the points of face 3 together;
547 istart = iend;
548 for (size_t i = cnt = istart; i < nAllPoints; i++)
549 {
550 if (fabs(m_points[1][i] + m_points[0][i] + m_points[2][i] + 1.0) <
551 1E-9) // nek zero tol too small
552 {
553 std::swap(m_points[0][cnt], m_points[0][i]);
554 std::swap(m_points[1][cnt], m_points[1][i]);
555 std::swap(m_points[2][cnt], m_points[2][i]);
556 cnt++;
557 }
558 }
559
560 // bubble sort face3 (tensor numbering)
561 iend = istart + nFaceInteriorPoints;
562 repeat = true;
563 while (repeat)
564 {
565 repeat = false;
566 for (size_t i = istart; i < iend - 1; i++)
567 {
568 if (m_points[2][i] > m_points[2][i + 1])
569 {
570 std::swap(m_points[0][i + 1], m_points[0][i]);
571 std::swap(m_points[1][i + 1], m_points[1][i]);
572 std::swap(m_points[2][i + 1], m_points[2][i]);
573 repeat = true;
574 }
575 }
576 }
577 offset = 0;
578 npl = GetNumPoints() - 3;
579 while (npl > 1)
580 {
581 repeat = true;
582 while (repeat)
583 {
584 repeat = false;
585 for (size_t i = offset + istart; i < offset + istart + npl - 1; i++)
586 {
587 if (m_points[1][i] > m_points[1][i + 1])
588 {
589 std::swap(m_points[0][i + 1], m_points[0][i]);
590 std::swap(m_points[1][i + 1], m_points[1][i]);
591 std::swap(m_points[2][i + 1], m_points[2][i]);
592 repeat = true;
593 }
594 }
595 }
596 offset += npl;
597 npl--;
598 }
599
600 // group the points of face 4 together;
601 istart = iend;
602 for (size_t i = cnt = istart; i < nAllPoints; i++)
603 {
604 if (fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol)
605 {
606 std::swap(m_points[0][cnt], m_points[0][i]);
607 std::swap(m_points[1][cnt], m_points[1][i]);
608 std::swap(m_points[2][cnt], m_points[2][i]);
609 cnt++;
610 }
611 }
612
613 // bubble sort face4 (tensor numbering)
614 iend = istart + nFaceInteriorPoints;
615 repeat = true;
616 while (repeat)
617 {
618 repeat = false;
619 for (size_t i = istart; i < iend - 1; i++)
620 {
621 if (m_points[2][i] > m_points[2][i + 1])
622 {
623 std::swap(m_points[0][i + 1], m_points[0][i]);
624 std::swap(m_points[1][i + 1], m_points[1][i]);
625 std::swap(m_points[2][i + 1], m_points[2][i]);
626 repeat = true;
627 }
628 }
629 }
630 offset = 0;
631 npl = GetNumPoints() - 3;
632 while (npl > 1)
633 {
634 repeat = true;
635 while (repeat)
636 {
637 repeat = false;
638 for (size_t i = offset + istart; i < offset + istart + npl - 1; i++)
639 {
640 if (m_points[1][i] > m_points[1][i + 1])
641 {
642 std::swap(m_points[0][i + 1], m_points[0][i]);
643 std::swap(m_points[1][i + 1], m_points[1][i]);
644 std::swap(m_points[2][i + 1], m_points[2][i]);
645 repeat = true;
646 }
647 }
648 }
649 offset += npl;
650 npl--;
651 }
652}
653
654} // namespace LibUtilities
655} // namespace Nektar
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
bool RegisterCreator(const KeyType &key, const CreateFuncType &createFunc)
Register the given function and associate it with the key. The return value is just to facilitate cal...
Definition: NekManager.hpp:169
static std::shared_ptr< PointsBaseType > Create(const PointsKey &key)
virtual void v_CalculateDerivMatrix() override final
virtual void v_CalculateWeights() override final
virtual void v_CalculatePoints() override final
void CalculateInterpMatrix(const Array< OneD, const NekDouble > &xia, const Array< OneD, const NekDouble > &yia, const Array< OneD, const NekDouble > &zia, Array< OneD, NekDouble > &interp)
std::shared_ptr< NodalUtilTetrahedron > m_util
Definition: NodalTetElec.h:91
Array< OneD, DataType > m_points[3]
Storage for the point locations, allowing for up to a 3D points storage.
Definition: Points.h:361
MatrixSharedPtrType m_derivmatrix[3]
Derivative matrices.
Definition: Points.h:367
virtual void v_CalculatePoints()
Definition: Points.h:381
PointsKey m_pointsKey
Points type for this points distributions.
Definition: Points.h:358
Array< OneD, DataType > m_weights
Quadrature weights for the weights.
Definition: Points.h:363
Defines a specification for a set of points.
Definition: Points.h:55
size_t GetTotNumPoints() const
Definition: Points.h:163
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static const size_t perm24_3d[24][4]
static const size_t perm12B_3d[12][4]
PointsManagerT & PointsManager(void)
static const size_t perm12C_3d[12][4]
static const NekDouble NodalTetElecData[][9]
static const size_t perm12A_3d[12][4]
@ eNodalTetElec
3D Nodal Electrostatic Points on a Tetrahedron
Definition: PointsType.h:87
static const size_t perm6_3d[6][4]
static const size_t perm4_3d[4][4]
static const size_t NodalTetElecNPTS[NodalTetElecAvailable]
static const NekDouble kNekZeroTol
std::vector< double > w(NPUPPER)
std::vector< double > d(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191