Nektar++
Loading...
Searching...
No Matches
TetGeom.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: TetGeom.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: Tetrahedral geometry information.
32//
33////////////////////////////////////////////////////////////////////////////////
34
36
41
43{
44const unsigned int TetGeom::VertexEdgeConnectivity[4][3] = {
45 {0, 2, 3}, {0, 1, 4}, {1, 2, 5}, {3, 4, 5}};
46const unsigned int TetGeom::VertexFaceConnectivity[4][3] = {
47 {0, 1, 3}, {0, 1, 2}, {0, 2, 3}, {1, 2, 3}};
48const unsigned int TetGeom::EdgeFaceConnectivity[6][2] = {
49 {0, 1}, {0, 2}, {0, 3}, {1, 3}, {1, 2}, {2, 3}};
50const unsigned int TetGeom::EdgeNormalToFaceVert[4][3] = {
51 {3, 4, 5}, {1, 2, 5}, {0, 2, 3}, {0, 1, 4}};
52
58
63
64TetGeom::TetGeom(int id, std::array<TriGeom *, kNfaces> faces)
65 : Geometry3D(faces[0]->GetEdge(0)->GetVertex(0)->GetCoordim())
66{
68 m_globalID = id;
69 m_faces = faces;
70
75}
76
77int TetGeom::v_GetDir(const int faceidx, const int facedir) const
78{
79 if (faceidx == 0)
80 {
81 return facedir;
82 }
83 else if (faceidx == 1)
84 {
85 return 2 * facedir;
86 }
87 else
88 {
89 return 1 + facedir;
90 }
91}
92
93int TetGeom::v_GetVertexEdgeMap(const int i, const int j) const
94{
95 return VertexEdgeConnectivity[i][j];
96}
97
98int TetGeom::v_GetVertexFaceMap(const int i, const int j) const
99{
100 return VertexFaceConnectivity[i][j];
101}
102
103int TetGeom::v_GetEdgeFaceMap(const int i, const int j) const
104{
105 return EdgeFaceConnectivity[i][j];
106}
107
108int TetGeom::v_GetEdgeNormalToFaceVert(const int i, const int j) const
109{
110 return EdgeNormalToFaceVert[i][j];
111}
112
114{
115
116 // find edge 0
117 int i, j;
118 unsigned int check;
119
120 // First set up the 3 bottom edges
121
122 if (m_faces[0]->GetEid(0) != m_faces[1]->GetEid(0))
123 {
124 std::ostringstream errstrm;
125 errstrm << "Local edge 0 (eid=" << m_faces[0]->GetEid(0);
126 errstrm << ") on face " << m_faces[0]->GetGlobalID();
127 errstrm << " must be the same as local edge 0 (eid="
128 << m_faces[1]->GetEid(0);
129 errstrm << ") on face " << m_faces[1]->GetGlobalID();
130 NEKERROR(ErrorUtil::efatal, errstrm.str());
131 }
132
133 int faceConnected;
134 for (faceConnected = 1; faceConnected < 4; faceConnected++)
135 {
136 check = 0;
137 for (i = 0; i < 3; i++)
138 {
139 if ((m_faces[0])->GetEid(i) == (m_faces[faceConnected])->GetEid(0))
140 {
141 m_edges[faceConnected - 1] =
142 static_cast<SegGeom *>((m_faces[0])->GetEdge(i));
143 check++;
144 }
145 }
146
147 if (check < 1)
148 {
149 std::ostringstream errstrm;
150 errstrm << "Face 0 does not share an edge with first edge of "
151 "adjacent face. Faces ";
152 errstrm << (m_faces[0])->GetGlobalID() << ", "
153 << (m_faces[faceConnected])->GetGlobalID();
154 NEKERROR(ErrorUtil::efatal, errstrm.str());
155 }
156 else if (check > 1)
157 {
158 std::ostringstream errstrm;
159 errstrm << "Connected faces share more than one edge. Faces ";
160 errstrm << (m_faces[0])->GetGlobalID() << ", "
161 << (m_faces[faceConnected])->GetGlobalID();
162 NEKERROR(ErrorUtil::efatal, errstrm.str());
163 }
164 }
165
166 // Then, set up the 3 vertical edges
167 check = 0;
168 for (i = 0; i < 3; i++) // Set up the vertical edge :face(1) and face(3)
169 {
170 for (j = 0; j < 3; j++)
171 {
172 if ((m_faces[1])->GetEid(i) == (m_faces[3])->GetEid(j))
173 {
174 m_edges[3] = static_cast<SegGeom *>((m_faces[1])->GetEdge(i));
175 check++;
176 }
177 }
178 }
179 if (check < 1)
180 {
181 std::ostringstream errstrm;
182 errstrm << "Connected faces do not share an edge. Faces ";
183 errstrm << (m_faces[1])->GetGlobalID() << ", "
184 << (m_faces[3])->GetGlobalID();
185 NEKERROR(ErrorUtil::efatal, errstrm.str());
186 }
187 else if (check > 1)
188 {
189 std::ostringstream errstrm;
190 errstrm << "Connected faces share more than one edge. Faces ";
191 errstrm << (m_faces[1])->GetGlobalID() << ", "
192 << (m_faces[3])->GetGlobalID();
193 NEKERROR(ErrorUtil::efatal, errstrm.str());
194 }
195 // Set up vertical edges: face(1) through face(3)
196 for (faceConnected = 1; faceConnected < 3; faceConnected++)
197 {
198 check = 0;
199 for (i = 0; i < 3; i++)
200 {
201 for (j = 0; j < 3; j++)
202 {
203 if ((m_faces[faceConnected])->GetEid(i) ==
204 (m_faces[faceConnected + 1])->GetEid(j))
205 {
206 m_edges[faceConnected + 3] = static_cast<SegGeom *>(
207 (m_faces[faceConnected])->GetEdge(i));
208 check++;
209 }
210 }
211 }
212
213 if (check < 1)
214 {
215 std::ostringstream errstrm;
216 errstrm << "Connected faces do not share an edge. Faces ";
217 errstrm << (m_faces[faceConnected])->GetGlobalID() << ", "
218 << (m_faces[faceConnected + 1])->GetGlobalID();
219 NEKERROR(ErrorUtil::efatal, errstrm.str());
220 }
221 else if (check > 1)
222 {
223 std::ostringstream errstrm;
224 errstrm << "Connected faces share more than one edge. Faces ";
225 errstrm << (m_faces[faceConnected])->GetGlobalID() << ", "
226 << (m_faces[faceConnected + 1])->GetGlobalID();
227 NEKERROR(ErrorUtil::efatal, errstrm.str());
228 }
229 }
230}
231
233{
234
235 // Set up the first 2 vertices (i.e. vertex 0,1)
236 if ((m_edges[0]->GetVid(0) == m_edges[1]->GetVid(0)) ||
237 (m_edges[0]->GetVid(0) == m_edges[1]->GetVid(1)))
238 {
239 m_verts[0] = m_edges[0]->GetVertex(1);
240 m_verts[1] = m_edges[0]->GetVertex(0);
241 }
242 else if ((m_edges[0]->GetVid(1) == m_edges[1]->GetVid(0)) ||
243 (m_edges[0]->GetVid(1) == m_edges[1]->GetVid(1)))
244 {
245 m_verts[0] = m_edges[0]->GetVertex(0);
246 m_verts[1] = m_edges[0]->GetVertex(1);
247 }
248 else
249 {
250 std::ostringstream errstrm;
251 errstrm << "Connected edges do not share a vertex. Edges ";
252 errstrm << m_edges[0]->GetGlobalID() << ", "
253 << m_edges[1]->GetGlobalID();
254 NEKERROR(ErrorUtil::efatal, errstrm.str());
255 }
256
257 // set up the other bottom vertices (i.e. vertex 2)
258 for (int i = 1; i < 2; i++)
259 {
260 if (m_edges[i]->GetVid(0) == m_verts[i]->GetGlobalID())
261 {
262 m_verts[2] = m_edges[i]->GetVertex(1);
263 }
264 else if (m_edges[i]->GetVid(1) == m_verts[i]->GetGlobalID())
265 {
266 m_verts[2] = m_edges[i]->GetVertex(0);
267 }
268 else
269 {
270 std::ostringstream errstrm;
271 errstrm << "Connected edges do not share a vertex. Edges ";
272 errstrm << m_edges[i]->GetGlobalID() << ", "
273 << m_edges[i - 1]->GetGlobalID();
274 NEKERROR(ErrorUtil::efatal, errstrm.str());
275 }
276 }
277
278 // set up top vertex
279 if (m_edges[3]->GetVid(0) == m_verts[0]->GetGlobalID())
280 {
281 m_verts[3] = m_edges[3]->GetVertex(1);
282 }
283 else
284 {
285 m_verts[3] = m_edges[3]->GetVertex(0);
286 }
287
288 // Check the other edges match up.
289 int check = 0;
290 for (int i = 4; i < 6; ++i)
291 {
292 if ((m_edges[i]->GetVid(0) == m_verts[i - 3]->GetGlobalID() &&
293 m_edges[i]->GetVid(1) == m_verts[3]->GetGlobalID()) ||
294 (m_edges[i]->GetVid(1) == m_verts[i - 3]->GetGlobalID() &&
295 m_edges[i]->GetVid(0) == m_verts[3]->GetGlobalID()))
296 {
297 check++;
298 }
299 }
300 if (check != 2)
301 {
302 std::ostringstream errstrm;
303 errstrm << "Connected edges do not share a vertex. Edges ";
304 errstrm << m_edges[3]->GetGlobalID() << ", "
305 << m_edges[2]->GetGlobalID();
306 NEKERROR(ErrorUtil::efatal, errstrm.str());
307 }
308}
309
311{
312
313 // This 2D array holds the local id's of all the vertices
314 // for every edge. For every edge, they are ordered to what we
315 // define as being Forwards
316 const unsigned int edgeVerts[kNedges][2] = {{0, 1}, {1, 2}, {0, 2},
317 {0, 3}, {1, 3}, {2, 3}};
318
319 int i;
320 for (i = 0; i < kNedges; i++)
321 {
322 if (m_edges[i]->GetVid(0) == m_verts[edgeVerts[i][0]]->GetGlobalID())
323 {
325 }
326 else if (m_edges[i]->GetVid(0) ==
327 m_verts[edgeVerts[i][1]]->GetGlobalID())
328 {
330 }
331 else
332 {
334 "Could not find matching vertex for the edge");
335 }
336 }
337}
338
340{
341
342 int f, i;
343
344 // These arrays represent the vector of the A and B
345 // coordinate of the local elemental coordinate system
346 // where A corresponds with the coordinate direction xi_i
347 // with the lowest index i (for that particular face)
348 // Coordinate 'B' then corresponds to the other local
349 // coordinate (i.e. with the highest index)
350 Array<OneD, NekDouble> elementAaxis(m_coordim);
351 Array<OneD, NekDouble> elementBaxis(m_coordim);
352
353 // These arrays correspond to the local coordinate
354 // system of the face itself (i.e. the Geometry2D)
355 // faceAaxis correspond to the xi_0 axis
356 // faceBaxis correspond to the xi_1 axis
359
360 // This is the base vertex of the face (i.e. the Geometry2D)
361 // This corresponds to thevertex with local ID 0 of the
362 // Geometry2D
363 unsigned int baseVertex;
364
365 // The lenght of the vectors above
366 NekDouble elementAaxis_length;
367 NekDouble elementBaxis_length;
368 NekDouble faceAaxis_length;
369 NekDouble faceBaxis_length;
370
371 // This 2D array holds the local id's of all the vertices
372 // for every face. For every face, they are ordered in such
373 // a way that the implementation below allows a unified approach
374 // for all faces.
375 const unsigned int faceVerts[kNfaces][TriGeom::kNverts] = {
376 {0, 1, 2}, {0, 1, 3}, {1, 2, 3}, {0, 2, 3}};
377
378 NekDouble dotproduct1 = 0.0;
379 NekDouble dotproduct2 = 0.0;
380
381 unsigned int orientation;
382
383 // Loop over all the faces to set up the orientation
384 for (f = 0; f < kNqfaces + kNtfaces; f++)
385 {
386 // initialisation
387 elementAaxis_length = 0.0;
388 elementBaxis_length = 0.0;
389 faceAaxis_length = 0.0;
390 faceBaxis_length = 0.0;
391
392 dotproduct1 = 0.0;
393 dotproduct2 = 0.0;
394
395 baseVertex = m_faces[f]->GetVid(0);
396
397 // We are going to construct the vectors representing the A
398 // and B axis of every face. These vectors will be constructed
399 // as a vector-representation of the edges of the
400 // face. However, for both coordinate directions, we can
401 // represent the vectors by two different edges. That's why we
402 // need to make sure that we pick the edge to which the
403 // baseVertex of the Geometry2D-representation of the face
404 // belongs...
405
406 // Compute the length of edges on a base-face
407 if (baseVertex == m_verts[faceVerts[f][0]]->GetGlobalID())
408 {
409 for (i = 0; i < m_coordim; i++)
410 {
411 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
412 (*m_verts[faceVerts[f][0]])[i];
413 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
414 (*m_verts[faceVerts[f][0]])[i];
415 }
416 }
417 else if (baseVertex == m_verts[faceVerts[f][1]]->GetGlobalID())
418 {
419 for (i = 0; i < m_coordim; i++)
420 {
421 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
422 (*m_verts[faceVerts[f][0]])[i];
423 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
424 (*m_verts[faceVerts[f][1]])[i];
425 }
426 }
427 else if (baseVertex == m_verts[faceVerts[f][2]]->GetGlobalID())
428 {
429 for (i = 0; i < m_coordim; i++)
430 {
431 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
432 (*m_verts[faceVerts[f][2]])[i];
433 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
434 (*m_verts[faceVerts[f][0]])[i];
435 }
436 }
437 else
438 {
440 "Could not find matching vertex for the face");
441 }
442
443 // Now, construct the edge-vectors of the local coordinates of
444 // the Geometry2D-representation of the face
445 for (i = 0; i < m_coordim; i++)
446 {
447 faceAaxis[i] =
448 (*m_faces[f]->GetVertex(1))[i] - (*m_faces[f]->GetVertex(0))[i];
449 faceBaxis[i] =
450 (*m_faces[f]->GetVertex(2))[i] - (*m_faces[f]->GetVertex(0))[i];
451
452 elementAaxis_length += pow(elementAaxis[i], 2);
453 elementBaxis_length += pow(elementBaxis[i], 2);
454 faceAaxis_length += pow(faceAaxis[i], 2);
455 faceBaxis_length += pow(faceBaxis[i], 2);
456 }
457
458 elementAaxis_length = sqrt(elementAaxis_length);
459 elementBaxis_length = sqrt(elementBaxis_length);
460 faceAaxis_length = sqrt(faceAaxis_length);
461 faceBaxis_length = sqrt(faceBaxis_length);
462
463 // Calculate the inner product of both the A-axis
464 // (i.e. Elemental A axis and face A axis)
465 for (i = 0; i < m_coordim; i++)
466 {
467 dotproduct1 += elementAaxis[i] * faceAaxis[i];
468 }
469
470 NekDouble norm =
471 fabs(dotproduct1) / elementAaxis_length / faceAaxis_length;
472 orientation = 0;
473
474 // if the innerproduct is equal to the (absolute value of the ) products
475 // of the lengths of both vectors, then, the coordinate systems will NOT
476 // be transposed
477 if (fabs(norm - 1.0) < NekConstants::kNekZeroTol)
478 {
479 // if the inner product is negative, both A-axis point
480 // in reverse direction
481 if (dotproduct1 < 0.0)
482 {
483 orientation += 2;
484 }
485
486 // calculate the inner product of both B-axis
487 for (i = 0; i < m_coordim; i++)
488 {
489 dotproduct2 += elementBaxis[i] * faceBaxis[i];
490 }
491
492 norm = fabs(dotproduct2) / elementBaxis_length / faceBaxis_length;
493
494 // check that both these axis are indeed parallel
495 if (fabs(norm - 1.0) >= NekConstants::kNekZeroTol)
496 {
498 "These vectors should be parallel");
499 }
500
501 // if the inner product is negative, both B-axis point
502 // in reverse direction
503 if (dotproduct2 < 0.0)
504 {
505 orientation++;
506 }
507 }
508 // The coordinate systems are transposed
509 else
510 {
511 orientation = 4;
512
513 // Calculate the inner product between the elemental A-axis
514 // and the B-axis of the face (which are now the corresponding axis)
515 dotproduct1 = 0.0;
516 for (i = 0; i < m_coordim; i++)
517 {
518 dotproduct1 += elementAaxis[i] * faceBaxis[i];
519 }
520
521 norm = fabs(dotproduct1) / elementAaxis_length / faceBaxis_length;
522
523 // check that both these axis are indeed parallel
524 if (fabs(norm - 1.0) >= NekConstants::kNekZeroTol)
525 {
527 "These vectors should be parallel");
528 }
529
530 // if the result is negative, both axis point in reverse
531 // directions
532 if (dotproduct1 < 0.0)
533 {
534 orientation += 2;
535 }
536
537 // Do the same for the other two corresponding axis
538 dotproduct2 = 0.0;
539 for (i = 0; i < m_coordim; i++)
540 {
541 dotproduct2 += elementBaxis[i] * faceAaxis[i];
542 }
543
544 norm = fabs(dotproduct2) / elementBaxis_length / faceAaxis_length;
545
546 // check that both these axis are indeed parallel
547 if (fabs(norm - 1.0) >= NekConstants::kNekZeroTol)
548 {
550 "These vectors should be parallel");
551 }
552
553 if (dotproduct2 < 0.0)
554 {
555 orientation++;
556 }
557 }
558
559 orientation = orientation + 5;
560
562 "Orientation of triangular face (id = " +
563 std::to_string(m_faces[f]->GetGlobalID()) +
564 ") is inconsistent with face " + std::to_string(f) +
565 " of tet element (id = " + std::to_string(m_globalID) +
566 ") since Dir2 is aligned with Dir1. Mesh setup "
567 "needs investigation");
568
569 // Fill the m_forient array
570 m_forient[f] = (StdRegions::Orientation)orientation;
571 }
572}
573
574void TetGeom::v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
575{
576 Geometry::v_Reset(curvedEdges, curvedFaces);
577
578 for (int i = 0; i < 4; ++i)
579 {
580 m_faces[i]->Reset(curvedEdges, curvedFaces);
581 }
582}
583
585{
586 if (!m_setupState)
587 {
588 for (int i = 0; i < 4; ++i)
589 {
590 m_faces[i]->Setup();
591 }
592 SetUpXmap();
593 SetUpCoeffs(m_xmap->GetNcoeffs());
594
595 // check to see if expansions are linear
596 m_straightEdge = 1;
597 if (m_xmap->GetBasisNumModes(0) != 2 ||
598 m_xmap->GetBasisNumModes(1) != 2 ||
599 m_xmap->GetBasisNumModes(2) != 2)
600 {
601 m_straightEdge = 0;
602 }
603
604 m_setupState = true;
605 }
606}
607
608/**
609 * Generate the geometry factors for this element.
610 */
612{
613 if (!m_setupState)
614 {
616 }
617 v_FillGeom();
618
619 GeomType Gtype = eRegular;
620
621 // check to see if expansions are linear
622 if (m_xmap->GetBasisNumModes(0) != 2 || m_xmap->GetBasisNumModes(1) != 2 ||
623 m_xmap->GetBasisNumModes(2) != 2)
624 {
625 Gtype = eDeformed;
626 }
627
628 if (Gtype == eRegular)
629 {
631 for (int i = 0; i < 3; ++i)
632 {
634 NekDouble A = (*m_verts[0])(i);
635 NekDouble B = (*m_verts[1])(i);
636 NekDouble C = (*m_verts[2])(i);
637 NekDouble D = (*m_verts[3])(i);
638 m_isoParameter[i][0] = 0.5 * (-A + B + C + D);
639
640 m_isoParameter[i][1] = 0.5 * (-A + B); // xi1
641 m_isoParameter[i][2] = 0.5 * (-A + C); // xi2
642 m_isoParameter[i][3] = 0.5 * (-A + D); // xi3
643 }
644 }
645
646 if (Gtype == eRegular)
647 {
649 }
650
651 return Gtype;
652}
653
662
663/**
664 * @brief Set up the #m_xmap object by determining the order of each
665 * direction from derived faces.
666 */
668{
669 std::vector<int> tmp;
670 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(0));
671 int order0 = *std::max_element(tmp.begin(), tmp.end());
672
673 tmp.clear();
674 tmp.push_back(order0);
675 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(1));
676 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(2));
677 int order1 = *std::max_element(tmp.begin(), tmp.end());
678
679 tmp.clear();
680 tmp.push_back(order0);
681 tmp.push_back(order1);
682 tmp.push_back(m_faces[1]->GetXmap()->GetTraceNcoeffs(1));
683 tmp.push_back(m_faces[1]->GetXmap()->GetTraceNcoeffs(2));
684 tmp.push_back(m_faces[3]->GetXmap()->GetTraceNcoeffs(1));
685 int order2 = *std::max_element(tmp.begin(), tmp.end());
686
687 std::array<LibUtilities::BasisKey, 3> basis = {
690 LibUtilities::PointsKey(order0 + 1,
695 LibUtilities::eGaussRadauMAlpha1Beta0)),
699 LibUtilities::eGaussRadauMAlpha2Beta0))};
700
701 m_xmap = GetStdTetFactory().CreateInstance(basis);
702}
703
704/**
705 * @brief Put all quadrature information into face/edge structure and
706 * backward transform.
707 *
708 * Note verts, edges, and faces are listed according to anticlockwise
709 * convention but points in _coeffs have to be in array format from left
710 * to right.
711 */
713{
714 if (m_state == ePtsFilled)
715 {
716 return;
717 }
718
719 int i, j, k;
720
721 for (i = 0; i < kNfaces; i++)
722 {
723 m_faces[i]->FillGeom();
724
725 int nFaceCoeffs = m_faces[i]->GetXmap()->GetNcoeffs();
726
727 Array<OneD, unsigned int> mapArray(nFaceCoeffs);
728 Array<OneD, int> signArray(nFaceCoeffs);
729
730 if (m_forient[i] < 9)
731 {
732 m_xmap->GetTraceToElementMap(
733 i, mapArray, signArray, m_forient[i],
734 m_faces[i]->GetXmap()->GetTraceNcoeffs(0),
735 m_faces[i]->GetXmap()->GetTraceNcoeffs(1));
736 }
737 else
738 {
739 m_xmap->GetTraceToElementMap(
740 i, mapArray, signArray, m_forient[i],
741 m_faces[i]->GetXmap()->GetTraceNcoeffs(1),
742 m_faces[i]->GetXmap()->GetTraceNcoeffs(0));
743 }
744
745 for (j = 0; j < m_coordim; j++)
746 {
747 const Array<OneD, const NekDouble> &coeffs =
748 m_faces[i]->GetCoeffs(j);
749
750 for (k = 0; k < nFaceCoeffs; k++)
751 {
752 NekDouble v = signArray[k] * coeffs[k];
753 m_coeffs[j][mapArray[k]] = v;
754 }
755 }
756 }
757
759}
760
761} // namespace Nektar::SpatialDomains
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
static std::unique_ptr< DataType, UniquePtrDeleter > AllocateUniquePtr(const Args &...args)
3D geometry information
Definition Geometry3D.h:50
bool m_setupState
Wether or not the setup routines have been run.
Definition Geometry.h:190
GeomState m_state
Enumeration to dictate whether coefficients are filled.
Definition Geometry.h:188
void SetUpCoeffs(const int nCoeffs)
Initialise the Geometry::m_coeffs array.
Definition Geometry.h:694
int GetVid(int i) const
Returns global id of vertex i of this object.
Definition Geometry.h:345
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
Definition Geometry.h:199
virtual void v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated Geo...
Definition Geometry.cpp:366
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:314
PointGeom * GetVertex(int i) const
Returns vertex i of this object.
Definition Geometry.h:353
std::vector< Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition Geometry.h:196
LibUtilities::ShapeType m_shapeType
Type of shape.
Definition Geometry.h:192
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition Geometry.h:186
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition Geometry.h:440
Geometry1D * GetEdge(int i) const
Returns edge i of this object.
Definition Geometry.h:361
int m_coordim
Coordinate dimension of this geometry object.
Definition Geometry.h:184
int GetEid(int i) const
Get the ID of edge i of this object.
Definition Geometry.cpp:83
std::array< SegGeom *, kNedges > m_edges
Definition TetGeom.h:117
int v_GetEdgeFaceMap(const int i, const int j) const override
Returns the standard element edge IDs that are connected to a given face.
Definition TetGeom.cpp:103
std::array< StdRegions::Orientation, kNfaces > m_forient
Definition TetGeom.h:120
GeomFactorsUniquePtr v_GenGeomFactors(LibUtilities::PointsKeyVector &keyTgt) override
Used by Expansion to generate associated GeomFactors.
Definition TetGeom.cpp:654
int v_GetVertexFaceMap(const int i, const int j) const override
Returns the standard element face IDs that are connected to a given vertex.
Definition TetGeom.cpp:98
void v_FillGeom() override
Put all quadrature information into face/edge structure and backward transform.
Definition TetGeom.cpp:712
int v_GetVertexEdgeMap(const int i, const int j) const override
Returns the standard element edge IDs that are connected to a given vertex.
Definition TetGeom.cpp:93
static const unsigned int VertexEdgeConnectivity[4][3]
Definition TetGeom.h:129
static const unsigned int EdgeNormalToFaceVert[4][3]
Definition TetGeom.h:132
int v_GetEdgeNormalToFaceVert(const int i, const int j) const override
Returns the standard lement edge IDs that are normal to a given face vertex.
Definition TetGeom.cpp:108
std::array< TriGeom *, kNfaces > m_faces
Definition TetGeom.h:118
static const int kNfaces
Definition TetGeom.h:55
GeomType v_CalcGeomType() override
Definition TetGeom.cpp:611
void v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces) override
Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated Geo...
Definition TetGeom.cpp:574
static const int kNqfaces
Definition TetGeom.h:53
static const int kNtfaces
Definition TetGeom.h:54
void SetUpXmap()
Set up the m_xmap object by determining the order of each direction from derived faces.
Definition TetGeom.cpp:667
static const int kNedges
Definition TetGeom.h:52
std::array< PointGeom *, kNverts > m_verts
Definition TetGeom.h:116
int v_GetDir(const int faceidx, const int facedir) const override
Returns the element coordinate direction corresponding to a given face coordinate direction.
Definition TetGeom.cpp:77
static const unsigned int VertexFaceConnectivity[4][3]
Definition TetGeom.h:130
static const unsigned int EdgeFaceConnectivity[6][2]
Definition TetGeom.h:131
std::array< StdRegions::Orientation, kNedges > m_eorient
Definition TetGeom.h:119
static const int kNverts
Definition TriGeom.h:58
A simple factory for Xmap objects that is based on the element type, the basis and quadrature selecti...
std::vector< PointsKey > PointsKeyVector
Definition Points.h:313
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eModified_B
Principle Modified Functions .
Definition BasisType.h:49
@ eModified_C
Principle Modified Functions .
Definition BasisType.h:50
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
static const NekDouble kNekZeroTol
unique_ptr_objpool< GeomFactors > GeomFactorsUniquePtr
Definition Geometry.h:62
XmapFactory< StdRegions::StdTetExp, 3 > & GetStdTetFactory()
Definition TetGeom.cpp:53
std::map< int, CurveUniquePtr > CurveMap
Definition Geometry.h:71
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eDeformed
Geometry is curved or has non-constant factors.
@ ePtsFilled
Geometric information has been generated.
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290