// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause /** * @class vtkStructuredImplicitConnectivity * a distributed structured dataset that is implicitly connected among * partitions without abutting. This creates a gap between partitions and * introduces a cell that spans multiple zones. This typically arises with * finite difference grids, which are partitioned with respect to the * nodes of the grid, or, when a filter samples the grid, e.g., to get a * lower resolution representation. * * * This class is intended as a lower-level helper for higher level VTK filters * that provides functionality for resolving the implicit connectivity (gap) * between two or more partitions of a distributed structured dataset. * * @warning * The present implementation requires: * * */ #ifndef vtkStructuredImplicitConnectivity_h #define vtkStructuredImplicitConnectivity_h #include "vtkFiltersParallelMPIModule.h" // For export macro #include "vtkObject.h" // Forward declarations VTK_ABI_NAMESPACE_BEGIN class vtkDataArray; class vtkImageData; class vtkMPIController; class vtkMultiProcessStream; class vtkPointData; class vtkPoints; class vtkRectilinearGrid; class vtkStructuredGrid; VTK_ABI_NAMESPACE_END namespace vtk { namespace detail { VTK_ABI_NAMESPACE_BEGIN class CommunicationManager; struct DomainMetaData; struct StructuredGrid; VTK_ABI_NAMESPACE_END } // END namespace detail } // END namespace vtk VTK_ABI_NAMESPACE_BEGIN class VTKFILTERSPARALLELMPI_EXPORT vtkStructuredImplicitConnectivity : public vtkObject { public: static vtkStructuredImplicitConnectivity* New(); void PrintSelf(ostream& os, vtkIndent indent) override; vtkTypeMacro(vtkStructuredImplicitConnectivity, vtkObject); /** * \brief Sets the whole extent for the distributed structured domain. * \param wholeExt the extent of the entire domain (in). * \note All ranks must call this method with the same whole extent. * \post this->DomainInfo != nullptr */ void SetWholeExtent(int wholeExt[6]); // \brief Registers the structured grid dataset belonging to this process. // \param gridID the ID of the grid in this rank. // \param extent the [imin,imax,jmin,jmax,kmin,kmax] of the grid. // \param gridPnts pointer to the points of the grid (nullptr for uniform grid). // \param pointData pointer to the node-centered fields of the grid. // \pre gridID >= 0. The code uses values of gridID < -1 as flag internally. // \pre vtkStructuredExtent::Smaller(extent,wholeExtent) == true. // \note A rank with no or an empty grid, should not call this method. void RegisterGrid(int gridID, int extent[6], vtkPoints* gridPnts, vtkPointData* pointData); // \brief Registers the rectilinear grid dataset belonging to this process. // \param gridID the ID of the in this rank. // \param extent the [imin,imax,jmin,jmax,kmin,kmax] of the grid. // \param xcoords the x-coordinates array of the rectilinear grid. // \param ycoords the y-coordinates array of the rectilinear grid. // \param zcoords the z-coordinates array of the rectilinear grid. // \param pointData pointer to the node-centered fields of the grid. // \pre gridID >= 0. The code uses values of gridID < -1 as flag internally. // \pre vtkStructuredExtent::Smaller(extent,wholeExtent) == true. // \note A rank with no or an empty grid, should not call this method. void RegisterRectilinearGrid(int gridID, int extent[6], vtkDataArray* xcoords, vtkDataArray* ycoords, vtkDataArray* zcoords, vtkPointData* pointData); /** * \brief Finds implicit connectivity for a distributed structured dataset. * \note This is a collective operation, all ranks must call this method. * \pre this->Controller != nullptr * \pre this->DomainInfo != nullptr */ void EstablishConnectivity(); /** * \brief Checks if there is implicit connectivity. * \return status true if implicit connectivity in one or more dimensions. */ bool HasImplicitConnectivity(); /** * \brief Exchanges one layer (row or column) of data between neighboring * grids to fix the implicit connectivity. * \note This is a collective operation, all ranks must call this method. * \pre this->Controller != nullptr * \pre this->DomainInfo != nullptr */ void ExchangeData(); /** * \brief Gets the output structured grid instance on this process. * \param gridID the ID of the grid * \param grid pointer to data-structure where to store the output. */ void GetOutputStructuredGrid(int gridID, vtkStructuredGrid* grid); /** * \brief Gets the output uniform grid instance on this process. * \param gridID the ID of the grid. * \param grid pointer to data-structure where to store the output. */ void GetOutputImageData(int gridID, vtkImageData* grid); /** * \brief Gets the output rectilinear grid instance on this process. * \param gridID the ID of the grid. * \param grid pointer to data-structure where to store the output. */ void GetOutputRectilinearGrid(int gridID, vtkRectilinearGrid* grid); protected: vtkStructuredImplicitConnectivity(); ~vtkStructuredImplicitConnectivity() override; void SetController(vtkMPIController*); vtkMPIController* Controller; vtk::detail::DomainMetaData* DomainInfo; vtk::detail::StructuredGrid* InputGrid; vtk::detail::StructuredGrid* OutputGrid; vtk::detail::CommunicationManager* CommManager; /** * \brief Checks if the data description matches globally. */ bool GlobalDataDescriptionMatch(); /** * \brief Packs the data to send into a bytestream */ void PackData(int ext[6], vtkMultiProcessStream& bytestream); /** * \brief Unpacks the data to the output grid */ void UnPackData(unsigned char* buffer, unsigned int size); /** * \brief Allocates send/rcv buffers needed to carry out the communication. */ void AllocateBuffers(int dim); /** * \brief Computes the neighbors with implicit connectivity. */ void ComputeNeighbors(); /** * \brief Constructs the output data-structures. */ void ConstructOutput(); /** * \brief Grows grid along a given dimension. * \param dim the dimension in query. */ void GrowGrid(int dim); /** * \brief Updates the list of neighbors after growing the grid along the * given dimension dim. * \param dim the dimension in query. */ void UpdateNeighborList(int dim); /** * \brief Gets whether there is implicit connectivity across all processes. */ void GetGlobalImplicitConnectivityState(); /** * \brief Exchanges extents among processes. * \pre this->Controller != nullptr. * \note This method is collective operation. All ranks must call it. */ void ExchangeExtents(); private: vtkStructuredImplicitConnectivity(const vtkStructuredImplicitConnectivity&) = delete; void operator=(const vtkStructuredImplicitConnectivity&) = delete; }; VTK_ABI_NAMESPACE_END #endif