35 #include <boost/iostreams/filter/gzip.hpp> 40 namespace io = boost::iostreams;
44 namespace NekMeshUtils
79 string fname =
m_config[
"infile"].as<
string>();
81 if (fname.size() > 3 && fname.substr(fname.size() - 3, 3) ==
".gz")
95 cerr <<
"Error opening file: " << fname << endl;
105 string fname =
m_config[
"outfile"].as<
string>();
107 if (fname.size() > 3 && fname.substr(fname.size() - 3, 3) ==
".gz")
121 cerr <<
"Error opening file: " << fname << endl;
136 vector<ElementSharedPtr> &elmt =
m_mesh->m_element[
m_mesh->m_expDim];
138 m_mesh->m_vertexSet.clear();
140 for (
int i = 0, vid = 0; i < elmt.size(); ++i)
142 for (
int j = 0; j < elmt[i]->GetVertexCount(); ++j)
144 pair<NodeSet::iterator,bool> testIns =
145 m_mesh->m_vertexSet.insert(elmt[i]->GetVertex(j));
149 (*(testIns.first))->m_id = vid++;
153 elmt[i]->SetVertex(j,*testIns.first);
176 if (
m_mesh->m_expDim < 2)
return;
180 vector<ElementSharedPtr> &elmt =
m_mesh->m_element[
m_mesh->m_expDim];
182 m_mesh->m_edgeSet.clear();
187 for (
int i = 0, eid = 0; i < elmt.size(); ++i)
189 for (
int j = 0; j < elmt[i]->GetEdgeCount(); ++j)
191 pair<EdgeSet::iterator,bool> testIns;
193 testIns =
m_mesh->m_edgeSet.insert(ed);
199 ed2->m_elLink.push_back(
200 pair<ElementSharedPtr,int>(elmt[i],j));
205 elmt[i]->SetEdge(j, e2);
206 if (e2->m_edgeNodes.size() == 0 &&
207 ed->m_edgeNodes.size() > 0)
209 e2->m_curveType = ed->m_curveType;
210 e2->m_edgeNodes = ed->m_edgeNodes;
213 if (e2->m_n1->m_id != ed->m_n1->m_id)
215 reverse(e2->m_edgeNodes.begin(),
216 e2->m_edgeNodes.end());
220 e2->m_parentCAD = ed->m_parentCAD;
223 e2->m_elLink.push_back(
224 pair<ElementSharedPtr,int>(elmt[i],j));
231 for (
int i = 0; i <
m_mesh->m_element[1].size(); ++i)
236 vector<NodeSharedPtr> edgeNodes;
238 new Edge(v0, v1, edgeNodes, elmt->GetConf().m_edgeCurveType));
240 EdgeSet::iterator it =
m_mesh->m_edgeSet.find(E);
241 if (it ==
m_mesh->m_edgeSet.end())
243 cerr <<
"Cannot find corresponding element edge for " 244 <<
"1D element " << i << endl;
247 elmt->SetEdgeLink(*it);
250 pair<ElementSharedPtr, int> eMap = (*it)->m_elLink.at(0);
251 eMap.first->SetBoundaryLink(eMap.second, i);
254 elmt->SetVertex(0, (*it)->m_n1,
false);
255 elmt->SetVertex(1, (*it)->m_n2,
false);
258 if ((*it)->m_edgeNodes.size() > 0)
261 if (edge->GetVertex(0) == (*it)->m_n1)
263 edge->SetVolumeNodes((*it)->m_edgeNodes);
265 elmt->SetCurveType((*it)->m_curveType);
288 if (
m_mesh->m_expDim < 3)
return;
292 vector<ElementSharedPtr> &elmt =
m_mesh->m_element[
m_mesh->m_expDim];
294 m_mesh->m_faceSet.clear();
297 for (
int i = 0, fid = 0; i < elmt.size(); ++i)
299 for (
int j = 0; j < elmt[i]->GetFaceCount(); ++j)
301 pair<FaceSet::iterator,bool> testIns;
302 testIns =
m_mesh->m_faceSet.insert(elmt[i]->GetFace(j));
306 (*(testIns.first))->m_id = fid++;
307 (*(testIns.first))->m_elLink.push_back(
308 pair<ElementSharedPtr,int>(elmt[i],j));
312 elmt[i]->SetFace(j,*testIns.first);
314 (*(testIns.first))->m_elLink.push_back(
315 pair<ElementSharedPtr,int>(elmt[i],j));
322 for (
int i = 0; i <
m_mesh->m_element[2].size(); ++i)
325 vector<NodeSharedPtr> vertices = elmt->GetVertexList();
326 vector<NodeSharedPtr> faceNodes;
327 vector<EdgeSharedPtr> edgeList = elmt->GetEdgeList();
329 new Face(vertices, faceNodes, edgeList,
330 elmt->GetConf().m_faceCurveType));
332 FaceSet::iterator it =
m_mesh->m_faceSet.find(F);
333 if (it ==
m_mesh->m_faceSet.end())
335 cout <<
"Cannot find corresponding element face for 2D " 336 <<
"element " << i << endl;
340 elmt->SetFaceLink(*it);
343 for (
int j = 0; j < elmt->GetVertexCount(); ++j)
345 elmt->SetVertex(j, (*it)->m_vertexList[j],
false);
346 elmt->SetEdge(j, (*it)->m_edgeList[j],
false);
349 EdgeSet tmp(edgeList.begin(),edgeList.end());
351 for (
int j = 0; j < elmt->GetEdgeCount(); ++j)
354 EdgeSet::iterator f = tmp.find(e);
357 e->m_parentCAD = (*f)->m_parentCAD;
362 pair<ElementSharedPtr, int> eMap = (*it)->m_elLink.at(0);
363 eMap.first->SetBoundaryLink(eMap.second, i);
366 if ((*it)->m_faceNodes.size() > 0)
368 elmt->SetVolumeNodes((*it)->m_faceNodes);
369 elmt->SetCurveType((*it)->m_curveType);
385 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim].size(); ++i)
402 m_mesh->m_composite.clear();
407 for (
int d = 0; d <=
m_mesh->m_expDim; ++d)
409 vector<ElementSharedPtr> &elmt =
m_mesh->m_element[d];
411 for (
int i = 0; i < elmt.size(); ++i)
413 CompositeMap::iterator it;
414 unsigned int tagid = elmt[i]->GetTagList()[0];
416 it =
m_mesh->m_composite.find(tagid);
418 if (it ==
m_mesh->m_composite.end())
422 pair<CompositeMap::iterator, bool> testIns;
424 tmp->m_tag = elmt[i]->GetTag();
425 if(
m_mesh->m_faceLabels.count(tmp->m_id) != 0)
427 tmp->m_label =
m_mesh->m_faceLabels[tmp->m_id];
430 testIns =
m_mesh->m_composite.insert(
431 pair<unsigned int, CompositeSharedPtr>(tagid,tmp));
435 if (elmt[i]->GetTag() != it->second->m_tag)
437 cout <<
"Different types of elements in same composite!" << endl;
438 cout <<
" -> Composite uses " << it->second->m_tag << endl;
439 cout <<
" -> Element uses " << elmt[i]->GetTag() << endl;
440 cout <<
"Have you specified physical volumes and surfaces?" << endl;
442 it->second->m_items.push_back(elmt[i]);
452 EdgeSet::iterator eit;
454 for(eit =
m_mesh->m_edgeSet.begin(); eit !=
m_mesh->m_edgeSet.end(); eit++)
456 (*eit)->m_elLink.clear();
459 FaceSet::iterator fit;
461 for(fit =
m_mesh->m_faceSet.begin(); fit !=
m_mesh->m_faceSet.end(); fit++)
463 (*fit)->m_elLink.clear();
504 set<int> prismsDone, tetsDone;
505 PerMap::iterator pIt;
508 for (i = 0; i <
m_mesh->m_element[3].size(); ++i)
514 prismsDone.insert(i);
523 NodeSet::iterator it;
524 for (it =
m_mesh->m_vertexSet.begin(); it !=
m_mesh->m_vertexSet.end(); ++it)
531 int prismTris[2][3] = {{0,1,4}, {3,2,5}};
534 bool warnCurvature =
false;
538 std::unordered_set<int> facesDone;
539 std::unordered_set<int>::iterator fIt[2], fIt2;
542 while (prismsDone.size() > 0)
544 vector<ElementSharedPtr> line;
548 PrismLines(*prismsDone.begin(), perFaces, prismsDone, line);
552 for (i = 0; i < line.size(); ++i)
555 vector<int> tags = line[i]->GetTagList();
556 vector<NodeSharedPtr> nodes = line[i]->GetVertexList();
561 line[i]->GetFace(1), line[i]->GetFace(3)
564 fIt[0] = facesDone.find(f[0]->m_id);
565 fIt[1] = facesDone.find(f[1]->m_id);
569 for (j = 0; j < 2; ++j)
571 pIt = perFaces.find(f[j]->m_id);
573 if (pIt == perFaces.end())
578 fIt2 = facesDone.find(pIt->second.first->m_id);
580 if (fIt[j] == facesDone.end() &&
581 fIt2 != facesDone.end())
587 if (fIt[0] != facesDone.end() &&
588 fIt[1] != facesDone.end())
592 ASSERTL0(
false,
"Renumbering error!");
594 else if (fIt[0] == facesDone.end() &&
595 fIt[1] == facesDone.end())
598 for (j = 0; j < 2; ++j)
600 for (k = 0; k < 3; ++k)
610 facesDone.insert(f[0]->m_id);
611 facesDone.insert(f[1]->m_id);
617 int t = fIt[0] == facesDone.end() ? 0 : 1;
619 ASSERTL1(fIt[o] != facesDone.end(),
"Renumbering error");
625 nodes[prismTris[o][0]]->m_id,
626 nodes[prismTris[o][1]]->m_id,
627 nodes[prismTris[o][2]]->m_id
629 int tmp2[3] = {0,1,2};
631 if (tmp1[0] > tmp1[1])
633 swap(tmp1[0], tmp1[1]);
634 swap(tmp2[0], tmp2[1]);
637 if (tmp1[1] > tmp1[2])
639 swap(tmp1[1], tmp1[2]);
640 swap(tmp2[1], tmp2[2]);
643 if (tmp1[0] > tmp1[2])
645 swap(tmp1[0], tmp1[2]);
646 swap(tmp2[0], tmp2[2]);
650 for (j = 0; j < 3; ++j)
659 facesDone.insert(f[t]->m_id);
662 for (j = 0; j < 6; ++j)
664 ASSERTL1(nodes[j]->m_id != -1,
"Renumbering error");
674 for (j = 0; j < 9; ++j)
677 for (k = 0; k < 9; ++k)
680 if (e1->m_n1 == e2->m_n1 && e1->m_n2 == e2->m_n2)
682 e2->m_edgeNodes = e1->m_edgeNodes;
684 else if (e1->m_n1 == e2->m_n1 && e1->m_n2 == e2->m_n2)
686 e2->m_edgeNodes = e1->m_edgeNodes;
687 std::reverse(e2->m_edgeNodes.begin(),
688 e2->m_edgeNodes.end());
696 for (j = 0; j < 5; ++j)
698 if (line[i]->GetFace(j)->m_faceNodes.size() > 0)
700 warnCurvature =
true;
707 m_mesh->m_element[3][line[i]->GetId()] = el;
713 cerr <<
"[ReorderPrisms] WARNING: Face curvature detected in " 714 <<
"some prisms; this will be ignored in further module " 720 for (pIt = perFaces.begin(); pIt != perFaces.end(); ++pIt)
724 vector<int> perVerts = pIt->second.second;
725 int nVerts = perVerts.size();
728 for (j = 0; j < nVerts; ++j)
733 if (n1->m_id == -1 && n2->m_id == -1)
738 else if (n1->m_id != -1 && n2->m_id != -1)
744 ASSERTL0(
false,
"Periodic face renumbering error");
750 set<int>::iterator it2;
751 for (it2 = tetsDone.begin(); it2 != tetsDone.end(); ++it2)
754 vector<NodeSharedPtr> nodes = el->GetVertexList();
755 vector<int> tags = el->GetTagList();
757 for (i = 0; i < 4; ++i)
759 if (nodes[i]->m_id == -1)
761 nodes[i]->m_id = nodeId++;
772 for (it =
m_mesh->m_vertexSet.begin(); it !=
m_mesh->m_vertexSet.end(); ++it)
774 if ((*it)->m_id == -1)
776 (*it)->m_id = nodeId++;
787 set<int> &prismsDone,
788 vector<ElementSharedPtr> &line)
791 set<int>::iterator it = prismsDone.find(prism);
792 PerMap::iterator it2;
794 if (it == prismsDone.end())
800 prismsDone.erase(it);
801 line.push_back(
m_mesh->m_element[3][prism]);
804 for (i = 1; i <= 3; i += 2)
810 it2 = perFaces.find(f->m_id);
812 if (it2 != perFaces.end())
814 int id2 = it2->second.first->m_id;
815 nextId = it2->second.first->m_elLink[0].first->GetId();
818 PrismLines(nextId, perFaces, prismsDone, line);
822 if (f->m_elLink.size() == 1)
827 nextId = f->m_elLink[0].first->GetId();
828 if (nextId ==
m_mesh->m_element[3][prism]->GetId())
830 nextId = f->m_elLink[1].first->GetId();
833 PrismLines(nextId, perFaces, prismsDone, line);
842 map<string, ConfigOption>::iterator it =
m_config.find(key);
845 cerr <<
"WARNING: Unrecognised config option " << key
846 <<
", proceeding anyway." << endl;
849 it->second.beenSet =
true;
851 if (it->second.isBool)
853 it->second.value =
"1";
859 it->second.value = it->second.defValue;
863 it->second.value = val;
873 map<string, ConfigOption>::iterator it;
877 cerr <<
"No configuration options for this module." << endl;
883 cerr << setw(10) << it->first <<
": " << it->second.desc
894 map<string, ConfigOption>::iterator it;
898 if (!it->second.beenSet)
900 it->second.value = it->second.defValue;
912 cerr <<
"Expansion dimension is " <<
m_mesh->m_expDim << endl;
913 cerr <<
"Space dimension is " <<
m_mesh->m_spaceDim << endl;
914 cerr <<
"Read " <<
m_mesh->m_node.size() <<
" nodes" << endl;
915 cerr <<
"Read " <<
m_mesh->GetNumElements() <<
" " 916 <<
m_mesh->m_expDim <<
"-D elements" << endl;
917 cerr <<
"Read " <<
m_mesh->GetNumBndryElements()
918 <<
" boundary elements" << endl;
NEKMESHUTILS_EXPORT void SetDefaults()
Sets default configuration options for those which have not been set.
#define ASSERTL0(condition, msg)
Basic information about an element.
io::filtering_ostream m_mshFile
Output stream.
Represents an edge which joins two points.
std::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
NEKMESHUTILS_EXPORT void OpenStream()
Open a file for output.
Represents a face comprised of three or more edges.
std::map< int, std::pair< FaceSharedPtr, std::vector< int > > > PerMap
MeshSharedPtr m_mesh
Mesh object.
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
NEKMESHUTILS_EXPORT void PrintConfig()
Print out all configuration options for a module.
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
NEKMESHUTILS_EXPORT void RegisterConfig(std::string key, std::string value=std::string())
Register a configuration option with a module.
ElementFactory & GetElementFactory()
std::shared_ptr< Node > NodeSharedPtr
std::shared_ptr< Face > FaceSharedPtr
std::ofstream m_mshFileStream
Input stream.
ModuleFactory & GetModuleFactory()
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
A composite is a collection of elements.
NEKMESHUTILS_EXPORT void ReorderPrisms(PerMap &perFaces)
Reorder node IDs so that prisms and tetrahedra are aligned correctly.
const char *const ModuleTypeMap[]
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.
virtual NEKMESHUTILS_EXPORT void ClearElementLinks()
NEKMESHUTILS_EXPORT OutputModule(MeshSharedPtr p_m)
NEKMESHUTILS_EXPORT void PrismLines(int prism, PerMap &perFaces, std::set< int > &prismsDone, std::vector< ElementSharedPtr > &line)
std::ostream & operator<<(std::ostream &os, const ModuleKey &rhs)
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
std::shared_ptr< Composite > CompositeSharedPtr
Shared pointer to a composite.
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
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.
Provides a generic Factory class.