vtkAMRDualGridHelper.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkAMRDualGridHelper.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
28 #ifndef vtkAMRDualGridHelper_h
29 #define vtkAMRDualGridHelper_h
30 
31 #include "vtkObject.h"
32 #include "vtkPVVTKExtensionsAMRModule.h" //needed for exports
33 #include <map>
34 #include <vector>
35 
36 class vtkDataArray;
37 class vtkIntArray;
38 class vtkIdTypeArray;
41 class vtkAMRDualGridHelperLevel;
43 class vtkImageData;
44 class vtkAMRDualGridHelperDegenerateRegion;
46 class vtkAMRDualGridHelperCommRequestList;
47 
48 //----------------------------------------------------------------------------
50 {
51 public:
52  static vtkAMRDualGridHelper* New();
54  void PrintSelf(ostream& os, vtkIndent indent) override;
55 
57 
63  vtkGetMacro(SkipGhostCopy, int);
64  vtkSetMacro(SkipGhostCopy, int);
65  vtkBooleanMacro(SkipGhostCopy, int);
67 
69 
73  vtkGetMacro(EnableDegenerateCells, int);
74  vtkSetMacro(EnableDegenerateCells, int);
75  vtkBooleanMacro(EnableDegenerateCells, int);
77 
79 
85  vtkGetMacro(EnableAsynchronousCommunication, int);
86  vtkSetMacro(EnableAsynchronousCommunication, int);
87  vtkBooleanMacro(EnableAsynchronousCommunication, int);
89 
91 
94  vtkGetObjectMacro(Controller, vtkMultiProcessController);
95  virtual void SetController(vtkMultiProcessController*);
97 
98  int Initialize(vtkNonOverlappingAMR* input);
99  int SetupData(vtkNonOverlappingAMR* input, const char* arrayName);
100  const double* GetGlobalOrigin() { return this->GlobalOrigin; }
101  const double* GetRootSpacing() { return this->RootSpacing; }
102  int GetNumberOfBlocks() { return this->NumberOfBlocksInThisProcess; }
103  int GetNumberOfLevels() { return (int)(this->Levels.size()); }
104  int GetNumberOfBlocksInLevel(int level);
105  vtkAMRDualGridHelperBlock* GetBlock(int level, int blockIdx);
106  vtkAMRDualGridHelperBlock* GetBlock(int level, int xGrid, int yGrid, int zGrid);
107 
118  void CopyDegenerateRegionBlockToBlock(int regionX, int regionY, int regionZ,
119  vtkAMRDualGridHelperBlock* lowResBlock, vtkDataArray* lowResArray,
120  vtkAMRDualGridHelperBlock* highResBlock, vtkDataArray* highResArray);
126  void QueueRegionRemoteCopy(int regionX, int regionY, int regionZ,
127  vtkAMRDualGridHelperBlock* lowResBlock, vtkDataArray* lowResArray,
128  vtkAMRDualGridHelperBlock* highResBlock, vtkDataArray* highResArray);
133  void ProcessRegionRemoteCopyQueue(bool hackLevelFlag);
137  void ClearRegionRemoteCopyQueue();
139 
142  vtkGetStringMacro(ArrayName);
144 
145 private:
147  ~vtkAMRDualGridHelper() override;
148 
149  char* ArrayName;
150  int DataTypeSize;
151  vtkSetStringMacro(ArrayName);
152 
153  // Distributed execution
154  void ShareMetaData();
155  void ShareBlocks();
156  void ShareBlocksWithNeighbors(vtkIntArray* neighbors);
157  void ShareBlocksWithNeighborsAsynchronous(vtkIntArray* neighbors);
158  void ShareBlocksWithNeighborsSynchronous(vtkIntArray* neighbors);
159  void MarshalBlocks(vtkIntArray* buffer);
160  void UnmarshalBlocks(vtkIntArray* buffer);
161  void UnmarshalBlocksFromOne(vtkIntArray* buffer, int blockProc);
162 
163  vtkMultiProcessController* Controller;
164  void ComputeGlobalMetaData(vtkNonOverlappingAMR* input);
165  void AddBlock(int level, int id, vtkImageData* volume);
166 
167  // Manage connectivity seeds between blocks.
168  void CreateFaces();
169  void FindExistingFaces(vtkAMRDualGridHelperBlock* block, int level, int x, int y, int z);
170 
171  // Assign shared cells between blocks and meshing
172  // changes in level.
173  void AssignSharedRegions();
174  void AssignBlockSharedRegions(
175  vtkAMRDualGridHelperBlock* block, int blockLevel, int blockX, int blockY, int blockZ);
176  int ClaimBlockSharedRegion(vtkAMRDualGridHelperBlock* block, int blockX, int blockY, int blockZ,
177  int regionX, int regionY, int regionZ);
178 
179  int NumberOfBlocksInThisProcess;
180 
181  // Cell dimension of block without ghost layers.
182  int StandardBlockDimensions[3];
183  double RootSpacing[3];
184 
185  // Global origin is chosen by ignoring ghost layers.
186  // All indexes will be positive.
187  // If we complete the ghost layer on boundary blocks,
188  // the ghost layer will still be positive.
189  double GlobalOrigin[3];
190 
191  // Each level will have a grid to help find neighbors.
192  std::vector<vtkAMRDualGridHelperLevel*> Levels;
193 
194  int EnableDegenerateCells;
195 
196  void ProcessRegionRemoteCopyQueueSynchronous(bool hackLevelFlag);
197  void SendDegenerateRegionsFromQueueSynchronous(int destProc, vtkIdType messageLength);
198  void ReceiveDegenerateRegionsFromQueueSynchronous(
199  int srcProc, vtkIdType messageLength, bool hackLevelFlag);
200 
201  // NOTE: These methods are NOT DEFINED if not compiled with MPI.
202  void ProcessRegionRemoteCopyQueueMPIAsynchronous(bool hackLevelFlag);
203  void SendDegenerateRegionsFromQueueMPIAsynchronous(
204  int recvProc, vtkIdType messageLength, vtkAMRDualGridHelperCommRequestList& sendList);
205  void ReceiveDegenerateRegionsFromQueueMPIAsynchronous(
206  int sendProc, vtkIdType messageLength, vtkAMRDualGridHelperCommRequestList& receiveList);
207  void FinishDegenerateRegionsCommMPIAsynchronous(bool hackLevelFlag,
208  vtkAMRDualGridHelperCommRequestList& sendList,
209  vtkAMRDualGridHelperCommRequestList& receiveList);
210 
211  // Degenerate regions that span processes. We keep them in a queue
212  // to communicate and process all at once.
213  std::vector<vtkAMRDualGridHelperDegenerateRegion> DegenerateRegionQueue;
214  void DegenerateRegionMessageSize(vtkIdTypeArray* srcProcs, vtkIdTypeArray* destProc);
215  void* CopyDegenerateRegionBlockToMessage(
216  const vtkAMRDualGridHelperDegenerateRegion& region, void* messagePtr);
217  const void* CopyDegenerateRegionMessageToBlock(
218  const vtkAMRDualGridHelperDegenerateRegion& region, const void* messagePtr, bool hackLevelFlag);
219  void MarshalDegenerateRegionMessage(void* messagePtr, int destProc);
220  void UnmarshalDegenerateRegionMessage(
221  const void* messagePtr, int messageLength, int srcProc, bool hackLevelFlag);
222 
223  int SkipGhostCopy;
224 
225  int EnableAsynchronousCommunication;
226 
227 private:
229  void operator=(const vtkAMRDualGridHelper&) = delete;
230 };
231 
232 // I need to define this small object in the namespace of this class.
233 
234 //----------------------------------------------------------------------------
235 // Is there a better way of defining these in the namespace?
236 #define vtkAMRRegionBitOwner 128
237 // mask: The first 7 bits are going to store the degenerate level difference.
238 #define vtkAMRRegionBitsDegenerateMask 127
240 {
241 public:
244 
245  void ResetRegionBits();
246  // We assume that all blocks have ghost levels and are the same
247  // dimension. The vtk spy reader strips the ghost cells on
248  // boundary blocks (on the outer surface of the data set).
249  // This method adds them back.
250  void AddBackGhostLevels(int standardBlockDimensions[3]);
251 
252  int Level;
253  int BlockId;
254 
255  // I am sick of looping over the grid to find the grid index
256  // of the blocks.
257  int GridIndex[3];
258 
259  // This is the global index of the origin of the image.
260  // This is important since not all blocks have ghost layers on minimum side.
261  // It appears that this is the origin of the ghost pixel if the image has a ghost pixel.
262  int OriginIndex[3];
263 
264  // The process that has the actual data (image).
266 
267  // If the block is local
269 
270  // How are we going to index faces.
272  void SetFace(int faceId, vtkAMRDualGridHelperFace* face);
273 
274  // This is set when we have a copy of the image.
275  // We need to modify the ghost layers of level interfaces.
276  unsigned char CopyFlag;
277 
278  // We have to assign cells shared between blocks so only one
279  // block will process them. Faces, edges and corners have to be
280  // considered separately (Extent does not work).
281  // If the two blocks are from different levels, then the higher
282  // level block always processes the cells. The high res cells
283  // are degenerate to mesh with low level neighbor cells.
284  // Save the assignment in the neighbor bits.
285  // The first bit means that this block processes these cells.
286  // The second bit is set when the neighbor has a lower resolution
287  // and points need to be placed in the lower grid.
288  // 3x3x3 neighborhood to get face, edge and corner neighbors.
289  unsigned char RegionBits[3][3][3];
290 
291  // Bits 1-6 are set if faces 1-6 are on boundary of dataset
292  // and have no neighbors.
293  unsigned char BoundaryBits;
294 
295  // Different algorithms need to store different information
296  // with the blocks. I could make this a vtkObject so the destructor
297  // would delete it.
298  void* UserData;
299 
300 private:
301 };
302 
303 //----------------------------------------------------------------------------
304 // Material surface point in the face. The point lies on an edge of the
305 // dual grid and has a material fraction array.
307 {
308 public:
311 
312  // Level is supplied externally.
313  // This is the index of the adjacent dual point in the object.
314  int Index[3];
316 
317 private:
318 };
319 
320 //----------------------------------------------------------------------------
321 // Neighbor interfaces (Faces) default to the lowest level (resolution) block.
322 // We do not actually care about the neighbor blocks yet.
324 {
325 public:
328 
329  // Sets Level, Origin and Normal axis from the parent block.
330  // Any block using the face will do as long as they have the same level.
331  void InheritBlockValues(vtkAMRDualGridHelperBlock* block, int faceIndex);
332 
333  // This is the lowest level of the two sides of the face.
334  int Level;
335  // This is the index of the face origin.
336  int OriginIndex[3];
337  // 0 = X, 1 = Y, 2 = Z.
339 
340  // Sparse array of points for equivalence computation.
341  std::vector<vtkAMRDualGridHelperSeed> FragmentIds;
342  void AddFragmentSeed(int level, int x, int y, int z, int fragmentId);
343 
344  // This is the number of blocks pointing to this face.
345  int UseCount;
346  // Decrement UseCount and delete if it hit 0.
347  void Unregister();
348 
349 private:
350 };
351 
352 #endif
353 
354 // VTK-HeaderTest-Exclude: vtkAMRDualGridHelper.h
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 &)