Commit 9fd1b267 authored by Yuanxin Liu's avatar Yuanxin Liu
Browse files

vtkOverlappingAMR: Generate correct blanking

Previously, blanking is not generated correctly: if a has a child b
that overlaps it but b is not loaded, a still gets blanked.  The fix
makes sure that a gets blanked only if b is loaded.

Change-Id: Ic0716ee182f946e8e924eab15fe5840297848888
parent f32f80f1
......@@ -25,63 +25,6 @@ vtkStandardNewMacro(vtkOverlappingAMR);
vtkInformationKeyMacro(vtkOverlappingAMR,NUMBER_OF_BLANKED_POINTS,IdType);
namespace
{
void BlankGridsAtLevel(vtkOverlappingAMR* amr, int levelIdx, std::vector<std::vector<unsigned int> >& children)
{
unsigned int numDataSets = amr->GetNumberOfDataSets(levelIdx);
int N;
for( unsigned int dataSetIdx=0; dataSetIdx<numDataSets; dataSetIdx++)
{
const vtkAMRBox& box = amr->GetAMRBox(levelIdx, dataSetIdx);
vtkUniformGrid* grid = amr->GetDataSet(levelIdx, dataSetIdx);
if (grid == NULL )
{
continue;
}
N = grid->GetNumberOfCells();
vtkUnsignedCharArray* vis = vtkUnsignedCharArray::New();
vis->SetName("visibility");
vis->SetNumberOfTuples( N );
vis->FillComponent(0,static_cast<char>(1));
grid->SetCellVisibilityArray(vis);
vis->Delete();
if (children.size() <= dataSetIdx)
continue;
std::vector<unsigned int>& dsChildren = children[dataSetIdx];
std::vector<unsigned int>::iterator iter;
// For each higher res box fill in the cells that
// it covers
for (iter=dsChildren.begin(); iter!=dsChildren.end(); iter++)
{
vtkAMRBox ibox;;
if (amr->GetAMRInfo()->GetCoarsenedAMRBox(levelIdx+1, *iter, ibox))
{
const int *loCorner=ibox.GetLoCorner();
int hi[3];
ibox.GetValidHiCorner(hi);
for( int iz=loCorner[2]; iz<=hi[2]; iz++ )
{
for( int iy=loCorner[1]; iy<=hi[1]; iy++ )
{
for( int ix=loCorner[0]; ix<=hi[0]; ix++ )
{
vtkIdType id = vtkAMRBox::GetCellLinearIndex(box,ix, iy, iz, grid->GetDimensions());
vis->SetValue(id, 0);
} // END for x
} // END for y
} // END for z
}
} // Processing all higher boxes for a specific coarse grid
}
}
}
//----------------------------------------------------------------------------
vtkOverlappingAMR::vtkOverlappingAMR()
{
......@@ -157,30 +100,6 @@ void vtkOverlappingAMR::GenerateParentChildInformation()
{
this->AMRInfo->GenerateParentChildInformation();
}
//----------------------------------------------------------------------------
void vtkOverlappingAMR::GenerateVisibilityArrays()
{
if(!this->AMRInfo->HasRefinementRatio())
{
this->AMRInfo->GenerateRefinementRatio();
}
if(!this->AMRInfo->IsValid())
{
vtkErrorMacro("Invalid vtkAMRInformation object. Failed to generate visibility arrays");
return;
}
unsigned int numLevels = this->GetNumberOfLevels();
if(!this->AMRInfo->HasChildrenInformation())
{
this->AMRInfo->GenerateParentChildInformation();
}
for(unsigned int i=0; i<numLevels; i++)
{
BlankGridsAtLevel(this, i, this->AMRInfo->GetChildrenAtLevel(i));
}
}
//----------------------------------------------------------------------------
bool vtkOverlappingAMR::
HasChildrenInformation()
......
......@@ -114,11 +114,6 @@ public:
// Returns the refinement ratio for the position pointed by the iterator.
int GetRefinementRatio(vtkCompositeDataIterator* iter);
// Description:
// Blank lower level cells if they are overlapped by higher
// level ones.
void GenerateVisibilityArrays();
//Description:
//Return whether parent child information has been generated
bool HasChildrenInformation();
......
......@@ -166,6 +166,6 @@ vtkHierarchicalBoxDataSet* GetAMRDataSet()
data->SetDataSet( level, blockId,grid3);
grid3->Delete();
data->GenerateVisibilityArrays();
vtkAMRUtilities::BlankCells(data,NULL);
return( data );
}
......@@ -175,7 +175,7 @@ vtkHierarchicalBoxDataSet* GetAMRDataSet()
data->SetDataSet( level, blockId,grid3);
grid3->Delete();
data->GenerateVisibilityArrays();
vtkAMRUtilities::BlankCells(data,NULL);
return( data );
}
......
......@@ -139,7 +139,7 @@ vtkOverlappingAMR* GetAMRDataSet(const int description)
assert(
"ERROR: Unhandled data description! Code should not reach here!" && false);
}
amrDataSet->GenerateVisibilityArrays();
vtkAMRUtilities::BlankCells(amrDataSet,NULL);
return( amrDataSet );
}
......
......@@ -337,6 +337,6 @@ int vtkAMRGaussianPulseSource::RequestData(
vtkErrorMacro("Dimensions must be either 2 or 3!");
}
output->GenerateVisibilityArrays();
vtkAMRUtilities::BlankCells(output,NULL);
return 1;
}
......@@ -428,9 +428,9 @@ void vtkAMRSliceFilter::GetAMRSliceInPlane(
vtkTimerLog::MarkEndEvent( "AMRSlice::GetAMRSliceInPlane" );
vtkTimerLog::MarkStartEvent( "AMRSlice::GenerateVisibility" );
out->GenerateVisibilityArrays();
vtkTimerLog::MarkEndEvent( "AMRSlice::GenerateVisibility" );
vtkTimerLog::MarkStartEvent( "AMRSlice::Generate Blanking" );
vtkAMRUtilities::BlankCells(out, this->Controller);
vtkTimerLog::MarkEndEvent( "AMRSlice::Generate Blanking" );
}
//------------------------------------------------------------------------------
......
......@@ -25,6 +25,9 @@
#include "vtkStructuredData.h"
#include "vtkUniformGrid.h"
#include "vtkAMRInformation.h"
#include "vtkUnsignedCharArray.h"
#include "vtkSmartPointer.h"
#include "vtkCompositeDataIterator.h"
#include <cmath>
#include <limits>
#include <cassert>
......@@ -37,6 +40,68 @@
#define KMAX(ext) ext[5]
#define PRINT(x) cout<<"("<<myRank<<")"<<x<<endl;
namespace
{
void BlankGridsAtLevel(vtkOverlappingAMR* amr, int levelIdx, std::vector<std::vector<unsigned int> >& children,
const std::vector<int>& processMap)
{
unsigned int numDataSets = amr->GetNumberOfDataSets(levelIdx);
int N;
for( unsigned int dataSetIdx=0; dataSetIdx<numDataSets; dataSetIdx++)
{
const vtkAMRBox& box = amr->GetAMRBox(levelIdx, dataSetIdx);
vtkUniformGrid* grid = amr->GetDataSet(levelIdx, dataSetIdx);
if (grid == NULL )
{
continue;
}
N = grid->GetNumberOfCells();
vtkUnsignedCharArray* vis = vtkUnsignedCharArray::New();
vis->SetName("visibility");
vis->SetNumberOfTuples( N );
vis->FillComponent(0,static_cast<char>(1));
grid->SetCellVisibilityArray(vis);
vis->Delete();
if (children.size() <= dataSetIdx)
continue;
std::vector<unsigned int>& dsChildren = children[dataSetIdx];
std::vector<unsigned int>::iterator iter;
// For each higher res box fill in the cells that
// it covers
for (iter=dsChildren.begin(); iter!=dsChildren.end(); iter++)
{
vtkAMRBox ibox;;
int childGridIndex = amr->GetCompositeIndex(levelIdx+1, *iter);
if(processMap[childGridIndex]<0)
{
continue;
}
if (amr->GetAMRInfo()->GetCoarsenedAMRBox(levelIdx+1, *iter, ibox))
{
const int *loCorner=ibox.GetLoCorner();
int hi[3];
ibox.GetValidHiCorner(hi);
for( int iz=loCorner[2]; iz<=hi[2]; iz++ )
{
for( int iy=loCorner[1]; iy<=hi[1]; iy++ )
{
for( int ix=loCorner[0]; ix<=hi[0]; ix++ )
{
vtkIdType id = vtkAMRBox::GetCellLinearIndex(box,ix, iy, iz, grid->GetDimensions());
vis->SetValue(id, 0);
} // END for x
} // END for y
} // END for z
}
} // Processing all higher boxes for a specific coarse grid
}
}
};
//------------------------------------------------------------------------------
void vtkAMRUtilities::PrintSelf( std::ostream& os, vtkIndent indent )
{
......@@ -48,9 +113,18 @@ void vtkAMRUtilities::DistributeProcessInformation(vtkOverlappingAMR* amr,
vtkMultiProcessController *controller,
std::vector<int>& processMap)
{
processMap.resize(amr->GetTotalNumberOfBlocks(),0);
processMap.resize(amr->GetTotalNumberOfBlocks(),-1);
vtkSmartPointer<vtkCompositeDataIterator> 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;
}
vtkAMRInformation* amrInfo = amr->GetAMRInfo();
......@@ -59,18 +133,10 @@ void vtkAMRUtilities::DistributeProcessInformation(vtkOverlappingAMR* amr,
//get the active process ids
std::vector<int> myBlocks;
for( unsigned int level=0; level < amr->GetNumberOfLevels(); ++level )
for(iter->GoToFirstItem(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
for(unsigned int idx=0;idx < amr->GetNumberOfDataSets(level);++idx )
{
vtkUniformGrid *myGrid = amr->GetDataSet( level, idx );
if( myGrid != NULL )
{
int index = amrInfo->GetIndex(level,idx);
myBlocks.push_back(index);
}
} // END for all data at current level
} // END for all levels
myBlocks.push_back(iter->GetCurrentFlatIndex());
}
vtkIdType myNumBlocks = myBlocks.size();
std::vector<vtkIdType> numBlocks(numProcs,0);
......@@ -433,3 +499,29 @@ void vtkAMRUtilities::StripGhostLayers(
controller->Barrier();
}
}
void vtkAMRUtilities::BlankCells(vtkOverlappingAMR* amr, vtkMultiProcessController *myController)
{
vtkAMRInformation* info = amr->GetAMRInfo();
if(!info->HasRefinementRatio())
{
info->GenerateRefinementRatio();
}
if(!info->IsValid())
{
cerr<<"ERROR: Invalid vtkAMRInformation object. Failed to generate visibility arrays\n";
return;
}
unsigned int numLevels =info->GetNumberOfLevels();
if(!info->HasChildrenInformation())
{
info->GenerateParentChildInformation();
}
std::vector<int> processorMap;
vtkAMRUtilities::DistributeProcessInformation(amr,myController,processorMap);
for(unsigned int i=0; i<numLevels; i++)
{
BlankGridsAtLevel(amr, i, info->GetChildrenAtLevel(i),processorMap);
}
}
......@@ -68,6 +68,10 @@ public:
// Compute map from block indices to process ids
static void DistributeProcessInformation(vtkOverlappingAMR* amr, vtkMultiProcessController *myController, std::vector<int>& ProcessMap);
// Description:
// Blank cells in overlapping AMR
static void BlankCells(vtkOverlappingAMR* amr, vtkMultiProcessController *myController);
protected:
vtkAMRUtilities() {};
~vtkAMRUtilities() {};
......
......@@ -39,9 +39,9 @@
#include <vtkPointData.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vector>
vtkStandardNewMacro(vtkDataObjectGenerator);
//============================================================================
......@@ -799,7 +799,6 @@ vtkDataObject * vtkDataObjectGenerator::FillOutputDataObjects(
}
gcnt++;
}
hbo->GenerateVisibilityArrays();
return outData;
}
case MBS:
......
......@@ -455,7 +455,6 @@ int vtkStreamTracer::RequestData(
{
vtkOverlappingAMR* amr =vtkOverlappingAMR::SafeDownCast(this->InputData);
amr->GenerateParentChildInformation();
amr->GenerateVisibilityArrays();
}
vtkCompositeDataIterator* iter = this->InputData->NewIterator();
......
......@@ -86,11 +86,6 @@ int vtkOverlappingAMRLevelIdScalars::RequestData(
}
this->AddColorLevels(input, output);
vtkOverlappingAMR *amr = vtkOverlappingAMR::SafeDownCast(output);
assert( "ERROR: cannot down-cast to overlapping AMR" && (amr != NULL) );
amr->GenerateParentChildInformation();
amr->GenerateVisibilityArrays();
return 1;
}
......
......@@ -844,9 +844,7 @@ public:
this->AMR = vtkOverlappingAMR::SafeDownCast(this->InputData);
vtkAMRUtilities::DistributeProcessInformation(this->AMR, this->Controller, BlockProcess);
this->AMR->GenerateParentChildInformation();
this->AMR->GenerateVisibilityArrays();
}
protected:
......
......@@ -57,11 +57,33 @@ int ComputeMaxNonEmptyLevel(vtkOverlappingAMR* amr)
return maxLevel+1;
}
int ComputeNumberOfVisibileCells(vtkOverlappingAMR* amr)
{
int numVisibleCells(0);
vtkCompositeDataIterator* iter = amr->NewIterator();
iter->SkipEmptyNodesOn();
for(iter->GoToFirstItem(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkUniformGrid* grid = vtkUniformGrid::SafeDownCast(iter->GetCurrentDataObject());
vtkIdType num = grid->GetNumberOfCells();
for(vtkIdType i=0; i<num; i++)
{
if(grid->IsCellVisible(i))
{
numVisibleCells++;
}
}
}
iter->Delete();
return numVisibleCells;
}
int TestEnzoReader( int argc, char *argv[] )
{
int rc = 0;
int NumBlocksPerLevel[] = { 1,3,1,1,1,1,1,1 };
int numVisibleCells[] = {4096, 6406, 13406, 20406, 23990, 25502, 26377, 27077};
vtkAMREnzoReader *myEnzoReader = vtkAMREnzoReader::New();
char *fileName =
vtkTestUtilities::ExpandDataFileName(argc,argv,
......@@ -88,6 +110,7 @@ int TestEnzoReader( int argc, char *argv[] )
static_cast<int>(amr->GetNumberOfDataSets(level)),
NumBlocksPerLevel[level]
);
rc+= EnzoReaderTest::CheckValue("Number of Visible cells ",ComputeNumberOfVisibileCells(amr), numVisibleCells[level]);
}
else
{
......
......@@ -4,6 +4,7 @@ vtk_module(vtkIOAMR
DEPENDS
vtkParallelCore
vtkhdf5
vtkFiltersAMR
TEST_DEPENDS
vtkIOXML
vtkTestingCore
......
......@@ -32,6 +32,7 @@
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTimerLog.h"
#include "vtkAMRInformation.h"
#include "vtkAMRUtilities.h"
#include <cassert>
......@@ -589,9 +590,9 @@ int vtkAMRBaseReader::RequestData(
{
this->AssignAndLoadBlocks( output );
vtkTimerLog::MarkStartEvent( "AMR::GenerateVisibilityArrays" );
output->GenerateVisibilityArrays();
vtkTimerLog::MarkEndEvent( "AMR::GenerateVisibilityArrays" );
vtkTimerLog::MarkStartEvent( "AMR::Generate Blanking" );
vtkAMRUtilities::BlankCells(output, this->Controller);
vtkTimerLog::MarkEndEvent( "AMR::Generate Blanking" );
}
// If this instance of the reader is not parallel, block until all processes
......
......@@ -212,6 +212,9 @@ int vtkAMRFlashReader::FillMetaData( )
b2level[ level ]++;
} // END for all blocks
amrInfo->GenerateRefinementRatio();
amrInfo->GenerateParentChildInformation();
assert(amrInfo->IsValid());
return( 1 );
}
......
......@@ -180,7 +180,7 @@ void vtkXMLHierarchicalBoxDataReader::ReadVersion0(vtkXMLDataElement* element,
}
dataSetIndex++;
}
hbox->GenerateVisibilityArrays();
//Blanking should be contained int the file.
}
//----------------------------------------------------------------------------
......@@ -287,8 +287,8 @@ void vtkXMLHierarchicalBoxDataReader::ReadComposite(vtkXMLDataElement* element,
dataSetIndex++;
}
}
hbox->GenerateVisibilityArrays();
//Blanking is not done right now.
//This information should be in the file.vtkAMRUtilities::BlankCells(hbox,NULL);
}
//----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment