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}, {n*(n-1),-n}};
458 for (
int i = 0; i < 4; ++i)
464 for (
int j = 1; j < n-1; ++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]);
552 bool operator==(FaceSharedPtr
const &p1, FaceSharedPtr
const &p2);
553 bool operator< (FaceSharedPtr
const &p1, FaceSharedPtr
const &p2);
555 struct FaceHash : std::unary_function<FaceSharedPtr, std::size_t>
557 std::size_t operator()(FaceSharedPtr
const& p)
const
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;
589 bool pReorient =
true,
598 m_reorient (pReorient),
599 m_edgeCurveType(pECt),
600 m_faceCurveType(pFCt)
607 m_volumeNodes (p.m_volumeNodes),
609 m_reorient (p.m_reorient),
610 m_edgeCurveType(p.m_edgeCurveType),
611 m_faceCurveType(p.m_faceCurveType)
650 unsigned int pNumNodes,
651 unsigned int pGotNodes);
656 if (m_faceLink.get() != 0)
return m_faceLink->m_id;
657 if (m_edgeLink.get() != 0)
return m_edgeLink->m_id;
670 if (m_faceLink.get() != 0)
return "F";
671 if (m_edgeLink.get() != 0)
return "E";
700 return m_volumeNodes;
703 m_volumeNodes = nodes;
715 unsigned int n = m_volumeNodes.size();
718 for (
int i = 0; i < m_edge.size(); ++i)
720 n += m_edge[i]->GetNodeCount();
722 n -= m_vertex.size();
726 cerr <<
"Not supported." << endl;
737 return m_vertex.size();
741 return m_edge.size();
745 return m_face.size();
756 void SetFace(
unsigned int p, FaceSharedPtr pNew);
778 m_boundaryLinks[i] = j;
783 if (it == m_boundaryLinks.end())
793 void SetTagList(
const std::vector<int> &tags)
804 for(
int j=0; j< m_vertex.size(); ++j)
806 s << std::setw(5) << m_vertex[j]->m_id <<
" ";
810 for(
int j=0; j< m_edge.size(); ++j)
812 s << std::setw(5) << m_edge[j]->m_id <<
" ";
816 for(
int j=0; j< m_face.size(); ++j)
818 s << std::setw(5) << m_face[j]->m_id <<
" ";
830 std::vector<NodeSharedPtr> nodeList;
834 if (m_vertex.size() == 3)
836 int n = m_edge[0]->GetNodeCount();
837 nodeList.resize(n*(n+1)/2);
840 std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin());
841 for (
int i = 0; i < 3; ++i)
843 std::copy(m_edge[i]->m_edgeNodes.begin(),
844 m_edge[i]->m_edgeNodes.end(),
845 nodeList.begin() + 3 + i*(n-2));
846 if (m_edge[i]->m_n1 != m_vertex[i])
850 std::reverse(nodeList.begin() + 3 + i*(n-2),
851 nodeList.begin() + 3 + (i+1)*(n-2));
856 std::copy(m_volumeNodes.begin(), m_volumeNodes.end(),
857 nodeList.begin() + 3*(n-1));
860 else if (m_dim == 2 && m_vertex.size() == 4)
862 int n = m_edge[0]->GetNodeCount();
863 nodeList.resize(n*n);
866 nodeList[0] = m_vertex[0];
867 nodeList[n-1] = m_vertex[1];
868 nodeList[n*n-1] = m_vertex[2];
869 nodeList[n*(n-1)] = m_vertex[3];
872 int skips[4][2] = {{0,1}, {n-1,n}, {n*n-1,-1}, {n*(n-1),-n}};
873 for (
int i = 0; i < 4; ++i)
875 bool reverseEdge = m_edge[i]->m_n1 == m_vertex[i];
879 for (
int j = 1; j < n-1; ++j)
881 nodeList[skips[i][0] + j*skips[i][1]] =
882 m_edge[i]->m_edgeNodes[n-2-j];
887 for (
int j = 1; j < n-1; ++j)
889 nodeList[skips[i][0] + j*skips[i][1]] =
890 m_edge[i]->m_edgeNodes[j-1];
896 for (
int i = 1; i < n-1; ++i)
898 for (
int j = 1; j < n-1; ++j)
900 nodeList[i*n+j] = m_volumeNodes[(i-1)*(n-2)+(j-1)];
906 cerr <<
"GetXmlCurveString for a " << m_vertex.size()
907 <<
"-vertex element is not yet implemented." << endl;
914 for (
int k = 0; k < nodeList.size(); ++k)
916 s << std::scientific << std::setprecision(8) <<
" "
917 << nodeList[k]->m_x <<
" " << nodeList[k]->m_y
918 <<
" " << nodeList[k]->m_z <<
" ";
927 ASSERTL0(
false,
"This function should be implemented at a shape level.");
928 return boost::shared_ptr<SpatialDomains::Geometry>();
932 virtual void Complete(
int order)
934 ASSERTL0(
false,
"This function should be implemented at a shape level.");
939 for (i = 0; i < m_vertex.size(); ++i)
941 cout << m_vertex[i]->m_x <<
" " << m_vertex[i]->m_y <<
" " << m_vertex[i]->m_z << endl;
943 for (i = 0; i < m_edge.size(); ++i)
945 for (j = 0; j < m_edge[i]->m_edgeNodes.size(); ++j)
948 cout << n->m_x <<
" " << n->m_y <<
" " << n->m_z << endl;
951 for (i = 0; i < m_face.size(); ++i)
953 for (j = 0; j < m_face[i]->m_faceNodes.size(); ++j)
956 cout << n->m_x <<
" " << n->m_y <<
" " << n->m_z << endl;
994 typedef std::map<unsigned int, std::vector<ElementSharedPtr> >
ElementMap;
1003 typedef boost::shared_ptr<Element>
pT;
1004 bool operator()(
const pT a,
const pT b)
const
1011 return b.get() != 0;
1013 else if (b.get() == 0)
1019 return a->GetId() < b->GetId();
1084 bool operator==(ConditionSharedPtr
const &c1, ConditionSharedPtr
const &c2);
1120 unsigned int GetNumElements();
1123 unsigned int GetNumBndryElements();
1125 unsigned int GetNumEntities();
1139 std::vector<NodeSharedPtr> pNodeList,
1140 std::vector<int> pTagList)
1142 return boost::shared_ptr<Element>(
1143 new Point(pConf, pNodeList, pTagList));
1149 std::vector<NodeSharedPtr> pNodeList,
1150 std::vector<int> pTagList);
1154 static unsigned int GetNumNodes(
ElmtConfig pConf);
1166 std::vector<NodeSharedPtr> pNodeList,
1167 std::vector<int> pTagList)
1169 return boost::shared_ptr<Element>(
1170 new Line(pConf, pNodeList, pTagList));
1176 std::vector<NodeSharedPtr> pNodeList,
1177 std::vector<int> pTagList);
1183 static unsigned int GetNumNodes(
ElmtConfig pConf);
1193 template<
typename T>
1197 vector<T> pSurfVerts) :
1198 vertId(pVertId), surfVerts(pSurfVerts) {}
1214 void Rotate(
int nrot)
1217 int np = ((int)sqrt(8.0*surfVerts.size()+1.0)-1)/2;
1218 vector<T> tmp(np*np);
1220 for (n = 0; n < nrot; ++n)
1222 for (cnt = i = 0; i < np; ++i)
1224 for (j = 0; j < np-i; ++j, cnt++)
1226 tmp[i*np+j] = surfVerts[cnt];
1229 for (cnt = i = 0; i < np; ++i)
1231 for (j = 0; j < np-i; ++j,cnt++)
1233 surfVerts[cnt] = tmp[(np-1-i-j)*np+i];
1253 int np = ((int)sqrt(8.0*surfVerts.size()+1.0)-1)/2;
1254 vector<T> tmp(np*np);
1256 for (cnt = i = 0; i < np; ++i)
1258 for (j = 0; j < np-i; ++j,cnt++)
1260 tmp[i*np+np-i-1-j] = surfVerts[cnt];
1264 for (cnt = i = 0; i < np; ++i)
1266 for(j = 0; j < np-i; ++j,cnt++)
1268 surfVerts[cnt] = tmp[i*np+j];
1276 void Align(vector<int> vertId)
1278 if (vertId[0] == this->vertId[0])
1280 if (vertId[1] == this->vertId[1] ||
1281 vertId[1] == this->vertId[2])
1283 if (vertId[1] == this->vertId[2])
1290 else if (vertId[0] == this->vertId[1])
1292 if (vertId[1] == this->vertId[0] ||
1293 vertId[1] == this->vertId[2])
1295 if (vertId[1] == this->vertId[0])
1305 else if (vertId[0] == this->vertId[2])
1307 if (vertId[1] == this->vertId[0] ||
1308 vertId[1] == this->vertId[1])
1310 if (vertId[1] == this->vertId[1])
1332 std::vector<NodeSharedPtr> pNodeList,
1333 std::vector<int> pTagList)
1336 new Triangle(pConf, pNodeList, pTagList));
1338 for (
int i = 0; i < m_edges.size(); ++i)
1340 m_edges[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1348 std::vector<NodeSharedPtr> pNodeList,
1349 std::vector<int> pTagList);
1354 virtual void Complete(
int order);
1356 static unsigned int GetNumNodes(
ElmtConfig pConf);
1368 std::vector<NodeSharedPtr> pNodeList,
1369 std::vector<int> pTagList)
1374 for (
int i = 0; i < m_edges.size(); ++i)
1376 m_edges[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1384 std::vector<NodeSharedPtr> pNodeList,
1385 std::vector<int> pTagList);
1390 virtual void Complete(
int order);
1392 static unsigned int GetNumNodes(
ElmtConfig pConf);
1404 std::vector<NodeSharedPtr> pNodeList,
1405 std::vector<int> pTagList)
1410 for (
int i = 0; i < faces.size(); ++i)
1412 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1420 std::vector<NodeSharedPtr> pNodeList,
1421 std::vector<int> pTagList);
1426 virtual void Complete(
int order);
1428 static unsigned int GetNumNodes(
ElmtConfig pConf);
1430 int m_orientationMap[4];
1431 int m_origVertMap[4];
1446 std::vector<NodeSharedPtr> pNodeList,
1447 std::vector<int> pTagList)
1450 new Pyramid(pConf, pNodeList, pTagList));
1452 for (
int i = 0; i < faces.size(); ++i)
1454 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1459 static LibUtilities::ShapeType
type;
1462 std::vector<NodeSharedPtr> pNodeList,
1463 std::vector<int> pTagList);
1468 static unsigned int GetNumNodes(
ElmtConfig pConf);
1473 int orientationMap[5];
1485 std::vector<NodeSharedPtr> pNodeList,
1486 std::vector<int> pTagList)
1489 new Prism(pConf, pNodeList, pTagList));
1491 for (
int i = 0; i < faces.size(); ++i)
1493 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1501 std::vector<NodeSharedPtr> pNodeList,
1502 std::vector<int> pTagList);
1507 virtual void Complete(
int order);
1509 static unsigned int GetNumNodes(
ElmtConfig pConf);
1530 std::vector<NodeSharedPtr> pNodeList,
1531 std::vector<int> pTagList)
1536 for (
int i = 0; i < faces.size(); ++i)
1538 faces[i]->m_elLink.push_back(pair<ElementSharedPtr, int>(e,i));
1546 std::vector<NodeSharedPtr> pNodeList,
1547 std::vector<int> pTagList);
1553 static unsigned int GetNumNodes(
ElmtConfig pConf);