vtkAMRDualGridHelper.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
3 // SPDX-License-Identifier: BSD-3-Clause
17 #ifndef vtkAMRDualGridHelper_h
18 #define vtkAMRDualGridHelper_h
19 
20 #include "vtkObject.h"
21 #include "vtkPVVTKExtensionsAMRModule.h" //needed for exports
22 #include <vector> // for std::vector
23 
24 class vtkDataArray;
25 class vtkIntArray;
26 class vtkIdTypeArray;
29 class vtkAMRDualGridHelperLevel;
31 class vtkImageData;
32 class vtkAMRDualGridHelperDegenerateRegion;
34 class vtkAMRDualGridHelperCommRequestList;
35 
36 //----------------------------------------------------------------------------
38 {
39 public:
40  static vtkAMRDualGridHelper* New();
42  void PrintSelf(ostream& os, vtkIndent indent) override;
43 
45 
51  vtkGetMacro(SkipGhostCopy, int);
52  vtkSetMacro(SkipGhostCopy, int);
53  vtkBooleanMacro(SkipGhostCopy, int);
55 
57 
61  vtkGetMacro(EnableDegenerateCells, int);
62  vtkSetMacro(EnableDegenerateCells, int);
63  vtkBooleanMacro(EnableDegenerateCells, int);
65 
67 
73  vtkGetMacro(EnableAsynchronousCommunication, int);
74  vtkSetMacro(EnableAsynchronousCommunication, int);
75  vtkBooleanMacro(EnableAsynchronousCommunication, int);
77 
79 
82  vtkGetObjectMacro(Controller, vtkMultiProcessController);
83  virtual void SetController(vtkMultiProcessController*);
85 
86  int Initialize(vtkNonOverlappingAMR* input);
87  int SetupData(vtkNonOverlappingAMR* input, const char* arrayName);
88  const double* GetGlobalOrigin() { return this->GlobalOrigin; }
89  const double* GetRootSpacing() { return this->RootSpacing; }
90  int GetNumberOfBlocks() { return this->NumberOfBlocksInThisProcess; }
91  int GetNumberOfLevels() { return (int)(this->Levels.size()); }
92  int GetNumberOfBlocksInLevel(int level);
93  vtkAMRDualGridHelperBlock* GetBlock(int level, int blockIdx);
94  vtkAMRDualGridHelperBlock* GetBlock(int level, int xGrid, int yGrid, int zGrid);
95 
106  void CopyDegenerateRegionBlockToBlock(int regionX, int regionY, int regionZ,
107  vtkAMRDualGridHelperBlock* lowResBlock, vtkDataArray* lowResArray,
108  vtkAMRDualGridHelperBlock* highResBlock, vtkDataArray* highResArray);
114  void QueueRegionRemoteCopy(int regionX, int regionY, int regionZ,
115  vtkAMRDualGridHelperBlock* lowResBlock, vtkDataArray* lowResArray,
116  vtkAMRDualGridHelperBlock* highResBlock, vtkDataArray* highResArray);
121  void ProcessRegionRemoteCopyQueue(bool hackLevelFlag);
125  void ClearRegionRemoteCopyQueue();
127 
130  vtkGetStringMacro(ArrayName);
132 
133 private:
135  ~vtkAMRDualGridHelper() override;
136 
137  char* ArrayName;
138  int DataTypeSize;
139  vtkSetStringMacro(ArrayName);
140 
141  // Distributed execution
142  void ShareMetaData();
143  void ShareBlocks();
144  void ShareBlocksWithNeighbors(vtkIntArray* neighbors);
145  void ShareBlocksWithNeighborsAsynchronous(vtkIntArray* neighbors);
146  void ShareBlocksWithNeighborsSynchronous(vtkIntArray* neighbors);
147  void MarshalBlocks(vtkIntArray* buffer);
148  void UnmarshalBlocks(vtkIntArray* buffer);
149  void UnmarshalBlocksFromOne(vtkIntArray* buffer, int blockProc);
150 
151  vtkMultiProcessController* Controller;
152  void ComputeGlobalMetaData(vtkNonOverlappingAMR* input);
153  void AddBlock(int level, int id, vtkImageData* volume);
154 
155  // Manage connectivity seeds between blocks.
156  void CreateFaces();
157  void FindExistingFaces(vtkAMRDualGridHelperBlock* block, int level, int x, int y, int z);
158 
159  // Assign shared cells between blocks and meshing
160  // changes in level.
161  void AssignSharedRegions();
162  void AssignBlockSharedRegions(
163  vtkAMRDualGridHelperBlock* block, int blockLevel, int blockX, int blockY, int blockZ);
164  int ClaimBlockSharedRegion(vtkAMRDualGridHelperBlock* block, int blockX, int blockY, int blockZ,
165  int regionX, int regionY, int regionZ);
166 
167  int NumberOfBlocksInThisProcess;
168 
169  // Cell dimension of block without ghost layers.
170  int StandardBlockDimensions[3];
171  double RootSpacing[3];
172 
173  // Global origin is chosen by ignoring ghost layers.
174  // All indexes will be positive.
175  // If we complete the ghost layer on boundary blocks,
176  // the ghost layer will still be positive.
177  double GlobalOrigin[3];
178 
179  // Each level will have a grid to help find neighbors.
180  std::vector<vtkAMRDualGridHelperLevel*> Levels;
181 
182  int EnableDegenerateCells;
183 
184  void ProcessRegionRemoteCopyQueueSynchronous(bool hackLevelFlag);
185  void SendDegenerateRegionsFromQueueSynchronous(int destProc, vtkIdType messageLength);
186  void ReceiveDegenerateRegionsFromQueueSynchronous(
187  int srcProc, vtkIdType messageLength, bool hackLevelFlag);
188 
189  // NOTE: These methods are NOT DEFINED if not compiled with MPI.
190  void ProcessRegionRemoteCopyQueueMPIAsynchronous(bool hackLevelFlag);
191  void SendDegenerateRegionsFromQueueMPIAsynchronous(
192  int recvProc, vtkIdType messageLength, vtkAMRDualGridHelperCommRequestList& sendList);
193  void ReceiveDegenerateRegionsFromQueueMPIAsynchronous(
194  int sendProc, vtkIdType messageLength, vtkAMRDualGridHelperCommRequestList& receiveList);
195  void FinishDegenerateRegionsCommMPIAsynchronous(bool hackLevelFlag,
196  vtkAMRDualGridHelperCommRequestList& sendList,
197  vtkAMRDualGridHelperCommRequestList& receiveList);
198 
199  // Degenerate regions that span processes. We keep them in a queue
200  // to communicate and process all at once.
201  std::vector<vtkAMRDualGridHelperDegenerateRegion> DegenerateRegionQueue;
202  void DegenerateRegionMessageSize(vtkIdTypeArray* srcProcs, vtkIdTypeArray* destProc);
203  void* CopyDegenerateRegionBlockToMessage(
204  const vtkAMRDualGridHelperDegenerateRegion& region, void* messagePtr);
205  const void* CopyDegenerateRegionMessageToBlock(
206  const vtkAMRDualGridHelperDegenerateRegion& region, const void* messagePtr, bool hackLevelFlag);
207  void MarshalDegenerateRegionMessage(void* messagePtr, int destProc);
208  void UnmarshalDegenerateRegionMessage(
209  const void* messagePtr, int messageLength, int srcProc, bool hackLevelFlag);
210 
211  int SkipGhostCopy;
212 
213  int EnableAsynchronousCommunication;
214 
216  void operator=(const vtkAMRDualGridHelper&) = delete;
217 };
218 
219 // I need to define this small object in the namespace of this class.
220 
221 //----------------------------------------------------------------------------
222 // Is there a better way of defining these in the namespace?
223 #define vtkAMRRegionBitOwner 128
224 // mask: The first 7 bits are going to store the degenerate level difference.
225 #define vtkAMRRegionBitsDegenerateMask 127
227 {
228 public:
231 
232  void ResetRegionBits();
233  // We assume that all blocks have ghost levels and are the same
234  // dimension. The vtk spy reader strips the ghost cells on
235  // boundary blocks (on the outer surface of the data set).
236  // This method adds them back.
237  void AddBackGhostLevels(int standardBlockDimensions[3]);
238 
239  int Level;
240  int BlockId;
241 
242  // I am sick of looping over the grid to find the grid index
243  // of the blocks.
244  int GridIndex[3];
245 
246  // This is the global index of the origin of the image.
247  // This is important since not all blocks have ghost layers on minimum side.
248  // It appears that this is the origin of the ghost pixel if the image has a ghost pixel.
249  int OriginIndex[3];
250 
251  // The process that has the actual data (image).
253 
254  // If the block is local
256 
257  // How are we going to index faces.
259  void SetFace(int faceId, vtkAMRDualGridHelperFace* face);
260 
261  // This is set when we have a copy of the image.
262  // We need to modify the ghost layers of level interfaces.
263  unsigned char CopyFlag;
264 
265  // We have to assign cells shared between blocks so only one
266  // block will process them. Faces, edges and corners have to be
267  // considered separately (Extent does not work).
268  // If the two blocks are from different levels, then the higher
269  // level block always processes the cells. The high res cells
270  // are degenerate to mesh with low level neighbor cells.
271  // Save the assignment in the neighbor bits.
272  // The first bit means that this block processes these cells.
273  // The second bit is set when the neighbor has a lower resolution
274  // and points need to be placed in the lower grid.
275  // 3x3x3 neighborhood to get face, edge and corner neighbors.
276  unsigned char RegionBits[3][3][3];
277 
278  // Bits 1-6 are set if faces 1-6 are on boundary of dataset
279  // and have no neighbors.
280  unsigned char BoundaryBits;
281 
282  // Different algorithms need to store different information
283  // with the blocks. I could make this a vtkObject so the destructor
284  // would delete it.
285  void* UserData;
286 
287 private:
288 };
289 
290 //----------------------------------------------------------------------------
291 // Material surface point in the face. The point lies on an edge of the
292 // dual grid and has a material fraction array.
294 {
295 public:
297  ~vtkAMRDualGridHelperSeed() = default;
298 
299  // Level is supplied externally.
300  // This is the index of the adjacent dual point in the object.
301  int Index[3];
303 
304 private:
305 };
306 
307 //----------------------------------------------------------------------------
308 // Neighbor interfaces (Faces) default to the lowest level (resolution) block.
309 // We do not actually care about the neighbor blocks yet.
311 {
312 public:
315 
316  // Sets Level, Origin and Normal axis from the parent block.
317  // Any block using the face will do as long as they have the same level.
318  void InheritBlockValues(vtkAMRDualGridHelperBlock* block, int faceIndex);
319 
320  // This is the lowest level of the two sides of the face.
321  int Level;
322  // This is the index of the face origin.
323  int OriginIndex[3];
324  // 0 = X, 1 = Y, 2 = Z.
326 
327  // Sparse array of points for equivalence computation.
328  std::vector<vtkAMRDualGridHelperSeed> FragmentIds;
329  void AddFragmentSeed(int level, int x, int y, int z, int fragmentId);
330 
331  // This is the number of blocks pointing to this face.
332  int UseCount;
333  // Decrement UseCount and delete if it hit 0.
334  void Unregister();
335 
336 private:
337 };
338 
339 #endif
level
void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
int vtkIdType
#define VTKPVVTKEXTENSIONSAMR_EXPORT
Tools for processing AMR as a dual grid.
const double * GetGlobalOrigin()
const double * GetRootSpacing()
std::vector< vtkAMRDualGridHelperSeed > FragmentIds
static vtkObject * New()
void operator=(const vtkObjectBase &)