// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkParallelAMRUtilities.h" #include "vtkAMRBox.h" #include "vtkCompositeDataIterator.h" #include "vtkMultiProcessController.h" #include "vtkOverlappingAMR.h" #include "vtkOverlappingAMRMetaData.h" #include "vtkSmartPointer.h" #include "vtkUniformGrid.h" #include #include #include #include //------------------------------------------------------------------------------ VTK_ABI_NAMESPACE_BEGIN void vtkParallelAMRUtilities::PrintSelf(std::ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } //------------------------------------------------------------------------------ void vtkParallelAMRUtilities::DistributeProcessInformation( vtkOverlappingAMR* amr, vtkMultiProcessController* controller, std::vector& processMap) { processMap.resize(amr->GetNumberOfBlocks(), -1); vtkSmartPointer iter; iter.TakeReference(amr->NewIterator()); iter->SkipEmptyNodesOn(); if (!controller || controller->GetNumberOfProcesses() == 1) { for (iter->GoToFirstItem(); !iter->IsDoneWithTraversal(); iter->GoToNextItem()) { unsigned int index = iter->GetCurrentFlatIndex(); processMap[index] = 0; } return; } int myRank = controller->GetLocalProcessId(); int numProcs = controller->GetNumberOfProcesses(); // get the active process ids std::vector myBlocks; for (iter->GoToFirstItem(); !iter->IsDoneWithTraversal(); iter->GoToNextItem()) { myBlocks.push_back(iter->GetCurrentFlatIndex()); } vtkIdType myNumBlocks = static_cast(myBlocks.size()); std::vector numBlocks(numProcs, 0); numBlocks[myRank] = myNumBlocks; // gather the active process counts controller->AllGather(&myNumBlocks, numBlocks.data(), 1); // gather the blocks each process owns into one array std::vector offsets(numProcs, 0); vtkIdType currentOffset(0); for (int i = 0; i < numProcs; i++) { offsets[i] = currentOffset; currentOffset += numBlocks[i]; } std::vector allBlocks(currentOffset, -1); controller->AllGatherV(myBlocks.data(), allBlocks.data(), (vtkIdType)myBlocks.size(), numBlocks.data(), offsets.data()); #ifdef DEBUG if (myRank == 0) { for (int i = 0; i < numProcs; i++) { vtkIdType offset = offsets[i]; int n = numBlocks[i]; std::cout << "Rank " << i << " has: "; for (vtkIdType j = offset; j < offset + n; j++) { std::cout << allBlocks[j] << " "; } std::cout << endl; } } #endif for (int rank = 0; rank < numProcs; rank++) { int offset = offsets[rank]; int n = numBlocks[rank]; for (int j = offset; j < offset + n; j++) { int index = allBlocks[j]; assert(index >= 0); processMap[index] = rank; } } } //------------------------------------------------------------------------------ void vtkParallelAMRUtilities::StripGhostLayers(vtkOverlappingAMR* ghostedAMRData, vtkOverlappingAMR* strippedAMRData, vtkMultiProcessController* controller) { vtkAMRUtilities::StripGhostLayers(ghostedAMRData, strippedAMRData); if (controller != nullptr) { controller->Barrier(); } } //------------------------------------------------------------------------------ void vtkParallelAMRUtilities::BlankCells( vtkOverlappingAMR* amr, vtkMultiProcessController* myController) { vtkOverlappingAMRMetaData* amrMData = amr->GetOverlappingAMRMetaData(); if (!amrMData) { vtkErrorWithObjectMacro(amr, "Could not recover AMR Meta Data, aborting"); return; } if (!amrMData->HasRefinementRatio()) { amrMData->GenerateRefinementRatio(); } if (!amrMData->HasChildrenInformation()) { amrMData->GenerateParentChildInformation(); } std::vector processorMap; vtkParallelAMRUtilities::DistributeProcessInformation(amr, myController, processorMap); unsigned int numLevels = amr->GetNumberOfLevels(); for (unsigned int i = 0; i < numLevels; i++) { vtkAMRUtilities::BlankGridsAtLevel(amr, i, amrMData->GetChildrenAtLevel(i), processorMap); } } VTK_ABI_NAMESPACE_END