38 #include <loki/Singleton.h>
64 Loki::NoDestroy > Type;
65 return Type::Instance();
69 unsigned int pNumNodes,
70 unsigned int pGotNodes)
75 if (pNumNodes != pGotNodes)
77 cerr <<
"Number of modes mismatch for type "
78 << pConf.
m_e <<
"! Should be " << pNumNodes
79 <<
" but got " << pGotNodes <<
" nodes." << endl;
98 unsigned int i, nElmt = 0;
112 unsigned int nEnt = 0;
114 for (
unsigned int d = 0; d <=
m_expDim; ++d)
128 int i, n = c1->type.size();
130 if (n != c2->type.size())
135 for (i = 0; i < n; ++i)
137 if (c1->type[i] != c2->type[i])
142 if (c1->field[i] != c2->field[i] || c1->value[i] != c2->value[i])
169 os << n->m_x <<
" " << n->m_y <<
" " << n->m_z;
179 return ( ((*(p1->m_n1) == *(p2->m_n1)) && (*(p1->m_n2) == *(p2->m_n2)))
180 || ((*(p1->m_n2) == *(p2->m_n1)) && (*(p1->m_n1) == *(p2->m_n2))));
188 return p1->m_id < p2->m_id;
198 for (it1 = p1->m_vertexList.begin(); it1 != p1->m_vertexList.end(); ++it1)
200 if (
find(p2->m_vertexList.begin(), p2->m_vertexList.end(), *it1)
201 == p2->m_vertexList.end())
215 return p1->m_id < p2->m_id;
232 for (
unsigned int i = 0; i <
m_edge.size(); ++i)
234 if (
m_edge[i]->m_n1 == vOld)
238 else if (
m_edge[i]->m_n2 == vOld)
243 for (
unsigned int i = 0; i <
m_face.size(); ++i)
246 for (
unsigned int j = 0; j <
m_face[i]->m_vertexList.size(); ++j)
248 if (
m_face[i]->m_vertexList[j] == vOld)
250 m_face[i]->m_vertexList[j] = pNew;
253 for (
unsigned int j = 0; j <
m_face[i]->m_edgeList.size(); ++j)
255 if (
m_face[i]->m_edgeList[j]->m_n1 == vOld)
257 m_face[i]->m_edgeList[j]->m_n1 = pNew;
259 else if (
m_face[i]->m_edgeList[j]->m_n2 == vOld)
261 m_face[i]->m_edgeList[j]->m_n2 = pNew;
280 for (
unsigned int i = 0; i <
m_face.size(); ++i)
282 for (
unsigned int j = 0; j <
m_face[i]->m_edgeList.size(); ++j)
284 if (
m_face[i]->m_edgeList[j] == vOld)
286 m_face[i]->m_edgeList[j] = pNew;
312 for (i = 0; i <
m_edge.size(); ++i)
314 int edgeOrder =
m_edge[i]->GetNodeCount()-1;
333 #if 0 // turn this option off since causes problem with InputNekpp.cpp
347 st <<
" " <<
m_tag <<
"[" << vId;
352 vId = (*it)->GetId();
355 if (prevId > -1 && vId == prevId + 1)
388 vector<NodeSharedPtr> pNodeList,
389 vector<int> pTagList)
390 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
414 vector<NodeSharedPtr> pNodeList,
415 vector<int> pTagList)
416 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
424 for (
int i = 0; i < 2; ++i) {
427 vector<NodeSharedPtr> edgeNodes;
429 for (
int j = 0; j<n; ++j) {
430 edgeNodes.push_back(pNodeList[2+j]);
433 m_edge.push_back(boost::shared_ptr<Edge>(
443 p[0] =
m_vertex[0]->GetGeom(coordDim);
444 p[1] =
m_vertex[1]->GetGeom(coordDim);
446 if (
m_edge[0]->m_edgeNodes.size() > 0)
452 c->m_points.push_back(p[0]);
453 for (
int i = 0; i <
m_edge[0]->m_edgeNodes.size(); ++i)
455 c->m_points.push_back(
m_edge[0]->m_edgeNodes[i]->
GetGeom(coordDim));
457 c->m_points.push_back(p[1]);
487 vector<NodeSharedPtr> pNodeList,
488 vector<int> pTagList)
489 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
500 map<pair<int,int>,
int> edgeNodeMap;
502 edgeNodeMap[pair<int,int>(1,2)] = 4;
503 edgeNodeMap[pair<int,int>(2,3)] = 4 + n;
504 edgeNodeMap[pair<int,int>(3,1)] = 4 + 2*n;
509 for (
int i = 0; i < 3; ++i) {
512 sum += (pNodeList[o]->m_x - pNodeList[i]->m_x) *
513 (pNodeList[o]->m_y + pNodeList[i]->m_y);
517 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
519 vector<NodeSharedPtr> edgeNodes;
521 for (
int j = it->second; j < it->second + n; ++j) {
522 edgeNodes.push_back(pNodeList[j-1]);
526 pNodeList[it->first.second-1],
553 for (
int i = 0; i < 3; ++i)
555 edges[i] =
m_edge [i]->GetGeom(coordDim);
556 verts[i] =
m_vertex[i]->GetGeom(coordDim);
578 return (n+1)+2*(n-1)+1;
580 return (n+1)*(n+2)/2;
623 int nqtot = tri->GetTotPoints();
633 tri->GetCoords(xi, yi, zi);
635 for (i = 0; i < 3; ++i)
638 tri->FwdTrans(alloc+i*nqtot, coeffs);
640 nodalTri->ModalToNodal(coeffs, tmp=alloc+(i+3)*nqtot);
645 for (i = 0; i < 3; ++i)
647 int pos = 3 + i*(order-1);
648 m_edge[i]->m_edgeNodes.clear();
649 for (j = 0; j < order-1; ++j)
651 m_edge[i]->m_edgeNodes.push_back(
657 int pos = 3 + 3*(order-1);
658 for (i = pos; i < (order+1)*(order+2)/2; ++i)
678 vector<NodeSharedPtr> pNodeList,
679 vector<int> pTagList)
680 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
690 map<pair<int,int>,
int> edgeNodeMap;
692 edgeNodeMap[pair<int,int>(1,2)] = 5;
693 edgeNodeMap[pair<int,int>(2,3)] = 5 + n;
694 edgeNodeMap[pair<int,int>(3,4)] = 5 + 2*n;
695 edgeNodeMap[pair<int,int>(4,1)] = 5 + 3*n;
700 for (
int i = 0; i < 4; ++i) {
703 sum += (pNodeList[o]->m_x - pNodeList[i]->m_x) *
704 (pNodeList[o]->m_y + pNodeList[i]->m_y);
708 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
710 vector<NodeSharedPtr> edgeNodes;
712 for (
int j = it->second; j < it->second + n; ++j) {
713 edgeNodes.push_back(pNodeList[j-1]);
717 pNodeList[it->first.second-1],
755 int nqtot = quad->GetTotPoints();
761 quad->GetCoords(x, y, z);
765 int edgeMap[4][2] = {{0,1},{order,order+1},
766 {nqtot-1,-1},{order*(order+1),-order-1}};
768 for (
int i = 0; i < 4; ++i)
770 int pos = edgeMap[i][0] + edgeMap[i][1];
771 m_edge[i]->m_edgeNodes.clear();
772 for (
int j = 1; j < order; ++j, pos += edgeMap[i][1])
774 m_edge[i]->m_edgeNodes.push_back(
781 for (
int i = 1; i < order; ++i)
783 int pos = i*(order+1);
784 for (
int j = 1; j < order; ++j)
802 for (
int i = 0; i < 4; ++i)
804 edges[i] =
m_edge [i]->GetGeom(coordDim);
805 verts[i] =
m_vertex[i]->GetGeom(coordDim);
841 vector<NodeSharedPtr> pNodeList,
842 vector<int> pTagList)
852 map<pair<int,int>,
int> edgeNodeMap;
854 edgeNodeMap[pair<int,int>(1,2)] = 5;
855 edgeNodeMap[pair<int,int>(2,3)] = 5 + n;
856 edgeNodeMap[pair<int,int>(1,3)] = 5 + 2*n;
857 edgeNodeMap[pair<int,int>(1,4)] = 5 + 3*n;
858 edgeNodeMap[pair<int,int>(2,4)] = 5 + 4*n;
859 edgeNodeMap[pair<int,int>(3,4)] = 5 + 5*n;
862 for (
int i = 0; i < 4; ++i)
869 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
871 vector<NodeSharedPtr> edgeNodes;
873 for (
int j = it->second; j < it->second + n; ++j) {
874 edgeNodes.push_back(pNodeList[j-1]);
879 pNodeList[it->first.second-1],
882 m_edge.back()->m_id = eid++;
895 for (
int i = 0; i < 4; ++i)
902 int face_ids[4][3] = {
903 {0,1,2}, {0,1,3}, {1,2,3}, {0,2,3}
907 int face_edges[4][3];
910 for (
int j = 0; j < 4; ++j)
912 vector<NodeSharedPtr> faceVertices;
913 vector<EdgeSharedPtr> faceEdges;
914 vector<NodeSharedPtr> faceNodes;
919 for (
int k = 0; k < 3; ++k)
921 faceVertices.push_back(
m_vertex[face_ids[j][k]]);
924 for (
unsigned int i = 0; i <
m_edge.size(); ++i)
926 if ( ((*(
m_edge[i]->m_n1)==*a) && (*(
m_edge[i]->m_n2)==*b))
927 || ((*(
m_edge[i]->m_n1)==*b) && (*(
m_edge[i]->m_n2) == *a)) )
929 face_edges[j][k] = i;
930 faceEdges.push_back(
m_edge[i]);
942 const int nFaceNodes = n*(n-1)/2;
945 vector<int> faceIds(3);
946 faceIds[0] = faceVertices[0]->m_id;
947 faceIds[1] = faceVertices[1]->m_id;
948 faceIds[2] = faceVertices[2]->m_id;
953 for (
int i = 0; i < 4; ++i)
962 ASSERTL0(origFace >= 0,
"Couldn't find face");
965 int N = 4 + 6*n + origFace * nFaceNodes;
966 for (
int i = 0; i < nFaceNodes; ++i)
968 faceNodes.push_back(pNodeList[N+i]);
972 vector<int> origFaceIds(3);
973 origFaceIds[0] = pNodeList[face_ids[origFace][0]]->m_id;
974 origFaceIds[1] = pNodeList[face_ids[origFace][1]]->m_id;
975 origFaceIds[2] = pNodeList[face_ids[origFace][2]]->m_id;
980 hoTri.
Align(faceIds);
990 vector<EdgeSharedPtr> tmp(6);
991 tmp[0] =
m_edge[face_edges[0][0]];
992 tmp[1] =
m_edge[face_edges[0][1]];
993 tmp[2] =
m_edge[face_edges[0][2]];
994 tmp[3] =
m_edge[face_edges[1][2]];
995 tmp[4] =
m_edge[face_edges[1][1]];
996 tmp[5] =
m_edge[face_edges[2][1]];
1005 for (
int i = 0; i < 4; ++i)
1007 tfaces[i] = boost::dynamic_pointer_cast
1024 return (n+1)*(n+2)*(n+3)/6;
1026 return 4*(n+1)*(n+2)/2-6*(n+1)+4;
1060 nodalTet->GetNodalPoints(x,y,z);
1086 int nqtot = tet->GetTotPoints();
1096 tet->GetCoords(xi, yi, zi);
1098 for (i = 0; i < 3; ++i)
1101 tet->FwdTrans(alloc+i*nqtot, coeffs);
1103 nodalTet->ModalToNodal(coeffs, tmp=alloc+(i+3)*nqtot);
1108 for (i = 0; i < 6; ++i)
1110 int pos = 4 + i*(order-1);
1111 m_edge[i]->m_edgeNodes.clear();
1112 for (j = 0; j < order-1; ++j)
1114 m_edge[i]->m_edgeNodes.push_back(
1120 for (i = 0; i < 4; ++i)
1122 int pos = 4 + 6*(order-1) + i*(order-2)*(order-1)/2;
1123 m_face[i]->m_faceNodes.clear();
1124 for (j = 0; j < (order-2)*(order-1)/2; ++j)
1126 m_face[i]->m_faceNodes.push_back(
1132 int pos = 4 + 6*(order-1) + 4*(order-2)*(order-1)/2;
1133 for (i = pos; i < (order+1)*(order+2)*(order+3)/6; ++i)
1155 return boost::hash_range(p.
nid.begin(), p.
nid.end());
1158 typedef boost::unordered_set<struct TetOrient, TetOrientHash>
TetOrientSet;
1162 if (a.
nid.size() != b.
nid.size())
1167 for (
int i = 0; i < a.
nid.size(); ++i)
1169 if (a.
nid[i] != b.
nid[i])
1193 static int face_ids[4][3] = {
1194 {0,1,2},{0,1,3},{1,2,3},{0,2,3}};
1201 for (
int i = 0; i < 4; ++i)
1203 vector<int> nodes(3);
1205 nodes[0] =
m_vertex[face_ids[i][0]]->m_id;
1206 nodes[1] =
m_vertex[face_ids[i][1]]->m_id;
1207 nodes[2] =
m_vertex[face_ids[i][2]]->m_id;
1209 sort(nodes.begin(), nodes.end());
1211 faces.insert(faceNodes);
1216 vector<NodeSharedPtr> origVert =
m_vertex;
1239 NekDouble nmag = sqrt(nx*nx+ny*ny+nz*nz);
1240 nx /= nmag; ny /= nmag; nz /= nmag;
1245 if (fabs(dist) <= 1e-4)
1247 cerr <<
"Warning: degenerate tetrahedron, 3rd vertex is = " << dist <<
" from face" << endl;
1258 nmag = sqrt(nx*nx+ny*ny+nz*nz);
1259 nx /= nmag; ny /= nmag; nz /= nmag;
1262 dist = bx*nx+by*ny+bz*nz;
1264 if (fabs(dist) <= 1e-4)
1266 cerr <<
"Warning: degenerate tetrahedron, 2nd vertex is = " << dist <<
" from face" << endl;
1272 nmag = sqrt(nx*nx+ny*ny+nz*nz);
1273 nx /= nmag; ny /= nmag; nz /= nmag;
1276 dist = ax*nx+ay*ny+az*nz;
1278 if (fabs(dist) <= 1e-4)
1280 cerr <<
"Warning: degenerate tetrahedron, 1st vertex is = " << dist <<
" from face" << endl;
1288 for (
int i = 0; i < 4; ++i)
1290 vector<int> nodes(3);
1292 nodes[0] =
m_vertex[face_ids[i][0]]->m_id;
1293 nodes[1] =
m_vertex[face_ids[i][1]]->m_id;
1294 nodes[2] =
m_vertex[face_ids[i][2]]->m_id;
1295 sort(nodes.begin(), nodes.end());
1299 it = faces.find(faceNodes);
1302 for (
int j = 0; j < 4; ++j)
1320 vector<NodeSharedPtr> pNodeList,
1321 vector<int> pTagList)
1322 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
1330 map<pair<int,int>,
int> edgeNodeMap;
1332 edgeNodeMap[pair<int,int>(1,2)] = 6;
1333 edgeNodeMap[pair<int,int>(2,3)] = 6 + n;
1334 edgeNodeMap[pair<int,int>(4,3)] = 6 + 2*n;
1335 edgeNodeMap[pair<int,int>(1,4)] = 6 + 3*n;
1336 edgeNodeMap[pair<int,int>(1,5)] = 6 + 4*n;
1337 edgeNodeMap[pair<int,int>(2,5)] = 6 + 5*n;
1338 edgeNodeMap[pair<int,int>(3,5)] = 6 + 6*n;
1339 edgeNodeMap[pair<int,int>(4,5)] = 6 + 7*n;
1342 for (
int i = 0; i < 5; ++i)
1349 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
1351 vector<NodeSharedPtr> edgeNodes;
1354 for (
int j = it->second; j < it->second + n; ++j)
1356 edgeNodes.push_back(pNodeList[j-1]);
1361 pNodeList[it->first.second-1],
1364 m_edge.back()->m_id = eid++;
1368 int face_ids[5][4] = {
1369 {0,1,2,3}, {0,1,4,-1}, {1,2,4,-1}, {3,2,4,-1}, {0,3,4,-1}
1371 int face_edges[5][4];
1372 int faceoffset = 5 + 8*n;
1373 for (
int j = 0; j < 5; ++j)
1375 vector<NodeSharedPtr> faceVertices;
1376 vector<EdgeSharedPtr> faceEdges;
1377 vector<NodeSharedPtr> faceNodes;
1378 int nEdge = j > 0 ? 3 : 4;
1380 for (
int k = 0; k < nEdge; ++k)
1382 faceVertices.push_back(
m_vertex[face_ids[j][k]]);
1385 for (
unsigned int i = 0; i <
m_edge.size(); ++i)
1390 faceEdges.push_back(
m_edge[i]);
1391 face_edges[j][k] = i;
1399 int facenodes = j == 0 ? n*n : n*(n-1)/2;
1400 for (
int i = 0; i < facenodes; ++i)
1402 faceNodes.push_back(pNodeList[faceoffset+i]);
1404 faceoffset += facenodes;
1411 vector<EdgeSharedPtr> tmp(8);
1412 tmp[0] =
m_edge[face_edges[0][0]];
1413 tmp[1] =
m_edge[face_edges[0][1]];
1414 tmp[2] =
m_edge[face_edges[0][2]];
1415 tmp[3] =
m_edge[face_edges[0][3]];
1416 tmp[4] =
m_edge[face_edges[1][2]];
1417 tmp[5] =
m_edge[face_edges[1][1]];
1418 tmp[6] =
m_edge[face_edges[3][1]];
1419 tmp[7] =
m_edge[face_edges[3][2]];
1427 for (
int i = 0; i < 5; ++i)
1429 faces[i] =
m_face[i]->GetGeom(coordDim);
1454 vector<NodeSharedPtr> pNodeList,
1455 vector<int> pTagList)
1456 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
1466 map<pair<int,int>,
int> edgeNodeMap;
1470 edgeNodeMap[pair<int,int>(1,2)] = 7;
1471 edgeNodeMap[pair<int,int>(2,3)] = 7 + n;
1472 edgeNodeMap[pair<int,int>(4,3)] = 7 + 2*n;
1473 edgeNodeMap[pair<int,int>(1,4)] = 7 + 3*n;
1474 edgeNodeMap[pair<int,int>(1,5)] = 7 + 4*n;
1475 edgeNodeMap[pair<int,int>(2,5)] = 7 + 5*n;
1476 edgeNodeMap[pair<int,int>(3,6)] = 7 + 6*n;
1477 edgeNodeMap[pair<int,int>(4,6)] = 7 + 7*n;
1478 edgeNodeMap[pair<int,int>(5,6)] = 7 + 8*n;
1481 for (
int i = 0; i < 6; ++i)
1488 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
1490 vector<NodeSharedPtr> edgeNodes;
1492 for (
int j = it->second; j < it->second + n; ++j) {
1493 edgeNodes.push_back(pNodeList[j-1]);
1497 new Edge(pNodeList[it->first.first-1],
1498 pNodeList[it->first.second-1],
1501 m_edge.back()->m_id = eid++;
1514 int face_ids[5][4] = {
1515 {0,1,2,3},{0,1,4,-1},{1,2,5,4},{3,2,5,-1},{0,3,5,4}};
1516 int face_edges[5][4];
1519 face_offset[0] = 6 + 9*n;
1520 for (
int j = 0; j < 4; ++j)
1522 int facenodes = j % 2 == 0 ? n*n : n*(n-1)/2;
1523 face_offset[j+1] = face_offset[j] + facenodes;
1526 for (
int j = 0; j < 5; ++j)
1528 vector<NodeSharedPtr> faceVertices;
1529 vector<EdgeSharedPtr> faceEdges;
1530 vector<NodeSharedPtr> faceNodes;
1531 int nEdge = 3 - (j % 2 - 1);
1533 for (
int k = 0; k < nEdge; ++k)
1535 faceVertices.push_back(
m_vertex[face_ids[j][k]]);
1539 for (i = 0; i <
m_edge.size(); ++i)
1541 if ((
m_edge[i]->m_n1->m_id == a->m_id
1542 &&
m_edge[i]->m_n2->m_id == b->m_id) ||
1543 (
m_edge[i]->m_n1->m_id == b->m_id
1544 &&
m_edge[i]->m_n2->m_id == a->m_id))
1546 faceEdges.push_back(
m_edge[i]);
1547 face_edges[j][k] = i;
1554 face_edges[j][k] = -1;
1560 int face = j, facenodes;
1567 face = (face+4) % 6;
1571 face = (face+2) % 6;
1577 facenodes = n*(n-1)/2;
1580 for (
int i = 0; i < facenodes; ++i)
1582 faceNodes.push_back(pNodeList[face_offset[face]+i]);
1590 vector<EdgeSharedPtr> tmp(9);
1591 ASSERTL1(face_edges[0][0] != -1,
"face_edges[0][0] == -1");
1592 tmp[0] =
m_edge[face_edges[0][0]];
1593 ASSERTL1(face_edges[0][1] != -1,
"face_edges[0][1] == -1");
1594 tmp[1] =
m_edge[face_edges[0][1]];
1595 ASSERTL1(face_edges[0][2] != -1,
"face_edges[0][2] == -1");
1596 tmp[2] =
m_edge[face_edges[0][2]];
1597 ASSERTL1(face_edges[0][3] != -1,
"face_edges[0][3] == -1");
1598 tmp[3] =
m_edge[face_edges[0][3]];
1599 ASSERTL1(face_edges[1][2] != -1,
"face_edges[1][2] == -1");
1600 tmp[4] =
m_edge[face_edges[1][2]];
1601 ASSERTL1(face_edges[1][1] != -1,
"face_edges[1][1] == -1");
1602 tmp[5] =
m_edge[face_edges[1][1]];
1603 ASSERTL1(face_edges[2][1] != -1,
"face_edges[2][1] == -1");
1604 tmp[6] =
m_edge[face_edges[2][1]];
1605 ASSERTL1(face_edges[3][2] != -1,
"face_edges[3][2] == -1");
1606 tmp[7] =
m_edge[face_edges[3][2]];
1607 ASSERTL1(face_edges[4][2] != -1,
"face_edges[4][2] == -1");
1608 tmp[8] =
m_edge[face_edges[4][2]];
1619 return (n+1)*(n+1)*(n+2)/2;
1621 return 3*(n+1)*(n+1)+2*(n+1)*(n+2)/2-9*(n+1)+6;
1631 for (
int i = 0; i < 5; ++i)
1633 faces[i] =
m_face[i]->GetGeom(coordDim);
1670 nodalPrism->GetNodalPoints(x,y,z);
1696 int nqtot = prism->GetTotPoints();
1706 prism->GetCoords(xi, yi, zi);
1708 for (i = 0; i < 3; ++i)
1711 prism->FwdTrans(alloc+i*nqtot, coeffs);
1713 nodalPrism->ModalToNodal(coeffs, tmp=alloc+(i+3)*nqtot);
1718 for (i = 0; i < 9; ++i)
1720 pos = 6 + i*(order-1);
1721 m_edge[i]->m_edgeNodes.clear();
1722 for (j = 0; j < order-1; ++j)
1724 m_edge[i]->m_edgeNodes.push_back(
1730 pos = 6 + 9*(order-1);
1731 for (i = 0; i < 5; ++i)
1733 int facesize = i % 2 ? (order-2)*(order-1)/2 : (order-1)*(order-1);
1734 m_face[i]->m_faceNodes.clear();
1735 for (j = 0; j < facesize; ++j)
1737 m_face[i]->m_faceNodes.push_back(
1744 for (i = pos; i < (order+1)*(order+1)*(order+2)/2; ++i)
1781 for (
int i = 0; i < 6; ++i)
1787 gid[0] = gid[3] = max(gid[0], gid[3]);
1788 gid[1] = gid[2] = max(gid[1], gid[2]);
1789 gid[4] = gid[5] = max(gid[4], gid[5]);
1791 for (
int i = 1; i < 6; ++i)
1793 if (gid[0] < gid[i])
1795 swap(gid[i], gid[0]);
1796 swap(lid[i], lid[0]);
1800 if (lid[0] == 4 || lid[0] == 5)
1804 else if (lid[0] == 1 || lid[0] == 2)
1807 vector<NodeSharedPtr> vertexmap(6);
1817 else if (lid[0] == 0 || lid[0] == 3)
1820 vector<NodeSharedPtr> vertexmap(6);
1832 cerr <<
"Warning: possible prism orientation problem." << endl;
1844 vector<NodeSharedPtr> pNodeList,
1845 vector<int> pTagList)
1846 :
Element(pConf, GetNumNodes(pConf), pNodeList.size())
1855 map<pair<int,int>,
int> edgeNodeMap;
1857 edgeNodeMap[pair<int,int>(1,2)] = 9;
1858 edgeNodeMap[pair<int,int>(2,3)] = 9 + n;
1859 edgeNodeMap[pair<int,int>(3,4)] = 9 + 2*n;
1860 edgeNodeMap[pair<int,int>(4,1)] = 9 + 3*n;
1861 edgeNodeMap[pair<int,int>(1,5)] = 9 + 4*n;
1862 edgeNodeMap[pair<int,int>(2,6)] = 9 + 5*n;
1863 edgeNodeMap[pair<int,int>(3,7)] = 9 + 6*n;
1864 edgeNodeMap[pair<int,int>(4,8)] = 9 + 7*n;
1865 edgeNodeMap[pair<int,int>(5,6)] = 9 + 8*n;
1866 edgeNodeMap[pair<int,int>(6,7)] = 9 + 9*n;
1867 edgeNodeMap[pair<int,int>(7,8)] = 9 + 10*n;
1868 edgeNodeMap[pair<int,int>(8,5)] = 9 + 11*n;
1871 for (
int i = 0; i < 8; ++i) {
1876 for (it = edgeNodeMap.begin(); it != edgeNodeMap.end(); ++it)
1878 vector<NodeSharedPtr> edgeNodes;
1880 for (
int j = it->second; j < it->second + n; ++j) {
1881 edgeNodes.push_back(pNodeList[j-1]);
1885 pNodeList[it->first.second-1],
1891 int face_edges[6][4];
1892 int face_ids[6][4] = {
1893 {0,1,2,3},{0,1,5,4},{1,2,6,5},{3,2,6,7},{0,3,7,4},{4,5,6,7}};
1894 for (
int j = 0; j < 6; ++j)
1896 vector<NodeSharedPtr> faceVertices;
1897 vector<EdgeSharedPtr> faceEdges;
1898 vector<NodeSharedPtr> faceNodes;
1899 for (
int k = 0; k < 4; ++k)
1901 faceVertices.push_back(
m_vertex[face_ids[j][k]]);
1904 for (
unsigned int i = 0; i <
m_edge.size(); ++i)
1906 if ( ((*(
m_edge[i]->m_n1)==*a) && (*(
m_edge[i]->m_n2)==*b))
1907 || ((*(
m_edge[i]->m_n1)==*b) && (*(
m_edge[i]->m_n2) == *a)) )
1909 face_edges[j][k] = i;
1910 faceEdges.push_back(
m_edge[i]);
1918 int N = 8 + 12*n + j*n*n;
1919 for (
int i = 0; i < n*n; ++i)
1921 faceNodes.push_back(pNodeList[N+i]);
1929 vector<EdgeSharedPtr> tmp(12);
1930 tmp[ 0] =
m_edge[face_edges[0][0]];
1931 tmp[ 1] =
m_edge[face_edges[0][1]];
1932 tmp[ 2] =
m_edge[face_edges[0][2]];
1933 tmp[ 3] =
m_edge[face_edges[0][3]];
1934 tmp[ 4] =
m_edge[face_edges[1][3]];
1935 tmp[ 5] =
m_edge[face_edges[1][1]];
1936 tmp[ 6] =
m_edge[face_edges[2][1]];
1937 tmp[ 7] =
m_edge[face_edges[4][1]];
1938 tmp[ 8] =
m_edge[face_edges[5][0]];
1939 tmp[ 9] =
m_edge[face_edges[5][1]];
1940 tmp[10] =
m_edge[face_edges[5][2]];
1941 tmp[11] =
m_edge[face_edges[5][3]];
1950 for (
int i = 0; i < 6; ++i)
1952 faces[i] = boost::dynamic_pointer_cast
1969 return (n+1)*(n+1)*(n+1);
1971 return 6*(n+1)*(n+1)-12*(n+1)+8;
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
Define element ordering based on ID.
static LibUtilities::ShapeType m_type
Element type.
#define ASSERTL0(condition, msg)
bool m_volumeNodes
Denotes whether the element contains volume (i.e. interior) nodes. These are not supported by either ...
std::ostream & operator<<(std::ostream &os, const ModuleKey &rhs)
LibUtilities::PointsType m_curveType
Volume curve type.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a prism.
TetOrient(vector< int > nid, int fid)
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
Represents an edge which joins two points.
static LibUtilities::ShapeType type
Element type.
unsigned int GetNumEntities()
Returns the total number of entities in the mesh.
std::vector< NodeSharedPtr > m_volumeNodes
List of element volume nodes.
unsigned int m_orientation
std::vector< int > m_taglist
List of integers specifying properties of the element.
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
boost::shared_ptr< QuadGeom > QuadGeomSharedPtr
Hexahedron(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a hexahedral element.
virtual void Complete(int order)
Complete this object.
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
std::vector< FaceSharedPtr > m_face
List of element faces.
virtual void Complete(int order)
Complete this object.
std::vector< ElementSharedPtr > m_items
List of elements in this composite.
Nektar::LibUtilities::NekFactory< LibUtilities::ShapeType, Element, ElmtConfig, std::vector< NodeSharedPtr >, std::vector< int > > ElementFactory
Element factory definition.
boost::shared_ptr< Face > FaceSharedPtr
Shared pointer to a face.
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
vector< T > surfVerts
The triangle surface vertices – templated so that this can either be nodes or IDs.
std::size_t operator()(struct TetOrient const &p) const
int GetMaxOrder()
Obtain the order of an element by looking at edges.
boost::shared_ptr< HexGeom > HexGeomSharedPtr
boost::shared_ptr< Node > NodeSharedPtr
Shared pointer to a Node.
boost::shared_ptr< TetExp > TetExpSharedPtr
boost::shared_ptr< StdNodalTriExp > StdNodalTriExpSharedPtr
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
static StdRegions::Orientation GetEdgeOrientation(const SegGeom &edge1, const SegGeom &edge2)
Get the orientation of edge1.
boost::shared_ptr< Curve > CurveSharedPtr
static LibUtilities::ShapeType m_type
Element type.
SpatialDomains::GeometrySharedPtr m_geom
Nektar++ geometry object for this element.
Gauss Radau pinned at x=-1, .
boost::shared_ptr< Condition > ConditionSharedPtr
Quadrilateral(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a quadrilateral element.
Principle Orthogonal Functions .
1D Evenly-spaced points using Lagrange polynomial
void SetVertex(unsigned int p, NodeSharedPtr pNew)
Replace a vertex with another vertex object.
virtual void Complete(int order)
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
bool m_reorient
Denotes whether the element needs to be re-orientated for a spectral element framework.
boost::shared_ptr< StdNodalPrismExp > StdNodalPrismExpSharedPtr
void SetFace(unsigned int p, FaceSharedPtr pNew)
Replace a face with another face object.
LibUtilities::ShapeType m_e
Element type (e.g. triangle, quad, etc).
unsigned int m_order
Order of the element.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a line.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a pyramid.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a hexahedron.
Point(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a point element.
boost::shared_ptr< SegGeom > SegGeomSharedPtr
unsigned int m_id
ID of the element.
void SetEdge(unsigned int p, EdgeSharedPtr pNew)
Replace an edge with another edge object.
std::string m_tag
Element type tag.
static LibUtilities::ShapeType m_type
Element type.
LibUtilities::PointsType m_faceCurveType
Distribution of points in faces.
bool m_faceNodes
Denotes whether the element contains face nodes. For 2D elements, if this is true then the element co...
Principle Orthogonal Functions .
Principle Orthogonal Functions .
static LibUtilities::ShapeType m_type
Element type.
Defines a specification for a set of points.
boost::shared_ptr< QuadExp > QuadExpSharedPtr
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a point (i.e. return 1).
bool operator<(NodeSharedPtr const &p1, NodeSharedPtr const &p2)
Defines ordering between two NodeSharedPtr objects.
static LibUtilities::ShapeType m_type
Element type.
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
Basic information about an element.
boost::shared_ptr< StdNodalTetExp > StdNodalTetExpSharedPtr
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
boost::shared_ptr< PrismExp > PrismExpSharedPtr
ElementMap m_element
Map for elements.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a tetrahedron.
std::string m_tag
Tag character describing the element.
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
static LibUtilities::ShapeType m_type
Element type.
unsigned int m_dim
Dimension of the element.
Represents a point in the domain.
3D Evenly-spaced points on a Tetrahedron
unsigned int m_expDim
Dimension of the expansion.
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
Prism(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a prism element.
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
unsigned int GetNumBndryElements()
Returns the total number of elements in the mesh with dimension < expDim.
LibUtilities::PointsType m_edgeCurveType
Distribution of points in edges.
boost::shared_ptr< Geometry2D > Geometry2DSharedPtr
Tetrahedron(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a tetrahedron element.
static LibUtilities::ShapeType m_type
Element type.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
Pyramid(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a pyramidic element.
bool operator==(TriFaceIDs const &p1, TriFaceIDs const &p2)
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
void OrientPrism()
Orient prism to align degenerate vertices.
std::vector< NodeSharedPtr > m_vertex
List of element vertex nodes.
boost::shared_ptr< PrismGeom > PrismGeomSharedPtr
Gauss Radau pinned at x=-1, .
boost::shared_ptr< TetGeom > TetGeomSharedPtr
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
boost::shared_ptr< TriGeom > TriGeomSharedPtr
std::string GetXmlString(bool doSort=true)
Generate the list of IDs of elements within this composite.
3D Evenly-spaced points on a Prism
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
Line(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a line element.
virtual void Complete(int order)
2D Evenly-spaced points on a Triangle
Represents a face comprised of three or more edges.
void Align(vector< int > vertId)
Align this surface to a given vertex ID.
boost::unordered_set< struct TetOrient, TetOrientHash > TetOrientSet
unsigned int GetNumElements()
Returns the total number of elements in the mesh with dimension expDim.
static ElementSharedPtr create(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Creates an instance of this class.
A lightweight struct for dealing with high-order triangle alignment.
std::vector< EdgeSharedPtr > m_edge
List of element edges.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Triangle(ElmtConfig pConf, std::vector< NodeSharedPtr > pNodeList, std::vector< int > pTagList)
Create a triangle element.
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a triangle.
boost::shared_ptr< Geometry > GeometrySharedPtr
Describes the specification for a Basis.
void OrientTet()
Orient tetrahedron to align degenerate vertices.
virtual SpatialDomains::GeometrySharedPtr GetGeom(int coordDim)
Generate a Nektar++ geometry object for this element.
ElementFactory & GetElementFactory()
boost::shared_ptr< PointGeom > PointGeomSharedPtr
1D Gauss-Lobatto-Legendre quadrature points
static unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a quadrilateral.
Base class for element definitions.
Provides a generic Factory class.
boost::shared_ptr< TriExp > TriExpSharedPtr
ElmtConfig m_conf
Contains configuration of the element.