35 #include <type_traits>
37 #include <boost/core/ignore_unused.hpp>
38 #include <boost/algorithm/string.hpp>
39 #include <boost/filesystem.hpp>
46 #define TIME_RESULT(verb, msg, timer) \
49 std::cout << " - " << msg << ": " \
50 << timer.TimePerTest(1) << std::endl; \
58 namespace SpatialDomains
63 const unsigned int MeshGraphHDF5::FORMAT_VERSION = 1;
65 std::string MeshGraphHDF5::className =
67 "HDF5", MeshGraphHDF5::create,
"IO with HDF5 geometry");
69 void MeshGraphHDF5::ReadGeometry(
73 boost::ignore_unused(rng);
85 MeshGraph::FillGraph();
100 std::pair<size_t, size_t>
SplitWork(
size_t vecsize,
int rank,
int nprocs)
102 size_t div = vecsize / nprocs;
103 size_t rem = vecsize % nprocs;
106 return std::make_pair(rank * (div + 1), div + 1);
110 return std::make_pair((rank - rem) * div + rem * (div + 1), div);
114 template<class T, typename std::enable_if<T::kDim == 0, int>::type = 0>
117 boost::ignore_unused(geomMap);
121 template<class T, typename std::enable_if<T::kDim == 1, int>::type = 0>
122 inline int GetGeomDataDim(std::map<
int, std::shared_ptr<T>> &geomMap)
124 boost::ignore_unused(geomMap);
128 template<class T, typename std::enable_if<T::kDim == 2, int>::type = 0>
129 inline int GetGeomDataDim(std::map<
int, std::shared_ptr<T>> &geomMap)
131 boost::ignore_unused(geomMap);
135 template<class T, typename std::enable_if<T::kDim == 3, int>::type = 0>
136 inline int GetGeomDataDim(std::map<
int, std::shared_ptr<T>> &geomMap)
138 boost::ignore_unused(geomMap);
145 boost::ignore_unused(unique);
150 const std::vector<int> &input,
161 std::string MeshGraphHDF5::cmdSwitch =
162 LibUtilities::SessionReader::RegisterCmdLineFlag(
163 "use-hdf5-node-comm",
"",
164 "Use a per-node communicator for HDF5 partitioning.");
175 int rank = comm->GetRank(), nproc = comm->GetSize();
182 session->InitSession();
187 m_xmlGeom = m_session->GetElement(
"NEKTAR/GEOMETRY");
188 TiXmlAttribute *attr = m_xmlGeom->FirstAttribute();
189 m_meshPartitioned =
true;
191 m_spaceDimension = 3;
195 std::string attrName(attr->Name());
196 if (attrName ==
"DIM")
198 err = attr->QueryIntValue(&m_meshDimension);
199 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read mesh dimension.");
201 else if (attrName ==
"SPACE")
203 err = attr->QueryIntValue(&m_spaceDimension);
204 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read space dimension.");
206 else if (attrName ==
"PARTITION")
209 "PARTITION parameter should only be used in XML meshes");
211 else if(attrName ==
"HDF5FILE")
213 m_hdf5Name = attr->Value();
214 ASSERTL1(err == TIXML_SUCCESS,
"Unable to read hdf5 name.");
216 else if(attrName ==
"PARTITIONED")
219 "PARTITIONED parameter should only be used in XML meshes");
223 std::string errstr(
"Unknown attribute: ");
231 ASSERTL0(m_hdf5Name.size() > 0,
"Unable to obtain mesh file name.");
232 ASSERTL0(m_meshDimension <= m_spaceDimension,
233 "Mesh dimension greater than space dimension.");
237 m_readPL = H5::PList::Default();
242 parallelProps = H5::PList::FileAccess();
243 parallelProps->SetMpio(comm);
245 m_readPL = H5::PList::DatasetXfer();
246 m_readPL->SetDxMpioCollective();
249 m_file = H5::File::Open(m_hdf5Name, H5F_ACC_RDONLY, parallelProps);
251 auto root = m_file->OpenGroup(
"NEKTAR");
252 ASSERTL0(root,
"Cannot find NEKTAR group in HDF5 file.");
254 auto root2 = root->OpenGroup(
"GEOMETRY");
255 ASSERTL0(root2,
"Cannot find NEKTAR/GEOMETRY group in HDF5 file.");
258 unsigned int formatVersion;
259 H5::Group::AttrIterator attrIt = root2->attr_begin();
260 H5::Group::AttrIterator attrEnd = root2->attr_end();
261 for (; attrIt != attrEnd; ++attrIt)
263 if (*attrIt ==
"FORMAT_VERSION")
269 "Unable to determine Nektar++ geometry HDF5 file version.");
270 root2->GetAttribute(
"FORMAT_VERSION", formatVersion);
272 ASSERTL0(formatVersion <= FORMAT_VERSION,
273 "File format in " + m_hdf5Name +
" is higher than supported in "
274 "this version of Nektar++");
276 m_mesh = root2->OpenGroup(
"MESH");
277 ASSERTL0(m_mesh,
"Cannot find NEKTAR/GEOMETRY/MESH group in HDF5 file.");
278 m_maps = root2->OpenGroup(
"MAPS");
279 ASSERTL0(m_mesh,
"Cannot find NEKTAR/GEOMETRY/MAPS group in HDF5 file.");
282 std::map<int, std::vector<std::tuple<
293 bool verbRoot = rank == 0 && m_session->DefinesCmdLineArgument(
"verbose");
297 std::cout <<
"Reading HDF5 geometry..." << std::endl;
305 int innerRank = 0, innerSize = 1, interRank = rank, interSize = nproc;
307 if (session->DefinesCmdLineArgument(
"use-hdf5-node-comm"))
309 auto splitComm = comm->SplitCommNode();
310 innerComm = splitComm.first;
311 interComm = splitComm.second;
312 innerRank = innerComm->GetRank();
313 innerSize = innerComm->GetSize();
317 interRank = interComm->GetRank();
318 interSize = interComm->GetSize();
324 std::unordered_set<int> toRead;
333 std::cout <<
" - beginning partitioning" << std::endl;
344 session->DefinesCmdLineArgument(
"verbose") && interRank == 0;
347 std::vector<int> ids;
351 std::vector<MeshEntity> elmts;
352 std::unordered_map<int, int> row2id, id2row;
362 auto parallelProps = H5::PList::FileAccess();
363 parallelProps->SetMpio(interComm);
366 readPL = H5::PList::DatasetXfer();
367 readPL->SetDxMpioCollective();
368 file = H5::File::Open(m_hdf5Name, H5F_ACC_RDONLY, parallelProps);
370 auto root = file->OpenGroup(
"NEKTAR");
371 auto root2 = root->OpenGroup(
"GEOMETRY");
372 mesh = root2->OpenGroup(
"MESH");
373 maps = root2->OpenGroup(
"MAPS");
377 for (
auto &it : dataSets[m_meshDimension])
379 std::string ds = std::get<0>(it);
381 if (!mesh->ContainsDataSet(ds))
389 vector<hsize_t> dims = space->GetDims();
393 vector<hsize_t> mdims = mspace->GetDims();
398 vector<int> tmpElmts, tmpIds;
399 mdata->Read(tmpIds, mspace, readPL);
400 data->Read(tmpElmts, space, readPL);
402 const int nGeomData = std::get<1>(it);
404 for (
int i = 0, cnt = 0; i < tmpIds.size(); ++i, ++rowCount)
407 row2id[rowCount] = tmpIds[i];
408 id2row[tmpIds[i]] = row2id[rowCount];
411 e.
list = std::vector<unsigned int>(
412 &tmpElmts[cnt], &tmpElmts[cnt+nGeomData]);
425 size_t numElmt = elmts.size();
427 "This mesh has more processors than elements!");
429 auto elRange =
SplitWork(numElmt, interRank, interSize);
432 std::map<int, MeshEntity> partElmts;
433 std::unordered_set<int> facetIDs;
437 for (
int el = elRange.first; el < elRange.first + elRange.second;
442 partElmts[el] = elmt;
444 for (
auto &facet : elmt.
list)
446 facetIDs.insert(facet);
453 for (
int i = 0; i < numElmt; ++i)
456 if (i >= elRange.first && i < elRange.first + elRange.second)
465 for (
auto &eId : elmt.
list)
467 if (facetIDs.find(eId) != facetIDs.end())
477 partElmts[elmt.
id] = elmt;
484 string partitionerName = nproc > 1 ?
"PtScotch" :
"Scotch";
487 partitionerName =
"ParMetis";
489 if (session->DefinesCmdLineArgument(
"use-parmetis"))
491 partitionerName =
"ParMetis";
493 if (session->DefinesCmdLineArgument(
"use-ptscotch"))
495 partitionerName =
"PtScotch";
500 partitionerName, session, interComm, m_meshDimension,
501 partElmts, CreateCompositeDescriptor(id2row));
504 TIME_RESULT(verbRoot2,
" - partitioner setup", t2);
507 partitioner->PartitionMesh(interSize,
true,
false, nLocal);
514 std::vector<unsigned int> nodeElmts;
515 partitioner->GetElementIDs(interRank, nodeElmts);
520 std::map<int, MeshEntity> partElmts;
521 std::unordered_map<int, int> row2elmtid, elmtid2row;
528 for (
auto &elmtRow : nodeElmts)
530 row2elmtid[vcnt] = elmts[elmtRow].origId;
531 elmtid2row[elmts[elmtRow].origId] = vcnt;
534 partElmts[vcnt++] = elmt;
543 "Scotch", session, tmpComm, m_meshDimension,
544 partElmts, CreateCompositeDescriptor(elmtid2row));
547 TIME_RESULT(verbRoot2,
" - inner partition setup", t2);
550 partitioner->PartitionMesh(innerSize,
true,
false, 0);
553 TIME_RESULT(verbRoot2,
" - inner partitioning", t2);
557 for (
int i = 1; i < innerSize; ++i)
559 std::vector<unsigned int> tmp;
560 partitioner->GetElementIDs(i, tmp);
561 size_t tmpsize = tmp.size();
562 for (
int j = 0; j < tmpsize; ++j)
564 tmp[j] = row2elmtid[tmp[j]];
566 innerComm->Send(i, tmpsize);
567 innerComm->Send(i, tmp);
571 TIME_RESULT(verbRoot2,
" - inner partition scatter", t2);
573 std::vector<unsigned int> tmp;
574 partitioner->GetElementIDs(0, tmp);
576 for (
auto &tmpId : tmp)
578 toRead.insert(row2elmtid[tmpId]);
583 for (
auto &tmpId : nodeElmts)
585 toRead.insert(row2id[tmpId]);
594 innerComm->Recv(0, tmpSize);
595 std::vector<unsigned int> tmp(tmpSize);
596 innerComm->Recv(0, tmp);
598 for (
auto &tmpId : tmp)
600 toRead.insert(tmpId);
610 std::vector<int> vertIDs, segIDs, triIDs, quadIDs;
611 std::vector<int> tetIDs, prismIDs, pyrIDs, hexIDs;
612 std::vector<int> segData, triData, quadData, tetData;
613 std::vector<int> prismData, pyrData, hexData;
614 std::vector<NekDouble> vertData;
616 if (m_meshDimension == 3)
620 ReadGeometryData(m_hexGeoms,
"HEX", toRead, hexIDs, hexData);
621 ReadGeometryData(m_pyrGeoms,
"PYR", toRead, pyrIDs, pyrData);
622 ReadGeometryData(m_prismGeoms,
"PRISM", toRead, prismIDs, prismData);
623 ReadGeometryData(m_tetGeoms,
"TET", toRead, tetIDs, tetData);
626 UniqueValues(toRead, hexData, pyrData, prismData, tetData);
631 if (m_meshDimension >= 2)
635 ReadGeometryData(m_triGeoms,
"TRI", toRead, triIDs, triData);
636 ReadGeometryData(m_quadGeoms,
"QUAD", toRead, quadIDs, quadData);
644 if (m_meshDimension >= 1)
648 ReadGeometryData(m_segGeoms,
"SEG", toRead, segIDs, segData);
657 ReadGeometryData(m_vertSet,
"VERT", toRead, vertIDs, vertData);
663 FillGeomMap(m_vertSet,
CurveMap(), vertIDs, vertData);
667 if (m_meshDimension >= 1)
671 for (
auto &edge : segIDs)
675 ReadCurveMap(m_curvedEdges,
"CURVE_EDGE", toRead);
678 FillGeomMap(m_segGeoms, m_curvedEdges, segIDs, segData);
683 if (m_meshDimension >= 2)
687 for (
auto &face : triIDs)
691 for (
auto &face : quadIDs)
695 ReadCurveMap(m_curvedFaces,
"CURVE_FACE", toRead);
698 FillGeomMap(m_triGeoms, m_curvedFaces, triIDs, triData);
699 FillGeomMap(m_quadGeoms, m_curvedFaces, quadIDs, quadData);
704 if (m_meshDimension >= 3)
707 FillGeomMap(m_hexGeoms,
CurveMap(), hexIDs, hexData);
708 FillGeomMap(m_prismGeoms,
CurveMap(), prismIDs, prismData);
709 FillGeomMap(m_pyrGeoms,
CurveMap(), pyrIDs, pyrData);
710 FillGeomMap(m_tetGeoms,
CurveMap(), tetIDs, tetData);
716 if (m_session->DefinesElement(
"NEKTAR/CONDITIONS"))
718 std::set<int> vBndRegionIdList;
719 TiXmlElement *vConditions =
720 new TiXmlElement(*m_session->GetElement(
"Nektar/Conditions"));
721 TiXmlElement *vBndRegions =
722 vConditions->FirstChildElement(
"BOUNDARYREGIONS");
727 vItem = vBndRegions->FirstChildElement();
730 std::string vSeqStr =
731 vItem->FirstChild()->ToText()->Value();
732 std::string::size_type indxBeg =
733 vSeqStr.find_first_of(
'[') + 1;
734 std::string::size_type indxEnd =
735 vSeqStr.find_last_of(
']') - 1;
736 vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
738 std::vector<unsigned int> vSeq;
739 ParseUtils::GenerateSeqVector(vSeqStr.c_str(), vSeq);
741 int p = atoi(vItem->Attribute(
"ID"));
742 m_bndRegOrder[
p] = vSeq;
743 vItem = vItem->NextSiblingElement();
752 template<
class T,
typename DataType>
void MeshGraphHDF5::ConstructGeomObject(
753 std::map<
int, std::shared_ptr<T>> &geomMap,
int id,
756 boost::ignore_unused(geomMap,
id, data, curve);
759 template<>
void MeshGraphHDF5::ConstructGeomObject(
760 std::map<
int, std::shared_ptr<PointGeom>> &geomMap,
int id,
763 boost::ignore_unused(curve);
765 m_spaceDimension,
id, data[0], data[1], data[2]);
768 template<>
void MeshGraphHDF5::ConstructGeomObject(
769 std::map<
int, std::shared_ptr<SegGeom>> &geomMap,
int id,
int *data,
774 id, m_spaceDimension, pts, curve);
777 template<>
void MeshGraphHDF5::ConstructGeomObject(
778 std::map<
int, std::shared_ptr<TriGeom>> &geomMap,
int id,
int *data,
782 GetSegGeom(data[0]), GetSegGeom(data[1]), GetSegGeom(data[2]) };
786 template<>
void MeshGraphHDF5::ConstructGeomObject(
787 std::map<
int, std::shared_ptr<QuadGeom>> &geomMap,
int id,
int *data,
791 GetSegGeom(data[0]), GetSegGeom(data[1]), GetSegGeom(data[2]),
797 template<>
void MeshGraphHDF5::ConstructGeomObject(
798 std::map<
int, std::shared_ptr<TetGeom>> &geomMap,
int id,
int *data,
801 boost::ignore_unused(curve);
803 std::static_pointer_cast<TriGeom>(GetGeometry2D(data[0])),
804 std::static_pointer_cast<TriGeom>(GetGeometry2D(data[1])),
805 std::static_pointer_cast<TriGeom>(GetGeometry2D(data[2])),
806 std::static_pointer_cast<TriGeom>(GetGeometry2D(data[3]))
810 PopulateFaceToElMap(tetGeom, TetGeom::kNfaces);
811 geomMap[id] = tetGeom;
814 template<>
void MeshGraphHDF5::ConstructGeomObject(
815 std::map<
int, std::shared_ptr<PyrGeom>> &geomMap,
int id,
int *data,
818 boost::ignore_unused(curve);
820 GetGeometry2D(data[0]), GetGeometry2D(data[1]), GetGeometry2D(data[2]),
821 GetGeometry2D(data[3]), GetGeometry2D(data[4])
825 PopulateFaceToElMap(pyrGeom, PyrGeom::kNfaces);
826 geomMap[id] = pyrGeom;
829 template<>
void MeshGraphHDF5::ConstructGeomObject(
830 std::map<
int, std::shared_ptr<PrismGeom>> &geomMap,
int id,
int *data,
833 boost::ignore_unused(curve);
835 GetGeometry2D(data[0]), GetGeometry2D(data[1]), GetGeometry2D(data[2]),
836 GetGeometry2D(data[3]), GetGeometry2D(data[4])
840 PopulateFaceToElMap(prismGeom, PrismGeom::kNfaces);
841 geomMap[id] = prismGeom;
844 template<>
void MeshGraphHDF5::ConstructGeomObject(
845 std::map<
int, std::shared_ptr<HexGeom>> &geomMap,
int id,
int *data,
848 boost::ignore_unused(curve);
850 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[0])),
851 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[1])),
852 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[2])),
853 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[3])),
854 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[4])),
855 std::static_pointer_cast<QuadGeom>(GetGeometry2D(data[5]))
859 PopulateFaceToElMap(hexGeom, HexGeom::kNfaces);
860 geomMap[id] = hexGeom;
863 template<
class T,
typename DataType>
864 void MeshGraphHDF5::FillGeomMap(
865 std::map<
int, std::shared_ptr<T>> &geomMap,
867 std::vector<int> &ids,
868 std::vector<DataType> &geomData)
871 const int nRows = geomData.size() / nGeomData;
875 if (curveMap.size() > 0)
877 for(
int i = 0, cnt = 0; i < nRows; i++, cnt += nGeomData)
879 auto cIt = curveMap.find(ids[i]);
881 geomMap, ids[i], &geomData[cnt],
882 cIt == curveMap.end() ? empty : cIt->second);
887 for(
int i = 0, cnt = 0; i < nRows; i++, cnt += nGeomData)
889 ConstructGeomObject(geomMap, ids[i], &geomData[cnt], empty);
894 template<
class T,
typename DataType>
895 void MeshGraphHDF5::ReadGeometryData(
896 std::map<
int, std::shared_ptr<T>> &geomMap,
898 const std::unordered_set<int> &readIds,
899 std::vector<int> &ids,
900 std::vector<DataType> &geomData)
902 if (!m_mesh->ContainsDataSet(dataSet))
910 vector<hsize_t> dims = space->GetDims();
915 vector<hsize_t> mdims = mspace->GetDims();
917 ASSERTL0(mdims[0] == dims[0],
"map and data set lengths do not match");
923 mdata->Read(allIds, mspace);
930 std::vector<hsize_t> coords;
931 for (
auto &
id : allIds)
933 if (readIds.find(
id) != readIds.end())
935 for (
int j = 0; j < nGeomData; ++j)
945 space->SetSelection(coords.size() / 2, coords);
948 data->Read(geomData, space, m_readPL);
951 void MeshGraphHDF5::ReadCurveMap(
954 const std::unordered_set<int> &readIds)
957 if (!m_mesh->ContainsDataSet(dsName))
971 vector<int> ids, newIds;
972 idData->Read(ids, idSpace);
973 curveSpace->ClearRange();
976 vector<hsize_t> curveSel;
981 if (readIds.find(
id) != readIds.end())
983 curveSel.push_back(cnt);
984 curveSel.push_back(0);
985 curveSel.push_back(cnt);
986 curveSel.push_back(1);
987 curveSel.push_back(cnt);
988 curveSel.push_back(2);
989 newIds.push_back(
id);
996 auto toRead = newIds.size();
1005 vector<int> curveInfo;
1006 curveSpace->SetSelection(curveSel.size() / 2, curveSel);
1007 curveData->Read(curveInfo, curveSpace, m_readPL);
1011 std::unordered_map<int, int> curvePtOffset;
1014 for (
int i = 0, cnt = 0, cnt2 = 0; i < curveInfo.size() / 3; ++i, cnt += 3)
1019 curve->m_points.resize(curveInfo[cnt]);
1021 const int ptOffset = curveInfo[cnt + 2];
1023 for (
int j = 0; j < curveInfo[cnt]; ++j)
1027 curveSel.push_back(ptOffset + j);
1028 curveSel.push_back(0);
1029 curveSel.push_back(ptOffset + j);
1030 curveSel.push_back(1);
1031 curveSel.push_back(ptOffset + j);
1032 curveSel.push_back(2);
1037 curvePtOffset[newIds[i]] = 3 * cnt2;
1038 cnt2 += curveInfo[cnt];
1040 curveMap[newIds[i]] = curve;
1049 nodeSpace->ClearRange();
1050 nodeSpace->SetSelection(curveSel.size() / 2, curveSel);
1052 vector<NekDouble> nodeRawData;
1053 nodeData->Read(nodeRawData, nodeSpace, m_readPL);
1056 for (
auto &cIt : curvePtOffset)
1061 int cnt = cIt.second;
1062 for (
int i = 0; i < curve->m_points.size(); ++i, cnt += 3)
1065 0, m_spaceDimension, nodeRawData[cnt], nodeRawData[cnt+1],
1066 nodeRawData[cnt+2]);
1071 void MeshGraphHDF5::ReadDomain()
1073 map<int, CompositeSharedPtr> fullDomain;
1077 vector<string> data;
1078 dst->ReadVectorString(data, space, m_readPL);
1079 GetCompositeList(data[0], fullDomain);
1080 m_domain.push_back(fullDomain);
1083 void MeshGraphHDF5::ReadComposites()
1085 string nm =
"COMPOSITE";
1089 vector<hsize_t> dims = space->GetDims();
1091 vector<string> comps;
1092 data->ReadVectorString(comps, space);
1096 vector<hsize_t> mdims = mspace->GetDims();
1099 mdata->Read(ids, mspace);
1101 for(
int i = 0; i < dims[0]; i++)
1103 string compStr = comps[i];
1106 istringstream strm(compStr);
1113 string::size_type indxBeg = compStr.find_first_of(
'[') + 1;
1114 string::size_type indxEnd = compStr.find_last_of(
']') - 1;
1116 string indxStr = compStr.substr(indxBeg, indxEnd - indxBeg + 1);
1117 vector<unsigned int> seqVector;
1119 ParseUtils::GenerateSeqVector(indxStr, seqVector);
1120 m_compOrder[ids[i]] = seqVector;
1125 for (
auto &i : seqVector)
1127 auto it = m_vertSet.find(i);
1128 if (it != m_vertSet.end())
1130 comp->m_geomVec.push_back(it->second);
1136 for (
auto &i : seqVector)
1138 auto it = m_segGeoms.find(i);
1139 if (it != m_segGeoms.end())
1141 comp->m_geomVec.push_back(it->second);
1146 for (
auto &i : seqVector)
1148 auto it = m_quadGeoms.find(i);
1149 if (it != m_quadGeoms.end())
1151 comp->m_geomVec.push_back(it->second);
1156 for (
auto &i : seqVector)
1158 auto it = m_triGeoms.find(i);
1159 if (it != m_triGeoms.end())
1161 comp->m_geomVec.push_back(it->second);
1166 for(
auto &i : seqVector)
1168 auto it1 = m_quadGeoms.find(i);
1169 if (it1 != m_quadGeoms.end())
1171 comp->m_geomVec.push_back(it1->second);
1174 auto it2 = m_triGeoms.find(i);
1175 if (it2 != m_triGeoms.end())
1177 comp->m_geomVec.push_back(it2->second);
1182 for(
auto &i : seqVector)
1184 auto it = m_tetGeoms.find(i);
1185 if (it != m_tetGeoms.end())
1187 comp->m_geomVec.push_back(it->second);
1192 for(
auto &i : seqVector)
1194 auto it = m_pyrGeoms.find(i);
1195 if (it != m_pyrGeoms.end())
1197 comp->m_geomVec.push_back(it->second);
1202 for(
auto &i : seqVector)
1204 auto it = m_prismGeoms.find(i);
1205 if (it != m_prismGeoms.end())
1207 comp->m_geomVec.push_back(it->second);
1212 for(
auto &i : seqVector)
1214 auto it = m_hexGeoms.find(i);
1215 if (it != m_hexGeoms.end())
1217 comp->m_geomVec.push_back(it->second);
1223 if (comp->m_geomVec.size() > 0)
1225 m_meshComposites[ids[i]] = comp;
1231 std::unordered_map<int, int> &id2row)
1235 string nm =
"COMPOSITE";
1239 vector<hsize_t> dims = space->GetDims();
1241 vector<string> comps;
1242 data->ReadVectorString(comps, space);
1246 vector<hsize_t> mdims = mspace->GetDims();
1249 mdata->Read(ids, mspace);
1251 for (
int i = 0; i < dims[0]; i++)
1253 string compStr = comps[i];
1256 istringstream strm(compStr);
1260 string::size_type indxBeg = compStr.find_first_of(
'[') + 1;
1261 string::size_type indxEnd = compStr.find_last_of(
']') - 1;
1263 string indxStr = compStr.substr(indxBeg, indxEnd - indxBeg + 1);
1264 vector<unsigned int> seqVector;
1265 ParseUtils::GenerateSeqVector(indxStr, seqVector);
1302 std::vector<int> filteredVector;
1303 for (
auto &compElmt : seqVector)
1305 if (id2row.find(compElmt) == id2row.end())
1310 filteredVector.push_back(compElmt);
1313 if (filteredVector.size() == 0)
1318 ret[ids[i]] = std::make_pair(shapeType, filteredVector);
1325 template<class T, typename std::enable_if<T::kDim == 0, int>::type = 0>
1331 template<class T, typename std::enable_if<T::kDim == 1, int>::type = 0>
1334 return geom->GetVid(i);
1337 template<class T, typename std::enable_if<T::kDim == 2, int>::type = 0>
1338 inline int GetGeomData(std::shared_ptr<T> &geom,
int i)
1340 return geom->GetEid(i);
1343 template<class T, typename std::enable_if<T::kDim == 3, int>::type = 0>
1344 inline int GetGeomData(std::shared_ptr<T> &geom,
int i)
1346 return geom->GetFid(i);
1350 void MeshGraphHDF5::WriteGeometryMap(std::map<
int, std::shared_ptr<T>> &geomMap,
1351 std::string datasetName)
1353 typedef typename std::conditional<
1354 std::is_same<T, PointGeom>::value,
NekDouble,
int>::type DataType;
1357 const size_t nGeom = geomMap.size();
1365 vector<int> idMap(nGeom);
1366 vector<DataType> data(nGeom * nGeomData);
1368 int cnt1 = 0, cnt2 = 0;
1369 for (
auto &it : geomMap)
1371 idMap[cnt1++] = it.first;
1373 for (
int j = 0; j < nGeomData; ++j)
1381 vector<hsize_t> dims = {
static_cast<hsize_t
>(nGeom),
1382 static_cast<hsize_t
>(nGeomData) };
1387 dst->Write(data, ds);
1389 tp = H5::DataType::OfObject(idMap[0]);
1391 ds = std::shared_ptr<H5::DataSpace>(
new H5::DataSpace(dims));
1392 dst = m_maps->CreateDataSet(datasetName, tp, ds);
1393 dst->Write(idMap, ds);
1402 vector<int> data, map;
1405 for (
auto &c : curves)
1407 map.push_back(c.first);
1408 data.push_back(c.second->m_points.size());
1409 data.push_back(c.second->m_ptype);
1410 data.push_back(ptOffset);
1412 ptOffset += c.second->m_points.size();
1414 for (
auto &pt : c.second->m_points)
1418 pt->GetCoords(v.
x, v.
y, v.
z);
1419 curvedPts.
pts.push_back(v);
1420 curvedPts.
index.push_back(newIdx++);
1425 vector<hsize_t> dims = { data.size() / 3, 3 };
1430 dst->Write(data, ds);
1432 tp = H5::DataType::OfObject(map[0]);
1433 dims = { map.size() };
1434 ds = std::shared_ptr<H5::DataSpace>(
new H5::DataSpace(dims));
1435 dst = m_maps->CreateDataSet(dsName, tp, ds);
1436 dst->Write(map, ds);
1441 vector<double> vertData(curvedPts.
pts.size() * 3);
1444 for (
auto &pt : curvedPts.
pts)
1446 vertData[cnt++] = pt.x;
1447 vertData[cnt++] = pt.y;
1448 vertData[cnt++] = pt.z;
1451 vector<hsize_t> dims = { curvedPts.
pts.size(), 3 };
1456 dst->Write(vertData, ds);
1461 vector<string> comps;
1468 for (
auto &cIt : composites)
1470 if (cIt.second->m_geomVec.size() == 0)
1475 comps.push_back(GetCompositeString(cIt.second));
1476 c_map.push_back(cIt.first);
1482 dst->WriteVectorString(comps, ds, tp);
1484 tp = H5::DataType::OfObject(c_map[0]);
1485 ds = H5::DataSpace::OneD(c_map.size());
1486 dst = m_maps->CreateDataSet(
"COMPOSITE", tp, ds);
1487 dst->Write(c_map, ds);
1490 void MeshGraphHDF5::WriteDomain(vector<CompositeMap> &domain)
1492 vector<unsigned int> idxList;
1493 for (
auto cIt = domain[0].begin(); cIt != domain[0].end(); ++cIt)
1495 idxList.push_back(cIt->first);
1497 stringstream domString;
1498 vector<string> doms;
1499 doms.push_back(ParseUtils::GenerateSeqString(idxList));
1504 dst->WriteVectorString(doms, ds, tp);
1507 void MeshGraphHDF5::WriteGeometry(
1508 std::string &outfilename,
1512 boost::ignore_unused(metadata);
1515 boost::split(tmp, outfilename, boost::is_any_of(
"."));
1516 string filenameXml = tmp[0] +
".xml";
1517 string filenameHdf5 = tmp[0] +
".nekg";
1526 TiXmlDocument *doc =
new TiXmlDocument;
1528 TiXmlElement *geomTag;
1530 if(boost::filesystem::exists(filenameXml.c_str()))
1532 ifstream file(filenameXml.c_str());
1534 TiXmlHandle docHandle(doc);
1535 root = docHandle.FirstChildElement(
"NEKTAR").Element();
1536 ASSERTL0(root,
"Unable to find NEKTAR tag in file.");
1537 geomTag = root->FirstChildElement(
"GEOMETRY");
1542 TiXmlDeclaration *decl =
new TiXmlDeclaration(
"1.0",
"utf-8",
"");
1543 doc->LinkEndChild(decl);
1544 root =
new TiXmlElement(
"NEKTAR");
1545 doc->LinkEndChild(root);
1547 geomTag =
new TiXmlElement(
"GEOMETRY");
1548 root->LinkEndChild(geomTag);
1552 geomTag->SetAttribute(
"DIM", m_meshDimension);
1553 geomTag->SetAttribute(
"SPACE", m_spaceDimension);
1554 geomTag->SetAttribute(
"HDF5FILE", filenameHdf5);
1560 TiXmlElement *expTag =
new TiXmlElement(
"EXPANSIONS");
1562 for (
auto it = m_meshComposites.begin(); it != m_meshComposites.end();
1565 if (it->second->m_geomVec[0]->GetShapeDim() == m_meshDimension)
1567 TiXmlElement *exp =
new TiXmlElement(
"E");
1570 "C[" + boost::lexical_cast<string>(it->first) +
"]");
1571 exp->SetAttribute(
"NUMMODES", 4);
1572 exp->SetAttribute(
"TYPE",
"MODIFIED");
1573 exp->SetAttribute(
"FIELDS",
"u");
1575 expTag->LinkEndChild(exp);
1578 root->LinkEndChild(expTag);
1581 doc->SaveFile(filenameXml);
1588 m_file = H5::File::Create(filenameHdf5, H5F_ACC_TRUNC);
1589 auto hdfRoot = m_file->CreateGroup(
"NEKTAR");
1590 auto hdfRoot2 = hdfRoot->CreateGroup(
"GEOMETRY");
1593 hdfRoot2->SetAttribute(
"FORMAT_VERSION", FORMAT_VERSION);
1596 m_mesh = hdfRoot2->CreateGroup(
"MESH");
1597 m_maps = hdfRoot2->CreateGroup(
"MAPS");
1599 WriteGeometryMap(m_vertSet,
"VERT");
1600 WriteGeometryMap(m_segGeoms,
"SEG");
1601 if (m_meshDimension > 1)
1603 WriteGeometryMap(m_triGeoms,
"TRI");
1604 WriteGeometryMap(m_quadGeoms,
"QUAD");
1606 if (m_meshDimension > 2)
1608 WriteGeometryMap(m_tetGeoms,
"TET");
1609 WriteGeometryMap(m_pyrGeoms,
"PYR");
1610 WriteGeometryMap(m_prismGeoms,
"PRISM");
1611 WriteGeometryMap(m_hexGeoms,
"HEX");
1615 int ptOffset = 0, newIdx = 0;
1617 WriteCurveMap(m_curvedEdges,
"CURVE_EDGE", curvePts, ptOffset, newIdx);
1618 WriteCurveMap(m_curvedFaces,
"CURVE_FACE", curvePts, ptOffset, newIdx);
1619 WriteCurvePoints(curvePts);
1622 WriteComposites(m_meshComposites);
1623 WriteDomain(m_domain);
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define TIME_RESULT(verb, msg, timer)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< DataSpace > DataSpaceSharedPtr
std::shared_ptr< PList > PListSharedPtr
std::shared_ptr< File > FileSharedPtr
std::shared_ptr< DataType > DataTypeSharedPtr
std::shared_ptr< Group > GroupSharedPtr
std::shared_ptr< DataSet > DataSetSharedPtr
std::map< std::string, std::string > FieldMetaDataMap
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< DomainRange > DomainRangeShPtr
CommFactory & GetCommFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
void UniqueValues(std::unordered_set< int > &unique, const std::vector< int > &input, T &... args)
std::map< int, std::pair< LibUtilities::ShapeType, std::vector< int > > > CompositeDescriptor
int GetGeomDataDim(std::map< int, std::shared_ptr< T >> &geomMap)
MeshPartitionFactory & GetMeshPartitionFactory()
std::pair< size_t, size_t > SplitWork(size_t vecsize, int rank, int nprocs)
Utility function to split a vector equally amongst a number of processors.
std::shared_ptr< Curve > CurveSharedPtr
std::unordered_map< int, CurveSharedPtr > CurveMap
std::map< int, CompositeSharedPtr > CompositeMap
int GetGeomData(std::shared_ptr< T > &geom, int i)
std::shared_ptr< SegGeom > SegGeomSharedPtr
std::shared_ptr< PointGeom > PointGeomSharedPtr
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
std::shared_ptr< MeshPartition > MeshPartitionSharedPtr
std::shared_ptr< TriGeom > TriGeomSharedPtr
MeshGraphFactory & GetMeshGraphFactory()
std::shared_ptr< Composite > CompositeSharedPtr
The above copyright notice and this permission notice shall be included.
std::vector< MeshVertex > pts
mapping to access pts value.
std::vector< NekInt64 > index
id of this Point set
std::vector< unsigned int > list