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