VTK  9.3.1
vtkStructuredAMRGridConnectivity.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
22 #ifndef vtkStructuredAMRGridConnectivity_h
23 #define vtkStructuredAMRGridConnectivity_h
24 
26 #include "vtkFiltersGeometryModule.h" // For export macro
27 
28 #include "vtkStructuredAMRNeighbor.h" // For vtkStructuredAMRNeighbor def.
29 
30 // C++ includes
31 #include <map> // For STL map
32 #include <ostream> // For STL stream
33 #include <set> // For STL set
34 #include <vector> // For STL vector
35 
36 VTK_ABI_NAMESPACE_BEGIN
37 class VTKFILTERSGEOMETRY_EXPORT vtkStructuredAMRGridConnectivity
39 {
40 public:
43  void PrintSelf(ostream& os, vtkIndent indent) override;
44 
52  void Initialize(unsigned int NumberOfLevels, unsigned int N, int RefinementRatio = -1);
53 
57  void ComputeNeighbors() override;
58 
62  void CreateGhostLayers(int N = 1) override;
63 
69  virtual void RegisterGrid(int gridIdx, int level, int refinementRatio, int extents[6],
70  vtkUnsignedCharArray* nodesGhostArray, vtkUnsignedCharArray* cellGhostArray,
71  vtkPointData* pointData, vtkCellData* cellData, vtkPoints* gridNodes);
72 
78  virtual void RegisterGrid(int gridIdx, int level, int extents[6],
79  vtkUnsignedCharArray* nodesGhostArray, vtkUnsignedCharArray* cellGhostArray,
80  vtkPointData* pointData, vtkCellData* cellData, vtkPoints* gridNodes);
81 
83 
88  vtkSetMacro(BalancedRefinement, bool);
89  vtkGetMacro(BalancedRefinement, bool);
91 
93 
98  vtkSetMacro(NodeCentered, bool);
99  vtkGetMacro(NodeCentered, bool);
101 
103 
107  vtkSetMacro(CellCentered, bool);
108  vtkGetMacro(CellCentered, bool);
110 
115  int GetNumberOfNeighbors(int gridID);
116 
120  void GetGhostedExtent(int gridID, int ext[6]);
121 
125  vtkStructuredAMRNeighbor GetNeighbor(int gridID, int nei);
126 
127 protected:
130 
134  void SetNumberOfGrids(unsigned int N) override;
135 
139  void CreateGhostedMaskArrays(int gridID);
140 
144  void CreateGhostedExtent(int gridID, int N);
145 
149  void SetGhostedExtent(int gridID, int ext[6]);
150 
154  void GetCoarsenedExtent(int gridIdx, int fromLevel, int toLevel, int ext[6]);
155 
159  void GetRefinedExtent(int gridIdx, int fromLevel, int toLevel, int ext[6]);
160 
164  void RefineExtent(int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
165 
170  void GetCellRefinedExtent(
171  int orient[3], int ndim, int i, int j, int k, int fromLevel, int toLevel, int ext[6]);
172 
176  void CoarsenExtent(int orient[3], int ndim, int fromLevel, int toLevel, int ext[6]);
177 
181  void GetGridExtent(int gridIdx, int ext[6]);
182 
186  int GetGridLevel(int gridIdx);
187 
191  bool LevelExists(int level);
192 
196  bool IsNodeInterior(int i, int j, int k, int GridExtent[6]);
197 
201  bool IsNodeWithinExtent(int i, int j, int k, int GridExtent[6]);
202 
206  bool IsNodeOnSharedBoundary(int i, int j, int k, int gridId, int gridExt[6]);
207 
211  bool IsNodeOnBoundaryOfExtent(int i, int j, int k, int ext[6]);
212 
216  void InsertGridAtLevel(int level, int gridID);
217 
222  void ComputeNeighborSendAndRcvExtent(int gridID, int N);
223 
228  void ComputeWholeExtent();
229 
234  void GetWholeExtentAtLevel(int level, int ext[6]);
235 
240  void EstablishNeighbors(int i, int j);
241 
245  void GetNodeOrientation(int i, int j, int k, int gridExt[6], int nodeOrientation[3]);
246 
254  void GetOrientationVector(int dataDescription, int orient[3], int& ndim);
255 
259  bool HasConstantRefinementRatio();
260 
264  void SetRefinementRatioAtLevel(int level, int r);
265 
269  int GetRefinementRatioAtLevel(int level);
270 
274  bool AreExtentsEqual(int ext1[6], int ext2[6]);
275 
279  void SetBlockTopology(int gridID);
280 
288  int GetNumberOfConnectingBlockFaces(int gridID);
289 
291 
305  bool HasBlockConnection(int gridID, int blockDirection)
306  {
307  // Sanity check
308  assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
309  (gridID < static_cast<int>(this->NumberOfGrids)));
310  assert("pre: BlockTopology has not been properly allocated" &&
311  (this->NumberOfGrids == this->BlockTopology.size()));
312  assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
313  bool status = false;
314  if (this->BlockTopology[gridID] & (1 << blockDirection))
315  {
316  status = true;
317  }
318  return (status);
319  }
321 
336  void RemoveBlockConnection(int gridID, int blockDirection);
337 
352  void AddBlockConnection(int gridID, int blockDirection);
353 
358  void ClearBlockConnections(int gridID);
359 
363  virtual void MarkNodeProperty(
364  int gridId, int i, int j, int k, int gridExt[6], int wholeExt[6], unsigned char& p);
365 
369  virtual void FillNodesGhostArray(int gridId, vtkUnsignedCharArray* nodesArray);
370 
374  virtual void FillCellsGhostArray(int gridId, vtkUnsignedCharArray* cellsArray);
375 
379  void FillGhostArrays(
380  int gridId, vtkUnsignedCharArray* nodesArray, vtkUnsignedCharArray* cellsArray) override;
381 
393  vtkStructuredAMRNeighbor GetAMRNeighbor(int i, int iLevel, int next1[6], int j, int jLevel,
394  int next2[6], int normalizedLevel, int levelDiff, vtkStructuredNeighbor& nei);
395 
401  void ComputeAMRNeighborOverlapExtents(int iLevel, int jLevel, int normalizedLevel,
402  const vtkStructuredNeighbor& nei, int orient[3], int ndim, int gridOverlapExtent[6],
403  int neiOverlapExtent[6]);
404 
408  int Get1DOrientation(int idx, int ExtentLo, int ExtentHi, int OnLo, int OnHi, int NotOnBoundary);
409 
413  void PrintExtent(std::ostream& os, int ext[6]);
414 
418  void InitializeGhostData(int gridID);
419 
423  void TransferRegisteredDataToGhostedData(int gridID);
424 
428  void TransferLocalNodeCenteredNeighborData(int gridID, vtkStructuredAMRNeighbor& nei);
429 
434  void GetLocalCellCentersFromCoarserLevel(int gridID, vtkStructuredAMRNeighbor& nei);
435 
439  void GetLocalCellCentersFromFinerLevel(int gridID, vtkStructuredAMRNeighbor& nei);
440 
445  void GetLocalCellCentersAtSameLevel(int gridID, vtkStructuredAMRNeighbor& nei);
446 
450  void TransferLocalCellCenteredNeighborData(int gridID, vtkStructuredAMRNeighbor& nei);
451 
455  void TransferLocalNeighborData(int gridID, vtkStructuredAMRNeighbor& nei);
456 
460  virtual void TransferGhostDataFromNeighbors(int gridID);
461 
466  void AverageFieldData(
467  vtkFieldData* source, vtkIdType* sourceIds, int N, vtkFieldData* target, vtkIdType targetIdx);
468 
475  void CopyFieldData(
476  vtkFieldData* source, vtkIdType sourceIdx, vtkFieldData* target, vtkIdType targetIdx);
477 
478  unsigned int NumberOfLevels; // The total number of levels;
479  int DataDimension; // The dimension of the data, i.e. 2 or 3
480  int DataDescription; // The data description, i.e., VTK_XY_PLANE, etc.
481  int WholeExtent[6]; // The whole extent w.r.t. to the root level, level 0.
482  int MaxLevel; // The max level of the AMR hierarchy
483  int RefinementRatio; // The refinement ratio, set in the initialization,iff,
484  // a constant refinement ratio is used. A value of -1
485  // indicates that the refinement ratio is not constant
486  // and the RefinementRatios vector is used instead.
487 
488  bool NodeCentered; // Indicates if the data is node-centered
489  bool CellCentered; // Indicates if the data is cell-centered
490 
491  bool BalancedRefinement; // If Balanced refinement is true, then adjacent
492  // grids in the hierarchy can only differ by one
493  // level.
494 
495  // AMRHierarchy stores the set of grid Ids in [0,N] for each level
496  std::map<int, std::set<int>> AMRHierarchy;
497 
498  // For each grid, [0,N] store the grid extents,level, and list of neighbors
499  std::vector<int> GridExtents; // size of this vector is 6*N
500  std::vector<int> GhostedExtents; // size of this vector is 6*N
501  std::vector<unsigned char> BlockTopology; // size of this vector is N
502  std::vector<int> GridLevels; // size of this vector is N
503  std::vector<std::vector<vtkStructuredAMRNeighbor>> Neighbors;
504 
505  // For each grid, [0,N], store the donor level,grid and cell information, a
506  // DonorLevel of -1 indicates that the cell is not receiving any information
507  // from a donor.
508  std::vector<std::vector<int>> CellCenteredDonorLevel;
509 
510  // RefinementRatios stores the refinement ratio at each level, this vector
511  // is used only when the refinement ratio varies across levels
512  std::vector<int> RefinementRatios;
513 
514 private:
516  void operator=(const vtkStructuredAMRGridConnectivity&) = delete;
517 };
518 
519 //=============================================================================
520 // INLINE METHODS
521 //=============================================================================
522 
523 //------------------------------------------------------------------------------
525 {
526  assert("pre: grid ID is out-of-bounds" && (gridID >= 0) &&
527  (gridID < static_cast<int>(this->NumberOfGrids)));
528  assert("pre: neighbors vector has not been properly allocated" &&
529  (this->Neighbors.size() == this->NumberOfGrids));
530  return (static_cast<int>(this->Neighbors[gridID].size()));
531 }
532 
533 //------------------------------------------------------------------------------
535 {
536  assert("pre: grid ID is out-of-bounds" && (gridID >= 0) &&
537  (gridID < static_cast<int>(this->NumberOfGrids)));
538  assert("pre: neighbors vector has not been properly allocated" &&
539  (this->Neighbors.size() == this->NumberOfGrids));
540  assert("pre: nei index is out-of-bounds" && (nei >= 0) &&
541  (nei < static_cast<int>(this->Neighbors[gridID].size())));
542  return (this->Neighbors[gridID][nei]);
543 }
544 
545 //------------------------------------------------------------------------------
547  int idx, int ExtentLo, int ExtentHi, int OnLo, int OnHi, int NotOnBoundary)
548 {
549  if (idx == ExtentLo)
550  {
551  return OnLo;
552  }
553  else if (idx == ExtentHi)
554  {
555  return OnHi;
556  }
557  return NotOnBoundary;
558 }
559 
560 //------------------------------------------------------------------------------
562 {
563  // Sanity check
564  assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
565  (gridID < static_cast<int>(this->NumberOfGrids)));
566  assert("pre: BlockTopology has not been properly allocated" &&
567  (this->NumberOfGrids == this->BlockTopology.size()));
568 
569  int count = 0;
570  for (int i = 0; i < 6; ++i)
571  {
572  if (this->HasBlockConnection(gridID, i))
573  {
574  ++count;
575  }
576  }
577  assert("post: count must be in [0,5]" && (count >= 0 && count <= 6));
578  return (count);
579 }
580 
581 //------------------------------------------------------------------------------
582 inline void vtkStructuredAMRGridConnectivity::RemoveBlockConnection(int gridID, int blockDirection)
583 {
584  // Sanity check
585  assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
586  (gridID < static_cast<int>(this->NumberOfGrids)));
587  assert("pre: BlockTopology has not been properly allocated" &&
588  (this->NumberOfGrids == this->BlockTopology.size()));
589  assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
590 
591  this->BlockTopology[gridID] &= ~(1 << blockDirection);
592 }
593 
594 //------------------------------------------------------------------------------
595 inline void vtkStructuredAMRGridConnectivity::AddBlockConnection(int gridID, int blockDirection)
596 {
597  // Sanity check
598  assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
599  (gridID < static_cast<int>(this->NumberOfGrids)));
600  assert("pre: BlockTopology has not been properly allocated" &&
601  (this->NumberOfGrids == this->BlockTopology.size()));
602  assert("pre: blockDirection is out-of-bounds" && (blockDirection >= 0) && (blockDirection < 6));
603  this->BlockTopology[gridID] |= (1 << blockDirection);
604 }
605 
606 //------------------------------------------------------------------------------
608 {
609  // Sanity check
610  assert("pre: gridID is out-of-bounds" && (gridID >= 0) &&
611  (gridID < static_cast<int>(this->NumberOfGrids)));
612  assert("pre: BlockTopology has not been properly allocated" &&
613  (this->NumberOfGrids == this->BlockTopology.size()));
614  for (int i = 0; i < 6; ++i)
615  {
616  this->RemoveBlockConnection(gridID, i);
617  } // END for all block directions
618 }
619 
620 //------------------------------------------------------------------------------
621 inline bool vtkStructuredAMRGridConnectivity::AreExtentsEqual(int ext1[6], int ext2[6])
622 {
623  for (int i = 0; i < 6; ++i)
624  {
625  if (ext1[i] != ext2[i])
626  {
627  return false;
628  }
629  } // END for
630  return true;
631 }
632 
633 //------------------------------------------------------------------------------
634 inline void vtkStructuredAMRGridConnectivity::PrintExtent(std::ostream& os, int ext[6])
635 {
636  for (int i = 0; i < 6; i += 2)
637  {
638  os << "[";
639  os << ext[i] << " ";
640  os << ext[i + 1] << "] ";
641  } // END for
642 }
643 
644 //------------------------------------------------------------------------------
646 {
647  assert("pre: grid Index is out-of-bounds!" && (gridIdx < static_cast<int>(this->NumberOfGrids)));
648  assert("pre: grid levels vector has not been allocated" &&
649  (this->GridLevels.size() == this->NumberOfGrids));
650  return (this->GridLevels[gridIdx]);
651 }
652 
653 //------------------------------------------------------------------------------
655 {
656  assert("pre: RefinementRatios vector is not properly allocated" &&
657  this->RefinementRatios.size() == this->NumberOfLevels);
658  assert("pre: leve is out-of-bounds!" && (level >= 0) &&
659  (level < static_cast<int>(this->RefinementRatios.size())));
660  assert("pre: invalid refinement ratio" && (r >= 2));
661 
662  this->RefinementRatios[level] = r;
663 }
664 
665 //------------------------------------------------------------------------------
667 {
668  assert("pre: RefinementRatios vector is not properly allocated" &&
669  this->RefinementRatios.size() == this->NumberOfLevels);
670  assert("pre: leve is out-of-bounds!" && (level >= 0) &&
671  (level < static_cast<int>(this->RefinementRatios.size())));
672  assert(
673  "pre: refinement ratio for level has not been set" && (this->RefinementRatios[level] >= 2));
674 
675  return (this->RefinementRatios[level]);
676 }
677 
678 //------------------------------------------------------------------------------
680 {
681  if (this->RefinementRatio < 2)
682  {
683  return false;
684  }
685  return true;
686 }
687 
688 //------------------------------------------------------------------------------
689 inline void vtkStructuredAMRGridConnectivity::GetGridExtent(int gridIdx, int ext[6])
690 {
691  assert("pre: grid index is out-of-bounds" &&
692  ((gridIdx >= 0) && (gridIdx < static_cast<int>(this->GridExtents.size()))));
693 
694  for (int i = 0; i < 6; ++i)
695  {
696  ext[i] = this->GridExtents[gridIdx * 6 + i];
697  }
698 }
699 
700 //------------------------------------------------------------------------------
702 {
703  if (this->AMRHierarchy.find(level) != this->AMRHierarchy.end())
704  {
705  return true;
706  }
707  return false;
708 }
709 
710 //------------------------------------------------------------------------------
712 {
713  if (this->LevelExists(level))
714  {
715  this->AMRHierarchy[level].insert(gridID);
716  }
717  else
718  {
719  std::set<int> grids;
720  grids.insert(gridID);
721  this->AMRHierarchy[level] = grids;
722  }
723 }
724 
725 VTK_ABI_NAMESPACE_END
726 #endif /* VTKSTRUCTUREDAMRGRIDCONNECTIVITY_H_ */
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
int GetGridLevel(int gridIdx)
Returns the level of the grid with the corresponding grid ID.
vtkStructuredAMRNeighbor GetNeighbor(int gridID, int nei)
Returns the AMR neighbor for the patch with the corresponding grid ID.
void RemoveBlockConnection(int gridID, int blockDirection)
Removes a block connection along the given direction for the block corresponding to the given gridID...
bool HasBlockConnection(int gridID, int blockDirection)
Checks if the block corresponding to the given grid ID has a block adjacent to it in the given block ...
represent and manipulate point attribute data
Definition: vtkPointData.h:29
void GetGridExtent(int gridIdx, int ext[6])
Gets the grid extent for the grid with the given grid ID.
bool LevelExists(int level)
Checks if the given level has been registered.
std::map< int, std::set< int > > AMRHierarchy
virtual void ComputeNeighbors()=0
Computes the grid neighboring topology for the domain.
represent and manipulate cell attribute data
Definition: vtkCellData.h:30
std::vector< std::vector< int > > CellCenteredDonorLevel
int vtkIdType
Definition: vtkType.h:315
int Get1DOrientation(int idx, int ExtentLo, int ExtentHi, int OnLo, int OnHi, int NotOnBoundary)
Get 1-D orientation.
void SetRefinementRatioAtLevel(int level, int r)
Sets the refinement ratio at the given level.
int GetNumberOfNeighbors(int gridID)
Returns the number of neighbors for the grid corresponding to the given grid ID.
a simple class to control print indentation
Definition: vtkIndent.h:28
int GetNumberOfConnectingBlockFaces(int gridID)
Returns the number of faces of the block corresponding to the given grid ID that are adjacent to at l...
boost::graph_traits< vtkGraph * >::vertex_descriptor target(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
A superclass that defines the interface to be implemented by all concrete grid connectivity classes...
virtual void CreateGhostLayers(int N=1)=0
Creates N layers of ghost layers where N is the number of cells that will be added to each grid...
void ClearBlockConnections(int gridID)
Clears all block connections for the block corresponding to the given grid ID.
virtual void SetNumberOfGrids(unsigned int N)=0
Sets the total number of grids in the domain.
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
dynamic, self-adjusting array of unsigned char
An internal, light-weight class used to store neighbor information.
void PrintExtent(std::ostream &os, int ext[6])
Prints the extent.
void InsertGridAtLevel(int level, int gridID)
Inserts the grid corresponding to the given ID at the prescribed level.
std::vector< std::vector< vtkStructuredAMRNeighbor > > Neighbors
An internal, light-weight object used to store neighbor information for AMR grids.
virtual void FillGhostArrays(int gridId, vtkUnsignedCharArray *nodesArray, vtkUnsignedCharArray *cellsArray)=0
Fills the ghost arrays for the given grid.
void AddBlockConnection(int gridID, int blockDirection)
Adds a block connection along the given direction for the block corresponding to the given gridID...
static vtkObject * New()
Create an object with Debug turned off, modified time initialized to zero, and reference counting on...
int GetRefinementRatioAtLevel(int level)
Returns the refinement ratio at the given level.
bool AreExtentsEqual(int ext1[6], int ext2[6])
Checks if the extent ext1 and ext2 are equal.
bool HasConstantRefinementRatio()
Checks if a constant refinement ratio has been specified.
represent and manipulate 3D points
Definition: vtkPoints.h:28
represent and manipulate fields of data
Definition: vtkFieldData.h:51