53 #ifndef vtk_m_worklet_contourtree_distributed_boundary_tree_maker_h
54 #define vtk_m_worklet_contourtree_distributed_boundary_tree_maker_h
110 namespace contourtree_distributed
115 template <
typename MeshType,
typename MeshBoundaryExecObjType>
181 MeshBoundaryExecObjType& meshBoundaryExecObj,
205 localToGlobalIdRelabeler =
nullptr,
206 bool boundaryCritical =
true);
267 localToGlobalIdRelabeler =
nullptr);
271 std::string
DebugPrint(
const char* message,
const char* fileName,
long lineNum)
const;
280 template <
typename MeshType,
typename MeshBoundaryExecObjType>
283 bool boundaryCritical)
294 this->FindBoundaryVertices(boundaryCritical);
297 this->ComputeDependentBoundaryCounts();
301 this->PropagateBoundaryCounts();
304 this->FindNecessaryInteriorSupernodes();
307 this->AugmentBoundaryWithNecessaryInteriorSupernodes();
311 this->FindBoundaryTreeSuperarcs();
315 this->SuppressRegularisedInteriorSupernodes();
318 this->SetInteriorForest(localToGlobalIdRelabeler);
322 this->BoundaryTreeData->DebugPrint(
"All Completed\n", __FILE__, __LINE__));
332 template <
typename MeshType,
typename MeshBoundaryExecObjType>
334 bool boundaryCritical)
338 this->Mesh->GetBoundaryVertices(
339 this->BoundaryVertexSuperset, this->BoundaryIndices, &(this->MeshBoundaryExecutionObject));
341 this->BoundaryTreeData->NumBoundary = this->BoundaryVertexSuperset.GetNumberOfValues();
345 if (boundaryCritical)
350 this->Invoke(isNecessaryWorklet,
351 this->BoundaryVertexSuperset,
352 &(this->MeshBoundaryExecutionObject),
357 this->BoundaryVertexSuperset, isBoundaryCritical, necessaryBoundaryVertexSuperset);
358 this->BoundaryVertexSuperset = necessaryBoundaryVertexSuperset;
360 this->BoundaryIndices, isBoundaryCritical, necessaryBoundaryIndices);
361 this->BoundaryIndices = necessaryBoundaryIndices;
365 this->BoundaryTreeData->NumBoundaryUsed = this->NumBoundary;
369 this->DebugPrint(
"Boundary Vertices Set", __FILE__, __LINE__));
381 template <
typename MeshType,
typename MeshBoundaryExecObjType>
385 auto permutedContourTreeSuperparents =
398 this->SuperarcIntrinsicBoundaryCount);
408 this->Invoke(tempWorklet1,
409 this->BoundarySuperparents,
410 this->SuperarcIntrinsicBoundaryCount
416 this->Invoke(tempWorklet2,
417 this->BoundarySuperparents,
418 this->SuperarcIntrinsicBoundaryCount
422 this->BoundarySuperparents.ReleaseResources();
426 this->DebugPrint(
"Initial Counts Set", __FILE__, __LINE__));
437 template <
typename MeshType,
typename MeshBoundaryExecObjType>
444 this->SupernodeTransferBoundaryCount);
447 this->SuperarcDependentBoundaryCount);
450 this->HyperarcDependentBoundaryCount);
454 this->DebugPrint(
"Arrays initialised", __FILE__, __LINE__));
458 for (
vtkm::Id iteration = 0; iteration < this->ContourTree.NumIterations; iteration++)
469 if (lastSupernode == firstSupernode)
473 "BoundaryTreeMaker::PropagateBoundaryCounts(): lastSupernode == firstSupernode "
474 " -> Skipping iteration");
489 this->SupernodeTransferBoundaryCount, this->SuperarcIntrinsicBoundaryCount);
490 auto fancyTempSumArray =
496 lastSupernode - firstSupernode,
497 this->SuperarcDependentBoundaryCount,
508 this->SuperarcDependentBoundaryCount, firstSupernode, lastSupernode - firstSupernode);
518 this->SuperarcDependentBoundaryCount,
525 this->DebugPrint(
"After Prefix Sum", __FILE__, __LINE__));
533 lastSupernode - firstSupernode,
534 newSuperArcDependentBoundaryCount);
535 auto subtractDependentCountsWorklet =
540 subtractDependentCountsWorklet,
543 lastSupernode - 1, -1, lastSupernode - firstSupernode - 1),
544 this->ContourTree.Hyperparents,
545 this->ContourTree.Hypernodes,
546 this->SuperarcDependentBoundaryCount,
547 newSuperArcDependentBoundaryCount
553 this->SuperarcDependentBoundaryCount,
558 this->DebugPrint(
"After Hyperarc Subtraction", __FILE__, __LINE__));
563 auto transferDependentCountsWorklet =
565 this->ContourTree.Supernodes.GetNumberOfValues(),
566 this->ContourTree.Hypernodes.GetNumberOfValues());
568 transferDependentCountsWorklet,
571 firstHypernode, 1, lastHypernode - firstHypernode),
572 this->ContourTree.Hypernodes,
573 this->SuperarcDependentBoundaryCount,
574 this->HyperarcDependentBoundaryCount
580 this->DebugPrint(
"After Dependent Count transfer", __FILE__, __LINE__));
590 firstHypernode, 1, lastHypernode - firstHypernode),
591 hyperarcTargetSortPermutation);
601 auto permutedHyperarcDependentCount =
603 this->HyperarcDependentBoundaryCount
606 accumulatedBoundaryCount);
610 auto transferCumulativeCountsWorklet =
612 this->Invoke(transferCumulativeCountsWorklet,
613 hyperarcTargetSortPermutation,
614 this->ContourTree.Hyperarcs,
615 accumulatedBoundaryCount,
616 this->SupernodeTransferBoundaryCount);
620 this->DebugPrint(
"After Tail Addition", __FILE__, __LINE__));
626 auto computeGroupTotalsWorklet =
628 this->Invoke(computeGroupTotalsWorklet,
629 hyperarcTargetSortPermutation,
630 this->ContourTree.Hyperarcs,
631 accumulatedBoundaryCount,
632 this->SupernodeTransferBoundaryCount);
636 this->DebugPrint(
"After Hyperarc Transfer", __FILE__, __LINE__));
642 vtkm::Id rootSuperId = this->ContourTree.Supernodes.GetNumberOfValues() - 1;
647 this->SuperarcDependentBoundaryCount);
649 this->ContourTree.Hypernodes.GetNumberOfValues() - 1,
651 this->HyperarcDependentBoundaryCount);
655 this->DebugPrint(
"Iterations Complete", __FILE__, __LINE__));
673 template <
typename MeshType,
typename MeshBoundaryExecObjType>
681 this->InteriorForestData->IsNecessary);
685 auto findNodesWorklet =
687 this->Invoke(findNodesWorklet,
688 this->ContourTree.Superarcs,
689 this->SuperarcDependentBoundaryCount,
690 this->InteriorForestData->IsNecessary
694 this->DebugPrint(
"Is Necessary Based on Dependency", __FILE__, __LINE__));
698 auto setSuperparentNecessaryWorklet =
700 this->Invoke(setSuperparentNecessaryWorklet,
701 this->BoundaryIndices,
702 this->ContourTree.Superparents,
703 this->ContourTree.Superarcs,
704 this->InteriorForestData->IsNecessary);
716 template <
typename MeshType,
typename MeshBoundaryExecObjType>
718 MeshBoundaryExecObjType>::AugmentBoundaryWithNecessaryInteriorSupernodes()
725 auto unsetBoundarySupernodesWorklet =
727 this->Invoke(unsetBoundarySupernodesWorklet,
728 this->BoundaryIndices,
729 this->ContourTree.Superparents,
730 this->ContourTree.Supernodes,
731 isNecessaryAndInterior
735 DebugPrint(
"Flags Unset", __FILE__, __LINE__);
745 if (this->NumNecessary == 0)
749 "BoundaryTreeMaker::AugmentBoundaryWithNecessaryInteriorSupernodes():"
750 "No additional nodes necessary. Returning.");
757 tempBoundaryVertexSuperset.
Allocate(this->NumBoundary + this->NumNecessary);
759 this->BoundaryVertexSuperset,
762 tempBoundaryVertexSuperset,
768 vtkm::cont::make_ArrayHandleConstant<vtkm::Id>(0, this->NumBoundary),
771 tempBoundaryVertexSuperset,
775 this->BoundaryVertexSuperset.ReleaseResources();
776 this->BoundaryVertexSuperset = tempBoundaryVertexSuperset;
782 tempBoundaryIndices.
Allocate(this->NumBoundary + this->NumNecessary);
784 this->BoundaryIndices,
793 vtkm::cont::make_ArrayHandleConstant<vtkm::Id>(0, this->NumBoundary),
800 this->BoundaryIndices.ReleaseResources();
801 this->BoundaryIndices = tempBoundaryIndices;
806 boundaryNecessaryId.
Allocate(this->ContourTree.Supernodes.GetNumberOfValues());
811 auto appendNecessarySupernodesWorklet =
814 this->Invoke(appendNecessarySupernodesWorklet,
815 this->ContourTree.Supernodes,
816 isNecessaryAndInterior,
818 this->Mesh->SortOrder,
819 this->BoundaryIndices,
820 this->BoundaryVertexSuperset);
824 this->DebugPrint(
"Necessary Appended", __FILE__, __LINE__));
837 template <
typename MeshType,
typename MeshBoundaryExecObjType>
843 this->ContourTree.Supernodes.GetNumberOfValues()),
844 this->TreeToSuperset);
848 this->ContourTree.Superarcs, this->ContourTree.Superparents);
853 this->DebugPrint(
"Sorted by Superparent", __FILE__, __LINE__));
859 this->Mesh->SortOrder
861 this->BoundaryVertexSuperset
870 this->BoundaryVertexSuperset.GetNumberOfValues()),
871 this->BoundaryTreeData->Superarcs);
889 this->ContourTree.Nodes.GetNumberOfValues()),
890 this->BoundaryTreeId);
892 auto tempPermutedBoundaryTreeId =
898 this->BoundaryVertexSuperset.GetNumberOfValues()),
899 tempPermutedBoundaryTreeId
905 this->Invoke(superarcToWorklet,
906 this->BoundaryVertexSuperset,
907 this->BoundaryIndices,
908 this->BoundaryTreeId,
909 this->ContourTree.Superparents,
910 this->ContourTree.Hyperparents,
911 this->ContourTree.Hyperarcs,
912 this->ContourTree.Supernodes,
913 this->Mesh->SortOrder,
914 this->TreeToSuperset,
915 this->BoundaryTreeData->Superarcs
920 this->DebugPrint(
"Restricted to Boundary", __FILE__, __LINE__));
933 template <
typename MeshType,
typename MeshBoundaryExecObjType>
940 SetUpAndDownNeighbours();
943 IdentifyRegularisedSupernodes();
946 AddTerminalFlagsToUpDownNeighbours();
949 PointerDoubleUpDownNeighbours();
952 CompressRegularisedNodes();
962 template <
typename MeshType,
typename MeshBoundaryExecObjType>
967 auto tempNoSuchElementArray =
969 this->BoundaryVertexSuperset.GetNumberOfValues());
975 this->Invoke(setUpAndDownNeighboursWorklet,
976 this->BoundaryVertexSuperset,
977 this->BoundaryTreeData->Superarcs,
978 this->Mesh->SortIndices,
985 this->DebugPrint(
"Initial Up/Down Neighbours Set", __FILE__, __LINE__));
994 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1003 this->BoundaryVertexSuperset.GetNumberOfValues()),
1007 this->Invoke(stepOneWorklet,
1008 this->BoundaryVertexSuperset,
1009 this->BoundaryTreeData->Superarcs,
1010 this->Mesh->SortIndices,
1012 this->DownNeighbour,
1018 this->Invoke(stepTwoWorklet,
1019 this->BoundaryVertexSuperset,
1021 this->DownNeighbour,
1022 this->MeshBoundaryExecutionObject,
1028 this->DebugPrint(
"Boundaries & Leaves Set", __FILE__, __LINE__));
1039 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1043 auto addTerminalFlagsToUpDownNeighboursWorklet =
1045 this->Invoke(addTerminalFlagsToUpDownNeighboursWorklet,
1053 this->DebugPrint(
"Up/Down Neighbours Terminated", __FILE__, __LINE__));
1063 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1069 for (
vtkm::Id shifter = this->BoundaryVertexSuperset.GetNumberOfValues(); shifter != 0;
1076 for (
vtkm::Id iteration = 0; iteration < nLogSteps; iteration++)
1080 this->Invoke(pointerDoubleUpDownNeighboursWorklet, this->UpNeighbour, this->DownNeighbour);
1084 this->DebugPrint(
"Pointer Doubling Done", __FILE__, __LINE__));
1096 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1108 keptInBoundaryTree);
1112 auto copyNecessaryRegularNodesWorklet =
1114 this->Invoke(copyNecessaryRegularNodesWorklet,
1121 this->DebugPrint(
"Compressed IDs Computed", __FILE__, __LINE__));
1152 this->Invoke(findNewSuperarcsWorklet,
1154 this->BoundaryTreeData->Superarcs,
1156 this->DownNeighbour,
1162 this->DebugPrint(
"New Superarcs Found", __FILE__, __LINE__));
1167 this->Invoke(resolveRootWorklet,
1178 newVertexIndex.
Allocate(this->NumKept);
1180 this->Invoke(transferVerticesWorklet,
1181 this->BoundaryVertexSuperset,
1191 this->DebugPrint(
"Vertices Transferred", __FILE__, __LINE__));
1197 auto bractNodeComparator =
1205 auto permutedReverseSorter =
1212 this->DebugPrint(
"Indirect Sort Complete", __FILE__, __LINE__));
1226 this->Mesh->SortIndices),
1227 this->BoundaryTreeData->VertexIndex);
1231 auto fillBoundaryTreeSuperarcsWorklet =
1233 this->Invoke(fillBoundaryTreeSuperarcsWorklet,
1237 this->BoundaryTreeData->Superarcs);
1241 this->DebugPrint(
"Regularised Nodes Compressed", __FILE__, __LINE__));
1252 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1257 auto tempNoSuchElementArray =
1259 this->ContourTree.Supernodes.GetNumberOfValues());
1264 auto meshGlobalIds =
1266 ->template GetGlobalIdsFromMeshIndices<vtkm::worklet::contourtree_augmented::IdArrayType>(
1267 this->BoundaryVertexSuperset, localToGlobalIdRelabeler);
1268 auto setInteriorForestWorklet =
1271 this->Invoke(setInteriorForestWorklet,
1272 this->ContourTree.Supernodes,
1273 this->InteriorForestData->IsNecessary,
1274 this->TreeToSuperset,
1277 this->DownNeighbour,
1278 this->InteriorForestData->Above,
1279 this->InteriorForestData->Below
1283 InteriorForestData->BoundaryTreeMeshIndices.Allocate(
1284 this->BoundaryTreeData->VertexIndex.GetNumberOfValues());
1287 this->BoundaryTreeData->VertexIndex, this->Mesh->SortOrder),
1288 InteriorForestData->BoundaryTreeMeshIndices);
1294 template <
typename MeshType,
typename MeshBoundaryExecObjType>
1296 const char* fileName,
1299 std::stringstream resultStream;
1300 resultStream << std::setw(30) << std::left << fileName <<
":" << std::right << std::setw(4)
1302 resultStream << std::left << std::string(message) << std::endl;
1304 resultStream <<
"------------------------------------------------------" << std::endl;
1305 resultStream <<
"BRACT Contains: " << std::endl;
1306 resultStream <<
"------------------------------------------------------" << std::endl;
1308 this->BoundaryTreeData->VertexIndex.GetNumberOfValues(), resultStream);
1310 "BRACT Vertices", this->BoundaryTreeData->VertexIndex, -1, resultStream);
1312 "BRACT Superarcs", this->BoundaryTreeData->Superarcs, -1, resultStream);
1313 resultStream <<
"------------------------------------------------------" << std::endl;
1314 resultStream <<
"BRACT Maker Contains: " << std::endl;
1315 resultStream <<
"------------------------------------------------------" << std::endl;
1316 resultStream <<
"nBoundary: " << this->NumBoundary << std::endl;
1317 resultStream <<
"nNecessary: " << this->NumNecessary << std::endl;
1323 "ID in Boundary Tree", this->BoundaryTreeId, -1, resultStream);
1324 resultStream << std::endl;
1330 "Boundary Sort Indices", this->BoundaryIndices, -1, resultStream);
1332 "Boundary Vertex Superset", this->BoundaryVertexSuperset, -1, resultStream);
1334 "Boundary Superparents", this->BoundarySuperparents, -1, resultStream);
1335 resultStream << std::endl;
1339 this->SupernodeTransferBoundaryCount.GetNumberOfValues(), resultStream);
1341 "Supernode Transfer Count", this->SupernodeTransferBoundaryCount, -1, resultStream);
1343 "Superarc Intrinsic Count", this->SuperarcIntrinsicBoundaryCount, -1, resultStream);
1345 "Superarc Dependent Count", this->SuperarcDependentBoundaryCount, -1, resultStream);
1348 "isNecessary", this->InteriorForestData->IsNecessary, -1, resultStream);
1350 "Tree To Superset", this->TreeToSuperset, -1, resultStream);
1351 resultStream << std::endl;
1355 this->HyperarcDependentBoundaryCount.GetNumberOfValues(), resultStream);
1357 "Hyperarc Dependent Count", this->HyperarcDependentBoundaryCount, -1, resultStream);
1358 resultStream << std::endl;
1364 "New Vertex ID", this->NewVertexId, -1, resultStream);
1370 "Up Neighbour", this->UpNeighbour, -1, resultStream);
1372 "Down Neighbour", this->DownNeighbour, -1, resultStream);
1374 resultStream <<
"------------------------------------------------------" << std::endl;
1375 resultStream << std::endl;
1376 resultStream << std::flush;
1377 return resultStream.str();