48 #include <boost/unordered_map.hpp>
54 typedef std::pair<int,int>
ipair;
59 "Split prismatic elements to tetrahedra");
64 "Number of points in high order elements.");
74 int nodeId =
m_mesh->m_vertexSet.size();
81 map<ipair, ipair> edgeMap;
86 int nft = (ne-1)*ne/2;
134 static int indir[6][6] = {
146 static int prismTet[6][4] = {
156 static int tetEdges[6][2] = {
162 static int tetFaceNodes[4][3] = {
163 {0,1,2},{0,1,3},{1,2,3},{0,2,3}};
175 Array<OneD, NekDouble> rp(nq*(nq+1)/2), sp(nq*(nq+1)/2);
180 vector<ElementSharedPtr> el =
m_mesh->m_element[
m_mesh->m_expDim];
183 for (
int i = 0; i < el.size(); ++i)
191 vector<NodeSharedPtr> nodeList(6);
195 int mapPrism[6] = {0,1,4,3,2,5};
196 for (
int j = 0; j < 6; ++j)
198 nodeList[j] = el[i]->GetVertex(mapPrism[j]);
202 int minElId = nodeList[0]->m_id;
204 for (
int j = 1; j < 6; ++j)
206 int curId = nodeList[j]->m_id;
217 int id1 = min(nodeList[indir[minId][1]]->m_id,
218 nodeList[indir[minId][5]]->m_id);
219 int id2 = min(nodeList[indir[minId][2]]->m_id,
220 nodeList[indir[minId][4]]->m_id);
232 cerr <<
"Connectivity issue with prism->tet splitting."
241 el[i]->GetGeom(
m_mesh->m_spaceDim));
252 B0, B0, B1, geomLayer);
255 Array<OneD, NekDouble> wsp(3*nq*nq*nq);
256 Array<OneD, Array<OneD, NekDouble> > x(3);
258 x[1] = wsp + 1*nq*nq*nq;
259 x[2] = wsp + 2*nq*nq*nq;
260 qs->GetCoords(x[0], x[1], x[2]);
274 int nCoeffs = nodalPrism->GetNcoeffs();
275 Array<OneD, NekDouble> wsp2(3*nCoeffs);
276 Array<OneD, Array<OneD, NekDouble> > xn(3);
278 xn[1] = wsp2 + 1*nCoeffs;
279 xn[2] = wsp2 + 2*nCoeffs;
281 for (
int j = 0; j < 3; ++j)
283 Array<OneD, NekDouble> tmp(nodalPrism->GetNcoeffs());
284 qs ->FwdTrans (x[j], tmp);
285 nodalPrism->ModalToNodal(tmp, xn[j]);
289 map<int, int> prismVerts;
290 for (
int j = 0; j < 6; ++j)
292 prismVerts[el[i]->GetVertex(j)->m_id] = j;
295 for (
int j = 0; j < 3; ++j)
297 vector<NodeSharedPtr> tetNodes(4);
300 for (
int k = 0; k < 4; ++k)
302 tetNodes[k] = nodeList[indir[minId][prismTet[j+offset][k]]];
306 for (
int k = 0; k < 6; ++k)
313 indir[minId][prismTet[j+offset][tetEdges[k][0]]]];
315 indir[minId][prismTet[j+offset][tetEdges[k][1]]]];
318 it = edgeMap.find(pair<int,int>(n1,n2));
319 if (it == edgeMap.end())
321 it = edgeMap.find(pair<int,int>(n2,n1));
322 if (it == edgeMap.end())
324 cerr <<
"Couldn't find prism edges " << n1
325 <<
" " << n2 << endl;
329 for (
int l = ne-1; l >= 0; --l)
331 int pos = it->second.first + l*it->second.second;
334 new Node(nodeId++, xn[0][pos], xn[1][pos], xn[2][pos])));
340 for (
int l = 0; l < ne; ++l)
342 int pos = it->second.first + l*it->second.second;
345 new Node(nodeId++, xn[0][pos], xn[1][pos], xn[2][pos])));
351 vector<int> tags = el[i]->GetTagList();
357 for (
int k = 0; k < 4; ++k)
362 vector<NodeSharedPtr> triNodes(3);
364 for (
int l = 0; l < 3; ++l)
368 stdPrismNodes[prismVerts[v->m_id]];
383 for (
int l = 0; l < nft; ++l)
385 Array<OneD, NekDouble> tmp1(2), tmp2(3);
388 tmp2[0] = triGeom->GetCoord(0, tmp1);
389 tmp2[1] = triGeom->GetCoord(1, tmp1);
390 tmp2[2] = triGeom->GetCoord(2, tmp1);
393 NekDouble xc = geomLayer->GetCoord(0, tmp2);
394 NekDouble yc = geomLayer->GetCoord(1, tmp2);
395 NekDouble zc = geomLayer->GetCoord(2, tmp2);
396 face->m_faceNodes.push_back(
412 for (
int fid = 0; fid < 5; fid += 2)
414 int bl = el[i]->GetBoundaryLink(fid);
421 vector<NodeSharedPtr> triNodeList(3);
422 vector<int> faceNodes (3);
430 tagBE =
m_mesh->m_element[
m_mesh->m_expDim-1][bl]->GetTagList();
433 for (
int j = 0; j < 3; ++j)
436 for (
int k = 0; k < 4; ++k)
440 for (
int l = 0; l < 3; ++l)
442 faceNodes[l] = mapPrism[indir[minId][prismTet[j+offset][tetFaceNodes[k][l]]]];
446 sort(faceNodes.begin(), faceNodes.end());
451 (faceNodes[0] == 0 && faceNodes[1] == 1 && faceNodes[2] == 2) ||
452 (faceNodes[0] == 0 && faceNodes[1] == 2 && faceNodes[2] == 3) ||
453 (faceNodes[0] == 0 && faceNodes[1] == 1 && faceNodes[2] == 3) ||
454 (faceNodes[0] == 1 && faceNodes[1] == 2 && faceNodes[2] == 3))) ||
456 (faceNodes[0] == 1 && faceNodes[1] == 2 && faceNodes[2] == 5) ||
457 (faceNodes[0] == 1 && faceNodes[1] == 4 && faceNodes[2] == 5) ||
458 (faceNodes[0] == 1 && faceNodes[1] == 2 && faceNodes[2] == 4) ||
459 (faceNodes[0] == 2 && faceNodes[1] == 4 && faceNodes[2] == 5))) ||
461 (faceNodes[0] == 0 && faceNodes[1] == 3 && faceNodes[2] == 5) ||
462 (faceNodes[0] == 0 && faceNodes[1] == 4 && faceNodes[2] == 5) ||
463 (faceNodes[0] == 0 && faceNodes[1] == 3 && faceNodes[2] == 4) ||
464 (faceNodes[0] == 3 && faceNodes[1] == 4 && faceNodes[2] == 5))))
466 triNodeList[0] = nodeList[mapPrism[tmp[0]]];
467 triNodeList[1] = nodeList[mapPrism[tmp[1]]];
468 triNodeList[2] = nodeList[mapPrism[tmp[2]]];
479 vector<ElementSharedPtr> tmp;
480 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim-1].size(); ++i)
483 if (it == toRemove.end())
485 tmp.push_back(
m_mesh->m_element[
m_mesh->m_expDim-1][i]);