// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause /** * @class vtkAMRResampleFilter * * * This filter is a concrete instance of vtkMultiBlockDataSetAlgorithm and * provides functionality for extracting portion of the AMR dataset, specified * by a bounding box, in a uniform grid of the desired level of resolution. * The resulting uniform grid is stored in a vtkMultiBlockDataSet where the * number of blocks correspond to the number of processors utilized for the * operation. * * @warning * This filter does not support AMR of rectilinear grids yet. * * @warning * Data of the input AMR dataset is assumed to be cell-centered. * * @sa * vtkOverlappingAMR, vtkUniformGrid */ #ifndef vtkAMRResampleFilter_h #define vtkAMRResampleFilter_h #include "vtkFiltersAMRModule.h" // For export macro #include "vtkMultiBlockDataSetAlgorithm.h" #include // For STL vector VTK_ABI_NAMESPACE_BEGIN class vtkInformation; class vtkInformationVector; class vtkUniformGrid; class vtkOverlappingAMR; class vtkMultiBlockDataSet; class vtkMultiProcessController; class vtkFieldData; class vtkCellData; class vtkPointData; class vtkIndent; class vtkAMRBox; class VTKFILTERSAMR_EXPORT vtkAMRResampleFilter : public vtkMultiBlockDataSetAlgorithm { public: static vtkAMRResampleFilter* New(); vtkTypeMacro(vtkAMRResampleFilter, vtkMultiBlockDataSetAlgorithm); void PrintSelf(ostream& oss, vtkIndent indent) override; ///@{ /** * Set & Get macro for the number of samples (cells) in each dimension. * Nominal value for the number of samples is 10x10x10. */ vtkSetVector3Macro(NumberOfSamples, int); vtkGetVector3Macro(NumberOfSamples, int); ///@} ///@{ /** * Set & Get macro for the TransferToNodes flag */ vtkSetMacro(TransferToNodes, vtkTypeBool); vtkGetMacro(TransferToNodes, vtkTypeBool); ///@} ///@{ /** * Set & Get macro to allow the filter to operate in both demand-driven * and standard modes */ vtkSetMacro(DemandDrivenMode, int); vtkGetMacro(DemandDrivenMode, int); ///@} ///@{ /** * Set & Get macro for the number of subdivisions */ vtkSetMacro(NumberOfPartitions, int); vtkGetMacro(NumberOfPartitions, int); ///@} ///@{ /** * Set and Get the min corner */ vtkSetVector3Macro(Min, double); vtkGetVector3Macro(Min, double); ///@} ///@{ /** * Set and Get the max corner */ vtkSetVector3Macro(Max, double); vtkGetVector3Macro(Max, double); ///@} ///@{ /** * Set & Get macro for the number of subdivisions */ vtkSetMacro(UseBiasVector, bool); vtkGetMacro(UseBiasVector, bool); ///@} ///@{ /** * Set and Get the bias vector. If UseBiasVector is true * then the largest component of this vector can not have * the max number of samples */ vtkSetVector3Macro(BiasVector, double); vtkGetVector3Macro(BiasVector, double); ///@} ///@{ /** * Set & Get macro for the multi-process controller */ virtual void SetController(vtkMultiProcessController*); vtkGetObjectMacro(Controller, vtkMultiProcessController); ///@} // Standard pipeline routines /** * Gets the metadata from upstream module and determines which blocks * should be loaded by this instance. */ int RequestInformation(vtkInformation* rqst, vtkInformationVector** inputVector, vtkInformationVector* outputVector) override; int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; int FillInputPortInformation(int port, vtkInformation* info) override; int FillOutputPortInformation(int port, vtkInformation* info) override; /** * Performs upstream requests to the reader */ int RequestUpdateExtent(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; protected: vtkAMRResampleFilter(); ~vtkAMRResampleFilter() override; vtkOverlappingAMR* AMRMetaData; vtkMultiBlockDataSet* ROI; // Pointer to the region of interest. int NumberOfSamples[3]; int GridNumberOfSamples[3]; double Min[3]; double Max[3]; double GridMin[3]; double GridMax[3]; int LevelOfResolution; int NumberOfPartitions; vtkTypeBool TransferToNodes; int DemandDrivenMode; vtkMultiProcessController* Controller; bool UseBiasVector; double BiasVector[3]; // Debugging Stuff int NumberOfBlocksTestedForLevel; int NumberOfBlocksTested; int NumberOfBlocksVisSkipped; int NumberOfTimesFoundOnDonorLevel; int NumberOfTimesLevelUp; int NumberOfTimesLevelDown; int NumberOfFailedPoints; double AverageLevel; std::vector BlocksToLoad; // Holds the ids of the blocks to load. /** * Checks if this filter instance is running on more than one processes */ bool IsParallel(); /** * Given the Region ID this function returns whether or not the region * belongs to this process or not. */ bool IsRegionMine(int regionIdx); /** * Given the Region ID, this method computes the corresponding process ID * that owns the region based on static block-cyclic distribution. */ int GetRegionProcessId(int regionIdx); /** * Given a cell index and a grid, this method computes the cell centroid. */ void ComputeCellCentroid(vtkUniformGrid* g, vtkIdType cellIdx, double c[3]); /** * Given the source cell data of an AMR grid, this method initializes the * field values, i.e., the number of arrays with the prescribed size. Note, * the size must correspond to the number of points if node-centered or the * the number of cells if cell-centered. */ void InitializeFields(vtkFieldData* f, vtkIdType size, vtkCellData* src); /** * Copies the data to the target from the given source. */ void CopyData(vtkFieldData* target, vtkIdType targetIdx, vtkCellData* src, vtkIdType srcIdx); /** * Given a query point q and a candidate donor grid, this method checks for * the corresponding donor cell containing the point in the given grid. */ bool FoundDonor(double q[3], vtkUniformGrid*& donorGrid, int& cellIdx); /** * Given a query point q and a target level, this method finds a suitable * grid at the given level that contains the point if one exists. If a grid * is not found, donorGrid is set to nullptr. */ bool SearchForDonorGridAtLevel(double q[3], vtkOverlappingAMR* amrds, unsigned int level, unsigned int& gridId, int& donorCellIdx); /** * Finds the AMR grid that contains the point q. If donorGrid points to a * valid AMR grid in the hierarchy, the algorithm will search this grid * first. The method returns the ID of the cell w.r.t. the donorGrid that * contains the probe point q. */ int ProbeGridPointInAMR(double q[3], unsigned int& donorLevel, unsigned int& donorGridId, vtkOverlappingAMR* amrds, unsigned int maxLevel, bool hadDonorGrid); /** * Finds the AMR grid that contains the point q. If donorGrid points to a * valid AMR grid in the hierarchy, the algorithm will search this grid * first. The method returns the ID of the cell w.r.t. the donorGrid that * contains the probe point q. - Makes use of Parent/Child Info */ int ProbeGridPointInAMRGraph(double q[3], unsigned int& donorLevel, unsigned int& donorGridId, vtkOverlappingAMR* amrds, unsigned int maxLevel, bool useCached); /** * Transfers the solution from the AMR dataset to the cell-centers of * the given uniform grid. */ void TransferToCellCenters(vtkUniformGrid* g, vtkOverlappingAMR* amrds); /** * Transfer the solution from the AMR dataset to the nodes of the * given uniform grid. */ void TransferToGridNodes(vtkUniformGrid* g, vtkOverlappingAMR* amrds); /** * Transfers the solution */ void TransferSolution(vtkUniformGrid* g, vtkOverlappingAMR* amrds); /** * Extract the region (as a multiblock) from the given AMR dataset. */ void ExtractRegion( vtkOverlappingAMR* amrds, vtkMultiBlockDataSet* mbds, vtkOverlappingAMR* metadata); /** * Checks if the AMR block, described by a uniform grid, is within the * bounds of the ROI perscribed by the user. */ bool IsBlockWithinBounds(double* grd); /** * Given a user-supplied region of interest and the metadata by a module * upstream, this method generates the list of linear AMR block indices * that need to be loaded. */ void ComputeAMRBlocksToLoad(vtkOverlappingAMR* metadata); /** * Computes the region parameters */ void ComputeRegionParameters( vtkOverlappingAMR* amrds, int N[3], double min[3], double max[3], double h[3]); /** * This method accesses the domain boundaries */ void GetDomainParameters(vtkOverlappingAMR* amr, double domainMin[3], double domainMax[3], double h[3], int dims[3], double& rf); /** * Checks if the domain and requested region intersect. */ bool RegionIntersectsWithAMR( double domainMin[3], double domainMax[3], double regionMin[3], double regionMax[3]); /** * This method adjust the numbers of samples in the region, N, if the * requested region falls outside, but, intersects the domain. */ void AdjustNumberOfSamplesInRegion(const double Rh[3], const bool outside[6], int N[3]); /** * This method computes the level of resolution based on the number of * samples requested, N, the root level spacing h0, the length of the box, * L (actual length after snapping) and the refinement ratio. */ void ComputeLevelOfResolution(const int N[3], const double h0[3], const double L[3], double rf); /** * This method snaps the bounds s.t. they are within the interior of the * domain described the root level uniform grid with h0, domainMin and * domain Max. The method computes and returns the new min/max bounds and * the corresponding ijkmin/ijkmax coordinates w.r.t. the root level. */ void SnapBounds(const double h0[3], const double domainMin[3], const double domainMax[3], const int dims[3], bool outside[6]); /** * This method computes and adjusts the region parameters s.t. the requested * region always fall within the AMR region and the number of samples is * adjusted if the region of interest moves outsided the domain. */ void ComputeAndAdjustRegionParameters(vtkOverlappingAMR* amrds, double h[3]); /** * This method gets the region of interest as perscribed by the user. */ void GetRegion(double h[3]); /** * Checks if two uniform grids intersect. */ bool GridsIntersect(double* g1, double* g2); /** * Returns a reference grid from the amrdataset. */ vtkUniformGrid* GetReferenceGrid(vtkOverlappingAMR* amrds); /** * Writes a uniform grid to a file. Used for debugging purposes. * void WriteUniformGrid( vtkUniformGrid *g, std::string prefix ); * void WriteUniformGrid( * double origin[3], int dims[3], double h[3], * std::string prefix ); */ /** * Find a descendant of the specified grid that contains the point. * If none is found then the original grid information is returned. * The search is limited to levels < maxLevel */ void SearchGridDecendants(double q[3], vtkOverlappingAMR* amrds, unsigned int maxLevel, unsigned int& level, unsigned int& gridId, int& id); /** * Find an ancestor of the specified grid that contains the point. * If none is found then the original grid information is returned */ bool SearchGridAncestors( double q[3], vtkOverlappingAMR* amrds, unsigned int& level, unsigned int& gridId, int& id); private: vtkAMRResampleFilter(const vtkAMRResampleFilter&) = delete; void operator=(const vtkAMRResampleFilter&) = delete; }; VTK_ABI_NAMESPACE_END #endif /* vtkAMRResampleFilter_h */