Commit 8fc6cf25 authored by Yuanxin Liu's avatar Yuanxin Liu
Browse files

AMR classes: major data structure changes

The main motivation for the changes is to improve the efficiency
of AMR data structures by replacing the data set containers and meta
data representation with new data structures.

First, the meta data associated with the AMR data is moved from
vtkInformation to a new class vtkAMRInformation so that they do not
have to be deep copied. Related changes also include:

- Before, when the LOAD_REQUESTED_BLOCKS() key is not set, the reader
  would recompute AMR meta data based on the requested blocks.  This
  is no longer done: meta data always represents what is on file.
  The reason is to avoid the sensitive meta data computation that
  depends on connectivitiy of the requested blocks.

- Processor ranks are no longer stored in the meta data. Filters
  can easily generate them by using
  vtkAMRUtilities::DistributeProcessInformation

- There used to be two types of 1D indices used to reference blocks in
  an AMR: vtkOverlappingAMR::GetFlatIndex and
  vtkOverlappingAMR::GetCompositeIndex. Now only the latter is used.
  The "other" 1D index is file type specific so now only the readers
  reference them (vtkAMRInformation::GetAMRBlockSourceIndex())

- To make it easy to traversal the bounding boxes in the meta data. A
  new key vtkObject::BOUNDING_BOX() has been added that works with
  vtkOverlappingAMRDataIterator. See its use in vtkCompositeCutter for
  an example.

- In a multiprocess setting, vtkAMRSliceFilter for each process computes
  the complete meta data to avoid communication

- Many functions in vtkAMRUtilities are removed because they provide
  support for computing meta data from data sets. In the new design,
  meta information is always created before data sets are constructed.

Second, VtkUniformGridAMR now use a more compact representation of the grid
blocks than the tree implementation done previously. To facilicate
this, vtkCompositeDataSet now becomes a fully abstract class and all
concrete implementation gest pushed to the class vtkDataObjectTree.
In the new implementation, the non-null blocks are stored in an stl
vector. So traversing them (using vtkUniformGridAMRDataIterator) is
efficient.
- The AMRBox has been reduced to store only the lower and upper
  corners.  Information such as origin and spacing are moved to the
  container class vtkAMRInformation, since they are often common to
  all boxes or boxes on the same level.

- File reoganization: - AMR File readers are moved from Filters/AMR to
  IO/AMR - AMR algorithms (vtk*AMR*Algorithm) are moved from
  Filters/General to Common/ExecutionModel

Finally, tkAMRVolumeWrapper is moved from filters to rendering.
The dependency on vtkAMRResampler and vtkParallelCore makes it
difficult for it go to Rendering/Volume so a new module
Rendering/VolumeAMR is created.

Change-Id: Id73d214e6a5ac4d4a08fde5d979365f46edfa390
parent aa770d24
......@@ -22,8 +22,8 @@ set(Module_SRCS
vtkCellLinks.cxx
vtkCellLocator.cxx
vtkCellTypes.cxx
vtkCompositeDataIterator.cxx
vtkCompositeDataSet.cxx
vtkCompositeDataIterator.cxx
vtkCone.cxx
vtkConvexPointSet.cxx
vtkCubicLine.cxx
......@@ -31,6 +31,8 @@ set(Module_SRCS
vtkDataObjectCollection.cxx
vtkDataObject.cxx
vtkDataObjectTypes.cxx
vtkDataObjectTree.cxx
vtkDataObjectTreeIterator.cxx
vtkDataSetAttributes.cxx
vtkDataSetCollection.cxx
vtkDataSet.cxx
......@@ -185,6 +187,8 @@ set(Module_SRCS
# New classes for AMR
vtkNonOverlappingAMR.cxx
vtkOverlappingAMR.cxx
vtkAMRInformation.cxx
vtkAMRDataInternals.cxx
vtkUniformGridAMR.cxx
vtkUniformGridAMRDataIterator.cxx
vtkExtentTranslator.cxx # needed by vtkDataSet
......@@ -201,6 +205,7 @@ set_source_files_properties(
vtkCell3D
vtkCompositeDataIterator
vtkCompositeDataSet
vtkDataObjectTree
vtkAbstractElectronicData
vtkDataSet
vtkDataSetGhostGenerator
......@@ -244,6 +249,7 @@ set_source_files_properties(
vtkColor
vtkRect
vtkVectorOperators
vtkAMRDataInternals
WRAP_EXCLUDE
)
......
......@@ -19,28 +19,16 @@
#include <string>
void Construct2DAMRBox(
vtkAMRBox& box,double origin[3],double h[3],int lo[3],int hi[3])
vtkAMRBox& box,int lo[3],int hi[3])
{
box.SetGridDescription( VTK_XY_PLANE );
box.SetDimensionality( 2 );
box.SetDataSetOrigin( origin );
box.SetGridSpacing( h );
box.SetDimensions( lo, hi );
box.SetBlockId( 0 );
box.SetLevel( 0 );
box.SetDimensions( lo, hi, VTK_XY_PLANE );
}
//------------------------------------------------------------------------------
void Construct3DAMRBox(
vtkAMRBox& box,double origin[3],double h[3],int lo[3],int hi[3])
vtkAMRBox& box,int lo[3],int hi[3])
{
box.SetGridDescription( VTK_XYZ_GRID );
box.SetDimensionality( 3 );
box.SetDataSetOrigin( origin );
box.SetGridSpacing( h );
box.SetDimensions( lo, hi );
box.SetBlockId( 0 );
box.SetLevel( 0 );
box.SetDimensions( lo, hi , VTK_XYZ_GRID);
}
//------------------------------------------------------------------------------
......@@ -58,15 +46,15 @@ int TestAMRBoxEquality()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi );
Construct3DAMRBox( B, X0, h, lo, hi );
Construct2DAMRBox( A2D, X0, h, lo, hi );
Construct3DAMRBox( A, lo, hi );
Construct3DAMRBox( B, lo, hi );
Construct2DAMRBox( A2D, lo, hi );
X0[0] = X0[1] = X0[2] = 0.0;
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 16;
hi[0] = hi[1] = hi[2] = 32;
Construct3DAMRBox( C, X0, h, lo, hi );
Construct3DAMRBox( C, lo, hi );
if( A != B )
{
......@@ -101,7 +89,7 @@ int TestAMRBoxAssignmentOperator()
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi );
Construct3DAMRBox( A, lo, hi );
B = A;
if( A != B )
{
......@@ -126,14 +114,14 @@ int TestAMRBoxCoarsenRefineOperators()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi);
Construct3DAMRBox( A, lo, hi);
// Here is the refined AMR box
X0[0] = X0[1] = X0[2] = 0.0;
h[0] = h[1] = h[2] = 0.5;
lo[0] = lo[1] = lo[2] = 16;
hi[0] = hi[1] = hi[2] = 33;
Construct3DAMRBox( Ar, X0, h, lo, hi );
Construct3DAMRBox( Ar, lo, hi );
// Save the intial AMR box to A0
A0 = A;
......@@ -179,7 +167,7 @@ int TestAMRBoxShiftOperator()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi);
Construct3DAMRBox( A, lo, hi);
A0 = A;
......@@ -191,7 +179,7 @@ int TestAMRBoxShiftOperator()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 11;
hi[0] = hi[1] = hi[2] = 19;
Construct3DAMRBox( Ashifted, X0, h, lo, hi);
Construct3DAMRBox( Ashifted, lo, hi);
A.Shift( shift );
if( A != Ashifted )
......@@ -231,7 +219,7 @@ int TestAMRBoxGrowShrinkOperators()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi);
Construct3DAMRBox( A, lo, hi);
A0 = A;
......@@ -240,7 +228,7 @@ int TestAMRBoxGrowShrinkOperators()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 6;
hi[0] = hi[1] = hi[2] = 18;
Construct3DAMRBox( Agrown, X0, h, lo, hi);
Construct3DAMRBox( Agrown, lo, hi);
A.Grow( 2 );
if( A != Agrown )
......@@ -275,7 +263,7 @@ int TestAMRBoxIntersection()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi);
Construct3DAMRBox( A, lo, hi);
// Save the initial
A0 = A;
......@@ -299,7 +287,7 @@ int TestAMRBoxIntersection()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 10;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox(I, X0, h, lo, hi );
Construct3DAMRBox(I, lo, hi );
doesIntersect = A.Intersect( B );
if( !doesIntersect || (A != I) )
......@@ -336,7 +324,7 @@ int TestAMRBoxSerialization()
h[0] = h[1] = h[2] = 1.0;
lo[0] = lo[1] = lo[2] = 8;
hi[0] = hi[1] = hi[2] = 16;
Construct3DAMRBox( A, X0, h, lo, hi);
Construct3DAMRBox( A, lo, hi);
vtkIdType bytesize = 0;
unsigned char *buffer = NULL;
......@@ -388,6 +376,7 @@ void CheckTestStatus( int rc, std::string TestName )
}
}
#include "assert.h"
//------------------------------------------------------------------------------
int TestAMRBox(int , char *[])
{
......
This diff is collapsed.
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAMRDataInternals.cxx
Copyright (c) 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 "vtkAMRDataInternals.h"
#include "vtkUniformGrid.h"
#include "vtkObjectFactory.h"
#include <assert.h>
vtkStandardNewMacro(vtkAMRDataInternals);
vtkAMRDataInternals::Block::Block(unsigned int i, vtkUniformGrid* g)
{
this->Index = i;
this->Grid = g;
}
//-----------------------------------------------------------------------------
vtkAMRDataInternals::vtkAMRDataInternals()
: InternalIndex(NULL)
{
}
void vtkAMRDataInternals::Initialize()
{
delete this->InternalIndex; this->InternalIndex=NULL;
this->Blocks.clear();
}
vtkAMRDataInternals::~vtkAMRDataInternals()
{
this->Blocks.clear();
delete this->InternalIndex;
}
void vtkAMRDataInternals::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
void vtkAMRDataInternals::Insert(unsigned int index, vtkUniformGrid* grid)
{
this->Blocks.push_back(Block(index,grid));
int i = this->Blocks.size()-2;
while( i>=0 && this->Blocks[i].Index > this->Blocks[i+1].Index)
{
std::swap(this->Blocks[i],this->Blocks[i+1]);
i--;
}
}
vtkUniformGrid* vtkAMRDataInternals::GetDataSet(unsigned int compositeIndex)
{
unsigned int internalIndex(0);
if(!this->GetInternalIndex(compositeIndex,internalIndex))
{
return NULL;
}
return this->Blocks[internalIndex].Grid;
}
bool vtkAMRDataInternals::GetInternalIndex(unsigned int compositeIndex, unsigned int& internalIndex)
{
this->GenerateIndex();
if (compositeIndex>=this->InternalIndex->size())
{
return false;
}
int idx = (*this->InternalIndex)[compositeIndex];
if(idx<0)
{
return false;
}
internalIndex= static_cast<unsigned int>(idx);
return true;
}
void vtkAMRDataInternals::GenerateIndex(bool force)
{
if(!force && this->InternalIndex)
{
return;
}
delete this->InternalIndex;
this->InternalIndex = new std::vector<int>();
std::vector<int>& internalIndex(*this->InternalIndex);
for(unsigned i=0; i<this->Blocks.size();i++)
{
unsigned int index = this->Blocks[i].Index;
for(unsigned int j = static_cast<unsigned int>(internalIndex.size()); j<=index; j++)
{
internalIndex.push_back(-1);
}
internalIndex[index] = static_cast<int>(i);
}
}
void vtkAMRDataInternals::ShallowCopy(vtkObject *src)
{
if( src == this )
{
return;
}
if(vtkAMRDataInternals * hbds = vtkAMRDataInternals::SafeDownCast(src))
{
this->Blocks = hbds->Blocks;
}
this->Modified();
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAMRDataInternals.h
Copyright (c) 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.
=========================================================================*/
// .NAME vtkAMRDataInternals - container of vtkUniformGrid for an AMR data set
//
// .SECTION Description
// vtkAMRDataInternals stores a list of non-empty blocks of an AMR data set
//
// .SECTION See Also
// vtkOverlappingAMR, vtkAMRBox
#ifndef __vtkAMRDataInternals_h
#define __vtkAMRDataInternals_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
#include <vtkSmartPointer.h> //for storing smart pointers to blocks
#include <vector> //for storing blocks
class vtkUniformGrid;
class VTKCOMMONDATAMODEL_EXPORT vtkAMRDataInternals : public vtkObject
{
public:
struct Block
{
vtkSmartPointer<vtkUniformGrid> Grid;
unsigned int Index;
Block(unsigned int i, vtkUniformGrid* g);
};
typedef std::vector<vtkAMRDataInternals::Block> BlockList;
static vtkAMRDataInternals* New();
vtkTypeMacro(vtkAMRDataInternals, vtkObject);
void Initialize();
void PrintSelf(ostream& os, vtkIndent indent);
void Insert(unsigned int index, vtkUniformGrid* grid);
vtkUniformGrid* GetDataSet(unsigned int compositeIndex);
virtual void ShallowCopy(vtkObject *src);
bool Empty()const{ return this->GetNumberOfBlocks()==0;}
public:
unsigned int GetNumberOfBlocks() const{ return static_cast<unsigned int>(this->Blocks.size());}
const Block& GetBlock(unsigned int i) { return this->Blocks[i];}
const BlockList& GetAllBlocks() const{ return this->Blocks;}
protected:
vtkAMRDataInternals();
~vtkAMRDataInternals();
void GenerateIndex(bool force=false);
std::vector<Block> Blocks;
std::vector<int>* InternalIndex; //map from the composite index to internal index
bool GetInternalIndex(unsigned int compositeIndex, unsigned int& internalIndex);
private:
vtkAMRDataInternals(const vtkAMRDataInternals&); // Not implemented.
void operator=(const vtkAMRDataInternals&); // Not implemented
};
#endif
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAMRInformation.h
Copyright (c) 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.
=========================================================================*/
// .NAME vtkAMRInformation - Meta data that describes the structure of an AMR data set
//
// .SECTION Description
// vtkAMRInformation encaspulates the following meta information for an AMR data set
// - a list of vtkAMRBox objects
// - Refinement ratio between AMR levels
// - Grid spacing for each level
// - The file block index for each block
// - parent child information, if requested
//
// .SECTION See Also
// vtkOverlappingAMR, vtkAMRBox
#ifndef __vtkAMRInformation_h
#define __vtkAMRInformation_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
#include "vtkAMRBox.h" //for storing AMR Boxes
#include "vtkSmartPointer.h" //for ivars
#include <vector> //for storing AMR Boxes
typedef std::vector<vtkAMRBox> vtkAMRBoxList;
class vtkUnsignedIntArray;
class vtkIntArray;
class vtkDoubleArray;
class vtkAMRIndexIterator;
class VTKCOMMONDATAMODEL_EXPORT vtkAMRInformation : public vtkObject
{
public:
static vtkAMRInformation* New();
vtkTypeMacro(vtkAMRInformation, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
bool operator==(const vtkAMRInformation& other);
//Description
//Initialize the meta information
// numLevels is the number of levels
// blocksPerLevel[i] is the number of blocks at level i
// origin is the global origin
// gridDescription is the type of vtkUniformGrid, e.g. VTK_XYZ_GRID
void Initialize(int numLevels, int* numPerBlocks, double origin[3], int gridDescription);
// Description
// If this is used, then SetOrigin and SetGridDescription should be called
// laster
void Initialize(int numLevels, int* blocksPerLevel);
// Description:
// returns the value of vtkUniformGrid::GridDescription() of any block
vtkGetMacro( GridDescription, int );
void SetGridDescription(int description);
// Description:
// Get the AMR dataset origin
// The origin is essentially the minimum of all the grids.
void GetOrigin( double origin[3] );
double* GetOrigin();
void SetOrigin( double* origin);
// Description:
// Return the number of levels
unsigned int GetNumberOfLevels() const
{ return static_cast<unsigned int>(this->NumBlocks.size()-1);}
// Description:
// Returns the number of datasets at the given levelx
unsigned int GetNumberOfDataSets(unsigned int level) const
{ return this->NumBlocks[level+1]-this->NumBlocks[level]; }
// Description:
// Returns total number of datasets
unsigned int GetTotalNumberOfBlocks()
{ return this->NumBlocks.back();}
// Description:
// Returns the single index from a pair of indices
unsigned int GetIndex(unsigned int level, unsigned int id) const
{ return this->NumBlocks[level] + id;}
// Description:
// Returns the an index pair given a single index
void ComputeIndexPair(unsigned int index, unsigned int& level, unsigned int& id);
// Description
// Returns the bounds of the entire domain
const double* GetBounds() const {return this->Bounds;}
// Description
// Returns the bounding box of a given box
void GetBounds(unsigned int level, unsigned int id, double* bb);
// Description
// Returns the origin of the grid at (level,id)
bool GetOrigin(unsigned int level, unsigned int id, double* origin);
//Description
//Return the spacing at the given fiven
void GetSpacing(unsigned int level, double spacing[3]);
// Description:
// Methods to set and get the AMR box at a given position
void SetAMRBox(unsigned int level, unsigned int id, const vtkAMRBox& box);
void SetAMRBox(unsigned int level, unsigned int id, const int* lo, const int* hi);
void SetAMRBox(unsigned int level, unsigned int id, double* min, double* max, int* dimensions);
void SetAMRBox(unsigned int level, unsigned int id, double* min, int* dimensions, double* h);
const vtkAMRBox& GetAMRBox(unsigned int level, unsigned int id) const;
// Description
// return the amr box coarsened to the previous level
bool GetCoarsenedAMRBox(unsigned int level, unsigned int id, vtkAMRBox& box) const;
// Description:
// Get/Set the SourceIndex of a block. Typically, this is a file-type specific index
// that can be used by a reader to load a particular file block
int GetAMRBlockSourceIndex(int index);
void SetAMRBlockSourceIndex(int index, int sourceId);
// Description:
// This method computes the refinement ratio at each level.
// At each level, l, the refinement ratio r_l is computed by
// r_l = D_{l} / D_{l+1}, where D_{l+1} and D_{l} are the grid
// spacings at the next and current level respectively.
//
// .SECTION Assumptions
// 1) Within each level, the refinement ratios are the same for all blocks.
// 2) The refinement ratio is uniform along each dimension of the block.
void GenerateRefinementRatio();
// Description:
// Returns Wether refinement ratio has been set (either by calling
// GenerateRefinementRatio() or by calling SetRefinementRatio()
bool HasRefinementRatio();
// Description:
// Set the refinement ratio at a level. This method should be
// called for all levels, if called at all.
void SetRefinementRatio(unsigned int level, int ratio);
// Description:
// Returns the refinement of a given level.
int GetRefinementRatio(unsigned int level) const;
//Description:
//Return whether parent child information has been generated
bool HasChildrenInformation();
// Description:
// Return a pointer to Parents of a block. The first entry is the number
// of parents the block has followed by its parent ids in level-1.
// If none exits it returns NULL.
unsigned int *GetParents(unsigned int level, unsigned int index, unsigned int& numParents);
// Description:
// Return a pointer to Children of a block. The first entry is the number
// of children the block has followed by its childern ids in level+1.
// If none exits it returns NULL.
unsigned int *GetChildren(unsigned int level, unsigned int index, unsigned int& numChildren);
// Description:
// Prints the parents and children of a requested block (Debug Routine)
void PrintParentChildInfo(unsigned int level, unsigned int index);
//Description:
// Generate the parent/child relationships - needed to be called
// before GetParents or GetChildren can be used!
void GenerateParentChildInformation();
// Description:
// Checks whether the meta data is internally consistent. Useful for testing
bool IsValid();
// Description:
//Given a point q, find whether q is bounded by the data set at
//(level,index). If it is, set cellIdx to the cell index and return
//true; otherwise return false
bool FindCell(double q[3],unsigned int level, unsigned int index,int &cellIdx);
// Description:
// Returns internal arrays.
const std::vector<int>& GetNumBlocks() const
{ return this->NumBlocks;}
std::vector<std::vector<unsigned int> >& GetChildrenAtLevel(unsigned int i)
{ return this->AllChildren[i];}
void DeepCopy(vtkAMRInformation *other);