59 #ifndef vtk_m_worklet_contourtree_distributed_tree_grafter_h
60 #define vtk_m_worklet_contourtree_distributed_tree_grafter_h
103 namespace contourtree_distributed
107 template <
typename MeshType,
typename FieldType>
176 template <
typename StorageTag>
193 template <
typename StorageTag>
253 template <
typename StorageTag>
266 std::string
DebugPrint(
const char* message,
const char* fileName,
long lineNum);
275 template <
typename MeshType,
typename FieldType>
276 template <
typename StorageTag>
304 this->DebugPrint(
"Before GraftResidue()", __FILE__, __LINE__));
307 this->ContourTree.DebugPrint(
"Contour Tree Before GraftResidue()", __FILE__, __LINE__));
309 hierarchicalTree.
DebugPrint(
"Hier Tree Before GraftResidue()", __FILE__, __LINE__));
315 this->GetHierarchicalIds(hierarchicalTree, meshDataValues, localToGlobalIdRelabeler);
319 this->InitializeActiveSuperarcs();
322 this->NumTransferIterations = 0;
337 while (this->ActiveSuperarcs.GetNumberOfValues() > 0)
340 this->FindCriticalPoints();
343 this->CollapseRegularChains();
348 this->IdentifyLeafHyperarcs();
351 this->CompressActiveArrays();
354 this->NumTransferIterations++;
359 DebugPrint(
"Finished Transfer Iterations", __FILE__, __LINE__));
367 calculateAttachementCounterWorklet;
368 this->Invoke(calculateAttachementCounterWorklet,
370 this->HierarchicalSuperId,
379 if (numAttachmentPoints > 0)
383 auto setTransferIterationWorklet = vtkm::worklet::contourtree_distributed::tree_grafter::
384 GraftInteriorForestsSetTransferIterationWorklet(this->NumTransferIterations);
385 this->Invoke(setTransferIterationWorklet,
387 this->HierarchicalSuperId,
388 this->WhenTransferred
391 this->NumTransferIterations++;
396 DebugPrint(
"Finished Setting Attachment Point Iterations", __FILE__, __LINE__));
403 ListNewHypernodes(hierarchicalTree);
404 ListNewSupernodes(hierarchicalTree);
405 ListNewNodes(hierarchicalTree, localToGlobalIdRelabeler);
410 CopyNewHypernodes(hierarchicalTree);
411 CopyNewSupernodes(hierarchicalTree, theRound);
412 CopyNewNodes(hierarchicalTree, meshDataValues, localToGlobalIdRelabeler);
415 CopyIterationDetails(hierarchicalTree, theRound);
419 hierarchicalTree.
DebugPrint(
"GraftInteriorForests() Completed", __FILE__, __LINE__));
432 template <
typename MeshType,
typename FieldType>
433 template <
typename StorageTag>
453 auto tempNoSuchElementArray =
455 this->ContourTree.Supernodes.GetNumberOfValues());
476 auto supernodeGlobalIds =
477 this->Mesh->GetGlobalIdsFromSortIndices(this->ContourTree.Supernodes, localToGlobalIdRelabeler);
480 auto getHierarchicalIdsWorklet =
487 this->Invoke(getHierarchicalIdsWorklet,
489 this->ContourTree.Supernodes,
493 this->Mesh->SortOrder,
495 this->InteriorForest->IsNecessary,
496 this->InteriorForest->Above,
497 this->InteriorForest->Below,
505 findSuperArcForUnknownNode,
508 this->HierarchicalRegularId,
509 this->HierarchicalSuperId,
510 this->HierarchicalHyperId,
511 this->HierarchicalSuperparent,
512 this->HierarchicalHyperparent);
516 DebugPrint(
"GetHierarchicalIDs() Complete", __FILE__, __LINE__));
530 template <
typename MeshType,
typename FieldType>
536 this->ContourTree.Supernodes.GetNumberOfValues()),
540 this->ContourTree.Supernodes.GetNumberOfValues()),
541 this->DownNeighbour);
549 activeSuperarcId.
Allocate(this->ContourTree.Supernodes.GetNumberOfValues() - 1);
552 auto tempSuperarcIndex =
554 auto initActiceSuperarcIdWorklet =
556 this->Invoke(initActiceSuperarcIdWorklet,
558 this->ContourTree.Superarcs,
559 this->InteriorForest->IsNecessary,
579 this->ActiveSuperarcs.Allocate(nFree);
584 auto tempSuperarcIndex =
586 auto initActiceSuperarcsWorklet =
588 this->Invoke(initActiceSuperarcsWorklet,
590 this->ContourTree.Superarcs,
591 this->InteriorForest->IsNecessary,
593 this->ActiveSuperarcs
599 DebugPrint(
"Active Superarc Array Initialized", __FILE__, __LINE__));
605 this->ContourTree.Supernodes.GetNumberOfValues()),
606 this->WhenTransferred);
609 this->ContourTree.Supernodes.GetNumberOfValues()),
610 this->SupernodeType);
613 this->ContourTree.Supernodes.GetNumberOfValues()),
614 this->HierarchicalHyperarc);
618 DebugPrint(
"InitializeActiveSuperarcs() Complete", __FILE__, __LINE__));
629 template <
typename MeshType,
typename FieldType>
635 this->ContourTree.Supernodes.GetNumberOfValues(),
640 this->UpNeighbour.GetNumberOfValues()),
644 this->DownNeighbour.GetNumberOfValues()),
645 this->DownNeighbour);
650 DebugPrint(
"Setting Up/Down Neighbours", __FILE__, __LINE__));
654 auto setUpDownNeighboursWorklet = vtkm::worklet::contourtree_distributed::tree_grafter::
655 FindCriticalPointsSetUpDownNeighboursWorklet();
656 this->Invoke(setUpDownNeighboursWorklet,
657 this->ActiveSuperarcs,
669 auto findSaddlesWorklet =
671 this->Invoke(findSaddlesWorklet,
672 this->ActiveSuperarcs,
684 auto findLeafsWorklet =
686 this->Invoke(findLeafsWorklet,
687 this->ActiveSuperarcs,
699 auto findTerminalElementsWorklet = vtkm::worklet::contourtree_distributed::tree_grafter::
700 FindCriticalPointsFindTerminalElementsWorklet();
701 this->Invoke(findTerminalElementsWorklet,
702 this->ActiveSuperarcs,
710 DebugPrint(
"FindCriticalPoints() Complete", __FILE__, __LINE__));
721 template <
typename MeshType,
typename FieldType>
726 for (
vtkm::Id shifter = this->ActiveSuperarcs.GetNumberOfValues(); shifter != 0; shifter >>= 1)
733 for (
vtkm::Id iteration = 0; iteration < nLogSteps; iteration++)
736 auto collapseRegularChainsWorklet =
738 this->Invoke(collapseRegularChainsWorklet,
739 this->ActiveSuperarcs,
747 DebugPrint(
"CollapseRegularChains() Complete", __FILE__, __LINE__));
759 template <
typename MeshType,
typename FieldType>
776 auto identifyLeafHyperarcsWorklet =
778 this->NumTransferIterations);
779 this->Invoke(identifyLeafHyperarcsWorklet,
780 this->ActiveSuperarcs,
784 this->HierarchicalHyperparent,
785 this->HierarchicalHyperarc,
786 this->WhenTransferred
795 DebugPrint(
"IdentifyLeafHyperarcs() Complete.", __FILE__, __LINE__));
805 template <
typename MeshType,
typename FieldType>
813 auto superarcWasTransferredPredicate =
815 this->WhenTransferred);
818 this->ActiveSuperarcs,
821 compressedActiveSuperarcs,
822 superarcWasTransferredPredicate
825 this->ActiveSuperarcs = compressedActiveSuperarcs;
829 DebugPrint(
"CompressActiveArrays() Complete", __FILE__, __LINE__));
838 template <
typename MeshType,
typename FieldType>
846 this->NewHypernodes);
851 auto notANewHypernodePredicate =
855 this->HierarchicalHyperarc,
856 compressedNewHypernodes,
857 notANewHypernodePredicate
859 this->NewHypernodes = compressedNewHypernodes;
862 auto hyperNodeWhenComparator =
864 this->WhenTransferred);
867 if (this->NewHypernodes.GetNumberOfValues() == 0)
871 "TreeGrafter::ListNewHypernodes(): No new hypernodes. Returning.");
879 auto permutedHierarchicalHyperId =
881 this->HierarchicalHyperId
884 nOldHypernodes, 1, this->NewHypernodes.GetNumberOfValues());
887 tempNewHierarchicalHyperIdValues,
889 permutedHierarchicalHyperId);
901 template <
typename MeshType,
typename FieldType>
910 this->NewSupernodes);
918 auto notANewSupernodePredicate =
922 this->WhenTransferred,
923 compressedNewSupernodes,
924 notANewSupernodePredicate
926 this->NewSupernodes = compressedNewSupernodes;
928 if (this->NewSupernodes.GetNumberOfValues() == 0)
932 "TreeGrafter::ListNewSupernodes(): No new supernodes. Returning.");
938 auto superNodeWhenComparator =
940 this->WhenTransferred,
941 this->HierarchicalHyperparent,
942 this->HierarchicalHyperId,
943 this->HierarchicalHyperarc,
944 this->ContourTree.Supernodes,
945 this->SupernodeType);
950 auto permutedHierarchicalSuperId =
952 this->HierarchicalSuperId);
954 nOldSupernodes, 1, this->NewSupernodes.GetNumberOfValues());
957 tempNewHierarchicalSuperIdValues,
959 permutedHierarchicalSuperId);
970 template <
typename MeshType,
typename FieldType>
978 this->ContourTree.Nodes.GetNumberOfValues()),
979 this->HierarchicalTreeId);
996 auto globalIdsForBoundaryTreeMeshIndices =
997 this->Mesh->template GetGlobalIdsFromMeshIndices<vtkm::cont::ArrayHandleIndex>(
999 localToGlobalIdRelabeler);
1005 auto listNewNodesCopyIdsWorklet =
1007 this->Invoke(listNewNodesCopyIdsWorklet,
1008 globalIdsForBoundaryTreeMeshIndices,
1009 findRegularByGlobal,
1010 this->HierarchicalTreeId);
1023 auto notANewNodePredicate =
1028 this->HierarchicalTreeId,
1030 notANewNodePredicate
1033 this->NewNodes = compressedNewNodes;
1035 if (this->NewNodes.GetNumberOfValues() == 0)
1039 "TreeGrafter::ListNewNodes(): No noew nodes. Returning.");
1047 auto permutedHierarchicalTreeId =
1049 this->HierarchicalTreeId);
1050 auto tempNewHierarchicalTreeIdValues =
1054 tempNewHierarchicalTreeIdValues,
1056 permutedHierarchicalTreeId);
1071 template <
typename MeshType,
typename FieldType>
1077 vtkm::Id nNewHypernodes = this->NewHypernodes.GetNumberOfValues();
1078 vtkm::Id totalNHypernodes = nOldHypernodes + nNewHypernodes;
1084 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1088 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1092 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1096 auto copyNewHypernodesWorklet =
1098 this->Invoke(copyNewHypernodesWorklet,
1099 this->NewHypernodes,
1100 this->HierarchicalSuperId,
1101 this->HierarchicalHyperarc,
1110 hierarchicalTree.
DebugPrint(
"New Hypernodes Copied", __FILE__, __LINE__));
1127 template <
typename MeshType,
typename FieldType>
1134 vtkm::Id nNewSupernodes = this->NewSupernodes.GetNumberOfValues();
1135 vtkm::Id totalNSupernodes = nOldSupernodes + nNewSupernodes;
1137 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1141 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1145 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1149 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1153 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1157 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1164 vtkm::Id nNewNodes = this->NewNodes.GetNumberOfValues();
1165 vtkm::Id totalNNodes = nOldNodes + nNewNodes;
1166 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1172 auto copyNewSupernodesWorklet =
1175 this->Invoke(copyNewSupernodesWorklet,
1176 this->NewSupernodes,
1177 this->ContourTree.Supernodes,
1178 this->Mesh->SortOrder,
1179 this->HierarchicalTreeId,
1180 this->WhenTransferred,
1181 this->HierarchicalSuperparent,
1182 this->HierarchicalHyperparent,
1183 this->HierarchicalSuperId,
1184 this->HierarchicalHyperId,
1185 this->HierarchicalHyperarc,
1190 this->HierarchicalRegularId,
1196 auto copyNewSupernodesSetSuperchildrenWorklet =
1201 copyNewSupernodesSetSuperchildrenWorklet,
1215 startHypernodeIndex,
1219 auto permutedHypernodes =
1221 auto permutedSuper2hypernode =
1223 if (newHypernodeIndex.GetNumberOfValues())
1231 hierarchicalTree.
DebugPrint(
"New Supernodes Copied", __FILE__, __LINE__));
1247 template <
typename MeshType,
typename FieldType>
1248 template <
typename StorageTag>
1256 vtkm::Id nNewNodes = this->NewNodes.GetNumberOfValues();
1257 vtkm::Id totalNNodes = nOldNodes + nNewNodes;
1260 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1266 auto newNodesGloablId =
1268 ->template GetGlobalIdsFromMeshIndices<vtkm::worklet::contourtree_augmented::IdArrayType>(
1269 this->NewNodes, localToGlobalIdRelabeler);
1273 newNodesGloablId.GetNumberOfValues(),
1281 hierarchicalTree.
DebugPrint(
"Global IDs Copied", __FILE__, __LINE__));
1291 meshValuesPermuted.GetNumberOfValues(),
1298 hierarchicalTree.
DebugPrint(
"Data Values Copied", __FILE__, __LINE__));
1304 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1314 tempCountingArray.GetNumberOfValues(),
1319 auto permuteComparator =
1327 hierarchicalTree.
DebugPrint(
"Sort Order Reset", __FILE__, __LINE__));
1333 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1345 tempStartIndex, 1, tempNumValues);
1349 if (tempNewSupernodeIndex.GetNumberOfValues())
1356 auto copyNewNodesSetSuperparentsWorklet =
1360 this->Invoke(copyNewNodesSetSuperparentsWorklet,
1362 this->Mesh->SortIndices,
1363 this->Mesh->SortOrder,
1364 this->ContourTree.Superparents,
1365 this->ContourTree.Superarcs,
1366 this->ContourTree.Supernodes,
1367 this->HierarchicalRegularId,
1368 this->HierarchicalTreeId,
1371 findSuperArcForUnknownNode,
1378 hierarchicalTree.
DebugPrint(
"New Nodes Copied", __FILE__, __LINE__));
1393 template <
typename MeshType,
typename FieldType>
1401 hierarchicalTree.
DebugPrint(
"Starting CopyIterationDetails()", __FILE__, __LINE__));
1413 theRound, this->NumTransferIterations, hierarchicalTree.
NumIterations);
1417 hierarchicalTree.
DebugPrint(
"Round Counts Updated", __FILE__, __LINE__));
1422 vtkm::Id nNewSupernodes = this->NewSupernodes.GetNumberOfValues();
1423 vtkm::Id nOldSupernodes = nTotalSupernodes - nNewSupernodes;
1425 vtkm::Id nNewHypernodes = this->NewHypernodes.GetNumberOfValues();
1426 vtkm::Id nOldHypernodes = nTotalHypernodes - nNewHypernodes;
1430 hierarchicalTree.
DebugPrint(
"Node Counts Retrieved", __FILE__, __LINE__));
1432 DebugPrint(
"About to Transfer Iteration Counts", __FILE__, __LINE__));
1436 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1438 this->NumTransferIterations + 1,
1441 auto copyFirstSupernodePerIterationWorklet =
1445 nOldSupernodes, 1, nTotalSupernodes - nOldSupernodes);
1447 copyFirstSupernodePerIterationWorklet,
1455 this->NumTransferIterations,
1461 #ifdef DEBUG_PRINT_GRAFT_RESIDUE
1463 hierarchicalTree.
DebugPrint(
"Supernode Iteration Counts Set", __FILE__, __LINE__));
1472 vtkm::worklet::contourtree_augmented::ResizeVector<vtkm::Id>(
1474 this->NumTransferIterations + 1,
1478 auto copyFirstHypernodePerIterationWorklet =
1482 nOldHypernodes, 1, nTotalHypernodes - nOldHypernodes);
1484 copyFirstHypernodePerIterationWorklet,
1494 hierarchicalTree.
DebugPrint(
"Hypernode Iteration Counts Set", __FILE__, __LINE__));
1496 DebugPrint(
"Iteration Details Copied", __FILE__, __LINE__));
1503 template <
typename MeshType,
typename FieldType>
1505 const char* fileName,
1508 std::stringstream resultStream;
1509 resultStream << std::endl;
1510 resultStream <<
"[CUTHERE]---------------------------------------------" << std::endl;
1511 resultStream << std::setw(30) << std::left << fileName <<
":" << std::right << std::setw(4)
1513 resultStream << std::left << std::string(message) << std::endl;
1515 resultStream <<
"------------------------------------------------------" << std::endl;
1516 resultStream <<
"Tree Grafter Contains: " << std::endl;
1517 resultStream <<
"------------------------------------------------------" << std::endl;
1523 "ID in Hierarchical Tree", this->HierarchicalTreeId, -1, resultStream);
1524 resultStream << std::endl;
1530 "Hierarchical Regular ID", this->HierarchicalRegularId, -1, resultStream);
1532 "Hierarchical Superparent", this->HierarchicalSuperparent, -1, resultStream);
1534 "Hierarchical Super ID", this->HierarchicalSuperId, -1, resultStream);
1536 "Hierarchical Hyperparent", this->HierarchicalHyperparent, -1, resultStream);
1538 "Hierarchical Hyper ID", this->HierarchicalHyperId, -1, resultStream);
1540 "Hierarchical Hyperarc", this->HierarchicalHyperarc, -1, resultStream);
1542 "When Transferred", this->WhenTransferred, -1, resultStream);
1544 "Supernode Type", this->SupernodeType, -1, resultStream);
1546 "Up Neighbour", this->UpNeighbour, -1, resultStream);
1548 "Down Neighbour", this->DownNeighbour, -1, resultStream);
1549 resultStream << std::endl;
1555 "Active Superarcs", this->ActiveSuperarcs, -1, resultStream);
1561 "New Hypernodes", this->NewHypernodes, -1, resultStream);
1566 "New Supernodes", this->NewSupernodes, -1, resultStream);
1572 resultStream <<
"------------------------------------------------------" << std::endl;
1573 resultStream << std::endl;
1575 resultStream << std::flush;
1576 return resultStream.str();