35 #include <boost/core/ignore_unused.hpp> 36 #include <boost/algorithm/string.hpp> 54 "Reads mesh from Star CCM (.ccm).");
61 "Just write out tags from star file for each surface/composite");
84 cout <<
"InputCCM: Start reading file..." << endl;
111 unordered_map<int, vector<int> > FaceNodes;
118 vector<vector<int> > BndElementFaces;
119 vector<string> Facelabels;
122 if (
m_config[
"writelabelsonly"].beenSet)
126 for (i = 0; i < BndElementFaces.size(); ++i)
128 cout <<
" 2D Zone (composite = " << nComposite
129 <<
", label = " << Facelabels[i] <<
")" << endl;
141 int nelements = ElementFaces.num_elements();
142 cout <<
" Generating 3D Zones: " << endl;
144 for (i = 0; i < nelements; ++i)
147 if (ElementFaces[i].size() > 4)
150 m_mesh->m_node, i, ElementFaces[i], FaceNodes, nComposite,
true);
154 cout <<
" \t" << cnt <<
" Prisms" << endl;
160 for (i = 0; i < nelements; ++i)
162 if (ElementFaces[i].size() == 4)
165 m_mesh->m_node, i, ElementFaces[i], FaceNodes, nComposite,
true);
169 cout <<
"\t" << cnt <<
" Tets" << endl;
173 for (
auto &node :
m_mesh->m_node)
175 m_mesh->m_vertexSet.insert(node);
179 for (i = 0; i < BndElementFaces.size(); ++i)
181 cout <<
" Generating 2D Zone (composite = " << nComposite
182 <<
", label = " << Facelabels[i] <<
")" << endl;
184 for (
int j = 0; j < BndElementFaces[i].size(); ++j)
186 auto it = FaceNodes.find(BndElementFaces[i][j]);
187 if (it != FaceNodes.end())
193 string msg =
"Failed to find FaceNodes for Face ";
194 msg += boost::lexical_cast<
string>(BndElementFaces[i][j]);
199 m_mesh->m_faceLabels[nComposite] = Facelabels[i];
205 map<int, int> &facelist,
206 vector<vector<int> > &FacesToPrisms,
207 vector<vector<int> > &PrismsToFaces,
208 vector<bool> &PrismDone);
212 unordered_map<
int, vector<int> > &FaceNodes)
216 int face1_map[3] = {0, 1, 4};
217 int face3_map[3] = {3, 2, 5};
219 map<int, bool> FacesRenumbered;
222 vector<vector<int> > FaceToPrisms(FaceNodes.size());
223 vector<vector<int> > PrismToFaces(ElementFaces.num_elements());
224 map<int, int> Prisms;
228 for (i = 0; i < ElementFaces.num_elements(); ++i)
231 if (ElementFaces[i].size() == 5)
233 vector<int> LocTriFaces;
235 for (j = 0; j < ElementFaces[i].size(); ++j)
237 if (FaceNodes[ElementFaces[i][j]].size() == 3)
239 LocTriFaces.push_back(j);
243 if (LocTriFaces.size() == 2)
247 PrismToFaces[i].push_back(ElementFaces[i][LocTriFaces[0]]);
248 PrismToFaces[i].push_back(ElementFaces[i][LocTriFaces[1]]);
250 FaceToPrisms[ElementFaces[i][LocTriFaces[0]]].push_back(i);
251 FaceToPrisms[ElementFaces[i][LocTriFaces[1]]].push_back(i);
256 vector<bool> FacesDone(FaceNodes.size(),
false);
257 vector<bool> PrismDone(ElementFaces.num_elements(),
false);
262 for (
auto &PrismIt : Prisms)
264 int elmtid = PrismIt.first;
265 map<int, int> facelist;
267 if (PrismDone[elmtid])
275 elmtid, facelist, FaceToPrisms, PrismToFaces, PrismDone);
278 for (
auto &faceIt : facelist)
280 int faceid = faceIt.second;
282 for (i = 0; i < FaceToPrisms[faceid].size(); ++i)
284 int prismid = FaceToPrisms[faceid][i];
286 if ((FacesDone[PrismToFaces[prismid][0]] ==
true) &&
287 (FacesDone[PrismToFaces[prismid][1]] ==
true))
295 if ((FacesDone[PrismToFaces[prismid][0]] ==
false) &&
296 (FacesDone[PrismToFaces[prismid][1]] ==
false))
300 for (i = 0; i < 3; ++i)
302 if (NodeReordering[Nodes[face1_map[i]]] == -1)
304 NodeReordering[Nodes[face1_map[i]]] = nodeid++;
308 for (i = 0; i < 3; ++i)
310 if (NodeReordering[Nodes[face3_map[i]]] == -1)
312 NodeReordering[Nodes[face3_map[i]]] = nodeid++;
316 else if ((FacesDone[PrismToFaces[prismid][0]] ==
false) &&
317 (FacesDone[PrismToFaces[prismid][1]] ==
true))
320 int max_id1, max_id2;
322 max_id1 = (NodeReordering[Nodes[face3_map[0]]] <
323 NodeReordering[Nodes[face3_map[1]]])
326 max_id2 = (NodeReordering[Nodes[face3_map[max_id1]]] <
327 NodeReordering[Nodes[face3_map[2]]])
332 int id0 = (max_id1 == 1) ? 0 : 1;
334 if (NodeReordering[Nodes[face1_map[id0]]] == -1)
336 NodeReordering[Nodes[face1_map[id0]]] = nodeid++;
339 if (NodeReordering[Nodes[face1_map[max_id1]]] == -1)
341 NodeReordering[Nodes[face1_map[max_id1]]] =
345 if (NodeReordering[Nodes[face1_map[max_id2]]] == -1)
347 NodeReordering[Nodes[face1_map[max_id2]]] =
351 else if ((FacesDone[PrismToFaces[prismid][0]] ==
true) &&
352 (FacesDone[PrismToFaces[prismid][1]] ==
false))
355 int max_id1, max_id2;
357 max_id1 = (NodeReordering[Nodes[face1_map[0]]] <
358 NodeReordering[Nodes[face1_map[1]]])
361 max_id2 = (NodeReordering[Nodes[face1_map[max_id1]]] <
362 NodeReordering[Nodes[face1_map[2]]])
367 int id0 = (max_id1 == 1) ? 0 : 1;
369 if (NodeReordering[Nodes[face3_map[id0]]] == -1)
371 NodeReordering[Nodes[face3_map[id0]]] = nodeid++;
374 if (NodeReordering[Nodes[face3_map[max_id1]]] == -1)
376 NodeReordering[Nodes[face3_map[max_id1]]] =
380 if (NodeReordering[Nodes[face3_map[max_id2]]] == -1)
382 NodeReordering[Nodes[face3_map[max_id2]]] =
392 for (i = 0; i < NodeReordering.num_elements(); ++i)
394 if (NodeReordering[i] == -1)
396 NodeReordering[i] = nodeid++;
400 ASSERTL1(nodeid == NodeReordering.num_elements(),
401 "Have not renumbered all nodes");
404 for (
auto &it : FaceNodes)
406 for (j = 0; j < it.second.size(); ++j)
408 it.second[j] = NodeReordering[it.second[j]];
412 vector<NodeSharedPtr> save(Vnodes);
413 for (i = 0; i < Vnodes.size(); ++i)
415 Vnodes[NodeReordering[i]] = save[i];
416 Vnodes[NodeReordering[i]]->SetID(NodeReordering[i]);
421 map<int, int> &facelist,
422 vector<vector<int> > &FaceToPrisms,
423 vector<vector<int> > &PrismToFaces,
424 vector<bool> &PrismDone)
426 if (PrismDone[prismid] ==
false)
428 PrismDone[prismid] =
true;
431 int face = PrismToFaces[prismid][0];
432 facelist[face] = face;
433 for (
int i = 0; i < FaceToPrisms[face].size(); ++i)
443 face = PrismToFaces[prismid][1];
444 facelist[face] = face;
445 for (
int i = 0; i < FaceToPrisms[face].size(); ++i)
458 vector<int> &FaceNodes,
461 boost::ignore_unused(i);
465 if (FaceNodes.size() == 3)
469 else if (FaceNodes.size() == 4)
475 ASSERTL0(
false,
"Not set up for elements which are not Tets or Prism");
480 tags.push_back(nComposite);
483 vector<NodeSharedPtr> nodeList;
485 for (
int j = 0; j < Nodes.num_elements(); ++j)
487 nodeList.push_back(VertNodes[Nodes[j]]);
495 m_mesh->m_element[E->GetDim()].push_back(E);
500 vector<int> &ElementFaces,
501 unordered_map<
int, vector<int> > &FaceNodes,
505 boost::ignore_unused(i);
510 int nnodes = Nodes.num_elements();
511 map<LibUtilities::ShapeType, int> domainComposite;
518 else if (nnodes == 5)
522 else if (nnodes == 6)
529 ASSERTL0(
false,
"Not set up for elements which are not Tets or Prism");
534 tags.push_back(nComposite);
537 vector<NodeSharedPtr> nodeList;
538 for (
int j = 0; j < Nodes.num_elements(); ++j)
540 nodeList.push_back(VertNodes[Nodes[j]]);
546 ElmtConfig conf(elType, 1,
true,
true, DoOrient);
550 m_mesh->m_element[E->GetDim()].push_back(E);
554 cout <<
"Warning: Pyramid detected " << endl;
559 vector<int> &FaceNodes)
563 if (FaceNodes.size() == 3)
567 returnval[0] = FaceNodes[0];
568 returnval[1] = FaceNodes[1];
569 returnval[2] = FaceNodes[2];
571 else if (FaceNodes.size() == 4)
575 int indx0 = FaceNodes[0];
576 int indx1 = FaceNodes[1];
577 int indx2 = FaceNodes[2];
578 int indx3 = FaceNodes[3];
581 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
583 Node b = *(Vnodes[indx2]) - *(Vnodes[indx0]);
587 Node c = *(Vnodes[indx1]) - *(Vnodes[indx2]);
589 Node d = *(Vnodes[indx3]) - *(Vnodes[indx2]);
593 if (acurlb_dot_acurld > 0.0)
595 returnval[0] = indx0;
596 returnval[1] = indx1;
597 returnval[2] = indx2;
598 returnval[3] = indx3;
602 returnval[0] = indx0;
603 returnval[1] = indx1;
604 returnval[2] = indx3;
605 returnval[3] = indx2;
613 vector<int> &ElementFaces,
614 unordered_map<
int, vector<int> > &FaceNodes)
620 if (ElementFaces.size() == 4)
622 ASSERTL1(FaceNodes[ElementFaces[0]].size() == 3,
623 "Face is not triangular");
627 auto it = FaceNodes.find(ElementFaces[0]);
628 int indx0 = it->second[0];
629 int indx1 = it->second[1];
630 int indx2 = it->second[2];
634 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
636 Node b = *(Vnodes[indx2]) - *(Vnodes[indx0]);
639 ASSERTL1(FaceNodes[ElementFaces[1]].size() == 3,
640 "Face is not triangular");
642 auto it2 = FaceNodes.find(ElementFaces[1]);
643 for (i = 0; i < 3; ++i)
645 if ((it2->second[i] != indx0) && (it2->second[i] != indx1) &&
646 (it2->second[i] != indx2))
648 indx3 = it2->second[i];
654 Node c = *(Vnodes[indx3]) - *(Vnodes[indx0]);
658 if (acurlb_dotc < 0.0)
660 returnval[0] = indx0;
661 returnval[1] = indx1;
662 returnval[2] = indx2;
663 returnval[3] = indx3;
667 returnval[0] = indx1;
668 returnval[1] = indx0;
669 returnval[2] = indx2;
670 returnval[3] = indx3;
673 else if (ElementFaces.size() == 5)
675 int triface0, triface1, triface2, triface3;
676 int quadface0, quadface1, quadface2;
680 triface0 = triface1 = triface2 = triface3 = -1;
681 quadface0 = quadface1 = quadface2 = -1;
682 for (i = 0; i < 5; ++i)
684 auto it = FaceNodes.find(ElementFaces[i]);
685 if (it->second.size() == 3)
691 else if (triface1 == -1)
695 else if (triface2 == -1)
700 else if (triface3 == -1)
706 if (it->second.size() == 4)
712 else if (quadface1 == -1)
716 else if (quadface2 == -1)
726 ASSERTL1(quadface0 != -1,
"Quad face 0 not found");
727 ASSERTL1(quadface1 != -1,
"Quad face 1 not found");
728 ASSERTL1(quadface2 != -1,
"Quad face 2 not found");
729 ASSERTL1(triface0 != -1,
"Tri face 0 not found");
730 ASSERTL1(triface1 != -1,
"Tri face 1 not found");
734 ASSERTL1(quadface0 != -1,
"Quad face 0 not found");
735 ASSERTL1(triface0 != -1,
"Tri face 0 not found");
736 ASSERTL1(triface1 != -1,
"Tri face 1 not found");
737 ASSERTL1(triface2 != -1,
"Tri face 2 not found");
738 ASSERTL1(triface3 != -1,
"Tri face 3 not found");
739 ASSERTL0(
false,
"Pyramids still not sorted");
744 int indx0, indx1, indx2, indx3, indx4;
746 indx0 = indx1 = indx2 = indx3 = indx4 = -1;
751 auto &triface0_vec = FaceNodes.find(ElementFaces[triface0])->second;
752 auto &quadface0_vec = FaceNodes.find(ElementFaces[quadface0])->second;
753 for (i = 0; i < 4; ++i)
755 for (j = 0; j < 3; ++j)
757 if (triface0_vec[j] == quadface0_vec[i])
767 indx2 = quadface0_vec[i];
769 else if (indx3 == -1)
771 indx3 = quadface0_vec[i];
777 "More than two vertices do not match triangular face");
784 indx0 = quadface0_vec[i];
788 indx1 = quadface0_vec[i];
794 for (
int i = 0; i < 3; ++i)
796 if (triface0_vec[i] != indx0 && triface0_vec[i] != indx1 &&
797 triface0_vec[i] != indx2)
799 indx4 = triface0_vec[i];
805 Node a = *(Vnodes[indx1]) - *(Vnodes[indx0]);
807 Node b = *(Vnodes[indx4]) - *(Vnodes[indx0]);
809 Node c = *(Vnodes[indx2]) - *(Vnodes[indx0]);
813 if (acurlb_dotc < 0.0)
815 returnval[0] = indx0;
816 returnval[1] = indx1;
817 returnval[4] = indx4;
821 returnval[0] = indx1;
822 returnval[1] = indx0;
823 returnval[4] = indx4;
830 auto &quadface1_vec = FaceNodes.find(ElementFaces[quadface1])->second;
831 auto &quadface2_vec = FaceNodes.find(ElementFaces[quadface2])->second;
833 for (
int i = 0; i < 4; ++i)
835 if (quadface1_vec[i] == returnval[1] || quadface1_vec[i] == indx2)
843 returnval[2] = indx2;
844 returnval[3] = indx3;
849 for (
int i = 0; i < 4; ++i)
851 if (quadface2_vec[i] == returnval[1] || quadface2_vec[i] == indx2)
860 returnval[2] = indx3;
861 returnval[3] = indx2;
865 returnval[2] = indx2;
866 returnval[3] = indx3;
873 auto &triface1_vec = FaceNodes.find(ElementFaces[triface1])->second;
874 for (
int i = 0; i < 3; ++i)
876 if (triface1_vec[i] != indx2 && triface1_vec[i] != indx3)
878 returnval[5] = triface1_vec[i];
886 ASSERTL0(
false,
"SortFaceNodes not set up for this number of faces");
900 string fname =
m_config[
"infile"].as<
string>();
901 m_ccmErr = CCMIOOpenFile(NULL, fname.c_str(), kCCMIORead, &root);
902 ASSERTL0(m_ccmErr == kCCMIONoErr,
"Error opening file");
905 CCMIOID state, problem;
911 CCMIOGetState(&m_ccmErr, root, kDefaultState, &problem, &state);
912 if (m_ccmErr != kCCMIONoErr)
914 cout <<
"No state named '" << kDefaultState <<
"'" << endl;
921 CCMIONextEntity(&m_ccmErr, state, kCCMIOProcessor, &i, &
m_ccmProcessor);
922 ASSERTL0(m_ccmErr == kCCMIONoErr,
"Failed to find Next Entity");
927 CCMIOID mapID, vertices;
934 CCMIOEntitySize(&
m_ccmErr, vertices, &nVertices, NULL);
935 ASSERTL0(
m_ccmErr == kCCMIONoErr,
"Error Reading NextEntitySize in ReadNodes");
943 int nvert = nVertices;
945 mapData.resize(nvert);
947 verts.resize(3*nvert);
949 for (
int k = 0; k < nvert; ++k)
951 verts[3 * k] = verts[3 * k + 1] = verts[3 * k + 2] = 0.0;
971 for (
int i = 0; i < nVertices; ++i)
973 Nodes.push_back(std::make_shared<Node>(
974 i, verts[3 * i], verts[3 * i + 1], verts[3 * i + 2]));
983 CCMIOSize nFaces, size;
984 vector<int> faces, faceCells, mapData;
988 CCMIOEntitySize(&
m_ccmErr,
id, &nFaces, NULL);
992 faceCells.resize(2 * nf);
1002 faces.resize((
size_t)size);
1005 kCCMIOInternalFaces,
1013 kCCMIOInternalFaces,
1025 for (
int i = 0; i < nf; ++i)
1029 if (cnt < faces.size())
1031 int nv = faces[cnt];
1033 "Can only handle meshes with " 1034 "up to four nodes per face");
1036 for (j = 0; j < nv; ++j)
1038 if (cnt + 1 + j < faces.size())
1040 Fnodes.push_back(faces[cnt + 1 + j] - 1);
1045 FacesNodes[mapData[i] - 1] = Fnodes;
1050 for (
int i = 0; i < faceCells.size(); ++i)
1052 nelmt = max(nelmt, faceCells[i]);
1056 for (
int i = 0; i < nf; ++i)
1059 if (faceCells[2 * i])
1061 ElementFaces[faceCells[2 * i] - 1].push_back(mapData[i] - 1);
1065 if (faceCells[2 * i + 1])
1067 ElementFaces[faceCells[2 * i + 1] - 1].push_back(mapData[i] - 1);
1073 unordered_map<
int, vector<int> > &FacesNodes,
1074 Array<
OneD, vector<int> > &ElementFaces,
1075 vector<string> &Facelabels)
1080 CCMIOSize nFaces, size;
1081 vector<int> faces, faceCells, mapData;
1082 vector<string> facelabel;
1084 while (CCMIONextEntity(
1090 CCMIOEntitySize(&
m_ccmErr,
id, &nFaces, NULL);
1091 CCMIOSize nf = nFaces;
1093 faceCells.resize(nf);
1096 kCCMIOBoundaryFaces,
1103 faces.resize((
size_t)size);
1106 kCCMIOBoundaryFaces,
1114 kCCMIOBoundaryFaces,
1124 CCMIOGetEntityIndex(&
m_ccmErr,
id, &boundaryVal);
1129 if (CCMIOReadOptstr(NULL,
id,
"Label", &size, NULL) == kCCMIONoErr)
1131 name =
new char[size + 1];
1132 CCMIOReadOptstr(NULL,
id,
"Label", NULL, name);
1133 Facelabels.push_back(
string(name));
1137 Facelabels.push_back(
"Not known");
1142 for (
int i = 0; i < nf; ++i)
1146 if (cnt < faces.size())
1148 int nv = faces[cnt];
1150 "Can only handle meshes with " 1151 "up to four nodes per face");
1153 for (j = 0; j < nv; ++j)
1155 if (cnt + 1 + j < faces.size())
1157 Fnodes.push_back(faces[cnt + 1 + j] - 1);
1162 FacesNodes[mapData[i] - 1] = Fnodes;
1165 vector<int> BndFaces;
1166 for (
int i = 0; i < nf; ++i)
1170 ElementFaces[faceCells[i] - 1].push_back(mapData[i] - 1);
1172 BndFaces.push_back(mapData[i] - 1);
1174 BndElementFaces.push_back(BndFaces);
#define ASSERTL0(condition, msg)
Basic information about an element.
NEKMESHUTILS_EXPORT NekDouble dot(const Node &pSrc) const
MeshSharedPtr m_mesh
Mesh object.
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
ElementFactory & GetElementFactory()
Represents a point in the domain.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
std::pair< ModuleType, std::string > ModuleKey
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
std::shared_ptr< Element > ElementSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
Represents a command-line configuration option.
std::map< std::string, ConfigOption > m_config
List of configuration values.
NEKMESHUTILS_EXPORT Node curl(const Node &pSrc) const
static void PrismLineFaces(int prismid, map< int, int > &facelist, vector< vector< int > > &FacesToPrisms, vector< vector< int > > &PrismsToFaces, vector< bool > &PrismDone)
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static char const kDefaultState[]
std::pair< ModuleType, std::string > ModuleKey
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
ModuleFactory & GetModuleFactory()