// 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:
*
* - one block/grid per rank.
* - 2-D (XY,YZ or XZ planes) or 3-D datasets.
* - node-center fields must match across processes.
*
*
*/
#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