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