Nektar++
PrismGeom.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: PrismGeom.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: Prismatic geometry definition.
32//
33////////////////////////////////////////////////////////////////////////////////
34
41
42using namespace std;
43
44namespace Nektar
45{
46namespace SpatialDomains
47{
48
49const unsigned int PrismGeom::VertexEdgeConnectivity[6][3] = {
50 {0, 3, 4}, {0, 1, 5}, {1, 2, 6}, {2, 3, 7}, {4, 5, 8}, {6, 7, 8}};
51const unsigned int PrismGeom::VertexFaceConnectivity[6][3] = {
52 {0, 1, 4}, {0, 1, 2}, {0, 2, 3}, {0, 3, 4}, {1, 2, 4}, {2, 3, 4}};
53const unsigned int PrismGeom::EdgeFaceConnectivity[9][2] = {
54 {0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 4}, {1, 2}, {2, 3}, {3, 4}, {2, 4}};
55const unsigned int PrismGeom::EdgeNormalToFaceVert[5][4] = {
56 {4, 5, 6, 7}, {1, 3, 8, -1}, {0, 2, 4, 7}, {1, 3, 8, -1}, {0, 2, 5, 6}};
57
59{
61}
62
64 : Geometry3D(faces[0]->GetEdge(0)->GetVertex(0)->GetCoordim())
65{
67 m_globalID = id;
68
69 /// Copy the face shared pointers.
70 m_faces.insert(m_faces.begin(), faces, faces + PrismGeom::kNfaces);
71
72 /// Set up orientation vectors with correct amount of elements.
73 m_eorient.resize(kNedges);
74 m_forient.resize(kNfaces);
75
76 /// Set up local objects.
81}
82
84{
85}
86
87int PrismGeom::v_GetDir(const int faceidx, const int facedir) const
88{
89 if (faceidx == 0)
90 {
91 return facedir;
92 }
93 else if (faceidx == 1 || faceidx == 3)
94 {
95 return 2 * facedir;
96 }
97 else
98 {
99 return 1 + facedir;
100 }
101}
102
104{
105 if (!m_setupState)
106 {
108 }
109
111 {
112 GeomType Gtype = eRegular;
113
114 v_FillGeom();
115
116 // check to see if expansions are linear
117 m_straightEdge = true;
118 if (m_xmap->GetBasisNumModes(0) != 2 ||
119 m_xmap->GetBasisNumModes(1) != 2 ||
120 m_xmap->GetBasisNumModes(2) != 2)
121 {
122 Gtype = eDeformed;
123 m_straightEdge = false;
124 }
125
126 // check to see if all quadrilateral faces are parallelograms
127 if (Gtype == eRegular)
128 {
130 for (int i = 0; i < 3; ++i)
131 {
133 NekDouble A = (*m_verts[0])(i);
134 NekDouble B = (*m_verts[1])(i);
135 NekDouble C = (*m_verts[2])(i);
136 NekDouble D = (*m_verts[3])(i);
137 NekDouble E = (*m_verts[4])(i);
138 NekDouble F = (*m_verts[5])(i);
139 m_isoParameter[i][0] = 0.25 * (B + C + E + F);
140
141 m_isoParameter[i][1] = 0.25 * (-A + B + C - D); // xi1
142 m_isoParameter[i][2] = 0.25 * (-B + C - E + F); // xi2
143 m_isoParameter[i][3] = 0.25 * (-A - D + E + F); // xi3
144
145 m_isoParameter[i][4] = 0.25 * (A - B + C - D); // xi1*xi2
146 m_isoParameter[i][5] = 0.25 * (A - D - E + F); // xi2*xi3
147 NekDouble tmp = fabs(m_isoParameter[i][1]) +
148 fabs(m_isoParameter[i][2]) +
149 fabs(m_isoParameter[i][3]);
151 for (int d = 4; d < 6; ++d)
152 {
153 if (fabs(m_isoParameter[i][d]) > tmp)
154 {
155 Gtype = eDeformed;
156 }
157 }
158 }
159 }
160
161 if (Gtype == eRegular)
162 {
164 }
165
167 Gtype, m_coordim, m_xmap, m_coeffs);
169 }
170}
171
172int PrismGeom::v_GetVertexEdgeMap(const int i, const int j) const
173{
174 return VertexEdgeConnectivity[i][j];
175}
176
177int PrismGeom::v_GetVertexFaceMap(const int i, const int j) const
178{
179 return VertexFaceConnectivity[i][j];
180}
181
182int PrismGeom::v_GetEdgeFaceMap(const int i, const int j) const
183{
184 return EdgeFaceConnectivity[i][j];
185}
186
187int PrismGeom::v_GetEdgeNormalToFaceVert(const int i, const int j) const
188{
189 return EdgeNormalToFaceVert[i][j];
190}
191
193{
194 // find edge 0
195 int i, j;
196 unsigned int check;
197
198 SegGeomSharedPtr edge;
199
200 // First set up the 4 bottom edges
201 int f; // Connected face index
202 for (f = 1; f < 5; f++)
203 {
204 int nEdges = m_faces[f]->GetNumEdges();
205 check = 0;
206 for (i = 0; i < 4; i++)
207 {
208 for (j = 0; j < nEdges; j++)
209 {
210 if (m_faces[0]->GetEid(i) == m_faces[f]->GetEid(j))
211 {
212 edge =
213 dynamic_pointer_cast<SegGeom>((m_faces[0])->GetEdge(i));
214 m_edges.push_back(edge);
215 check++;
216 }
217 }
218 }
219
220 if (check < 1)
221 {
222 std::ostringstream errstrm;
223 errstrm << "Connected faces do not share an edge. Faces ";
224 errstrm << (m_faces[0])->GetGlobalID() << ", "
225 << (m_faces[f])->GetGlobalID();
226 ASSERTL0(false, errstrm.str());
227 }
228 else if (check > 1)
229 {
230 std::ostringstream errstrm;
231 errstrm << "Connected faces share more than one edge. Faces ";
232 errstrm << (m_faces[0])->GetGlobalID() << ", "
233 << (m_faces[f])->GetGlobalID();
234 ASSERTL0(false, errstrm.str());
235 }
236 }
237
238 // Then, set up the 4 vertical edges
239 check = 0;
240 for (i = 0; i < 3; i++) // Set up the vertical edge :face(1) and face(4)
241 {
242 for (j = 0; j < 4; j++)
243 {
244 if ((m_faces[1])->GetEid(i) == (m_faces[4])->GetEid(j))
245 {
246 edge = dynamic_pointer_cast<SegGeom>((m_faces[1])->GetEdge(i));
247 m_edges.push_back(edge);
248 check++;
249 }
250 }
251 }
252 if (check < 1)
253 {
254 std::ostringstream errstrm;
255 errstrm << "Connected faces do not share an edge. Faces ";
256 errstrm << (m_faces[1])->GetGlobalID() << ", "
257 << (m_faces[4])->GetGlobalID();
258 ASSERTL0(false, errstrm.str());
259 }
260 else if (check > 1)
261 {
262 std::ostringstream errstrm;
263 errstrm << "Connected faces share more than one edge. Faces ";
264 errstrm << (m_faces[1])->GetGlobalID() << ", "
265 << (m_faces[4])->GetGlobalID();
266 ASSERTL0(false, errstrm.str());
267 }
268 // Set up vertical edges: face(1) through face(4)
269 for (f = 1; f < 4; f++)
270 {
271 check = 0;
272 for (i = 0; i < m_faces[f]->GetNumEdges(); i++)
273 {
274 for (j = 0; j < m_faces[f + 1]->GetNumEdges(); j++)
275 {
276 if ((m_faces[f])->GetEid(i) == (m_faces[f + 1])->GetEid(j))
277 {
278 edge =
279 dynamic_pointer_cast<SegGeom>((m_faces[f])->GetEdge(i));
280 m_edges.push_back(edge);
281 check++;
282 }
283 }
284 }
285
286 if (check < 1)
287 {
288 std::ostringstream errstrm;
289 errstrm << "Connected faces do not share an edge. Faces ";
290 errstrm << (m_faces[f])->GetGlobalID() << ", "
291 << (m_faces[f + 1])->GetGlobalID();
292 ASSERTL0(false, errstrm.str());
293 }
294 else if (check > 1)
295 {
296 std::ostringstream errstrm;
297 errstrm << "Connected faces share more than one edge. Faces ";
298 errstrm << (m_faces[f])->GetGlobalID() << ", "
299 << (m_faces[f + 1])->GetGlobalID();
300 ASSERTL0(false, errstrm.str());
301 }
302 }
303
304 // Finally, set up the 1 top edge
305 check = 0;
306 for (i = 0; i < 4; i++)
307 {
308 for (j = 0; j < 4; j++)
309 {
310 if ((m_faces[2])->GetEid(i) == (m_faces[4])->GetEid(j))
311 {
312 edge = dynamic_pointer_cast<SegGeom>((m_faces[2])->GetEdge(i));
313 m_edges.push_back(edge);
314 check++;
315 }
316 }
317 }
318
319 if (check < 1)
320 {
321 std::ostringstream errstrm;
322 errstrm << "Connected faces do not share an edge. Faces ";
323 errstrm << (m_faces[1])->GetGlobalID() << ", "
324 << (m_faces[3])->GetGlobalID();
325 ASSERTL0(false, errstrm.str());
326 }
327 else if (check > 1)
328 {
329 std::ostringstream errstrm;
330 errstrm << "Connected faces share more than one edge. Faces ";
331 errstrm << (m_faces[1])->GetGlobalID() << ", "
332 << (m_faces[3])->GetGlobalID();
333 ASSERTL0(false, errstrm.str());
334 }
335}
336
338{
339
340 // Set up the first 2 vertices (i.e. vertex 0,1)
341 if ((m_edges[0]->GetVid(0) == m_edges[1]->GetVid(0)) ||
342 (m_edges[0]->GetVid(0) == m_edges[1]->GetVid(1)))
343 {
344 m_verts.push_back(m_edges[0]->GetVertex(1));
345 m_verts.push_back(m_edges[0]->GetVertex(0));
346 }
347 else if ((m_edges[0]->GetVid(1) == m_edges[1]->GetVid(0)) ||
348 (m_edges[0]->GetVid(1) == m_edges[1]->GetVid(1)))
349 {
350 m_verts.push_back(m_edges[0]->GetVertex(0));
351 m_verts.push_back(m_edges[0]->GetVertex(1));
352 }
353 else
354 {
355 std::ostringstream errstrm;
356 errstrm << "Connected edges do not share a vertex. Edges ";
357 errstrm << m_edges[0]->GetGlobalID() << ", "
358 << m_edges[1]->GetGlobalID();
359 ASSERTL0(false, errstrm.str());
360 }
361
362 // set up the other bottom vertices (i.e. vertex 2,3)
363 for (int i = 1; i < 3; i++)
364 {
365 if (m_edges[i]->GetVid(0) == m_verts[i]->GetGlobalID())
366 {
367 m_verts.push_back(m_edges[i]->GetVertex(1));
368 }
369 else if (m_edges[i]->GetVid(1) == m_verts[i]->GetGlobalID())
370 {
371 m_verts.push_back(m_edges[i]->GetVertex(0));
372 }
373 else
374 {
375 std::ostringstream errstrm;
376 errstrm << "Connected edges do not share a vertex. Edges ";
377 errstrm << m_edges[i]->GetGlobalID() << ", "
378 << m_edges[i - 1]->GetGlobalID();
379 ASSERTL0(false, errstrm.str());
380 }
381 }
382
383 // set up top vertices
384 // First, set up vertices 4,5
385 if ((m_edges[8]->GetVid(0) == m_edges[4]->GetVid(0)) ||
386 (m_edges[8]->GetVid(0) == m_edges[4]->GetVid(1)))
387 {
388 m_verts.push_back(m_edges[8]->GetVertex(0));
389 m_verts.push_back(m_edges[8]->GetVertex(1));
390 }
391 else if ((m_edges[8]->GetVid(1) == m_edges[4]->GetVid(0)) ||
392 (m_edges[8]->GetVid(1) == m_edges[4]->GetVid(1)))
393 {
394 m_verts.push_back(m_edges[8]->GetVertex(1));
395 m_verts.push_back(m_edges[8]->GetVertex(0));
396 }
397 else
398 {
399 std::ostringstream errstrm;
400 errstrm << "Connected edges do not share a vertex. Edges ";
401 errstrm << m_edges[8]->GetGlobalID();
402 ASSERTL0(false, errstrm.str());
403 }
404}
405
407{
408
409 // This 2D array holds the local id's of all the vertices
410 // for every edge. For every edge, they are ordered to what we
411 // define as being Forwards
412 const unsigned int edgeVerts[kNedges][2] = {
413 {0, 1}, {1, 2}, {3, 2}, {0, 3}, {0, 4}, {1, 4}, {2, 5}, {3, 5}, {4, 5}};
414
415 int i;
416 for (i = 0; i < kNedges; i++)
417 {
418 if (m_edges[i]->GetVid(0) == m_verts[edgeVerts[i][0]]->GetGlobalID())
419 {
421 }
422 else if (m_edges[i]->GetVid(0) ==
423 m_verts[edgeVerts[i][1]]->GetGlobalID())
424 {
426 }
427 else
428 {
429 ASSERTL0(false, "Could not find matching vertex for the edge");
430 }
431 }
432}
433
435{
436 int f, i;
437
438 // These arrays represent the vector of the A and B
439 // coordinate of the local elemental coordinate system
440 // where A corresponds with the coordinate direction xi_i
441 // with the lowest index i (for that particular face)
442 // Coordinate 'B' then corresponds to the other local
443 // coordinate (i.e. with the highest index)
444 Array<OneD, NekDouble> elementAaxis(m_coordim);
445 Array<OneD, NekDouble> elementBaxis(m_coordim);
446
447 // These arrays correspond to the local coordinate
448 // system of the face itself (i.e. the Geometry2D)
449 // faceAaxis correspond to the xi_0 axis
450 // faceBaxis correspond to the xi_1 axis
453
454 // This is the base vertex of the face (i.e. the Geometry2D)
455 // This corresponds to thevertex with local ID 0 of the
456 // Geometry2D
457 unsigned int baseVertex;
458
459 // The lenght of the vectors above
460 NekDouble elementAaxis_length;
461 NekDouble elementBaxis_length;
462 NekDouble faceAaxis_length;
463 NekDouble faceBaxis_length;
464
465 // This 2D array holds the local id's of all the vertices
466 // for every face. For every face, they are ordered in such
467 // a way that the implementation below allows a unified approach
468 // for all faces.
469 const unsigned int faceVerts[kNfaces][QuadGeom::kNverts] = {
470 {0, 1, 2, 3},
471 {0, 1, 4, 0}, // This is triangle requires only three vertices
472 {1, 2, 5, 4},
473 {3, 2, 5, 0}, // This is triangle requires only three vertices
474 {0, 3, 5, 4},
475 };
476
477 NekDouble dotproduct1 = 0.0;
478 NekDouble dotproduct2 = 0.0;
479
480 unsigned int orientation;
481
482 // Loop over all the faces to set up the orientation
483 for (f = 0; f < kNqfaces + kNtfaces; f++)
484 {
485 // initialisation
486 elementAaxis_length = 0.0;
487 elementBaxis_length = 0.0;
488 faceAaxis_length = 0.0;
489 faceBaxis_length = 0.0;
490
491 dotproduct1 = 0.0;
492 dotproduct2 = 0.0;
493
494 baseVertex = m_faces[f]->GetVid(0);
495
496 // We are going to construct the vectors representing the A and B axis
497 // of every face. These vectors will be constructed as a
498 // vector-representation
499 // of the edges of the face. However, for both coordinate directions, we
500 // can
501 // represent the vectors by two different edges. That's why we need to
502 // make sure that
503 // we pick the edge to which the baseVertex of the
504 // Geometry2D-representation of the face
505 // belongs...
506
507 // Compute the length of edges on a base-face
508 if (f == 1 || f == 3)
509 { // Face is a Triangle
510 if (baseVertex == m_verts[faceVerts[f][0]]->GetVid())
511 {
512 for (i = 0; i < m_coordim; i++)
513 {
514 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
515 (*m_verts[faceVerts[f][0]])[i];
516 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
517 (*m_verts[faceVerts[f][0]])[i];
518 }
519 }
520 else if (baseVertex == m_verts[faceVerts[f][1]]->GetVid())
521 {
522 for (i = 0; i < m_coordim; i++)
523 {
524 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
525 (*m_verts[faceVerts[f][0]])[i];
526 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
527 (*m_verts[faceVerts[f][1]])[i];
528 }
529 }
530 else if (baseVertex == m_verts[faceVerts[f][2]]->GetVid())
531 {
532 for (i = 0; i < m_coordim; i++)
533 {
534 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
535 (*m_verts[faceVerts[f][2]])[i];
536 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
537 (*m_verts[faceVerts[f][0]])[i];
538 }
539 }
540 else
541 {
542 ASSERTL0(false, "Could not find matching vertex for the face");
543 }
544 }
545 else
546 { // Face is a Quad
547 if (baseVertex == m_verts[faceVerts[f][0]]->GetGlobalID())
548 {
549 for (i = 0; i < m_coordim; i++)
550 {
551 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
552 (*m_verts[faceVerts[f][0]])[i];
553 elementBaxis[i] = (*m_verts[faceVerts[f][3]])[i] -
554 (*m_verts[faceVerts[f][0]])[i];
555 }
556 }
557 else if (baseVertex == m_verts[faceVerts[f][1]]->GetGlobalID())
558 {
559 for (i = 0; i < m_coordim; i++)
560 {
561 elementAaxis[i] = (*m_verts[faceVerts[f][1]])[i] -
562 (*m_verts[faceVerts[f][0]])[i];
563 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
564 (*m_verts[faceVerts[f][1]])[i];
565 }
566 }
567 else if (baseVertex == m_verts[faceVerts[f][2]]->GetGlobalID())
568 {
569 for (i = 0; i < m_coordim; i++)
570 {
571 elementAaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
572 (*m_verts[faceVerts[f][3]])[i];
573 elementBaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
574 (*m_verts[faceVerts[f][1]])[i];
575 }
576 }
577 else if (baseVertex == m_verts[faceVerts[f][3]]->GetGlobalID())
578 {
579 for (i = 0; i < m_coordim; i++)
580 {
581 elementAaxis[i] = (*m_verts[faceVerts[f][2]])[i] -
582 (*m_verts[faceVerts[f][3]])[i];
583 elementBaxis[i] = (*m_verts[faceVerts[f][3]])[i] -
584 (*m_verts[faceVerts[f][0]])[i];
585 }
586 }
587 else
588 {
589 ASSERTL0(false, "Could not find matching vertex for the face");
590 }
591 }
592 // Now, construct the edge-vectors of the local coordinates of
593 // the Geometry2D-representation of the face
594 for (i = 0; i < m_coordim; i++)
595 {
596 int v = m_faces[f]->GetNumVerts() - 1;
597 faceAaxis[i] =
598 (*m_faces[f]->GetVertex(1))[i] - (*m_faces[f]->GetVertex(0))[i];
599 faceBaxis[i] =
600 (*m_faces[f]->GetVertex(v))[i] - (*m_faces[f]->GetVertex(0))[i];
601
602 elementAaxis_length += pow(elementAaxis[i], 2);
603 elementBaxis_length += pow(elementBaxis[i], 2);
604 faceAaxis_length += pow(faceAaxis[i], 2);
605 faceBaxis_length += pow(faceBaxis[i], 2);
606 }
607
608 elementAaxis_length = sqrt(elementAaxis_length);
609 elementBaxis_length = sqrt(elementBaxis_length);
610 faceAaxis_length = sqrt(faceAaxis_length);
611 faceBaxis_length = sqrt(faceBaxis_length);
612
613 // Calculate the inner product of both the A-axis
614 // (i.e. Elemental A axis and face A axis)
615 for (i = 0; i < m_coordim; i++)
616 {
617 dotproduct1 += elementAaxis[i] * faceAaxis[i];
618 }
619
620 orientation = 0;
621
622 // if the innerproduct is equal to the (absolute value of the ) products
623 // of the lengths of both vectors, then, the coordinate systems will NOT
624 // be transposed
625 if (fabs(elementAaxis_length * faceAaxis_length - fabs(dotproduct1)) <
627 {
628 // if the inner product is negative, both A-axis point
629 // in reverse direction
630 if (dotproduct1 < 0.0)
631 {
632 orientation += 2;
633 }
634
635 // calculate the inner product of both B-axis
636 for (i = 0; i < m_coordim; i++)
637 {
638 dotproduct2 += elementBaxis[i] * faceBaxis[i];
639 }
640
641 ASSERTL1(fabs(fabs(dotproduct2 / elementBaxis_length /
642 faceBaxis_length) -
644 "These vectors should be parallel");
645
646 // if the inner product is negative, both B-axis point
647 // in reverse direction
648 if (dotproduct2 < 0.0)
649 {
650 orientation++;
651 }
652 }
653 // The coordinate systems are transposed
654 else
655 {
656 orientation = 4;
657
658 // Calculate the inner product between the elemental A-axis
659 // and the B-axis of the face (which are now the corresponding axis)
660 dotproduct1 = 0.0;
661 for (i = 0; i < m_coordim; i++)
662 {
663 dotproduct1 += elementAaxis[i] * faceBaxis[i];
664 }
665
666 // check that both these axis are indeed parallel
667 ASSERTL1(fabs(fabs(dotproduct1) / elementAaxis_length /
668 faceBaxis_length -
670 "These vectors should be parallel");
671
672 // if the result is negative, both axis point in reverse
673 // directions
674 if (dotproduct1 < 0.0)
675 {
676 orientation += 2;
677 }
678
679 // Do the same for the other two corresponding axis
680 dotproduct2 = 0.0;
681 for (i = 0; i < m_coordim; i++)
682 {
683 dotproduct2 += elementBaxis[i] * faceAaxis[i];
684 }
685
686 ASSERTL1(fabs(fabs(dotproduct2) / elementBaxis_length /
687 faceAaxis_length -
689 "These vectors should be parallel");
690
691 if (dotproduct2 < 0.0)
692 {
693 orientation++;
694 }
695 }
696
697 orientation = orientation + 5;
698
699 if ((f == 1) || (f == 3)) // check triange orientation
700 {
701 ASSERTL0(
703 "Orientation of triangular face (id = " +
704 boost::lexical_cast<string>(m_faces[f]->GetGlobalID()) +
705 ") is inconsistent with face " +
706 boost::lexical_cast<string>(f) +
707 " of prism element (id = " +
708 boost::lexical_cast<string>(m_globalID) +
709 ") since Dir2 is aligned with Dir1. Mesh setup "
710 "needs investigation");
711 }
712
713 // Fill the m_forient array
714 m_forient[f] = (StdRegions::Orientation)orientation;
715 }
716}
717
718void PrismGeom::v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
719{
720 Geometry::v_Reset(curvedEdges, curvedFaces);
721
722 for (int i = 0; i < 5; ++i)
723 {
724 m_faces[i]->Reset(curvedEdges, curvedFaces);
725 }
726}
727
729{
730 if (!m_setupState)
731 {
732 for (int i = 0; i < 5; ++i)
733 {
734 m_faces[i]->Setup();
735 }
736 SetUpXmap();
737 SetUpCoeffs(m_xmap->GetNcoeffs());
738 m_setupState = true;
739 }
740}
741
742/**
743 * @brief Set up the #m_xmap object by determining the order of each
744 * direction from derived faces.
745 */
747{
748 vector<int> tmp;
749 int order0, order1;
750
751 if (m_forient[0] < 9)
752 {
753 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(0));
754 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(2));
755 order0 = *max_element(tmp.begin(), tmp.end());
756 }
757 else
758 {
759 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(1));
760 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(3));
761 order0 = *max_element(tmp.begin(), tmp.end());
762 }
763
764 if (m_forient[0] < 9)
765 {
766 tmp.clear();
767 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(1));
768 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(3));
769 tmp.push_back(m_faces[2]->GetXmap()->GetTraceNcoeffs(2));
770 order1 = *max_element(tmp.begin(), tmp.end());
771 }
772 else
773 {
774 tmp.clear();
775 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(0));
776 tmp.push_back(m_faces[0]->GetXmap()->GetTraceNcoeffs(2));
777 tmp.push_back(m_faces[2]->GetXmap()->GetTraceNcoeffs(2));
778 order1 = *max_element(tmp.begin(), tmp.end());
779 }
780
781 tmp.clear();
782 tmp.push_back(order0);
783 tmp.push_back(order1);
784 tmp.push_back(m_faces[1]->GetXmap()->GetTraceNcoeffs(1));
785 tmp.push_back(m_faces[1]->GetXmap()->GetTraceNcoeffs(2));
786 tmp.push_back(m_faces[3]->GetXmap()->GetTraceNcoeffs(1));
787 tmp.push_back(m_faces[3]->GetXmap()->GetTraceNcoeffs(2));
788 int order2 = *max_element(tmp.begin(), tmp.end());
789
792 LibUtilities::PointsKey(order0 + 1,
796 LibUtilities::PointsKey(order1 + 1,
800 LibUtilities::PointsKey(order2, LibUtilities::eGaussRadauMAlpha1Beta0));
801
803}
804
805} // namespace SpatialDomains
806} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
Describes the specification for a Basis.
Definition: Basis.h:47
Defines a specification for a set of points.
Definition: Points.h:55
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
3D geometry information
Definition: Geometry3D.h:68
std::vector< StdRegions::Orientation > m_forient
Definition: Geometry3D.h:84
virtual void v_CalculateInverseIsoParam() override
Definition: Geometry3D.cpp:572
virtual void v_FillGeom() override
Put all quadrature information into face/edge structure and backward transform.
Definition: Geometry3D.cpp:449
std::vector< StdRegions::Orientation > m_eorient
Definition: Geometry3D.h:83
bool m_setupState
Wether or not the setup routines have been run.
Definition: Geometry.h:196
PointGeomSharedPtr GetVertex(int i) const
Returns vertex i of this object.
Definition: Geometry.h:358
void SetUpCoeffs(const int nCoeffs)
Initialise the Geometry::m_coeffs array.
Definition: Geometry.h:690
Geometry1DSharedPtr GetEdge(int i) const
Returns edge i of this object.
Definition: Geometry.h:366
int GetVid(int i) const
Get the ID of vertex i of this object.
Definition: Geometry.cpp:139
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
Definition: Geometry.h:207
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:390
int GetGlobalID(void) const
Get the ID of this object.
Definition: Geometry.h:327
LibUtilities::ShapeType m_shapeType
Type of shape.
Definition: Geometry.h:200
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition: Geometry.h:204
GeomState m_geomFactorsState
State of the geometric factors.
Definition: Geometry.h:190
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition: Geometry.h:192
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition: Geometry.h:436
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
Definition: Geometry.h:188
int m_coordim
Coordinate dimension of this geometry object.
Definition: Geometry.h:186
int GetEid(int i) const
Get the ID of edge i of this object.
Definition: Geometry.cpp:147
virtual 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: PrismGeom.cpp:718
static const unsigned int EdgeFaceConnectivity[9][2]
Definition: PrismGeom.h:81
virtual 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: PrismGeom.cpp:177
void SetUpXmap()
Set up the m_xmap object by determining the order of each direction from derived faces.
Definition: PrismGeom.cpp:746
virtual int v_GetDir(const int faceidx, const int facedir) const override
Returns the element coordinate direction corresponding to a given face coordinate direction.
Definition: PrismGeom.cpp:87
virtual void v_GenGeomFactors() override
Definition: PrismGeom.cpp:103
static const unsigned int EdgeNormalToFaceVert[5][4]
Definition: PrismGeom.h:82
virtual 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: PrismGeom.cpp:182
virtual 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: PrismGeom.cpp:187
static const unsigned int VertexFaceConnectivity[6][3]
Definition: PrismGeom.h:80
virtual void v_Setup() override
Definition: PrismGeom.cpp:728
static const unsigned int VertexEdgeConnectivity[6][3]
Definition: PrismGeom.h:79
virtual 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: PrismGeom.cpp:172
static const int kNverts
Definition: QuadGeom.h:75
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:53
@ eModified_B
Principle Modified Functions .
Definition: BasisType.h:51
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:50
static const NekDouble kNekZeroTol
std::unordered_map< int, CurveSharedPtr > CurveMap
Definition: Curve.hpp:61
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.
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
Definition: Geometry.h:65
@ ePtsFilled
Geometric information has been generated.
std::vector< double > d(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294