1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkAMRResampleFilter.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 =========================================================================*/ 15 /** 16 * @class vtkAMRResampleFilter 17 * 18 * 19 * This filter is a concrete instance of vtkMultiBlockDataSetAlgorithm and 20 * provides functionality for extracting portion of the AMR dataset, specified 21 * by a bounding box, in a uniform grid of the desired level of resolution. 22 * The resulting uniform grid is stored in a vtkMultiBlockDataSet where the 23 * number of blocks correspond to the number of processors utilized for the 24 * operation. 25 * 26 * @warning 27 * Data of the input AMR dataset is assumed to be cell-centered. 28 * 29 * @sa 30 * vtkOverlappingAMR, vtkUniformGrid 31 */ 32 33 #ifndef vtkAMRResampleFilter_h 34 #define vtkAMRResampleFilter_h 35 36 #include "vtkFiltersAMRModule.h" // For export macro 37 #include "vtkMultiBlockDataSetAlgorithm.h" 38 #include <vector> // For STL vector 39 40 class vtkInformation; 41 class vtkInformationVector; 42 class vtkUniformGrid; 43 class vtkOverlappingAMR; 44 class vtkMultiBlockDataSet; 45 class vtkMultiProcessController; 46 class vtkFieldData; 47 class vtkCellData; 48 class vtkPointData; 49 class vtkIndent; 50 51 class vtkAMRBox; 52 class VTKFILTERSAMR_EXPORT vtkAMRResampleFilter : public vtkMultiBlockDataSetAlgorithm 53 { 54 public: 55 static vtkAMRResampleFilter* New(); 56 vtkTypeMacro(vtkAMRResampleFilter, vtkMultiBlockDataSetAlgorithm); 57 void PrintSelf(ostream& oss, vtkIndent indent) override; 58 59 ///@{ 60 /** 61 * Set & Get macro for the number of samples (cells) in each dimension. 62 * Nominal value for the number of samples is 10x10x10. 63 */ 64 vtkSetVector3Macro(NumberOfSamples, int); 65 vtkGetVector3Macro(NumberOfSamples, int); 66 ///@} 67 68 ///@{ 69 /** 70 * Set & Get macro for the TransferToNodes flag 71 */ 72 vtkSetMacro(TransferToNodes, int); 73 vtkGetMacro(TransferToNodes, int); 74 ///@} 75 76 ///@{ 77 /** 78 * Set & Get macro to allow the filter to operate in both demand-driven 79 * and standard modes 80 */ 81 vtkSetMacro(DemandDrivenMode, int); 82 vtkGetMacro(DemandDrivenMode, int); 83 ///@} 84 85 ///@{ 86 /** 87 * Set & Get macro for the number of subdivisions 88 */ 89 vtkSetMacro(NumberOfPartitions, int); 90 vtkGetMacro(NumberOfPartitions, int); 91 ///@} 92 93 ///@{ 94 /** 95 * Set and Get the min corner 96 */ 97 vtkSetVector3Macro(Min, double); 98 vtkGetVector3Macro(Min, double); 99 ///@} 100 101 ///@{ 102 /** 103 * Set and Get the max corner 104 */ 105 vtkSetVector3Macro(Max, double); 106 vtkGetVector3Macro(Max, double); 107 ///@} 108 109 ///@{ 110 /** 111 * Set & Get macro for the number of subdivisions 112 */ 113 vtkSetMacro(UseBiasVector, bool); 114 vtkGetMacro(UseBiasVector, bool); 115 ///@} 116 117 ///@{ 118 /** 119 * Set and Get the bias vector. If UseBiasVector is true 120 * then the largest component of this vector can not have 121 * the max number of samples 122 */ 123 vtkSetVector3Macro(BiasVector, double); 124 vtkGetVector3Macro(BiasVector, double); 125 ///@} 126 127 ///@{ 128 /** 129 * Set & Get macro for the multi-process controller 130 */ 131 vtkSetMacro(Controller, vtkMultiProcessController*); 132 vtkGetMacro(Controller, vtkMultiProcessController*); 133 ///@} 134 135 // Standard pipeline routines 136 137 /** 138 * Gets the metadata from upstream module and determines which blocks 139 * should be loaded by this instance. 140 */ 141 int RequestInformation(vtkInformation* rqst, vtkInformationVector** inputVector, 142 vtkInformationVector* outputVector) override; 143 144 int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 145 int FillInputPortInformation(int port, vtkInformation* info) override; 146 int FillOutputPortInformation(int port, vtkInformation* info) override; 147 148 /** 149 * Performs upstream requests to the reader 150 */ 151 int RequestUpdateExtent(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 152 153 protected: 154 vtkAMRResampleFilter(); 155 ~vtkAMRResampleFilter() override; 156 157 vtkOverlappingAMR* AMRMetaData; 158 vtkMultiBlockDataSet* ROI; // Pointer to the region of interest. 159 int NumberOfSamples[3]; 160 int GridNumberOfSamples[3]; 161 double Min[3]; 162 double Max[3]; 163 double GridMin[3]; 164 double GridMax[3]; 165 int LevelOfResolution; 166 int NumberOfPartitions; 167 int TransferToNodes; 168 int DemandDrivenMode; 169 vtkMultiProcessController* Controller; 170 bool UseBiasVector; 171 double BiasVector[3]; 172 173 // Debugging Stuff 174 int NumberOfBlocksTestedForLevel; 175 int NumberOfBlocksTested; 176 int NumberOfBlocksVisSkipped; 177 int NumberOfTimesFoundOnDonorLevel; 178 int NumberOfTimesLevelUp; 179 int NumberOfTimesLevelDown; 180 int NumberOfFailedPoints; 181 double AverageLevel; 182 183 std::vector<int> BlocksToLoad; // Holds the ids of the blocks to load. 184 185 /** 186 * Checks if this filter instance is running on more than one processes 187 */ 188 bool IsParallel(); 189 190 /** 191 * Given the Region ID this function returns whether or not the region 192 * belongs to this process or not. 193 */ 194 bool IsRegionMine(const int regionIdx); 195 196 /** 197 * Given the Region ID, this method computes the corresponding process ID 198 * that owns the region based on static block-cyclic distribution. 199 */ 200 int GetRegionProcessId(const int regionIdx); 201 202 /** 203 * Given a cell index and a grid, this method computes the cell centroid. 204 */ 205 void ComputeCellCentroid(vtkUniformGrid* g, const vtkIdType cellIdx, double c[3]); 206 207 /** 208 * Given the source cell data of an AMR grid, this method initializes the 209 * field values, i.e., the number of arrays with the prescribed size. Note, 210 * the size must correspond to the number of points if node-centered or the 211 * the number of cells if cell-centered. 212 */ 213 void InitializeFields(vtkFieldData* f, vtkIdType size, vtkCellData* src); 214 215 /** 216 * Copies the data to the target from the given source. 217 */ 218 void CopyData(vtkFieldData* target, vtkIdType targetIdx, vtkCellData* src, vtkIdType srcIdx); 219 220 /** 221 * Given a query point q and a candidate donor grid, this method checks for 222 * the corresponding donor cell containing the point in the given grid. 223 */ 224 bool FoundDonor(double q[3], vtkUniformGrid*& donorGrid, int& cellIdx); 225 226 /** 227 * Given a query point q and a target level, this method finds a suitable 228 * grid at the given level that contains the point if one exists. If a grid 229 * is not found, donorGrid is set to nullptr. 230 */ 231 bool SearchForDonorGridAtLevel(double q[3], vtkOverlappingAMR* amrds, unsigned int level, 232 unsigned int& gridId, int& donorCellIdx); 233 234 /** 235 * Finds the AMR grid that contains the point q. If donorGrid points to a 236 * valid AMR grid in the hierarchy, the algorithm will search this grid 237 * first. The method returns the ID of the cell w.r.t. the donorGrid that 238 * contains the probe point q. 239 */ 240 int ProbeGridPointInAMR(double q[3], unsigned int& donorLevel, unsigned int& donorGridId, 241 vtkOverlappingAMR* amrds, unsigned int maxLevel, bool hadDonorGrid); 242 243 /** 244 * Finds the AMR grid that contains the point q. If donorGrid points to a 245 * valid AMR grid in the hierarchy, the algorithm will search this grid 246 * first. The method returns the ID of the cell w.r.t. the donorGrid that 247 * contains the probe point q. - Makes use of Parent/Child Info 248 */ 249 int ProbeGridPointInAMRGraph(double q[3], unsigned int& donorLevel, unsigned int& donorGridId, 250 vtkOverlappingAMR* amrds, unsigned int maxLevel, bool useCached); 251 252 /** 253 * Transfers the solution from the AMR dataset to the cell-centers of 254 * the given uniform grid. 255 */ 256 void TransferToCellCenters(vtkUniformGrid* g, vtkOverlappingAMR* amrds); 257 258 /** 259 * Transfer the solution from the AMR dataset to the nodes of the 260 * given uniform grid. 261 */ 262 void TransferToGridNodes(vtkUniformGrid* g, vtkOverlappingAMR* amrds); 263 264 /** 265 * Transfers the solution 266 */ 267 void TransferSolution(vtkUniformGrid* g, vtkOverlappingAMR* amrds); 268 269 /** 270 * Extract the region (as a multiblock) from the given AMR dataset. 271 */ 272 void ExtractRegion( 273 vtkOverlappingAMR* amrds, vtkMultiBlockDataSet* mbds, vtkOverlappingAMR* metadata); 274 275 /** 276 * Checks if the AMR block, described by a uniform grid, is within the 277 * bounds of the ROI perscribed by the user. 278 */ 279 bool IsBlockWithinBounds(double* grd); 280 281 /** 282 * Given a user-supplied region of interest and the metadata by a module 283 * upstream, this method generates the list of linear AMR block indices 284 * that need to be loaded. 285 */ 286 void ComputeAMRBlocksToLoad(vtkOverlappingAMR* metadata); 287 288 /** 289 * Computes the region parameters 290 */ 291 void ComputeRegionParameters( 292 vtkOverlappingAMR* amrds, int N[3], double min[3], double max[3], double h[3]); 293 294 /** 295 * This method accesses the domain boundaries 296 */ 297 void GetDomainParameters(vtkOverlappingAMR* amr, double domainMin[3], double domainMax[3], 298 double h[3], int dims[3], double& rf); 299 300 /** 301 * Checks if the domain and requested region intersect. 302 */ 303 bool RegionIntersectsWithAMR( 304 double domainMin[3], double domainMax[3], double regionMin[3], double regionMax[3]); 305 306 /** 307 * This method adjust the numbers of samples in the region, N, if the 308 * requested region falls outside, but, intersects the domain. 309 */ 310 void AdjustNumberOfSamplesInRegion(const double Rh[3], const bool outside[6], int N[3]); 311 312 /** 313 * This method computes the level of resolution based on the number of 314 * samples requested, N, the root level spacing h0, the length of the box, 315 * L (actual length after snapping) and the refinement ratio. 316 */ 317 void ComputeLevelOfResolution( 318 const int N[3], const double h0[3], const double L[3], const double rf); 319 320 /** 321 * This method snaps the bounds s.t. they are within the interior of the 322 * domain described the root level uniform grid with h0, domainMin and 323 * domain Max. The method computes and returns the new min/max bounds and 324 * the corresponding ijkmin/ijkmax coordinates w.r.t. the root level. 325 */ 326 void SnapBounds(const double h0[3], const double domainMin[3], const double domainMax[3], 327 const int dims[3], bool outside[6]); 328 329 /** 330 * This method computes and adjusts the region parameters s.t. the requested 331 * region always fall within the AMR region and the number of samples is 332 * adjusted if the region of interest moves outsided the domain. 333 */ 334 void ComputeAndAdjustRegionParameters(vtkOverlappingAMR* amrds, double h[3]); 335 336 /** 337 * This method gets the region of interest as perscribed by the user. 338 */ 339 void GetRegion(double h[3]); 340 341 /** 342 * Checks if two uniform grids intersect. 343 */ 344 bool GridsIntersect(double* g1, double* g2); 345 346 /** 347 * Returns a reference grid from the amrdataset. 348 */ 349 vtkUniformGrid* GetReferenceGrid(vtkOverlappingAMR* amrds); 350 351 /** 352 * Writes a uniform grid to a file. Used for debugging purposes. 353 * void WriteUniformGrid( vtkUniformGrid *g, std::string prefix ); 354 * void WriteUniformGrid( 355 * double origin[3], int dims[3], double h[3], 356 * std::string prefix ); 357 */ 358 359 /** 360 * Find a descendant of the specified grid that contains the point. 361 * If none is found then the original grid information is returned. 362 * The search is limited to levels < maxLevel 363 */ 364 void SearchGridDecendants(double q[3], vtkOverlappingAMR* amrds, unsigned int maxLevel, 365 unsigned int& level, unsigned int& gridId, int& id); 366 367 /** 368 * Find an ancestor of the specified grid that contains the point. 369 * If none is found then the original grid information is returned 370 */ 371 bool SearchGridAncestors( 372 double q[3], vtkOverlappingAMR* amrds, unsigned int& level, unsigned int& gridId, int& id); 373 374 private: 375 vtkAMRResampleFilter(const vtkAMRResampleFilter&) = delete; 376 void operator=(const vtkAMRResampleFilter&) = delete; 377 }; 378 379 #endif /* vtkAMRResampleFilter_h */ 380