VTK
|
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_ */