167 const bool isRoot = comm->TreatAsRankZero();
174 session->InitSession();
179 m_xmlGeom = session->GetElement(
"NEKTAR/GEOMETRY");
180 TiXmlAttribute *attr =
m_xmlGeom->FirstAttribute();
181 int meshDimension = 3;
182 int spaceDimension = 3;
186 std::string attrName(attr->Name());
187 if (attrName ==
"DIM")
189 err = attr->QueryIntValue(&meshDimension);
190 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read mesh dimension.");
192 else if (attrName ==
"SPACE")
194 err = attr->QueryIntValue(&spaceDimension);
195 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read space dimension.");
197 else if (attrName ==
"PARTITION")
200 "PARTITION parameter should only be used in XML meshes");
202 else if (attrName ==
"HDF5FILE")
206 else if (attrName ==
"PARTITIONED")
209 "PARTITIONED parameter should only be used in XML meshes");
213 std::string errstr(
"Unknown attribute: ");
222 ASSERTL0(meshDimension <= spaceDimension,
223 "Mesh dimension greater than space dimension.");
232 if (commMesh->GetSize() > 1)
236 parallelProps->SetMpio(commMesh);
244 auto root =
m_file->OpenGroup(
"NEKTAR");
245 ASSERTL0(root,
"Cannot find NEKTAR group in HDF5 file.");
247 auto root2 = root->OpenGroup(
"GEOMETRY");
248 ASSERTL0(root2,
"Cannot find NEKTAR/GEOMETRY group in HDF5 file.");
253 for (; attrIt != attrEnd; ++attrIt)
255 if (*attrIt ==
"FORMAT_VERSION")
261 "Unable to determine Nektar++ geometry HDF5 file version.");
266 " is higher than supported in "
267 "this version of Nektar++");
269 m_mesh = root2->OpenGroup(
"MESH");
270 ASSERTL0(
m_mesh,
"Cannot find NEKTAR/GEOMETRY/MESH group in HDF5 file.");
271 m_maps = root2->OpenGroup(
"MAPS");
272 ASSERTL0(
m_mesh,
"Cannot find NEKTAR/GEOMETRY/MAPS group in HDF5 file.");
282 m_meshGraph->GetDomainRange()->m_compElmts = meshDimension;
292 std::vector<std::tuple<std::string, int, LibUtilities::ShapeType>>>
303 const bool verbRoot = isRoot && session->DefinesCmdLineArgument(
"verbose");
307 std::cout <<
"Reading HDF5 geometry..." << std::endl;
315 int innerRank = 0, innerSize = 1,
316 interRank = interComm->GetRowComm()->GetRank(),
317 interSize = interComm->GetRowComm()->GetSize();
319 if (session->DefinesCmdLineArgument(
"use-hdf5-node-comm"))
321 ASSERTL0(comm->GetSize() == commMesh->GetSize(),
322 "--use-hdf5-node-comm not available with Parallel-in-Time")
324 auto splitComm = comm->SplitCommNode();
325 innerComm = splitComm.first;
326 interComm = splitComm.second;
327 innerRank = innerComm->GetRank();
328 innerSize = innerComm->GetSize();
332 interRank = interComm->GetRank();
333 interSize = interComm->GetSize();
339 std::unordered_set<int> toRead;
348 std::cout <<
" - beginning partitioning" << std::endl;
358 const bool verbRoot2 =
359 isRoot && session->DefinesCmdLineArgument(
"verbose");
362 std::vector<int> ids;
366 std::vector<MeshEntity> elmts;
367 std::unordered_map<int, int> row2id, id2row;
378 parallelProps->SetMpio(interComm);
382 readPL->SetDxMpioCollective();
385 auto root = file->OpenGroup(
"NEKTAR");
386 auto root2 = root->OpenGroup(
"GEOMETRY");
387 mesh = root2->OpenGroup(
"MESH");
388 maps = root2->OpenGroup(
"MAPS");
392 for (
auto &it : dataSets[meshDimension])
394 std::string ds = std::get<0>(it);
396 if (!mesh->ContainsDataSet(ds))
404 std::vector<hsize_t> dims = space->GetDims();
408 std::vector<hsize_t> mdims = mspace->GetDims();
413 std::vector<int> tmpElmts, tmpIds;
414 mdata->Read(tmpIds, mspace, readPL);
415 data->Read(tmpElmts, space, readPL);
417 const int nGeomData = std::get<1>(it);
423 for (
int i = 0, cnt = 0; i < tmpIds.size(); ++i, ++rowCount)
426 row2id[rowCount] = tmpIds[i];
427 id2row[tmpIds[i]] = row2id[rowCount];
431 e.
list = std::vector<unsigned int>(
432 &tmpElmts[cnt], &tmpElmts[cnt + nGeomData]);
440 for (
int i = 0, cnt = 0; i < tmpIds.size(); ++i, ++rowCount)
443 row2id[rowCount] = tmpIds[i];
444 id2row[tmpIds[i]] = row2id[rowCount];
448 e.
list = std::vector<unsigned int>(
449 &tmpElmts[cnt], &tmpElmts[cnt + nGeomData]);
459 interComm->GetRowComm()->Block();
468 if (commMesh->GetSize() > 1)
471 size_t numElmt = elmts.size();
472 ASSERTL0(commMesh->GetSize() <= numElmt,
473 "This mesh has more processors than elements!");
475 auto elRange =
SplitWork(numElmt, interRank, interSize);
478 std::map<int, MeshEntity> partElmts;
479 std::unordered_set<int> facetIDs;
483 for (
int el = elRange.first; el < elRange.first + elRange.second;
488 partElmts[elmt.
id] = elmt;
490 for (
auto &facet : elmt.
list)
492 facetIDs.insert(facet);
499 for (
int i = 0; i < numElmt; ++i)
502 if (i >= elRange.first && i < elRange.first + elRange.second)
511 for (
auto &eId : elmt.
list)
513 if (facetIDs.find(eId) != facetIDs.end())
523 partElmts[elmt.
id] = elmt;
530 std::string partitionerName =
531 commMesh->GetSize() > 1 ?
"PtScotch" :
"Scotch";
534 partitionerName =
"ParMetis";
536 if (session->DefinesCmdLineArgument(
"use-parmetis"))
538 partitionerName =
"ParMetis";
540 if (session->DefinesCmdLineArgument(
"use-ptscotch"))
542 partitionerName =
"PtScotch";
547 partitionerName, session, interComm, meshDimension,
551 TIME_RESULT(verbRoot2,
" - partitioner setup", t2);
554 partitioner->PartitionMesh(interSize,
true,
false, nLocal);
561 std::vector<unsigned int> nodeElmts;
562 partitioner->GetElementIDs(interRank, nodeElmts);
567 std::map<int, MeshEntity> partElmts;
568 std::unordered_map<int, int> row2elmtid, elmtid2row;
575 for (
auto &elmtRow : nodeElmts)
577 row2elmtid[vcnt] = elmts[elmtRow].origId;
578 elmtid2row[elmts[elmtRow].origId] = vcnt;
581 partElmts[vcnt++] = elmt;
590 "Scotch", session, tmpComm, meshDimension, partElmts,
594 TIME_RESULT(verbRoot2,
" - inner partition setup", t2);
597 partitioner->PartitionMesh(innerSize,
true,
false, 0);
600 TIME_RESULT(verbRoot2,
" - inner partitioning", t2);
604 for (
int i = 1; i < innerSize; ++i)
606 std::vector<unsigned int> tmp;
607 partitioner->GetElementIDs(i, tmp);
608 size_t tmpsize = tmp.size();
609 for (
int j = 0; j < tmpsize; ++j)
611 tmp[j] = row2elmtid[tmp[j]];
613 innerComm->Send(i, tmpsize);
614 innerComm->Send(i, tmp);
618 TIME_RESULT(verbRoot2,
" - inner partition scatter", t2);
620 std::vector<unsigned int> tmp;
621 partitioner->GetElementIDs(0, tmp);
623 for (
auto &tmpId : tmp)
625 toRead.insert(row2elmtid[tmpId]);
630 for (
auto &tmpId : nodeElmts)
632 toRead.insert(row2id[tmpId]);
638 for (
auto &tmpId : elmts)
640 toRead.insert(tmpId.origId);
649 innerComm->Recv(0, tmpSize);
650 std::vector<unsigned int> tmp(tmpSize);
651 innerComm->Recv(0, tmp);
653 for (
auto &tmpId : tmp)
655 toRead.insert(tmpId);
665 std::vector<int> vertIDs, segIDs, triIDs, quadIDs;
666 std::vector<int> tetIDs, prismIDs, pyrIDs, hexIDs;
667 std::vector<int> segData, triData, quadData, tetData;
668 std::vector<int> prismData, pyrData, hexData;
669 std::vector<NekDouble> vertData;
682 if (meshDimension == 3)
692 UniqueValues(toRead, hexData, pyrData, prismData, tetData);
697 if (meshDimension >= 2)
710 if (meshDimension >= 1)
734 if (meshDimension >= 1)
738 for (
auto &edge : segIDs)
745 FillGeomMap(segGeoms, curvedEdges, segIDs, segData);
750 if (meshDimension >= 2)
754 for (
auto &face : triIDs)
758 for (
auto &face : quadIDs)
765 FillGeomMap(triGeoms, curvedFaces, triIDs, triData);
766 FillGeomMap(quadGeoms, curvedFaces, quadIDs, quadData);
771 if (meshDimension >= 3)
783 if (session->DefinesElement(
"NEKTAR/CONDITIONS"))
785 std::set<int> vBndRegionIdList;
786 TiXmlElement *vConditions =
787 new TiXmlElement(*session->GetElement(
"Nektar/Conditions"));
788 TiXmlElement *vBndRegions =
789 vConditions->FirstChildElement(
"BOUNDARYREGIONS");
796 auto &graph_bndRegOrder =
m_meshGraph->GetBndRegionOrdering();
797 vItem = vBndRegions->FirstChildElement();
800 std::string vSeqStr = vItem->FirstChild()->ToText()->Value();
801 std::string::size_type indxBeg = vSeqStr.find_first_of(
'[') + 1;
802 std::string::size_type indxEnd = vSeqStr.find_last_of(
']') - 1;
803 vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
805 std::vector<unsigned int> vSeq;
808 int p = atoi(vItem->Attribute(
"ID"));
810 graph_bndRegOrder[p] = vSeq;
811 vItem = vItem->NextSiblingElement();
1013 const std::unordered_set<int> &readIds)
1015 auto &curveNodes =
m_meshGraph->GetAllCurveNodes();
1018 if (!
m_mesh->ContainsDataSet(dsName))
1032 std::vector<int> ids, newIds;
1033 idData->Read(ids, idSpace);
1034 curveSpace->ClearRange();
1037 std::vector<hsize_t> curveSel;
1040 for (
auto &
id : ids)
1042 if (readIds.find(
id) != readIds.end())
1044 curveSel.push_back(cnt);
1045 curveSel.push_back(0);
1046 curveSel.push_back(cnt);
1047 curveSel.push_back(1);
1048 curveSel.push_back(cnt);
1049 curveSel.push_back(2);
1050 newIds.push_back(
id);
1057 auto toRead = newIds.size();
1058 m_session->GetComm()->GetRowComm()->AllReduce(toRead,
1067 std::vector<int> curveInfo;
1068 curveSpace->SetSelection(curveSel.size() / 2, curveSel);
1069 curveData->Read(curveInfo, curveSpace,
m_readPL);
1073 std::unordered_map<int, int> curvePtOffset;
1076 for (
int i = 0, cnt = 0, cnt2 = 0; i < curveInfo.size() / 3; ++i, cnt += 3)
1081 curve->m_points.resize(curveInfo[cnt]);
1083 const int ptOffset = curveInfo[cnt + 2];
1085 for (
int j = 0; j < curveInfo[cnt]; ++j)
1089 curveSel.push_back(ptOffset + j);
1090 curveSel.push_back(0);
1091 curveSel.push_back(ptOffset + j);
1092 curveSel.push_back(1);
1093 curveSel.push_back(ptOffset + j);
1094 curveSel.push_back(2);
1099 curvePtOffset[newIds[i]] = 3 * cnt2;
1100 cnt2 += curveInfo[cnt];
1102 curveMap[newIds[i]] = curve;
1111 nodeSpace->ClearRange();
1112 nodeSpace->SetSelection(curveSel.size() / 2, curveSel);
1114 std::vector<NekDouble> nodeRawData;
1115 nodeData->Read(nodeRawData, nodeSpace,
m_readPL);
1118 for (
auto &cIt : curvePtOffset)
1123 int cnt = cIt.second;
1124 for (
int i = 0; i < curve->m_points.size(); ++i, cnt += 3)
1126 curveNodes.emplace_back(
1128 0,
m_meshGraph->GetSpaceDimension(), nodeRawData[cnt],
1129 nodeRawData[cnt + 1], nodeRawData[cnt + 2]));
1130 curve->m_points[i] = curveNodes.back().get();
1245 std::string nm =
"COMPOSITE";
1249 std::vector<hsize_t> dims = space->GetDims();
1251 std::vector<std::string> comps;
1252 data->ReadVectorString(comps, space);
1256 std::vector<hsize_t> mdims = mspace->GetDims();
1258 std::vector<int> ids;
1259 mdata->Read(ids, mspace);
1261 auto &graph_compOrder =
m_meshGraph->GetCompositeOrdering();
1262 for (
int i = 0; i < dims[0]; i++)
1264 std::string compStr = comps[i];
1267 std::istringstream strm(compStr);
1273 std::string::size_type indxBeg = compStr.find_first_of(
'[') + 1;
1274 std::string::size_type indxEnd = compStr.find_last_of(
']') - 1;
1276 std::string indxStr = compStr.substr(indxBeg, indxEnd - indxBeg + 1);
1277 std::vector<unsigned int> seqVector;
1281 graph_compOrder[ids[i]] = seqVector;
1286 for (
auto &i : seqVector)
1288 auto it = vertSet.find(i);
1289 if (it != vertSet.end())
1291 comp->m_geomVec.push_back((*it).second);
1297 for (
auto &i : seqVector)
1299 auto it = segGeoms.find(i);
1300 if (it != segGeoms.end())
1302 comp->m_geomVec.push_back((*it).second);
1307 for (
auto &i : seqVector)
1309 auto it = quadGeoms.find(i);
1310 if (it != quadGeoms.end())
1314 comp->m_geomVec.push_back((*it).second);
1320 for (
auto &i : seqVector)
1322 auto it = triGeoms.find(i);
1323 if (it != triGeoms.end())
1327 comp->m_geomVec.push_back((*it).second);
1333 for (
auto &i : seqVector)
1335 auto it1 = quadGeoms.find(i);
1336 if (it1 != quadGeoms.end())
1340 comp->m_geomVec.push_back((*it1).second);
1343 auto it2 = triGeoms.find(i);
1344 if (it2 != triGeoms.end())
1348 comp->m_geomVec.push_back((*it2).second);
1354 for (
auto &i : seqVector)
1356 auto it = tetGeoms.find(i);
1357 if (it != tetGeoms.end())
1361 comp->m_geomVec.push_back((*it).second);
1367 for (
auto &i : seqVector)
1369 auto it = pyrGeoms.find(i);
1370 if (it != pyrGeoms.end())
1374 comp->m_geomVec.push_back((*it).second);
1380 for (
auto &i : seqVector)
1382 auto it = prismGeoms.find(i);
1383 if (it != prismGeoms.end())
1387 comp->m_geomVec.push_back((*it).second);
1393 for (
auto &i : seqVector)
1395 auto it = hexGeoms.find(i);
1396 if (it != hexGeoms.end())
1400 comp->m_geomVec.push_back((*it).second);
1407 if (comp->m_geomVec.size() > 0)
1409 meshComposites[ids[i]] = comp;