You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

743 lines
26 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkStructuredAMRGridConnectivity.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.
=========================================================================*/
/**
* @class vtkStructuredAMRGridConnectivity
* grid connectivity.
*
*
* A concrete instance of vtkAbstractGridConnectivity that implements
* functionality for computing the neighboring topology within a structured
* AMR grid, as well as, generating ghost-layers. Support is provided for
* 1-D, 2-D (XY,XZ,YZ) and 3-D cell-centered datasets. This implementation
* does not have any support for distributed data. For the parallel
* implementation see vtkPStructuredAMRGridConnectivity.
*
* @sa
* vtkPStructuredAMRGridConnectivity vtkAbstractGridConnectivity
*/
#ifndef vtkStructuredAMRGridConnectivity_h
#define vtkStructuredAMRGridConnectivity_h
#include "vtkAbstractGridConnectivity.h"
#include "vtkFiltersGeometryModule.h" // For export macro
#include "vtkStructuredAMRNeighbor.h" // For vtkStructuredAMRNeighbor def.
// C++ includes
#include <map> // For STL map
#include <ostream> // For STL stream
#include <set> // For STL set
#include <vector> // For STL vector
class VTKFILTERSGEOMETRY_EXPORT vtkStructuredAMRGridConnectivity
: public vtkAbstractGridConnectivity
{
public:
static vtkStructuredAMRGridConnectivity* New();
vtkTypeMacro(vtkStructuredAMRGridConnectivity, vtkAbstractGridConnectivity);
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Initializes this instance of vtkStructuredAMRGridConnectivity where N
* is the total number of grids in the AMR hierarchy. Optionally, if the
* AMR dataset has a constant refinement, it should be specified during
* initialization as the code optimizes for it. If a -1 or no refinement
* ratio is specified a varying refinement ratio is assumed.
*/
void Initialize(
const unsigned int NumberOfLevels, const unsigned int N, const int RefinementRatio = -1);
/**
* Computes neighboring information.
*/
void ComputeNeighbors() override;
/**
* Creates ghost layers.
*/
void CreateGhostLayers(const int N = 1) override;
/**
* Registers the AMR grid with the given global linear grid ID (starting
* numbering from 0) and level and refinement ratio. This method is to be
* used when the refinement ratio is not constant.
*/
virtual void RegisterGrid(const int gridIdx, const int level, const int refinementRatio,
int extents[6], vtkUnsignedCharArray* nodesGhostArray, vtkUnsignedCharArray* cellGhostArray,
vtkPointData* pointData, vtkCellData* cellData, vtkPoints* gridNodes);
/**
* Registers the AMR grid with the given global linear grid ID (starting
* numbering from 0) and level. The extents of the grid are expected to be
* global node extents.
*/
virtual void RegisterGrid(const int gridIdx, const int level, int extents[6],
vtkUnsignedCharArray* nodesGhostArray, vtkUnsignedCharArray* cellGhostArray,
vtkPointData* pointData, vtkCellData* cellData, vtkPoints* gridNodes);
//@{
/**
* Get/Set macro for BalancedRefinement property, default is true. If the
* refinement is balanced, then, adjacent grids in the AMR hierarchy can
* only differ by one level. By default, a balanced refinement is assumed.
*/
vtkSetMacro(BalancedRefinement, bool);
vtkGetMacro(BalancedRefinement, bool);
//@}
//@{
/**
* Get/Set macro NodeCentered property which indicates if the data is
* node-centered or cell-centered. By default, node-centered is set to false
* since AMR datasets are primarily cell-centered.
*/
vtkSetMacro(NodeCentered, bool);
vtkGetMacro(NodeCentered, bool);
//@}
//@{
/**
* Get/Set CellCentered property which indicates if the data is cell-centered
* By default, cell-centered is set to true.
*/
vtkSetMacro(CellCentered, bool);
vtkGetMacro(CellCentered, bool);
//@}
/**
* Returns the number of neighbors for the grid corresponding to the given
* grid ID.
*/
int GetNumberOfNeighbors(const int gridID);
/**
* Returns the ghost extend for the grid corresponding to the given grid ID.
*/
void GetGhostedExtent(const int gridID, int ext[6]);
/**
* Returns the AMR neighbor for the patch with the corresponding grid ID.
*/
vtkStructuredAMRNeighbor GetNeighbor(const int gridID, const int nei);
protected:
vtkStructuredAMRGridConnectivity();
~vtkStructuredAMRGridConnectivity() override;
/**
* Sets the total number of grids(blocks) in the AMR hierarchy
*/
void SetNumberOfGrids(const unsigned int N) override;
/**
* Creates the ghosted mask arrays
*/
void CreateGhostedMaskArrays(const int gridID);
/**
* Creates the ghosted extent of the given grid
*/
void CreateGhostedExtent(const int gridID, const int N);
/**
* Sets the ghost extent for the grid corresponding to the given grid ID.
*/
void SetGhostedExtent(const int gridID, int ext[6]);
/**
* Gets the coarsened extent for the grid with the given grid index.
*/
void GetCoarsenedExtent(const int gridIdx, int fromLevel, int toLevel, int ext[6]);
/**
* Gets the refined extent for the grid with the given grid index.
*/
void GetRefinedExtent(const int gridIdx, int fromLevel, int toLevel, int ext[6]);
/**
* Refines the given extent.
*/
void RefineExtent(int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
/**
* Given the global i,j,k index of a cell at a coarse level, fromLevel, this
* method computes the range of cells on the refined grid.
*/
void GetCellRefinedExtent(int orient[3], int ndim, const int i, const int j, const int k,
const int fromLevel, const int toLevel, int ext[6]);
/**
* Coarsens the given extent.
*/
void CoarsenExtent(int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
/**
* Gets the grid extent for the grid with the given grid ID.
*/
void GetGridExtent(const int gridIdx, int ext[6]);
/**
* Returns the level of the grid with the corresponding grid ID.
*/
int GetGridLevel(const int gridIdx);
/**
* Checks if the given level has been registered
*/
bool LevelExists(const int level);
/**
* Checks if the node is an interior node in the given extent.
*/
bool IsNodeInterior(const int i, const int j, const int k, int ext[6]);
/**
* Checks if the node is within the extent.
*/
bool IsNodeWithinExtent(const int i, const int j, const int k, int ext[6]);
/**
* Checks if the node is on a shared boundary.
*/
bool IsNodeOnSharedBoundary(
const int i, const int j, const int k, const int gridId, int gridExt[6]);
/**
* Checks if the node is on the boundary of the given extent.
*/
bool IsNodeOnBoundaryOfExtent(const int i, const int j, const int k, int ext[6]);
/**
* Inserts the grid corresponding to the given ID at the prescribed level.
*/
void InsertGridAtLevel(const int level, const int gridID);
/**
* Loops through the neighbors of this grid and computes the send and rcv
* extents for the N requested ghost layers.
*/
void ComputeNeighborSendAndRcvExtent(const int gridID, const int N);
/**
* Computes the whole extent w.r.t. level 0 as well as the AMR dataset
* description and dimension.
*/
void ComputeWholeExtent();
/**
* Gets the whole extent with respect to the given level.
* NOTE: This method assument that the whole extent has been computed.
*/
void GetWholeExtentAtLevel(const int level, int ext[6]);
/**
* Establishes neighboring relationship between grids i,j wheren i,j are
* global indices.
*/
void EstablishNeighbors(const int i, const int j);
/**
* Computes the node orientation tuple for the given i,j,k node.
*/
void GetNodeOrientation(
const int i, const int j, const int k, int gridExt[6], int nodeOrientation[3]);
/**
* Establishes the orientation vector and dimension based on the computed
* data description. The orientation vector is a 3-tuple, which encodes the
* dimensions that are used. For example, let's say that we want to define
* the orientation to be in the XZ plane, then, the orient array would be
* constructed as follows: {0,2 -1}, where -1 indicates a NIL value.
*/
void GetOrientationVector(const int dataDescription, int orient[3], int& ndim);
/**
* Checks if a constant refinement ratio has been specified.
*/
bool HasConstantRefinementRatio();
/**
* Sets the refinement ratio at the given level.
*/
void SetRefinementRatioAtLevel(const int level, const int r);
/**
* Returns the refinement ratio at the given level.
*/
int GetRefinementRatioAtLevel(const int level);
/**
* Checks if the extent ext1 and ext2 are equal.
*/
bool AreExtentsEqual(int ext1[6], int ext2[6]);
/**
* Constructs the block topology for the given grid.
*/
void SetBlockTopology(const int gridID);
/**
* Returns the number of faces of the block corresponding to the given grid
* ID that are adjacent to at least one other block. Note, this is not the
* total number of neighbors for the block. This method simply checks how
* many out of the 6 block faces have connections. Thus, the return value
* has an upper-bound of 6.
*/
int GetNumberOfConnectingBlockFaces(const int gridID);
//@{
/**
* Checks if the block corresponding to the given grid ID has a block
* adjacent to it in the given block direction.
* NOTE: The block direction is essentially one of the 6 faces of the
* block defined as follows:
* <ul>
* <li> FRONT = 0 (+k diretion) </li>
* <li> BACK = 1 (-k direction) </li>
* <li> RIGHT = 2 (+i direction) </li>
* <li> LEFT = 3 (-i direction) </li>
* <li> TOP = 4 (+j direction) </li>
* <li> BOTTOM = 5 (-j direction) </li>
* </ul>
*/
bool HasBlockConnection(const int gridID, const int blockDirection)
{
// Sanity check
assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: BlockTopology has not been properly allocated" &&
(this->NumberOfGrids == this->BlockTopology.size()));
assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
bool status = false;
if (this->BlockTopology[gridID] & (1 << blockDirection))
{
status = true;
}
return (status);
}
//@}
/**
* Removes a block connection along the given direction for the block
* corresponding to the given gridID.
* NOTE: The block direction is essentially one of the 6 faces of the
* block defined as follows:
* <ul>
* <li> FRONT = 0 (+k diretion) </li>
* <li> BACK = 1 (-k direction) </li>
* <li> RIGHT = 2 (+i direction) </li>
* <li> LEFT = 3 (-i direction) </li>
* <li> TOP = 4 (+j direction) </li>
* <li> BOTTOM = 5 (-j direction) </li>
* </ul>
*/
void RemoveBlockConnection(const int gridID, const int blockDirection);
/**
* Adds a block connection along the given direction for the block
* corresponding to the given gridID.
* NOTE: The block direction is essentially one of the 6 faces of the
* block defined as follows:
* <ul>
* <li> FRONT = 0 (+k diretion) </li>
* <li> BACK = 1 (-k direction) </li>
* <li> RIGHT = 2 (+i direction) </li>
* <li> LEFT = 3 (-i direction) </li>
* <li> TOP = 4 (+j direction) </li>
* <li> BOTTOM = 5 (-j direction) </li>
* </ul>
*/
void AddBlockConnection(const int gridID, const int blockDirection);
/**
* Clears all block connections for the block corresponding to the given
* grid ID.
*/
void ClearBlockConnections(const int gridID);
/**
* Marks the ghost property for the given node.
*/
virtual void MarkNodeProperty(const int gridId, const int i, const int j, const int k,
int gridExt[6], int wholeExt[6], unsigned char& p);
/**
* Fills the node ghost arrays for the given grid
*/
virtual void FillNodesGhostArray(const int gridId, vtkUnsignedCharArray* nodesArray);
/**
* Fills the cell ghost arrays for the given grid
*/
virtual void FillCellsGhostArray(const int gridId, vtkUnsignedCharArray* cellArray);
/**
* Fills ghost arrays.
*/
void FillGhostArrays(
const int gridId, vtkUnsignedCharArray* nodesArray, vtkUnsignedCharArray* cellsArray) override;
/**
* Compute the AMR neighbor of grid "i" and its neighbor grid "j".
* Given the structured neighbors computed in normalized space (i.e., at
* the same level) between the two grids, this method computes the
* corresponding AMR neighbor which essentially adds other bits of
* information, such as level, relationship type, etc.
* NOTE:
* The extents next1 and next2 for each grid are the normalized extents
*/
vtkStructuredAMRNeighbor GetAMRNeighbor(const int i, const int iLevel, int next1[6], const int j,
const int jLevel, int next2[6], const int normalizedLevel, const int levelDiff,
vtkStructuredNeighbor& nei);
/**
* A Helper method to compute the AMR neighbor overlap extents. The method
* coarsens/refines the gridOverlap and neiOverlap extents accordingly s.t.
* they are w.r.t. to the level of the grid they refer to.
*/
void ComputeAMRNeighborOverlapExtents(const int iLevel, const int jLevel,
const int normalizedLevel, const vtkStructuredNeighbor& nei, int orient[3], int ndim,
int gridOverlapExtent[6], int neiOverlapExtent[6]);
/**
* Get 1-D orientation.
*/
int Get1DOrientation(const int idx, const int ExtentLo, const int ExtentHi, const int OnLo,
const int OnHi, const int NotOnBoundary);
/**
* Prints the extent
*/
void PrintExtent(std::ostream& os, int ext[6]);
/**
* Initializes the ghost data-structures
*/
void InitializeGhostData(const int gridID);
/**
* Transfers the data of the registered grid, to the ghosted data-structures.
*/
void TransferRegisteredDataToGhostedData(const int gridID);
/**
* Transfers local node-centered neighbor data
*/
void TransferLocalNodeCenteredNeighborData(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Copy cell center value from a coarser level by direct-injection, i.e., the
* values within the coarse cell is assumed to be constant.
*/
void GetLocalCellCentersFromCoarserLevel(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Copy cell center values from a finer level by cell averaging.
*/
void GetLocalCellCentersFromFinerLevel(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Copy cell center values to fill in the ghost levels from a neighbor at
* the same level as the grid corresponding to the given grid ID.
*/
void GetLocalCellCentersAtSameLevel(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Transfers local cell-centered neighbor data
*/
void TransferLocalCellCenteredNeighborData(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Transfers local neighbor data
*/
void TransferLocalNeighborData(const int gridID, vtkStructuredAMRNeighbor& nei);
/**
* Fills in the ghost data from the neighbors
*/
virtual void TransferGhostDataFromNeighbors(const int gridID);
/**
* Loops through all arrays and computes the average of the supplied source
* indices and stores the corresponding average
*/
void AverageFieldData(vtkFieldData* source, vtkIdType* sourceIds, const int N,
vtkFieldData* target, vtkIdType targetIdx);
/**
* Loops through all arrays in the source and for each array, it copies the
* tuples from sourceIdx to the target at targetIdx. This method assumes
* that the source and target have a one-to-one array correspondence, that
* is array i in the source corresponds to array i in the target.
*/
void CopyFieldData(
vtkFieldData* source, vtkIdType sourceIdx, vtkFieldData* target, vtkIdType targetIdx);
unsigned int NumberOfLevels; // The total number of levels;
int DataDimension; // The dimension of the data, i.e. 2 or 3
int DataDescription; // The data description, i.e., VTK_XY_PLANE, etc.
int WholeExtent[6]; // The whole extent w.r.t. to the root level, level 0.
int MaxLevel; // The max level of the AMR hierarchy
int RefinementRatio; // The refinement ratio, set in the initialization,iff,
// a constant refinement ratio is used. A value of -1
// indicates that the refinement ratio is not constant
// and the RefinementRatios vector is used instead.
bool NodeCentered; // Indicates if the data is node-centered
bool CellCentered; // Indicates if the data is cell-centered
bool BalancedRefinement; // If Balanced refinement is true, then adjacent
// grids in the hierarchy can only differ by one
// level.
// AMRHierarchy stores the set of grid Ids in [0,N] for each level
std::map<int, std::set<int> > AMRHierarchy;
// For each grid, [0,N] store the grid extents,level, and list of neighbors
std::vector<int> GridExtents; // size of this vector is 6*N
std::vector<int> GhostedExtents; // size of this vector is 6*N
std::vector<unsigned char> BlockTopology; // size of this vector is N
std::vector<int> GridLevels; // size of this vector is N
std::vector<std::vector<vtkStructuredAMRNeighbor> > Neighbors;
// For each grid, [0,N], store the donor level,grid and cell information, a
// DonorLevel of -1 indicates that the cell is not receiving any information
// from a donor.
std::vector<std::vector<int> > CellCenteredDonorLevel;
// RefinementRatios stores the refinement ratio at each level, this vector
// is used only when the refinement ratio varies across levels
std::vector<int> RefinementRatios;
private:
vtkStructuredAMRGridConnectivity(const vtkStructuredAMRGridConnectivity&) = delete;
void operator=(const vtkStructuredAMRGridConnectivity&) = delete;
};
//=============================================================================
// INLINE METHODS
//=============================================================================
//------------------------------------------------------------------------------
inline int vtkStructuredAMRGridConnectivity::GetNumberOfNeighbors(const int gridID)
{
assert("pre: grid ID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: neighbors vector has not been properly allocated" &&
(this->Neighbors.size() == this->NumberOfGrids));
return (static_cast<int>(this->Neighbors[gridID].size()));
}
//------------------------------------------------------------------------------
inline vtkStructuredAMRNeighbor vtkStructuredAMRGridConnectivity::GetNeighbor(
const int gridID, const int nei)
{
assert("pre: grid ID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: neighbors vector has not been properly allocated" &&
(this->Neighbors.size() == this->NumberOfGrids));
assert("pre: nei index is out-of-bounds" && (nei >= 0) &&
(nei < static_cast<int>(this->Neighbors[gridID].size())));
return (this->Neighbors[gridID][nei]);
}
//------------------------------------------------------------------------------
inline int vtkStructuredAMRGridConnectivity::Get1DOrientation(const int idx, const int ExtentLo,
const int ExtentHi, const int OnLo, const int OnHi, const int NotOnBoundary)
{
if (idx == ExtentLo)
{
return OnLo;
}
else if (idx == ExtentHi)
{
return OnHi;
}
return NotOnBoundary;
}
//------------------------------------------------------------------------------
inline int vtkStructuredAMRGridConnectivity::GetNumberOfConnectingBlockFaces(const int gridID)
{
// Sanity check
assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: BlockTopology has not been properly allocated" &&
(this->NumberOfGrids == this->BlockTopology.size()));
int count = 0;
for (int i = 0; i < 6; ++i)
{
if (this->HasBlockConnection(gridID, i))
{
++count;
}
}
assert("post: count must be in [0,5]" && (count >= 0 && count <= 6));
return (count);
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::RemoveBlockConnection(
const int gridID, const int blockDirection)
{
// Sanity check
assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: BlockTopology has not been properly allocated" &&
(this->NumberOfGrids == this->BlockTopology.size()));
assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
this->BlockTopology[gridID] &= ~(1 << blockDirection);
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::AddBlockConnection(
const int gridID, const int blockDirection)
{
// Sanity check
assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: BlockTopology has not been properly allocated" &&
(this->NumberOfGrids == this->BlockTopology.size()));
assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
this->BlockTopology[gridID] |= (1 << blockDirection);
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::ClearBlockConnections(const int gridID)
{
// Sanity check
assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
(gridID < static_cast<int>(this->NumberOfGrids)));
assert("pre: BlockTopology has not been properly allocated" &&
(this->NumberOfGrids == this->BlockTopology.size()));
for (int i = 0; i < 6; ++i)
{
this->RemoveBlockConnection(gridID, i);
} // END for all block directions
}
//------------------------------------------------------------------------------
inline bool vtkStructuredAMRGridConnectivity::AreExtentsEqual(int ext1[6], int ext2[6])
{
for (int i = 0; i < 6; ++i)
{
if (ext1[i] != ext2[i])
{
return false;
}
} // END for
return true;
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::PrintExtent(std::ostream& os, int ext[6])
{
for (int i = 0; i < 6; i += 2)
{
os << "[";
os << ext[i] << " ";
os << ext[i + 1] << "] ";
} // END for
}
//------------------------------------------------------------------------------
inline int vtkStructuredAMRGridConnectivity::GetGridLevel(const int gridIdx)
{
assert("pre: grid Index is out-of-bounds!" && (gridIdx < static_cast<int>(this->NumberOfGrids)));
assert("pre: grid levels vector has not been allocated" &&
(this->GridLevels.size() == this->NumberOfGrids));
return (this->GridLevels[gridIdx]);
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::SetRefinementRatioAtLevel(
const int level, const int r)
{
assert("pre: RefinementRatios vector is not properly allocated" &&
this->RefinementRatios.size() == this->NumberOfLevels);
assert("pre: leve is out-of-bounds!" && (level >= 0) &&
(level < static_cast<int>(this->RefinementRatios.size())));
assert("pre: invalid refinement ratio" && (r >= 2));
this->RefinementRatios[level] = r;
}
//------------------------------------------------------------------------------
inline int vtkStructuredAMRGridConnectivity::GetRefinementRatioAtLevel(const int level)
{
assert("pre: RefinementRatios vector is not properly allocated" &&
this->RefinementRatios.size() == this->NumberOfLevels);
assert("pre: leve is out-of-bounds!" && (level >= 0) &&
(level < static_cast<int>(this->RefinementRatios.size())));
assert(
"pre: refinement ratio for level has not been set" && (this->RefinementRatios[level] >= 2));
return (this->RefinementRatios[level]);
}
//------------------------------------------------------------------------------
inline bool vtkStructuredAMRGridConnectivity::HasConstantRefinementRatio()
{
if (this->RefinementRatio < 2)
{
return false;
}
return true;
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::GetGridExtent(const int gridIdx, int ext[6])
{
assert("pre: grid index is out-of-bounds" &&
((gridIdx >= 0) && (gridIdx < static_cast<int>(this->GridExtents.size()))));
for (int i = 0; i < 6; ++i)
{
ext[i] = this->GridExtents[gridIdx * 6 + i];
}
}
//------------------------------------------------------------------------------
inline bool vtkStructuredAMRGridConnectivity::LevelExists(const int level)
{
if (this->AMRHierarchy.find(level) != this->AMRHierarchy.end())
{
return true;
}
return false;
}
//------------------------------------------------------------------------------
inline void vtkStructuredAMRGridConnectivity::InsertGridAtLevel(const int level, const int gridID)
{
if (this->LevelExists(level))
{
this->AMRHierarchy[level].insert(gridID);
}
else
{
std::set<int> grids;
grids.insert(gridID);
this->AMRHierarchy[level] = grids;
}
}
#endif /* VTKSTRUCTUREDAMRGRIDCONNECTIVITY_H_ */