44 #include <boost/algorithm/string.hpp>
59 "Reads Tecplot polyhedron ascii format converted from Star CCM (.dat).");
89 cout <<
"InputStarTec: Start reading file..." << endl;
103 if(line.find(
"ZONE") != string::npos)
113 if(line.find(
"ZONE") != string::npos)
132 int nfaces, nnodes, nelements;
140 nnodes = nfaces = nelements = 0;
147 boost::to_upper(line);
150 if(sscanf(line.c_str(),
"%lf",&value) == 1)
156 if ((line.find(
"NODES") != string::npos)&&
157 (line.find(
"TOTALNUMFACENODES") == string::npos))
163 start = tag.find(
"NODES=");
164 end = tag.find_first_of(
',',start);
165 nnodes = atoi(tag.substr(start+6,end).c_str());
168 if ((line.find(
"FACES") != string::npos)&&
169 (line.find(
"NUMCONNECTEDBOUNDARYFACES") == string::npos))
175 start = tag.find(
"FACES=");
176 end = tag.find_first_of(
',',start);
177 nfaces = atoi(tag.substr(start+6,end).c_str());
180 if (line.find(
"ELEMENTS") != string::npos)
186 start = tag.find(
"ELEMENTS=");
187 end = tag.find_first_of(
',',start);
188 nelements = atoi(tag.substr(start+9,end).c_str());
191 if (line.find(
"ZONETYPE") != string::npos)
196 if((line.find(
"FEPOLYGON") == string::npos)&&
197 (line.find(
"FEPOLYHEDRON") == string::npos))
199 ASSERTL0(
false,
"Routine only set up for FEPolygon or FEPolyhedron");
208 cout <<
"Setting up zone "<< zcnt++;
210 vector<NekDouble> x,y,z;
213 for(i = 0; i < nnodes; ++i)
219 for(i = 0; i < nnodes; ++i)
225 for(i = 0; i < nnodes; ++i)
231 std::vector<NodeSharedPtr> Nodes;
232 for(i = 0; i < nnodes; ++i)
234 Nodes.push_back(boost::shared_ptr<Node>(
new Node(i,x[i],y[i],z[i])));
239 if(line.find(
"node count per face") == string::npos)
241 if(line.find(
"face nodes") == string::npos)
250 vector<int> Nodes_per_face;
251 if(line.find(
"node count per face") != string::npos)
254 for(i = 0; i < nfaces; ++i)
257 ASSERTL0(nodes <= 4,
"Can only handle meshes with "
258 "up to four nodes per face");
259 Nodes_per_face.push_back(nodes);
266 if(line.find(
"face nodes") == string::npos)
273 vector<vector<int> > FaceNodes;
275 if(line.find(
"face nodes") != string::npos)
278 for(i = 0; i < nfaces; ++i)
282 int nodes = (Nodes_per_face.size())? Nodes_per_face[i]: 2;
286 for(
int j = 0; j < nodes; ++j)
291 Fnodes.push_back(nodeID-1);
294 FaceNodes.push_back(Fnodes);
300 ASSERTL0(
false,
"Failed to find face node section");
304 Array<OneD, vector< int> > ElementFaces(nelements);
308 if(line.find(
"left elements") == string::npos)
313 if(line.find(
"left elements") != string::npos)
317 for(i = 0; i < nfaces; ++i)
323 ElementFaces[elmtID-1].push_back(i);
329 ASSERTL0(
false,
"Left element not found");
335 if(line.find(
"right elements") == string::npos)
340 if(line.find(
"right elements") != string::npos)
345 for(i = 0; i < nfaces; ++i)
351 ElementFaces[elmtID-1].push_back(i);
360 ASSERTL0(
false,
"Left element not found");
365 if(Nodes_per_face.size())
367 cout <<
" (3D) "<< endl;
376 for(i = 0; i < nelements; ++i)
378 if(ElementFaces[i].size() > 4)
380 GenElement3D(Nodes,i,ElementFaces[i],FaceNodes,nComposite,
true);
387 for(i = 0; i < nelements; ++i)
389 if(ElementFaces[i].size() == 4)
391 GenElement3D(Nodes,i,ElementFaces[i],FaceNodes,nComposite,
true);
401 cout <<
" (2D)" << endl;
404 for(i = 0; i < Nodes.size(); ++i)
408 if (it ==
m_mesh->m_vertexSet.end())
410 ASSERTL0(
false,
"Failed to find face vertex in 3D list");
418 for(i = 0; i < nelements; ++i)
420 GenElement2D(Nodes,i,ElementFaces[i],FaceNodes,nComposite);
429 vector<vector<int> > &FacesToPrisms,
430 vector<vector<int> > &PrismsToFaces,
431 vector<bool> &PrismDone);
434 Array<
OneD, vector<int> >&ElementFaces,
435 vector<vector<int> >&FaceNodes)
438 Array<OneD,int> NodeReordering(Vnodes.size(),-1);
439 int face1_map[3] = {0,1,4};
440 int face3_map[3] = {3,2,5};
442 map<int,bool> FacesRenumbered;
445 vector<vector<int> > FaceToPrisms(FaceNodes.size());
446 vector<vector<int> > PrismToFaces(ElementFaces.num_elements());
452 for(i = 0; i < ElementFaces.num_elements(); ++i)
455 if(ElementFaces[i].size() == 5)
457 vector<int> LocTriFaces;
459 for(j = 0; j < ElementFaces[i].size(); ++j)
461 if(FaceNodes[ElementFaces[i][j]].size() == 3)
463 LocTriFaces.push_back(j);
467 if(LocTriFaces.size() == 2)
471 PrismToFaces[i].push_back(ElementFaces[i][LocTriFaces[0]]);
472 PrismToFaces[i].push_back(ElementFaces[i][LocTriFaces[1]]);
474 FaceToPrisms[ElementFaces[i][LocTriFaces[0]]].push_back(i);
475 FaceToPrisms[ElementFaces[i][LocTriFaces[1]]].push_back(i);
481 vector<bool> FacesDone(FaceNodes.size(),
false);
482 vector<bool> PrismDone(ElementFaces.num_elements(),
false);
487 for(PrismIt = Prisms.begin(); PrismIt != Prisms.end(); ++PrismIt)
489 int elmtid = PrismIt->first;
490 map<int,int> facelist;
494 if(PrismDone[elmtid])
502 PrismToFaces, PrismDone);
505 for(faceIt = facelist.begin(); faceIt != facelist.end(); faceIt++)
507 int faceid = faceIt->second;
509 for(i = 0; i < FaceToPrisms[faceid].size(); ++i)
511 int prismid = FaceToPrisms[faceid][i];
513 if((FacesDone[PrismToFaces[prismid][0]] ==
true)&&
514 (FacesDone[PrismToFaces[prismid][1]] ==
true))
520 ElementFaces[prismid],
523 if((FacesDone[PrismToFaces[prismid][0]] ==
false)&&
524 (FacesDone[PrismToFaces[prismid][1]] ==
false))
528 for(i = 0; i < 3; ++i)
530 if(NodeReordering[Nodes[face1_map[i]]] == -1)
532 NodeReordering[Nodes[face1_map[i]]] = nodeid++;
536 for(i = 0; i < 3; ++i)
538 if(NodeReordering[Nodes[face3_map[i]]] == -1)
540 NodeReordering[Nodes[face3_map[i]]] = nodeid++;
544 else if((FacesDone[PrismToFaces[prismid][0]] ==
false)&&
545 (FacesDone[PrismToFaces[prismid][1]] ==
true))
550 max_id1 = (NodeReordering[Nodes[face3_map[0]]] <
551 NodeReordering[Nodes[face3_map[1]]] )? 1:0;
552 max_id2 = (NodeReordering[Nodes[face3_map[max_id1]]] <
553 NodeReordering[Nodes[face3_map[2]]] )? 2:max_id1;
556 int id0 = (max_id1== 1)? 0:1;
558 if(NodeReordering[Nodes[face1_map[id0]]] == -1)
560 NodeReordering[Nodes[face1_map[id0]]] =
564 if(NodeReordering[Nodes[face1_map[max_id1]]] == -1)
566 NodeReordering[Nodes[face1_map[max_id1]]] =
570 if(NodeReordering[Nodes[face1_map[max_id2]]] == -1)
572 NodeReordering[Nodes[face1_map[max_id2]]] =
576 else if((FacesDone[PrismToFaces[prismid][0]] ==
true)&&
577 (FacesDone[PrismToFaces[prismid][1]] ==
false))
583 max_id1 = (NodeReordering[Nodes[face1_map[0]]] <
584 NodeReordering[Nodes[face1_map[1]]] )? 1:0;
585 max_id2 = (NodeReordering[Nodes[face1_map[max_id1]]] <
586 NodeReordering[Nodes[face1_map[2]]] )? 2:max_id1;
589 int id0 = (max_id1== 1)? 0:1;
592 if(NodeReordering[Nodes[face3_map[id0]]] == -1)
594 NodeReordering[Nodes[face3_map[id0]]] =
598 if(NodeReordering[Nodes[face3_map[max_id1]]] == -1)
600 NodeReordering[Nodes[face3_map[max_id1]]] =
604 if(NodeReordering[Nodes[face3_map[max_id2]]] == -1)
606 NodeReordering[Nodes[face3_map[max_id2]]] =
617 for(i = 0; i < NodeReordering.num_elements(); ++i)
619 if(NodeReordering[i] == -1)
621 NodeReordering[i] = nodeid++;
625 ASSERTL1(nodeid == NodeReordering.num_elements(),
"Have not renumbered all nodes");
628 for(i = 0; i < FaceNodes.size(); ++i)
630 for(j = 0; j < FaceNodes[i].size(); ++j)
632 FaceNodes[i][j] = NodeReordering[FaceNodes[i][j]];
636 vector<NodeSharedPtr> save(Vnodes);
637 for(i = 0; i < Vnodes.size(); ++i)
639 Vnodes[NodeReordering[i]] = save[i];
640 Vnodes[NodeReordering[i]]->SetID(NodeReordering[i]);
648 vector<vector<int> > &FaceToPrisms,
649 vector<vector<int> > &PrismToFaces,
650 vector<bool> &PrismDone)
652 if(PrismDone[prismid] ==
false)
654 PrismDone[prismid] =
true;
657 int face = PrismToFaces[prismid][0];
658 facelist[face] = face;
659 for(
int i = 0; i < FaceToPrisms[face].size(); ++i)
662 PrismToFaces, PrismDone);
666 face = PrismToFaces[prismid][1];
667 facelist[face] = face;
668 for(
int i = 0; i < FaceToPrisms[face].size(); ++i)
671 PrismToFaces, PrismDone);
677 int i, vector<int> &ElementFaces,
678 vector<vector<int> >&FaceNodes,
684 if(ElementFaces.size() == 3)
688 else if(ElementFaces.size() == 4)
694 ASSERTL0(
false,
"Not set up for elements which are not Tets or Prism");
699 tags.push_back(nComposite);
702 vector<NodeSharedPtr> nodeList;
703 Array<OneD, int> Nodes =
SortEdgeNodes(VertNodes, ElementFaces, FaceNodes);
704 for(
int j = 0; j < Nodes.num_elements(); ++j)
706 nodeList.push_back(VertNodes[Nodes[j]]);
714 m_mesh->m_element[E->GetDim()].push_back(E);
718 int i, vector<int> &ElementFaces,
719 vector<vector<int> >&FaceNodes,
720 int nComposite,
bool DoOrient)
724 Array<OneD, int> Nodes =
SortFaceNodes(VertNodes, ElementFaces, FaceNodes);
725 int nnodes = Nodes.num_elements();
726 map<LibUtilities::ShapeType,int> domainComposite;
748 ASSERTL0(
false,
"Not set up for elements which are not Tets or Prism");
753 tags.push_back(nComposite);
756 vector<NodeSharedPtr> nodeList;
757 for(
int j = 0; j < Nodes.num_elements(); ++j)
759 nodeList.push_back(VertNodes[Nodes[j]]);
770 m_mesh->m_element[E->GetDim()].push_back(E);
774 cout <<
"Warning: Pyramid detected " << endl;
779 vector<int> &ElementFaces,
780 vector<vector<int> >&FaceNodes)
783 Array<OneD, int> returnval;
785 if(ElementFaces.size() == 3)
787 returnval = Array<OneD, int>(3);
789 returnval[0] = FaceNodes[ElementFaces[0]][0];
790 returnval[1] = FaceNodes[ElementFaces[0]][1];
793 for(i = 0; i < 2; ++i)
795 if((FaceNodes[ElementFaces[1]][i] != returnval[0])&&(FaceNodes[ElementFaces[1]][i] != returnval[1]))
797 returnval[2]= FaceNodes[ElementFaces[1]][i];
802 else if(ElementFaces.size() == 4)
804 returnval = Array<OneD, int>(4);
806 int indx0 = FaceNodes[ElementFaces[0]][0];
807 int indx1 = FaceNodes[ElementFaces[0]][1];
812 for(j = 1; j < 4; ++j)
814 for(i = 0; i < 2; ++i)
816 if((FaceNodes[ElementFaces[j]][i] != indx0)&&(FaceNodes[ElementFaces[j]][i] != indx1))
820 indx2 = FaceNodes[ElementFaces[j]][i];
824 if(FaceNodes[ElementFaces[j]][i] != indx2)
826 indx3 = FaceNodes[ElementFaces[j]][i];
833 ASSERTL1((indx2 != -1)&&(indx3 != -1),
"Failed to find vertex 3 or 4");
837 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
839 Node b = *(Vnodes[indx2]) - *(Vnodes[indx0]);
844 Node c = *(Vnodes[indx1]) - *(Vnodes[indx2]);
846 Node d = *(Vnodes[indx3]) - *(Vnodes[indx2]);
850 if(acurlb_dot_acurld > 0.0)
852 returnval[0] = indx0;
853 returnval[1] = indx1;
854 returnval[2] = indx2;
855 returnval[3] = indx3;
859 returnval[0] = indx0;
860 returnval[1] = indx1;
861 returnval[2] = indx3;
862 returnval[3] = indx2;
870 vector<int> &ElementFaces,
871 vector<vector<int> >&FaceNodes)
875 Array<OneD, int> returnval;
878 if(ElementFaces.size() == 4)
880 ASSERTL1(FaceNodes[ElementFaces[0]].size() == 3,
"Face is not triangular");
882 returnval = Array<OneD, int>(4);
884 int indx0 = FaceNodes[ElementFaces[0]][0];
885 int indx1 = FaceNodes[ElementFaces[0]][1];
886 int indx2 = FaceNodes[ElementFaces[0]][2];
891 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
893 Node b = *(Vnodes[indx2]) - *(Vnodes[indx0]);
896 ASSERTL1(FaceNodes[ElementFaces[1]].size() == 3,
"Face is not triangular");
897 for(i = 0; i < 3; ++i)
900 if((FaceNodes[ElementFaces[1]][i] != indx0)&&(FaceNodes[ElementFaces[1]][i] != indx1)&&(FaceNodes[ElementFaces[1]][i] != indx2))
902 indx3 = FaceNodes[ElementFaces[1]][i];
908 Node c = *(Vnodes[indx3]) - *(Vnodes[indx0]);
912 if(acurlb_dotc < 0.0)
914 returnval[0] = indx0;
915 returnval[1] = indx1;
916 returnval[2] = indx2;
917 returnval[3] = indx3;
921 returnval[0] = indx1;
922 returnval[1] = indx0;
923 returnval[2] = indx2;
924 returnval[3] = indx3;
927 else if(ElementFaces.size() == 5)
929 int triface0, triface1;
935 triface0 = triface1 = -1;
936 for(i = 0; i < 5; ++i)
938 if(FaceNodes[ElementFaces[i]].size() == 3)
944 else if (triface1 == -1)
955 if(FaceNodes[ElementFaces[i]].size() == 4)
966 returnval = Array<OneD, int>(6);
970 returnval = Array<OneD, int>(5);
974 int indx0,indx1,indx2,indx3,indx4;
976 indx0 = indx1 = indx2 = indx3 = indx4 = -1;
981 for(i = 0; i < 4; ++i)
983 for(j = 0; j < 3; ++j)
985 if(FaceNodes[ElementFaces[triface0]][j] ==
986 FaceNodes[ElementFaces[quadface0]][i])
996 indx2 = FaceNodes[ElementFaces[quadface0]][i];
1001 indx3 = FaceNodes[ElementFaces[quadface0]][i];
1005 ASSERTL0(
false,
"More than two vertices do not match triangular face");
1012 indx0 = FaceNodes[ElementFaces[quadface0]][i];
1016 indx1 = FaceNodes[ElementFaces[quadface0]][i];
1022 for(
int i = 0; i < 3; ++i)
1024 if((FaceNodes[ElementFaces[triface0]][i] != indx0)&&
1025 (FaceNodes[ElementFaces[triface0]][i] != indx1)&&
1026 (FaceNodes[ElementFaces[triface0]][i] != indx2))
1028 indx4 = FaceNodes[ElementFaces[triface0]][i];
1034 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
1036 Node b = *(Vnodes[indx4]) - *(Vnodes[indx0]);
1038 Node c = *(Vnodes[indx2]) - *(Vnodes[indx0]);
1042 if(acurlb_dotc < 0.0)
1044 returnval[0] = indx0;
1045 returnval[1] = indx1;
1046 returnval[4] = indx4;
1050 returnval[0] = indx1;
1051 returnval[1] = indx0;
1052 returnval[4] = indx4;
1057 Node d = *(Vnodes[indx3]) - *(Vnodes[indx2]);
1062 if(ccurld_dotb > 0.0)
1064 returnval[2] = indx2;
1065 returnval[3] = indx3;
1069 returnval[2] = indx3;
1070 returnval[3] = indx2;
1076 for(
int i = 0; i < 3; ++i)
1078 if((FaceNodes[ElementFaces[triface1]][i] != indx2)&&
1079 (FaceNodes[ElementFaces[triface1]][i] != indx3)&&
1080 (FaceNodes[ElementFaces[triface1]][i] != indx3))
1082 returnval[5] = FaceNodes[ElementFaces[triface1]][i];
1091 ASSERTL0(
false,
"SortFaceNodes not set up for this number of faces");