/*========================================================================= Program: Visualization Toolkit Module: vtkXdmf3HeavyDataHandler.cxx Language: C++ Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkXdmf3HeavyDataHandler.h" #include "vtkCompositeDataSet.h" #include "vtkDataObject.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkMultiBlockDataSet.h" #include "vtkMutableDirectedGraph.h" #include "vtkRectilinearGrid.h" #include "vtkStructuredGrid.h" #include "vtkUniformGrid.h" #include "vtkUnstructuredGrid.h" #include "vtkXdmf3ArrayKeeper.h" #include "vtkXdmf3ArraySelection.h" #include "vtkXdmf3DataSet.h" // clang-format off #include "vtk_xdmf3.h" #include VTKXDMF3_HEADER(XdmfCurvilinearGrid.hpp) #include VTKXDMF3_HEADER(XdmfDomain.hpp) #include VTKXDMF3_HEADER(XdmfGraph.hpp) #include VTKXDMF3_HEADER(XdmfGrid.hpp) #include VTKXDMF3_HEADER(XdmfGridCollection.hpp) #include VTKXDMF3_HEADER(XdmfGridCollectionType.hpp) #include VTKXDMF3_HEADER(core/XdmfItem.hpp) #include VTKXDMF3_HEADER(XdmfRectilinearGrid.hpp) #include VTKXDMF3_HEADER(XdmfRegularGrid.hpp) #include VTKXDMF3_HEADER(XdmfSet.hpp) #include VTKXDMF3_HEADER(XdmfUnstructuredGrid.hpp) // clang-format on #include //------------------------------------------------------------------------------ shared_ptr vtkXdmf3HeavyDataHandler::New(vtkXdmf3ArraySelection* fs, vtkXdmf3ArraySelection* cs, vtkXdmf3ArraySelection* ps, vtkXdmf3ArraySelection* gc, vtkXdmf3ArraySelection* sc, unsigned int processor, unsigned int nprocessors, bool dt, double t, vtkXdmf3ArrayKeeper* keeper, bool asTime) { shared_ptr p(new vtkXdmf3HeavyDataHandler()); p->FieldArrays = fs; p->CellArrays = cs; p->PointArrays = ps; p->GridsCache = gc; p->SetsCache = sc; p->Rank = processor; p->NumProcs = nprocessors; p->doTime = dt; p->time = t; p->Keeper = keeper; p->AsTime = asTime; return p; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::Populate( shared_ptr item, vtkDataObject* toFill) { assert(toFill); shared_ptr group = shared_dynamic_cast(item); shared_ptr asGC = shared_dynamic_cast(item); bool isDomain = !asGC; bool isTemporal = false; if (asGC) { if (asGC->getType() == XdmfGridCollectionType::Temporal()) { isTemporal = true; } } // ignore groups that are not in timestep we were asked for // but be sure to return everything within them bool lastTime = this->doTime; if (this->doTime && !(isDomain || isTemporal)) { if (asGC->getTime()) { if (asGC->getTime()->getValue() != this->time) { // don't return MB that doesn't match the requested time return nullptr; } // inside a match, make sure we get everything underneath this->doTime = false; } } vtkMultiBlockDataSet* topB = vtkMultiBlockDataSet::SafeDownCast(toFill); vtkDataObject* result; unsigned int cnt = 0; unsigned int nGridCollections = group->getNumberGridCollections(); for (unsigned int i = 0; i < nGridCollections; i++) { if (!this->AsTime) { if (isDomain && !this->ShouldRead(i, nGridCollections)) { topB->SetBlock(cnt++, nullptr); continue; } vtkMultiBlockDataSet* child = vtkMultiBlockDataSet::New(); // result = this->Populate(group->getGridCollection(i), child); shared_ptr tempDomain = shared_dynamic_cast(group->getGridCollection(i)); result = this->Populate(tempDomain, child); topB->SetBlock(cnt++, result); child->Delete(); } else { vtkMultiBlockDataSet* child = vtkMultiBlockDataSet::New(); // result = this->Populate(group->getGridCollection(i), child); shared_ptr tempDomain = shared_dynamic_cast(group->getGridCollection(i)); result = this->Populate(tempDomain, child); if (result) { topB->SetBlock(cnt++, result); } child->Delete(); } } unsigned int nUnstructuredGrids = group->getNumberUnstructuredGrids(); for (unsigned int i = 0; i < nUnstructuredGrids; i++) { if (this->AsTime && !isTemporal && !this->ShouldRead(i, nUnstructuredGrids)) { topB->SetBlock(cnt++, nullptr); continue; } shared_ptr cGrid = group->getUnstructuredGrid(i); unsigned int nSets = cGrid->getNumberSets(); vtkDataObject* child; if (nSets > 0) { child = vtkMultiBlockDataSet::New(); } else { child = vtkUnstructuredGrid::New(); } result = this->Populate(group->getUnstructuredGrid(i), child); if (result) { topB->SetBlock(cnt, result); topB->GetMetaData(cnt)->Set(vtkCompositeDataSet::NAME(), cGrid->getName().c_str()); cnt++; } child->Delete(); } unsigned int nRectilinearGrids = group->getNumberRectilinearGrids(); for (unsigned int i = 0; i < nRectilinearGrids; i++) { if (this->AsTime && !isTemporal && !this->ShouldRead(i, nRectilinearGrids)) { topB->SetBlock(cnt++, nullptr); continue; } shared_ptr cGrid = group->getRectilinearGrid(i); unsigned int nSets = cGrid->getNumberSets(); vtkDataObject* child; if (nSets > 0) { child = vtkMultiBlockDataSet::New(); } else { child = vtkRectilinearGrid::New(); } result = this->Populate(cGrid, child); if (result) { topB->SetBlock(cnt, result); topB->GetMetaData(cnt)->Set(vtkCompositeDataSet::NAME(), cGrid->getName().c_str()); cnt++; } child->Delete(); } unsigned int nCurvilinearGrids = group->getNumberCurvilinearGrids(); for (unsigned int i = 0; i < nCurvilinearGrids; i++) { if (this->AsTime && !isTemporal && !this->ShouldRead(i, nCurvilinearGrids)) { topB->SetBlock(cnt++, nullptr); continue; } shared_ptr cGrid = group->getCurvilinearGrid(i); unsigned int nSets = cGrid->getNumberSets(); vtkDataObject* child; if (nSets > 0) { child = vtkMultiBlockDataSet::New(); } else { child = vtkStructuredGrid::New(); } result = this->Populate(cGrid, child); if (result) { topB->SetBlock(cnt, result); topB->GetMetaData(cnt)->Set(vtkCompositeDataSet::NAME(), cGrid->getName().c_str()); cnt++; } child->Delete(); } unsigned int nRegularGrids = group->getNumberRegularGrids(); for (unsigned int i = 0; i < nRegularGrids; i++) { if (this->AsTime && !isTemporal && !this->ShouldRead(i, nRegularGrids)) { topB->SetBlock(cnt++, nullptr); continue; } shared_ptr cGrid = group->getRegularGrid(i); unsigned int nSets = cGrid->getNumberSets(); vtkDataObject* child; if (nSets > 0) { child = vtkMultiBlockDataSet::New(); } else { child = vtkUniformGrid::New(); } result = this->Populate(cGrid, child); if (result) { topB->SetBlock(cnt, result); topB->GetMetaData(cnt)->Set(vtkCompositeDataSet::NAME(), cGrid->getName().c_str()); cnt++; } child->Delete(); } unsigned int nGraphs = group->getNumberGraphs(); for (unsigned int i = 0; i < nGraphs; i++) { if (this->AsTime && !isTemporal && !this->ShouldRead(i, nGraphs)) { topB->SetBlock(cnt++, nullptr); continue; } vtkMutableDirectedGraph* child = vtkMutableDirectedGraph::New(); result = this->Populate(group->getGraph(i), child); if (result) { topB->SetBlock(cnt, result); topB->GetMetaData(cnt)->Set( vtkCompositeDataSet::NAME(), group->getGraph(i)->getName().c_str()); cnt++; } child->Delete(); } if (lastTime) { // restore time search now that we've done the group contents this->doTime = true; } if (isTemporal && topB->GetNumberOfBlocks() == 1) { // temporal collection is just a place holder for its content return topB->GetBlock(0); } return topB; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::Populate(shared_ptr item, vtkDataObject* toFill) { assert(toFill); shared_ptr unsGrid = shared_dynamic_cast(item); if (unsGrid) { unsigned int nSets = unsGrid->getNumberSets(); if (nSets > 0) { vtkMultiBlockDataSet* mbds = vtkMultiBlockDataSet::SafeDownCast(toFill); vtkUnstructuredGrid* child = vtkUnstructuredGrid::New(); mbds->SetBlock(0, this->MakeUnsGrid(unsGrid, child, this->Keeper)); mbds->GetMetaData((unsigned int)0) ->Set(vtkCompositeDataSet::NAME(), unsGrid->getName().c_str()); for (unsigned int i = 0; i < nSets; i++) { vtkUnstructuredGrid* sub = vtkUnstructuredGrid::New(); mbds->SetBlock(i + 1, this->ExtractSet(i, unsGrid, child, sub, this->Keeper)); mbds->GetMetaData(i + 1)->Set( vtkCompositeDataSet::NAME(), unsGrid->getSet(i)->getName().c_str()); sub->Delete(); } child->Delete(); return mbds; } return this->MakeUnsGrid(unsGrid, vtkUnstructuredGrid::SafeDownCast(toFill), this->Keeper); } shared_ptr recGrid = shared_dynamic_cast(item); if (recGrid) { unsigned int nSets = recGrid->getNumberSets(); if (nSets > 0) { vtkMultiBlockDataSet* mbds = vtkMultiBlockDataSet::SafeDownCast(toFill); vtkRectilinearGrid* child = vtkRectilinearGrid::New(); mbds->SetBlock(0, this->MakeRecGrid(recGrid, child, this->Keeper)); mbds->GetMetaData((unsigned int)0) ->Set(vtkCompositeDataSet::NAME(), recGrid->getName().c_str()); for (unsigned int i = 0; i < nSets; i++) { vtkUnstructuredGrid* sub = vtkUnstructuredGrid::New(); mbds->SetBlock(i + 1, this->ExtractSet(i, recGrid, child, sub, this->Keeper)); mbds->GetMetaData(i + 1)->Set( vtkCompositeDataSet::NAME(), recGrid->getSet(i)->getName().c_str()); sub->Delete(); } child->Delete(); return mbds; } return this->MakeRecGrid(recGrid, vtkRectilinearGrid::SafeDownCast(toFill), this->Keeper); } shared_ptr crvGrid = shared_dynamic_cast(item); if (crvGrid) { unsigned int nSets = crvGrid->getNumberSets(); if (nSets > 0) { vtkMultiBlockDataSet* mbds = vtkMultiBlockDataSet::SafeDownCast(toFill); vtkStructuredGrid* child = vtkStructuredGrid::New(); mbds->SetBlock(0, this->MakeCrvGrid(crvGrid, child, this->Keeper)); mbds->GetMetaData((unsigned int)0) ->Set(vtkCompositeDataSet::NAME(), crvGrid->getName().c_str()); for (unsigned int i = 0; i < nSets; i++) { vtkUnstructuredGrid* sub = vtkUnstructuredGrid::New(); mbds->SetBlock(i + 1, this->ExtractSet(i, crvGrid, child, sub, this->Keeper)); mbds->GetMetaData(i + 1)->Set( vtkCompositeDataSet::NAME(), crvGrid->getSet(i)->getName().c_str()); sub->Delete(); } child->Delete(); return mbds; } return this->MakeCrvGrid(crvGrid, vtkStructuredGrid::SafeDownCast(toFill), this->Keeper); } shared_ptr regGrid = shared_dynamic_cast(item); if (regGrid) { unsigned int nSets = regGrid->getNumberSets(); if (nSets > 0) { vtkMultiBlockDataSet* mbds = vtkMultiBlockDataSet::SafeDownCast(toFill); vtkImageData* child = vtkImageData::New(); mbds->SetBlock(0, this->MakeRegGrid(regGrid, child, this->Keeper)); mbds->GetMetaData((unsigned int)0) ->Set(vtkCompositeDataSet::NAME(), regGrid->getName().c_str()); for (unsigned int i = 0; i < nSets; i++) { vtkUnstructuredGrid* sub = vtkUnstructuredGrid::New(); mbds->SetBlock(i + 1, this->ExtractSet(i, regGrid, child, sub, this->Keeper)); mbds->GetMetaData(i + 1)->Set( vtkCompositeDataSet::NAME(), crvGrid->getSet(i)->getName().c_str()); sub->Delete(); } child->Delete(); return mbds; } return this->MakeRegGrid(regGrid, vtkImageData::SafeDownCast(toFill), this->Keeper); } return nullptr; // already spit a warning out before this } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::Populate(shared_ptr item, vtkDataObject* toFill) { assert(toFill); shared_ptr graph = shared_dynamic_cast(item); if (graph) { return this->MakeGraph(graph, vtkMutableDirectedGraph::SafeDownCast(toFill), this->Keeper); } return nullptr; // already spit a warning out before this } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::ShouldRead(unsigned int piece, unsigned int npieces) { if (this->NumProcs < 1) { // no parallel information given to us, assume serial return true; } if (npieces == 1) { return true; } if (npieces < this->NumProcs) { return piece == this->Rank; } #if 1 unsigned int mystart = this->Rank * npieces / this->NumProcs; unsigned int myend = (this->Rank + 1) * npieces / this->NumProcs; if (piece >= mystart) { if (piece < myend || (this->Rank == this->NumProcs - 1)) { return true; } } return false; #else if ((piece % this->NumProcs) == this->Rank) { return true; } else { return false; } #endif } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::GridEnabled(shared_ptr grid) { return this->GridsCache->ArrayIsEnabled(grid->getName().c_str()); } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::GridEnabled(shared_ptr graph) { return this->GridsCache->ArrayIsEnabled(graph->getName().c_str()); } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::SetEnabled(shared_ptr set) { return this->SetsCache->ArrayIsEnabled(set->getName().c_str()); } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::ForThisTime(shared_ptr grid) { return (!this->doTime || (grid->getTime() && grid->getTime()->getValue() == this->time)); } //------------------------------------------------------------------------------ bool vtkXdmf3HeavyDataHandler::ForThisTime(shared_ptr graph) { return (!this->doTime || (graph->getTime() && graph->getTime()->getValue() == this->time)); } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::MakeUnsGrid( shared_ptr grid, vtkUnstructuredGrid* dataSet, vtkXdmf3ArrayKeeper* keeper) { if (dataSet && this->GridEnabled(grid) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfToVTK( this->FieldArrays, this->CellArrays, this->PointArrays, grid.get(), dataSet, keeper); return dataSet; } return nullptr; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::MakeRecGrid( shared_ptr grid, vtkRectilinearGrid* dataSet, vtkXdmf3ArrayKeeper* keeper) { if (dataSet && this->GridEnabled(grid) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfToVTK( this->FieldArrays, this->CellArrays, this->PointArrays, grid.get(), dataSet, keeper); return dataSet; } return nullptr; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::MakeCrvGrid( shared_ptr grid, vtkStructuredGrid* dataSet, vtkXdmf3ArrayKeeper* keeper) { if (dataSet && this->GridEnabled(grid) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfToVTK( this->FieldArrays, this->CellArrays, this->PointArrays, grid.get(), dataSet, keeper); return dataSet; } return nullptr; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::MakeRegGrid( shared_ptr grid, vtkImageData* dataSet, vtkXdmf3ArrayKeeper* keeper) { if (dataSet && this->GridEnabled(grid) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfToVTK( this->FieldArrays, this->CellArrays, this->PointArrays, grid.get(), dataSet, keeper); return dataSet; } return nullptr; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::MakeGraph( shared_ptr grid, vtkMutableDirectedGraph* dataSet, vtkXdmf3ArrayKeeper* keeper) { if (dataSet && this->GridEnabled(grid) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfToVTK( this->FieldArrays, this->CellArrays, this->PointArrays, grid.get(), dataSet, keeper); return dataSet; } return nullptr; } //------------------------------------------------------------------------------ vtkDataObject* vtkXdmf3HeavyDataHandler::ExtractSet(unsigned int setnum, shared_ptr grid, vtkDataSet* dataSet, vtkUnstructuredGrid* subSet, vtkXdmf3ArrayKeeper* keeper) { shared_ptr set = grid->getSet(setnum); if (dataSet && subSet && SetEnabled(set) && this->ForThisTime(grid)) { vtkXdmf3DataSet::XdmfSubsetToVTK(grid.get(), setnum, dataSet, subSet, keeper); return subSet; } return nullptr; }