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.");
233#if defined(NEKTAR_USE_MPI) && defined(NEKTAR_HDF5_PARALLEL)
234 if (commMesh->GetSize() > 1)
238 parallelProps->SetMpio(commMesh);
248 auto root =
m_file->OpenGroup(
"NEKTAR");
249 ASSERTL0(root,
"Cannot find NEKTAR group in HDF5 file.");
251 auto root2 = root->OpenGroup(
"GEOMETRY");
252 ASSERTL0(root2,
"Cannot find NEKTAR/GEOMETRY group in HDF5 file.");
257 for (; attrIt != attrEnd; ++attrIt)
259 if (*attrIt ==
"FORMAT_VERSION")
265 "Unable to determine Nektar++ geometry HDF5 file version.");
270 " is higher than supported in "
271 "this version of Nektar++");
273 m_mesh = root2->OpenGroup(
"MESH");
274 ASSERTL0(
m_mesh,
"Cannot find NEKTAR/GEOMETRY/MESH group in HDF5 file.");
275 m_maps = root2->OpenGroup(
"MAPS");
276 ASSERTL0(
m_mesh,
"Cannot find NEKTAR/GEOMETRY/MAPS group in HDF5 file.");
286 m_meshGraph->GetDomainRange()->m_compElmts = meshDimension;
296 std::vector<std::tuple<std::string, int, LibUtilities::ShapeType>>>
307 const bool verbRoot = isRoot && session->DefinesCmdLineArgument(
"verbose");
311 std::cout <<
"Reading HDF5 geometry..." << std::endl;
319 int innerRank = 0, innerSize = 1,
320 interRank = interComm->GetRowComm()->GetRank(),
321 interSize = interComm->GetRowComm()->GetSize();
323 if (session->DefinesCmdLineArgument(
"use-hdf5-node-comm"))
325 ASSERTL0(comm->GetSize() == commMesh->GetSize(),
326 "--use-hdf5-node-comm not available with Parallel-in-Time")
328 auto splitComm = comm->SplitCommNode();
329 innerComm = splitComm.first;
330 interComm = splitComm.second;
331 innerRank = innerComm->GetRank();
332 innerSize = innerComm->GetSize();
336 interRank = interComm->GetRank();
337 interSize = interComm->GetSize();
343 std::unordered_set<int> toRead;
352 std::cout <<
" - beginning partitioning" << std::endl;
362 const bool verbRoot2 =
363 isRoot && session->DefinesCmdLineArgument(
"verbose");
366 std::vector<int> ids;
370 std::vector<MeshEntity> elmts;
371 std::unordered_map<int, int> row2id, id2row;
382 parallelProps->SetMpio(interComm);
386#if defined(NEKTAR_USE_MPI) && defined(NEKTAR_HDF5_PARALLEL)
388 readPL->SetDxMpioCollective();
393 auto root = file->OpenGroup(
"NEKTAR");
394 auto root2 = root->OpenGroup(
"GEOMETRY");
395 mesh = root2->OpenGroup(
"MESH");
396 maps = root2->OpenGroup(
"MAPS");
400 for (
auto &it : dataSets[meshDimension])
402 std::string ds = std::get<0>(it);
404 if (!mesh->ContainsDataSet(ds))
412 std::vector<hsize_t> dims = space->GetDims();
416 std::vector<hsize_t> mdims = mspace->GetDims();
421 std::vector<int> tmpElmts, tmpIds;
422 mdata->Read(tmpIds, mspace, readPL);
423 data->Read(tmpElmts, space, readPL);
425 const int nGeomData = std::get<1>(it);
426 auto tmpIt = tmpElmts.begin();
432 for (
int i = 0; i < tmpIds.size();
433 ++i, ++rowCount, tmpIt += nGeomData)
436 row2id[rowCount] = tmpIds[i];
437 id2row[tmpIds[i]] = row2id[rowCount];
442 std::vector<unsigned int>(tmpIt, tmpIt + nGeomData);
449 for (
int i = 0; i < tmpIds.size();
450 ++i, ++rowCount, tmpIt += nGeomData)
453 row2id[rowCount] = tmpIds[i];
454 id2row[tmpIds[i]] = row2id[rowCount];
459 std::vector<unsigned int>(tmpIt, tmpIt + nGeomData);
468 interComm->GetRowComm()->Block();
477 if (commMesh->GetSize() > 1)
480 size_t numElmt = elmts.size();
481 ASSERTL0(commMesh->GetSize() <= numElmt,
482 "This mesh has more processors than elements!");
484 auto elRange =
SplitWork(numElmt, interRank, interSize);
487 std::map<int, MeshEntity> partElmts;
488 std::unordered_set<int> facetIDs;
492 for (
int el = elRange.first; el < elRange.first + elRange.second;
497 partElmts[elmt.
id] = elmt;
499 for (
auto &facet : elmt.
list)
501 facetIDs.insert(facet);
508 for (
int i = 0; i < numElmt; ++i)
511 if (i >= elRange.first && i < elRange.first + elRange.second)
520 for (
auto &eId : elmt.
list)
522 if (facetIDs.find(eId) != facetIDs.end())
532 partElmts[elmt.
id] = elmt;
539 std::string partitionerName =
540 commMesh->GetSize() > 1 ?
"PtScotch" :
"Scotch";
543 partitionerName =
"ParMetis";
545 if (session->DefinesCmdLineArgument(
"use-parmetis"))
547 partitionerName =
"ParMetis";
549 if (session->DefinesCmdLineArgument(
"use-ptscotch"))
551 partitionerName =
"PtScotch";
556 partitionerName, session, interComm, meshDimension,
560 TIME_RESULT(verbRoot2,
" - partitioner setup", t2);
563 partitioner->PartitionMesh(interSize,
true,
false, nLocal);
570 std::vector<unsigned int> nodeElmts;
571 partitioner->GetElementIDs(interRank, nodeElmts);
576 std::map<int, MeshEntity> partElmts;
577 std::unordered_map<int, int> row2elmtid, elmtid2row;
584 for (
auto &elmtRow : nodeElmts)
586 row2elmtid[vcnt] = elmts[elmtRow].origId;
587 elmtid2row[elmts[elmtRow].origId] = vcnt;
590 partElmts[vcnt++] = elmt;
599 "Scotch", session, tmpComm, meshDimension, partElmts,
603 TIME_RESULT(verbRoot2,
" - inner partition setup", t2);
606 partitioner->PartitionMesh(innerSize,
true,
false, 0);
609 TIME_RESULT(verbRoot2,
" - inner partitioning", t2);
613 for (
int i = 1; i < innerSize; ++i)
615 std::vector<unsigned int> tmp;
616 partitioner->GetElementIDs(i, tmp);
617 size_t tmpsize = tmp.size();
618 for (
int j = 0; j < tmpsize; ++j)
620 tmp[j] = row2elmtid[tmp[j]];
622 innerComm->Send(i, tmpsize);
623 innerComm->Send(i, tmp);
627 TIME_RESULT(verbRoot2,
" - inner partition scatter", t2);
629 std::vector<unsigned int> tmp;
630 partitioner->GetElementIDs(0, tmp);
632 for (
auto &tmpId : tmp)
634 toRead.insert(row2elmtid[tmpId]);
639 for (
auto &tmpId : nodeElmts)
641 toRead.insert(row2id[tmpId]);
647 for (
auto &tmpId : elmts)
649 toRead.insert(tmpId.origId);
658 innerComm->Recv(0, tmpSize);
659 std::vector<unsigned int> tmp(tmpSize);
660 innerComm->Recv(0, tmp);
662 for (
auto &tmpId : tmp)
664 toRead.insert(tmpId);
674 std::vector<int> vertIDs, segIDs, triIDs, quadIDs;
675 std::vector<int> tetIDs, prismIDs, pyrIDs, hexIDs;
676 std::vector<int> segData, triData, quadData, tetData;
677 std::vector<int> prismData, pyrData, hexData;
678 std::vector<NekDouble> vertData;
691 if (meshDimension == 3)
701 UniqueValues(toRead, hexData, pyrData, prismData, tetData);
706 if (meshDimension >= 2)
719 if (meshDimension >= 1)
743 if (meshDimension >= 1)
747 for (
auto &edge : segIDs)
754 FillGeomMap(segGeoms, curvedEdges, segIDs, segData);
759 if (meshDimension >= 2)
763 for (
auto &face : triIDs)
767 for (
auto &face : quadIDs)
774 FillGeomMap(triGeoms, curvedFaces, triIDs, triData);
775 FillGeomMap(quadGeoms, curvedFaces, quadIDs, quadData);
780 if (meshDimension >= 3)
792 if (session->DefinesElement(
"NEKTAR/CONDITIONS"))
794 std::set<int> vBndRegionIdList;
795 TiXmlElement *vConditions =
796 new TiXmlElement(*session->GetElement(
"Nektar/Conditions"));
797 TiXmlElement *vBndRegions =
798 vConditions->FirstChildElement(
"BOUNDARYREGIONS");
805 auto &graph_bndRegOrder =
m_meshGraph->GetBndRegionOrdering();
806 vItem = vBndRegions->FirstChildElement();
809 std::string vSeqStr = vItem->FirstChild()->ToText()->Value();
810 std::string::size_type indxBeg = vSeqStr.find_first_of(
'[') + 1;
811 std::string::size_type indxEnd = vSeqStr.find_last_of(
']') - 1;
812 vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
814 std::vector<unsigned int> vSeq;
817 int p = atoi(vItem->Attribute(
"ID"));
819 graph_bndRegOrder[p] = vSeq;
820 vItem = vItem->NextSiblingElement();
1023 const std::unordered_set<int> &readIds)
1025 auto &curveNodes =
m_meshGraph->GetAllCurveNodes();
1028 if (!
m_mesh->ContainsDataSet(dsName))
1042 std::vector<int> ids, newIds;
1043 idData->Read(ids, idSpace);
1044 curveSpace->ClearRange();
1047 std::vector<hsize_t> curveSel;
1050 for (
auto &
id : ids)
1052 if (readIds.find(
id) != readIds.end())
1054 curveSel.push_back(cnt);
1055 curveSel.push_back(0);
1056 curveSel.push_back(cnt);
1057 curveSel.push_back(1);
1058 curveSel.push_back(cnt);
1059 curveSel.push_back(2);
1060 newIds.push_back(
id);
1067 auto toRead = newIds.size();
1068 m_session->GetComm()->GetRowComm()->AllReduce(toRead,
1077 std::vector<int> curveInfo;
1078 curveSpace->SetSelection(curveSel.size() / 2, curveSel);
1079 curveData->Read(curveInfo, curveSpace,
m_readPL);
1083 std::unordered_map<int, int> curvePtOffset;
1086 for (
int i = 0, cnt = 0, cnt2 = 0; i < curveInfo.size() / 3; ++i, cnt += 3)
1091 curve->m_points.resize(curveInfo[cnt]);
1093 const int ptOffset = curveInfo[cnt + 2];
1095 for (
int j = 0; j < curveInfo[cnt]; ++j)
1099 curveSel.push_back(ptOffset + j);
1100 curveSel.push_back(0);
1101 curveSel.push_back(ptOffset + j);
1102 curveSel.push_back(1);
1103 curveSel.push_back(ptOffset + j);
1104 curveSel.push_back(2);
1109 curvePtOffset[newIds[i]] = 3 * cnt2;
1110 cnt2 += curveInfo[cnt];
1112 curveMap[newIds[i]] = std::move(curve);
1121 nodeSpace->ClearRange();
1122 nodeSpace->SetSelection(curveSel.size() / 2, curveSel);
1124 std::vector<NekDouble> nodeRawData;
1125 nodeData->Read(nodeRawData, nodeSpace,
m_readPL);
1128 for (
auto &cIt : curvePtOffset)
1130 Curve *curve = curveMap[cIt.first].get();
1133 int cnt = cIt.second;
1134 for (
int i = 0; i < curve->
m_points.size(); ++i, cnt += 3)
1136 curveNodes.emplace_back(
1138 0,
m_meshGraph->GetSpaceDimension(), nodeRawData[cnt],
1139 nodeRawData[cnt + 1], nodeRawData[cnt + 2]));
1140 curve->
m_points[i] = curveNodes.back().get();
1255 std::string nm =
"COMPOSITE";
1259 std::vector<hsize_t> dims = space->GetDims();
1261 std::vector<std::string> comps;
1262 data->ReadVectorString(comps, space);
1266 std::vector<hsize_t> mdims = mspace->GetDims();
1268 std::vector<int> ids;
1269 mdata->Read(ids, mspace);
1271 auto &graph_compOrder =
m_meshGraph->GetCompositeOrdering();
1272 for (
int i = 0; i < dims[0]; i++)
1274 std::string compStr = comps[i];
1277 std::istringstream strm(compStr);
1283 std::string::size_type indxBeg = compStr.find_first_of(
'[') + 1;
1284 std::string::size_type indxEnd = compStr.find_last_of(
']') - 1;
1286 std::string indxStr = compStr.substr(indxBeg, indxEnd - indxBeg + 1);
1287 std::vector<unsigned int> seqVector;
1291 graph_compOrder[ids[i]] = seqVector;
1296 for (
auto &i : seqVector)
1298 auto it = vertSet.find(i);
1299 if (it != vertSet.end())
1301 comp->m_geomVec.push_back((*it).second);
1307 for (
auto &i : seqVector)
1309 auto it = segGeoms.find(i);
1310 if (it != segGeoms.end())
1312 comp->m_geomVec.push_back((*it).second);
1317 for (
auto &i : seqVector)
1319 auto it = quadGeoms.find(i);
1320 if (it != quadGeoms.end())
1324 comp->m_geomVec.push_back((*it).second);
1330 for (
auto &i : seqVector)
1332 auto it = triGeoms.find(i);
1333 if (it != triGeoms.end())
1337 comp->m_geomVec.push_back((*it).second);
1343 for (
auto &i : seqVector)
1345 auto it1 = quadGeoms.find(i);
1346 if (it1 != quadGeoms.end())
1350 comp->m_geomVec.push_back((*it1).second);
1353 auto it2 = triGeoms.find(i);
1354 if (it2 != triGeoms.end())
1358 comp->m_geomVec.push_back((*it2).second);
1364 for (
auto &i : seqVector)
1366 auto it = tetGeoms.find(i);
1367 if (it != tetGeoms.end())
1371 comp->m_geomVec.push_back((*it).second);
1377 for (
auto &i : seqVector)
1379 auto it = pyrGeoms.find(i);
1380 if (it != pyrGeoms.end())
1384 comp->m_geomVec.push_back((*it).second);
1390 for (
auto &i : seqVector)
1392 auto it = prismGeoms.find(i);
1393 if (it != prismGeoms.end())
1397 comp->m_geomVec.push_back((*it).second);
1403 for (
auto &i : seqVector)
1405 auto it = hexGeoms.find(i);
1406 if (it != hexGeoms.end())
1410 comp->m_geomVec.push_back((*it).second);
1417 if (comp->m_geomVec.size() > 0)
1419 meshComposites[ids[i]] = comp;