36 #ifndef UTILITY_PREPROCESSING_MESHCONVERT_MESHELEMENTS
37 #define UTILITY_PREPROCESSING_MESHCONVERT_MESHELEMENTS
44 #include <boost/shared_ptr.hpp>
45 #include <boost/unordered_set.hpp>
46 #include <boost/unordered_map.hpp>
207 struct NodeHash : std::unary_function<NodeSharedPtr, std::size_t>
211 std::size_t seed = 0;
212 boost::hash_combine(seed, p->m_x);
213 boost::hash_combine(seed, p->m_y);
214 boost::hash_combine(seed, p->m_z);
218 typedef boost::unordered_set<NodeSharedPtr, NodeHash>
NodeSet;
231 std::vector<NodeSharedPtr> pEdgeNodes,
253 s << std::scientific << std::setprecision(8) <<
" "
254 <<
m_n1->m_x <<
" " <<
m_n1->m_y <<
" " <<
m_n1->m_z <<
" ";
256 s << std::scientific << std::setprecision(8) <<
" "
260 s << std::scientific << std::setprecision(8) <<
" "
272 p[0] =
m_n1->GetGeom(coordDim);
273 p[1] =
m_n2->GetGeom(coordDim);
282 c->m_points.push_back(p[0]);
287 c->m_points.push_back(p[1]);
330 struct EdgeHash : std::unary_function<EdgeSharedPtr, std::size_t>
334 std::size_t seed = 0;
335 unsigned int id1 = p->m_n1->m_id;
336 unsigned int id2 = p->m_n2->m_id;
337 boost::hash_combine(seed, id1 < id2 ? id1 : id2);
338 boost::hash_combine(seed, id2 < id1 ? id1 : id2);
342 typedef boost::unordered_set<EdgeSharedPtr, EdgeHash>
EdgeSet;
355 Face(std::vector<NodeSharedPtr> pVertexList,
356 std::vector<NodeSharedPtr> pFaceNodes,
357 std::vector<EdgeSharedPtr> pEdgeList,
412 vector<NodeSharedPtr> tmp;
418 tmp.insert(tmp.end(),
m_edgeList[k]->m_edgeNodes.begin(),
424 std::reverse(tmp.begin() + 3 + k*(n-2),
425 tmp.begin() + 3 + (k+1)*(n-2));
430 for (
int k = 0; k < tmp.size(); ++k) {
431 s << std::scientific << std::setprecision(8) <<
" "
432 << tmp[k]->m_x <<
" " << tmp[k]->m_y
433 <<
" " << tmp[k]->m_z <<
" ";
442 "Face nodes of tensor product only supported "
443 "for quadrilaterals.");
446 vector<NodeSharedPtr> tmp(n*n);
457 int skips[4][2] = {{0,1}, {n-1,n}, {n*(n-1),1}, {0,n}};
458 for (
int i = 0; i < 4; ++i)
464 for (
int j = n-2; j > 0; --j)
466 tmp[skips[i][0] + j*skips[i][1]] =
472 for (
int j = 1; j < n-1; ++j)
474 tmp[skips[i][0] + j*skips[i][1]] =
481 for (
int i = 1; i < n-1; ++i)
483 for (
int j = 1; j < n-1; ++j)
489 for (
int k = 0; k < tmp.size(); ++k) {
490 s << std::scientific << std::setprecision(8) <<
" "
491 << tmp[k]->m_x <<
" " << tmp[k]->m_y
492 <<
" " << tmp[k]->m_z <<
" ";
509 for (
int i = 0; i < nEdge; ++i)
514 for (
int i = 0; i < nEdge; ++i)
517 *edges[i], *edges[(i+1) % nEdge]);
555 struct FaceHash : std::unary_function<FaceSharedPtr, std::size_t>
559 unsigned int nVert = p->m_vertexList.size();
560 std::size_t seed = 0;
561 std::vector<unsigned int> ids(nVert);
563 for (
int i = 0; i < nVert; ++i)
565 ids[i] = p->m_vertexList[i]->m_id;
568 std::sort(ids.begin(), ids.end());
569 boost::hash_range(seed, ids.begin(), ids.end());
574 typedef boost::unordered_set<FaceSharedPtr, FaceHash>
FaceSet;
586 bool pFn,
bool pVn,
bool pReorient =
true,
589 m_e(pE),
m_faceNodes(pFn), m_volumeNodes(pVn), m_order(pOrder),
590 m_reorient(pReorient), m_edgeCurveType(pECt), m_faceCurveType(pFCt) {}
593 m_order(p.m_order), m_reorient(p.m_reorient),
594 m_edgeCurveType(p.m_edgeCurveType), m_faceCurveType(p.m_faceCurveType) {}
631 unsigned int pNumNodes,
632 unsigned int pGotNodes);
637 if (m_faceLink.get() != 0)
return m_faceLink->m_id;
638 if (m_edgeLink.get() != 0)
return m_edgeLink->m_id;
651 if (m_faceLink.get() != 0)
return "F";
652 if (m_edgeLink.get() != 0)
return "E";
681 return m_volumeNodes;
684 m_volumeNodes = nodes;
696 unsigned int n = m_volumeNodes.size();
699 for (
int i = 0; i < m_edge.size(); ++i)
701 n += m_edge[i]->GetNodeCount();
703 n -= m_vertex.size();
707 cerr <<
"Not supported." << endl;
718 return m_vertex.size();
722 return m_edge.size();
726 return m_face.size();
759 m_boundaryLinks[i] = j;
764 if (it == m_boundaryLinks.end())
774 void SetTagList(
const std::vector<int> &tags)
785 for(
int j=0; j< m_vertex.size(); ++j)
787 s << std::setw(5) << m_vertex[j]->m_id <<
" ";
791 for(
int j=0; j< m_edge.size(); ++j)
793 s << std::setw(5) << m_edge[j]->m_id <<
" ";
797 for(
int j=0; j< m_face.size(); ++j)
799 s << std::setw(5) << m_face[j]->m_id <<
" ";
814 std::vector<NodeSharedPtr> tensorNodeOrdering(
815 const std::vector<NodeSharedPtr> &nodes,
818 std::vector<NodeSharedPtr> nodeList;
822 if (m_vertex.size() == 3)
824 nodeList.resize(nodes.size());
827 nodeList[0] = nodes[0];
830 nodeList[n-1] = nodes[1];
831 nodeList[n*(n+1)/2 - 1] = nodes[2];
836 for (
int i = 1; i < n-1; ++i)
838 nodeList[i] = nodes[3+i-1];
839 nodeList[cnt] = nodes[3+3*(n-2)-i];
840 nodeList[cnt+n-i-1] = nodes[3+(n-2)+i-1];
848 std::vector<NodeSharedPtr> interior((n-3)*(n-2)/2);
849 std::copy(nodes.begin() + 3+3*(n-2), nodes.end(), interior.begin());
850 interior = tensorNodeOrdering(interior, n-3);
855 for (
int j = 1; j < n-2; ++j)
857 for (
int i = 0; i < n-j-2; ++i)
859 nodeList[cnt+i+1] = interior[cnt2+i];
867 else if (m_dim == 2 && m_vertex.size() == 4)
869 nodeList.resize(nodes.size());
872 nodeList[0] = nodes[0];
875 nodeList[n-1] = nodes[1];
876 nodeList[n*n-1] = nodes[2];
877 nodeList[n*(n-1)] = nodes[3];
879 for (
int i = 1; i < n-1; ++i)
881 nodeList[i] = nodes[4+i-1];
883 for (
int i = 1; i < n-1; ++i)
885 nodeList[n*n-1-i] = nodes[4+2*(n-2)+i-1];
892 std::vector<NodeSharedPtr> interior((n-2)*(n-2));
893 std::copy(nodes.begin() + 4+4*(n-2), nodes.end(), interior.begin());
894 interior = tensorNodeOrdering(interior, n-2);
897 for (
int j = 1; j < n-1; ++j)
899 nodeList[j*n] = nodes[4+3*(n-2)+n-2-j];
900 for (
int i = 1; i < n-1; ++i)
902 nodeList[j*n+i] = interior[(j-1)*(n-2)+(i-1)];
904 nodeList[(j+1)*n-1] = nodes[4+(n-2)+j-1];
910 cerr <<
"TensorNodeOrdering for a " << m_vertex.size()
911 <<
"-vertex element is not yet implemented." << endl;
921 std::vector<NodeSharedPtr> nodeList;
925 if (m_vertex.size() == 3)
927 int n = m_edge[0]->GetNodeCount();
928 nodeList.resize(n*(n+1)/2);
931 std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin());
932 for (
int i = 0; i < 3; ++i)
934 std::copy(m_edge[i]->m_edgeNodes.begin(), m_edge[i]->m_edgeNodes.end(), nodeList.begin() + 3 + i*(n-2));
935 if (m_edge[i]->m_n1 != m_vertex[i])
939 std::reverse(nodeList.begin() + 3 + i*(n-2),
940 nodeList.begin() + 3 + (i+1)*(n-2));
947 std::vector<NodeSharedPtr> interior(m_volumeNodes.size());
948 std::copy(m_volumeNodes.begin(), m_volumeNodes.end(), interior.begin());
949 interior = tensorNodeOrdering(interior, n-3);
950 std::copy(interior.begin(), interior.end(), nodeList.begin() + 3*(n-1));
953 else if (m_dim == 2 && m_vertex.size() == 4)
955 int n = m_edge[0]->GetNodeCount();
956 nodeList.resize(n*n);
959 std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin());
960 for (
int i = 0; i < 4; ++i)
962 std::copy(m_edge[i]->m_edgeNodes.begin(),
963 m_edge[i]->m_edgeNodes.end(),
964 nodeList.begin() + 4 + i*(n-2));
966 if (m_edge[i]->m_n1 != m_vertex[i])
970 std::reverse(nodeList.begin() + 4 + i*(n-2),
971 nodeList.begin() + 4 + (i+1)*(n-2));
974 std::copy(m_volumeNodes.begin(), m_volumeNodes.end(), nodeList.begin() + 4*(n-1));
979 nodeList = tensorNodeOrdering(nodeList, n);
983 cerr <<
"GetXmlCurveString for a " << m_vertex.size()
984 <<
"-vertex element is not yet implemented." << endl;
991 for (
int k = 0; k < nodeList.size(); ++k)
993 s << std::scientific << std::setprecision(8) <<
" "
994 << nodeList[k]->m_x <<
" " << nodeList[k]->m_y
995 <<
" " << nodeList[k]->m_z <<
" ";
1004 ASSERTL0(
false,
"This function should be implemented at a shape level.");
1005 return boost::shared_ptr<SpatialDomains::Geometry>();
1009 virtual void Complete(
int order)
1011 ASSERTL0(
false,
"This function should be implemented at a shape level.");
1016 for (i = 0; i < m_vertex.size(); ++i)
1018 cout << m_vertex[i]->m_x <<
" " << m_vertex[i]->m_y <<
" " << m_vertex[i]->m_z << endl;
1020 for (i = 0; i < m_edge.size(); ++i)
1022 for (j = 0; j < m_edge[i]->m_edgeNodes.size(); ++j)
1025 cout << n->m_x <<
" " << n->m_y <<
" " << n->m_z << endl;
1028 for (i = 0; i < m_face.size(); ++i)
1030 for (j = 0; j < m_face[i]->m_faceNodes.size(); ++j)
1033 cout << n->m_x <<
" " << n->m_y <<
" " << n->m_z << endl;
1071 typedef std::map<unsigned int, std::vector<ElementSharedPtr> >
ElementMap;
1080 typedef boost::shared_ptr<Element>
pT;
1081 bool operator()(
const pT a,
const pT b)
const
1088 return b.get() != 0;
1090 else if (b.get() == 0)
1096 return a->GetId() < b->GetId();
1197 unsigned int GetNumElements();
1200 unsigned int GetNumBndryElements();
1202 unsigned int GetNumEntities();
1216 std::vector<NodeSharedPtr> pNodeList,
1217 std::vector<int> pTagList)
1219 return boost::shared_ptr<Element>(
1220 new Point(pConf, pNodeList, pTagList));
1226 std::vector<NodeSharedPtr> pNodeList,
1227 std::vector<int> pTagList);
1231 static unsigned int GetNumNodes(
ElmtConfig pConf);
1243 std::vector<NodeSharedPtr> pNodeList,
1244 std::vector<int> pTagList)
1246 return boost::shared_ptr<Element>(
1247 new Line(pConf, pNodeList, pTagList));
1253 std::vector<NodeSharedPtr> pNodeList,
1254 std::vector<int> pTagList);
1260 static unsigned int GetNumNodes(
ElmtConfig pConf);
1272 std::vector<NodeSharedPtr> pNodeList,
1273 std::vector<int> pTagList)
1276 new Triangle(pConf, pNodeList, pTagList));
1278 for (
int i = 0; i < m_edges.size(); ++i)
1280 m_edges[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1288 std::vector<NodeSharedPtr> pNodeList,
1289 std::vector<int> pTagList);
1294 virtual void Complete(
int order);
1296 static unsigned int GetNumNodes(
ElmtConfig pConf);
1308 std::vector<NodeSharedPtr> pNodeList,
1309 std::vector<int> pTagList)
1314 for (
int i = 0; i < m_edges.size(); ++i)
1316 m_edges[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1324 std::vector<NodeSharedPtr> pNodeList,
1325 std::vector<int> pTagList);
1330 virtual void Complete(
int order);
1332 static unsigned int GetNumNodes(
ElmtConfig pConf);
1344 std::vector<NodeSharedPtr> pNodeList,
1345 std::vector<int> pTagList)
1350 for (
int i = 0; i < faces.size(); ++i)
1352 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1360 std::vector<NodeSharedPtr> pNodeList,
1361 std::vector<int> pTagList);
1366 virtual void Complete(
int order);
1368 static unsigned int GetNumNodes(
ElmtConfig pConf);
1373 int m_orientationMap[4];
1388 std::vector<NodeSharedPtr> pNodeList,
1389 std::vector<int> pTagList)
1392 new Pyramid(pConf, pNodeList, pTagList));
1394 for (
int i = 0; i < faces.size(); ++i)
1396 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1404 std::vector<NodeSharedPtr> pNodeList,
1405 std::vector<int> pTagList);
1410 static unsigned int GetNumNodes(
ElmtConfig pConf);
1415 int orientationMap[5];
1427 std::vector<NodeSharedPtr> pNodeList,
1428 std::vector<int> pTagList)
1431 new Prism(pConf, pNodeList, pTagList));
1433 for (
int i = 0; i < faces.size(); ++i)
1435 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1443 std::vector<NodeSharedPtr> pNodeList,
1444 std::vector<int> pTagList);
1449 virtual void Complete(
int order);
1451 static unsigned int GetNumNodes(
ElmtConfig pConf);
1472 std::vector<NodeSharedPtr> pNodeList,
1473 std::vector<int> pTagList)
1478 for (
int i = 0; i < faces.size(); ++i)
1480 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1488 std::vector<NodeSharedPtr> pNodeList,
1489 std::vector<int> pTagList);
1495 static unsigned int GetNumNodes(
ElmtConfig pConf);