VTK
dox/Filters/Geometry/vtkStructuredAMRGridConnectivity.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003  Program:   Visualization Toolkit
00004  Module:    vtkStructuredAMRGridConnectivity.h
00005 
00006  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007  All rights reserved.
00008  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010  This software is distributed WITHOUT ANY WARRANTY; without even
00011  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012  PURPOSE.  See the above copyright notice for more information.
00013 
00014  =========================================================================*/
00033 #ifndef VTKSTRUCTUREDAMRGRIDCONNECTIVITY_H_
00034 #define VTKSTRUCTUREDAMRGRIDCONNECTIVITY_H_
00035 
00036 #include "vtkFiltersGeometryModule.h" // For export macro
00037 #include "vtkAbstractGridConnectivity.h"
00038 
00039 #include "vtkStructuredAMRNeighbor.h" // For vtkStructuredAMRNeighbor def.
00040 
00041 
00042 // C++ includes
00043 #include <map>     // For STL map
00044 #include <ostream> // For STL stream
00045 #include <set>     // For STL set
00046 #include <vector>  // For STL vector
00047 
00048 class VTKFILTERSGEOMETRY_EXPORT vtkStructuredAMRGridConnectivity :
00049   public vtkAbstractGridConnectivity
00050 {
00051 public:
00052   static vtkStructuredAMRGridConnectivity* New();
00053   vtkTypeMacro(vtkStructuredAMRGridConnectivity, vtkAbstractGridConnectivity);
00054   void PrintSelf(ostream& os, vtkIndent indent );
00055 
00057 
00062   void Initialize(
00063       const unsigned int NumberOfLevels,
00064       const unsigned int N, const int RefinementRatio=-1);
00066 
00068   virtual void ComputeNeighbors();
00069 
00071   virtual void CreateGhostLayers(const int N=1);
00072 
00074 
00077   virtual void RegisterGrid(
00078         const int gridIdx, const int level, const int refinementRatio,
00079         int extents[6],
00080         vtkUnsignedCharArray* nodesGhostArray,
00081         vtkUnsignedCharArray* cellGhostArray,
00082         vtkPointData* pointData,
00083         vtkCellData* cellData,
00084         vtkPoints* gridNodes);
00086 
00088 
00091   virtual void RegisterGrid(
00092       const int gridIdx, const int level, int extents[6],
00093       vtkUnsignedCharArray* nodesGhostArray,
00094       vtkUnsignedCharArray* cellGhostArray,
00095       vtkPointData* pointData,
00096       vtkCellData* cellData,
00097       vtkPoints* gridNodes);
00099 
00101 
00105   vtkSetMacro(BalancedRefinement,bool);
00106   vtkGetMacro(BalancedRefinement,bool);
00108 
00110 
00113   vtkSetMacro(NodeCentered,bool);
00114   vtkGetMacro(NodeCentered,bool);
00116 
00118 
00120   vtkSetMacro(CellCentered,bool);
00121   vtkGetMacro(CellCentered,bool);
00123 
00126   int GetNumberOfNeighbors(const int gridID);
00127 
00130   void GetGhostedExtent(const int gridID, int ext[6]);
00131 
00134   vtkStructuredAMRNeighbor GetNeighbor(const int gridID, const int nei);
00135 
00136 protected:
00137   vtkStructuredAMRGridConnectivity();
00138   virtual ~vtkStructuredAMRGridConnectivity();
00139 
00141   virtual void SetNumberOfGrids( const unsigned int N );
00142 
00144   void CreateGhostedMaskArrays(const int gridID);
00145 
00147   void CreateGhostedExtent(const int gridID, const int N);
00148 
00151   void SetGhostedExtent(const int gridID, int ext[6]);
00152 
00154 
00155   void GetCoarsenedExtent(
00156       const int gridIdx, int fromLevel, int toLevel, int ext[6]);
00158 
00160 
00161   void GetRefinedExtent(
00162       const int gridIdx, int fromLevel, int toLevel, int ext[6]);
00164 
00166 
00167   void RefineExtent(
00168       int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
00170 
00172 
00174   void GetCellRefinedExtent(
00175         int orient[3], int ndim,
00176         const int i, const int j, const int k,
00177         const int fromLevel, const int toLevel,
00178         int ext[6]);
00180 
00182 
00183   void CoarsenExtent(
00184       int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
00186 
00188   void GetGridExtent( const int gridIdx, int ext[6] );
00189 
00191   int GetGridLevel( const int gridIdx );
00192 
00194   bool LevelExists( const int level );
00195 
00197 
00198   bool IsNodeInterior(
00199       const int i, const int j, const int k, int ext[6]);
00201 
00203 
00204   bool IsNodeWithinExtent(
00205       const int i, const int j, const int k, int ext[6]);
00207 
00209 
00210   bool IsNodeOnSharedBoundary(
00211         const int i, const int j, const int k,
00212         const int gridId,int gridExt[6]);
00214 
00216 
00217   bool IsNodeOnBoundaryOfExtent(
00218           const int i, const int j, const int k, int ext[6] );
00220 
00223   void InsertGridAtLevel( const int level, const int gridID);
00224 
00227   void ComputeNeighborSendAndRcvExtent(const int gridID, const int N);
00228 
00231   void ComputeWholeExtent();
00232 
00235   void GetWholeExtentAtLevel(const int level, int ext[6]);
00236 
00239   void EstablishNeighbors(const int i, const int j);
00240 
00242 
00243   void GetNodeOrientation(
00244       const int i, const int j, const int k,
00245       int gridExt[6], int nodeOrientation[3]);
00247 
00249 
00255   void GetOrientationVector(
00256       const int dataDescription, int orient[3], int &ndim);
00258 
00260   bool HasConstantRefinementRatio( );
00261 
00263   void SetRefinementRatioAtLevel( const int level, const int r);
00264 
00266   int GetRefinementRatioAtLevel(const int level);
00267 
00269   bool AreExtentsEqual(int ext1[6], int ext2[6] );
00270 
00272   void SetBlockTopology(const int gridID);
00273 
00279   int GetNumberOfConnectingBlockFaces( const int gridID );
00280 
00282 
00289   bool HasBlockConnection(const int gridID, const int blockDirection)
00290   {
00291     // Sanity check
00292     assert("pre: gridID is out-of-bounds" &&
00293           (gridID >=0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00294     assert("pre: BlockTopology has not been properly allocated" &&
00295           (this->NumberOfGrids == this->BlockTopology.size()));
00296     assert("pre: blockDirection is out-of-bounds" &&
00297           (blockDirection >= 0) && (blockDirection < 6) );
00298     bool status = false;
00299     if( this->BlockTopology[ gridID ] & (1 << blockDirection) )
00300       {
00301       status = true;
00302       }
00303     return( status );
00304   }
00306 
00314   void RemoveBlockConnection(const int gridID, const int blockDirection);
00315 
00323   void AddBlockConnection(const int gridID, const int blockDirection);
00324 
00327   void ClearBlockConnections( const int gridID );
00328 
00330 
00331   virtual void MarkNodeProperty(
00332       const int gridId, const int i, const int j, const int k,
00333       int gridExt[6], int wholeExt[6],
00334       unsigned char &p);
00336 
00338 
00339   virtual void FillNodesGhostArray(
00340       const int gridId, vtkUnsignedCharArray* nodesArray);
00342 
00344 
00345   virtual void FillCellsGhostArray(
00346       const int gridId, vtkUnsignedCharArray* cellArray);
00348 
00350 
00351   virtual void FillGhostArrays(
00352             const int gridId,
00353             vtkUnsignedCharArray* nodesArray,
00354             vtkUnsignedCharArray* cellsArray );
00356 
00358 
00364   vtkStructuredAMRNeighbor GetAMRNeighbor(
00365       const int i, const int iLevel, int next1[6],
00366       const int j, const int jLevel, int next2[6],
00367       const int normalizedLevel,
00368       const int levelDiff,
00369       vtkStructuredNeighbor &nei);
00371 
00373 
00377   void ComputeAMRNeighborOverlapExtents(
00378       const int iLevel, const int jLevel, const int normalizedLevel,
00379       const vtkStructuredNeighbor &nei,
00380       int orient[3], int ndim,
00381       int gridOverlapExtent[6],
00382       int neiOverlapExtent[6]);
00384 
00386 
00387   int Get1DOrientation(
00388       const int idx, const int ExtentLo, const int ExtentHi,
00389       const int OnLo, const int OnHi, const int NotOnBoundary);
00391 
00393   void PrintExtent(std::ostream& os, int ext[6]);
00394 
00396   void InitializeGhostData( const int gridID );
00397 
00400   void TransferRegisteredDataToGhostedData( const int gridID );
00401 
00403 
00404   void TransferLocalNodeCenteredNeighborData(
00405           const int gridID, vtkStructuredAMRNeighbor &nei);
00407 
00409 
00411   void GetLocalCellCentersFromCoarserLevel(
00412           const int gridID, vtkStructuredAMRNeighbor &nei);
00414 
00416 
00417   void GetLocalCellCentersFromFinerLevel(
00418           const int gridID, vtkStructuredAMRNeighbor &nei);
00420 
00422 
00424   void GetLocalCellCentersAtSameLevel(
00425           const int gridID, vtkStructuredAMRNeighbor &nei);
00427 
00429 
00430   void TransferLocalCellCenteredNeighborData(
00431           const int gridID, vtkStructuredAMRNeighbor &nei);
00433 
00435 
00436   void TransferLocalNeighborData(
00437       const int gridID, vtkStructuredAMRNeighbor &nei);
00439 
00441   virtual void TransferGhostDataFromNeighbors(const int gridID);
00442 
00444 
00446   void AverageFieldData(
00447       vtkFieldData *source, vtkIdType *sourceIds, const int N,
00448       vtkFieldData *target, vtkIdType targetIdx);
00450 
00452 
00457   void CopyFieldData(
00458       vtkFieldData *source, vtkIdType sourceIdx,
00459       vtkFieldData *target, vtkIdType targetIdx);
00461 
00462 
00463   unsigned int NumberOfLevels; // The total number of levels;
00464   int DataDimension;    // The dimension of the data, i.e. 2 or 3
00465   int DataDescription;  // The data description, i.e., VTK_XY_PLANE, etc.
00466   int WholeExtent[6];   // The whole extent w.r.t. to the root level, level 0.
00467   int MaxLevel;         // The max level of the AMR hierarchy
00468   int RefinementRatio;  // The refinement ratio, set in the initialization,iff,
00469                         // a constant refinement ratio is used. A value of -1
00470                         // indicates that the refinement ratio is not constant
00471                         // and the RefinementRatios vector is used instead.
00472 
00473   bool NodeCentered;  // Indicates if the data is node-centered
00474   bool CellCentered;  // Indicates if the data is cell-centered
00475 
00476   bool BalancedRefinement; // If Balanced refinement is true, then adjacent
00477                             // grids in the hierarchy can only differ by one
00478                             // level.
00479 
00480   // BTX
00481   // AMRHierarchy stores the the set of grid Ids in [0,N] for each level
00482   std::map< int, std::set<int> > AMRHierarchy;
00483 
00484   // For each grid, [0,N] store the grid extents,level, and list of neighbors
00485   std::vector< int > GridExtents; // size of this vector is 6*N
00486   std::vector< int > GhostedExtents; // size of this vector is 6*N
00487   std::vector< unsigned char > BlockTopology; // size of this vector is N
00488   std::vector< int > GridLevels;  // size of ths vector is N
00489   std::vector< std::vector<vtkStructuredAMRNeighbor> > Neighbors;
00490 
00491   // For each grid, [0,N], store the donor level,grid and cell information, a
00492   // DonorLevel of -1 indicates that the cell is not receiving any information
00493   // from a donor.
00494   std::vector< std::vector<int> > CellCenteredDonorLevel;
00495 
00496 
00497   // RefinementRatios stores the refinement ratio at each level, this vector
00498   // is used only when the refinement ratio varies across levels
00499   std::vector< int > RefinementRatios;
00500   // ETX
00501 
00502 private:
00503    vtkStructuredAMRGridConnectivity(const vtkStructuredAMRGridConnectivity&); // Not implemented
00504    void operator=(const vtkStructuredAMRGridConnectivity&); // Not implemented
00505 };
00506 
00507 //=============================================================================
00508 //  INLINE METHODS
00509 //=============================================================================
00510 
00511 //------------------------------------------------------------------------------
00512 inline int
00513 vtkStructuredAMRGridConnectivity::GetNumberOfNeighbors(
00514     const int gridID)
00515 {
00516   assert("pre: grid ID is out-of-bounds" &&
00517          (gridID >= 0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00518   assert("pre: neighbors vector has not been properly allocated" &&
00519           (this->Neighbors.size()==this->NumberOfGrids));
00520   return( static_cast<int>(this->Neighbors[gridID].size()) );
00521 }
00522 
00523 //------------------------------------------------------------------------------
00524 inline vtkStructuredAMRNeighbor
00525 vtkStructuredAMRGridConnectivity::GetNeighbor(
00526       const int gridID, const int nei)
00527 {
00528   assert("pre: grid ID is out-of-bounds" &&
00529          (gridID >= 0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00530   assert("pre: neighbors vector has not been properly allocated" &&
00531          (this->Neighbors.size()==this->NumberOfGrids));
00532   assert("pre: nei index is out-of-bounds" &&
00533          (nei >= 0) &&
00534          (nei < static_cast<int>(this->Neighbors[gridID].size())));
00535   return( this->Neighbors[gridID][nei] );
00536 }
00537 
00538 //------------------------------------------------------------------------------
00539 inline int
00540 vtkStructuredAMRGridConnectivity::Get1DOrientation(
00541     const int idx, const int ExtentLo, const int ExtentHi,
00542     const int OnLo, const int OnHi, const int NotOnBoundary)
00543 {
00544   if( idx == ExtentLo )
00545       {
00546       return OnLo;
00547       }
00548     else if( idx == ExtentHi )
00549       {
00550       return OnHi;
00551       }
00552     return NotOnBoundary;
00553 }
00554 
00555 //------------------------------------------------------------------------------
00556 inline
00557 int vtkStructuredAMRGridConnectivity::GetNumberOfConnectingBlockFaces(
00558     const int gridID )
00559 {
00560   // Sanity check
00561   assert("pre: gridID is out-of-bounds" &&
00562         (gridID >=0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00563   assert("pre: BlockTopology has not been properly allocated" &&
00564         (this->NumberOfGrids == this->BlockTopology.size()));
00565 
00566   int count = 0;
00567   for( int i=0; i < 6; ++i )
00568     {
00569     if( this->HasBlockConnection( gridID, i ) )
00570       {
00571       ++count;
00572       }
00573     }
00574   assert( "post: count must be in [0,5]" && (count >=0 && count <= 6) );
00575   return( count );
00576 }
00577 
00578 //------------------------------------------------------------------------------
00579 inline void vtkStructuredAMRGridConnectivity::RemoveBlockConnection(
00580     const int gridID, const int blockDirection )
00581 {
00582   // Sanity check
00583   assert("pre: gridID is out-of-bounds" &&
00584         (gridID >=0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00585   assert("pre: BlockTopology has not been properly allocated" &&
00586         (this->NumberOfGrids == this->BlockTopology.size()));
00587   assert("pre: blockDirection is out-of-bounds" &&
00588         (blockDirection >= 0) && (blockDirection < 6) );
00589 
00590   this->BlockTopology[ gridID ] &= ~(1 << blockDirection);
00591 }
00592 
00593 //------------------------------------------------------------------------------
00594 inline void vtkStructuredAMRGridConnectivity::AddBlockConnection(
00595     const int gridID, const int blockDirection )
00596 {
00597   // Sanity check
00598   assert("pre: gridID is out-of-bounds" &&
00599         (gridID >=0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00600   assert("pre: BlockTopology has not been properly allocated" &&
00601         (this->NumberOfGrids == this->BlockTopology.size()));
00602   assert("pre: blockDirection is out-of-bounds" &&
00603         (blockDirection >= 0) && (blockDirection < 6) );
00604   this->BlockTopology[ gridID ] |= (1 << blockDirection);
00605 }
00606 
00607 //------------------------------------------------------------------------------
00608 inline void vtkStructuredAMRGridConnectivity::ClearBlockConnections(
00609     const int gridID )
00610 {
00611   // Sanity check
00612   assert("pre: gridID is out-of-bounds" &&
00613         (gridID >=0) && (gridID < static_cast<int>(this->NumberOfGrids)));
00614   assert("pre: BlockTopology has not been properly allocated" &&
00615         (this->NumberOfGrids == this->BlockTopology.size()));
00616   for( int i=0; i < 6; ++i )
00617     {
00618     this->RemoveBlockConnection( gridID, i );
00619     } // END for all block directions
00620 }
00621 
00622 //------------------------------------------------------------------------------
00623 inline
00624 bool vtkStructuredAMRGridConnectivity::AreExtentsEqual(
00625         int ext1[6], int ext2[6])
00626 {
00627   for( int i=0; i < 6; ++i )
00628     {
00629     if( ext1[i] != ext2[i] )
00630       {
00631       return false;
00632       }
00633     } // END for
00634   return true;
00635 }
00636 
00637 //------------------------------------------------------------------------------
00638 inline
00639 void vtkStructuredAMRGridConnectivity::PrintExtent(
00640       std::ostream& os, int ext[6])
00641 {
00642   for( int i=0; i < 6; i+=2 )
00643     {
00644     os << "[";
00645     os << ext[i]   << " ";
00646     os << ext[i+1] << "] ";
00647     } // END for
00648 }
00649 
00650 //------------------------------------------------------------------------------
00651 inline
00652 int vtkStructuredAMRGridConnectivity::GetGridLevel(const int gridIdx)
00653 {
00654   assert("pre: grid Index is out-of-bounds!" &&
00655          (gridIdx < static_cast<int>(this->NumberOfGrids)));
00656   assert("pre: grid levels vector has not been allocated" &&
00657          (this->GridLevels.size()==this->NumberOfGrids) );
00658   return( this->GridLevels[gridIdx] );
00659 }
00660 
00661 //------------------------------------------------------------------------------
00662 inline
00663 void vtkStructuredAMRGridConnectivity::SetRefinementRatioAtLevel(
00664     const int level, const int r)
00665 {
00666   assert("pre: RefinementRatios vector is not propertly allocated" &&
00667          this->RefinementRatios.size()==this->NumberOfLevels);
00668   assert("pre: leve is out-of-bounds!" &&
00669          (level >= 0) &&
00670          (level < static_cast<int>(this->RefinementRatios.size())) );
00671   assert("pre: invalid refinement ratio" && (r >= 2) );
00672 
00673   this->RefinementRatios[ level ] = r;
00674 }
00675 
00676 //------------------------------------------------------------------------------
00677 inline
00678 int vtkStructuredAMRGridConnectivity::GetRefinementRatioAtLevel(
00679       const int level)
00680 {
00681   assert( "pre: RefinementRatios vector is not propertly allocated" &&
00682           this->RefinementRatios.size()==this->NumberOfLevels);
00683   assert( "pre: leve is out-of-bounds!" &&
00684           (level >= 0) &&
00685           (level < static_cast<int>(this->RefinementRatios.size())));
00686   assert( "pre: refinement ratio for level has not been set" &&
00687           (this->RefinementRatios[ level ] >= 2) );
00688 
00689  return(this->RefinementRatios[level]);
00690 }
00691 
00692 //------------------------------------------------------------------------------
00693 inline
00694 bool vtkStructuredAMRGridConnectivity::HasConstantRefinementRatio()
00695 {
00696   if( this->RefinementRatio < 2 )
00697     {
00698     return false;
00699     }
00700   return true;
00701 }
00702 
00703 //------------------------------------------------------------------------------
00704 inline void vtkStructuredAMRGridConnectivity::GetGridExtent(
00705                       const int gridIdx, int ext[6])
00706 {
00707   assert("pre: grid index is out-of-bounds" &&
00708          ( (gridIdx >= 0) &&
00709            (gridIdx < static_cast<int>(this->GridExtents.size()) ) ) );
00710 
00711   for( int i=0; i < 6; ++i )
00712     {
00713     ext[ i ] = this->GridExtents[ gridIdx*6+i ];
00714     }
00715 }
00716 
00717 //------------------------------------------------------------------------------
00718 inline bool vtkStructuredAMRGridConnectivity::LevelExists(
00719               const int level )
00720 {
00721   if( this->AMRHierarchy.find(level) != this->AMRHierarchy.end() )
00722     {
00723     return true;
00724     }
00725   return false;
00726 }
00727 
00728 //------------------------------------------------------------------------------
00729 inline void vtkStructuredAMRGridConnectivity::InsertGridAtLevel(
00730       const int level, const int gridID )
00731 {
00732   if( this->LevelExists( level ) )
00733     {
00734     this->AMRHierarchy[ level ].insert( gridID );
00735     }
00736   else
00737     {
00738     std::set<int> grids;
00739     grids.insert( gridID );
00740     this->AMRHierarchy[ level ] = grids;
00741     }
00742 }
00743 
00744 #endif /* VTKSTRUCTUREDAMRGRIDCONNECTIVITY_H_ */