You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
456 lines
18 KiB
456 lines
18 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkDistributedDataFilter.h,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
/*----------------------------------------------------------------------------
|
|
Copyright (c) Sandia Corporation
|
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
|
----------------------------------------------------------------------------*/
|
|
|
|
// .NAME vtkDistributedDataFilter - Distribute data among processors
|
|
//
|
|
// .SECTION Description
|
|
// This filter redistributes data among processors in a parallel
|
|
// application into spatially contiguous vtkUnstructuredGrids.
|
|
// The execution model anticipated is that all processes read in
|
|
// part of a large vtkDataSet. Each process sets the input of
|
|
// filter to be that DataSet. When executed, this filter builds
|
|
// in parallel a k-d tree, decomposing the space occupied by the
|
|
// distributed DataSet into spatial regions. It assigns each
|
|
// spatial region to a processor. The data is then redistributed
|
|
// and the output is a single vtkUnstructuredGrid containing the
|
|
// cells in the process' assigned regions.
|
|
//
|
|
// This filter is sometimes called "D3" for "distributed data decomposition".
|
|
//
|
|
// Enhancement: You can set the k-d tree decomposition, rather than
|
|
// have D3 compute it. This allows you to divide a dataset using
|
|
// the decomposition computed for another dataset. Obtain a description
|
|
// of the k-d tree cuts this way:
|
|
//
|
|
// vtkBSPCuts *cuts = D3Object1->GetKdtree()->GetCuts()
|
|
//
|
|
// And set it this way:
|
|
//
|
|
// D3Object2->GetKdtree()->SetCuts(cuts)
|
|
//
|
|
// .SECTION Caveats
|
|
// The Execute() method must be called by all processes in the
|
|
// parallel application, or it will hang. If you are not certain
|
|
// that your pipeline will execute identically on all processors,
|
|
// you may want to use this filter in an explicit execution mode.
|
|
//
|
|
// .SECTION See Also
|
|
// vtkKdTree vtkPKdTree vtkBSPCuts
|
|
|
|
#ifndef __vtkDistributedDataFilter_h
|
|
#define __vtkDistributedDataFilter_h
|
|
|
|
#include "vtkUnstructuredGridAlgorithm.h"
|
|
|
|
class vtkUnstructuredGrid;
|
|
class vtkPKdTree;
|
|
class vtkMultiProcessController;
|
|
class vtkDataArray;
|
|
class vtkIntArray;
|
|
class vtkFloatArray;
|
|
class vtkIdList;
|
|
class vtkUnstructuredGrid;
|
|
class vtkModelMetadata;
|
|
class vtkDistributedDataFilterSTLCloak;
|
|
|
|
class VTK_PARALLEL_EXPORT vtkDistributedDataFilter: public vtkUnstructuredGridAlgorithm
|
|
{
|
|
vtkTypeRevisionMacro(vtkDistributedDataFilter,
|
|
vtkUnstructuredGridAlgorithm);
|
|
|
|
public:
|
|
void PrintSelf(ostream& os, vtkIndent indent);
|
|
|
|
static vtkDistributedDataFilter *New();
|
|
|
|
// Description:
|
|
// Set/Get the communicator object
|
|
void SetController(vtkMultiProcessController *c);
|
|
vtkGetObjectMacro(Controller, vtkMultiProcessController);
|
|
|
|
// Description:
|
|
// It is desirable to have a field array of global node IDs
|
|
// for two reasons:
|
|
//
|
|
// 1. When merging together sub grids that were distributed
|
|
// across processors, global node IDs can be used to remove
|
|
// duplicate points and significantly reduce the size of the
|
|
// resulting output grid. If no such array is available,
|
|
// D3 will use a tolerance to merge points, which is much
|
|
// slower.
|
|
//
|
|
// 2. If ghost cells have been requested, D3 requires a
|
|
// global node ID array in order to request and transfer
|
|
// ghost cells in parallel among the processors. If there
|
|
// is no global node ID array, D3 will in parallel create
|
|
// a global node ID array, and the time to do this can be
|
|
// significant.
|
|
//
|
|
// If you know the name of a global node ID array in the input
|
|
// dataset, set that name with this method. If you leave
|
|
// it unset, D3 will search the input data set for certain
|
|
// common names of global node ID arrays. If none is found,
|
|
// and ghost cells have been requested, D3 will create a
|
|
// temporary global node ID array before aquiring ghost cells.
|
|
|
|
vtkSetStringMacro(GlobalNodeIdArrayName);
|
|
|
|
// Description:
|
|
// It is also desirable to have global element IDs. However,
|
|
// if they don't exist D3 can create them relatively quickly.
|
|
// Set the name of the global element ID array if you have it.
|
|
// If it is not set, D3 will search for it using common names.
|
|
// If still not found, D3 will create a temporary array of
|
|
// global element IDs.
|
|
|
|
vtkSetStringMacro(GlobalElementIdArrayName);
|
|
|
|
// Description:
|
|
// When this filter executes, it creates a vtkPKdTree (K-d tree)
|
|
// data structure in parallel which divides the total distributed
|
|
// data set into spatial regions. The K-d tree object also creates
|
|
// tables describing which processes have data for which
|
|
// regions. Only then does this filter redistribute
|
|
// the data according to the region assignment scheme. By default,
|
|
// the K-d tree structure and it's associated tables are deleted
|
|
// after the filter executes. If you anticipate changing only the
|
|
// region assignment scheme (input is unchanged) and explicitly
|
|
// re-executing, then RetainKdTreeOn, and the K-d tree structure and
|
|
// tables will be saved. Then, when you re-execute, this filter will
|
|
// skip the k-d tree build phase and go straight to redistributing
|
|
// the data according to region assignment. See vtkPKdTree for
|
|
// more information about region assignment.
|
|
|
|
vtkBooleanMacro(RetainKdtree, int);
|
|
vtkGetMacro(RetainKdtree, int);
|
|
vtkSetMacro(RetainKdtree, int);
|
|
|
|
// Description:
|
|
// Get a pointer to the parallel k-d tree object. Required for changing
|
|
// default behavior for region assignment, changing default depth of tree,
|
|
// or other tree building default parameters. See vtkPKdTree and
|
|
// vtkKdTree for more information about these options.
|
|
|
|
vtkPKdTree *GetKdtree();
|
|
|
|
// Description:
|
|
// Each cell in the data set is associated with one of the
|
|
// spatial regions of the k-d tree decomposition. In particular,
|
|
// the cell belongs to the region that it's centroid lies in.
|
|
// When the new vtkUnstructuredGrid is created, by default it
|
|
// is composed of the cells associated with the region(s)
|
|
// assigned to this process. If you also want it to contain
|
|
// cells that intersect these regions, but have their centroid
|
|
// elsewhere, then set this variable on. By default it is off.
|
|
|
|
vtkBooleanMacro(IncludeAllIntersectingCells, int);
|
|
vtkGetMacro(IncludeAllIntersectingCells, int);
|
|
vtkSetMacro(IncludeAllIntersectingCells, int);
|
|
|
|
// Description:
|
|
// Set this variable if you want the cells of the output
|
|
// vtkUnstructuredGrid to be clipped to the spatial region
|
|
// boundaries. By default this is off.
|
|
|
|
vtkBooleanMacro(ClipCells, int);
|
|
vtkGetMacro(ClipCells, int);
|
|
vtkSetMacro(ClipCells, int);
|
|
|
|
//BTX
|
|
enum BoundaryModes {
|
|
ASSIGN_TO_ONE_REGION=0,
|
|
ASSIGN_TO_ALL_INTERSECTING_REGIONS=1,
|
|
SPLIT_BOUNDARY_CELLS=2
|
|
};
|
|
//ETX
|
|
|
|
// Description:
|
|
// Handling of ClipCells and IncludeAllIntersectingCells.
|
|
void SetBoundaryMode(int mode);
|
|
void SetBoundaryModeToAssignToOneRegion()
|
|
{ this->SetBoundaryMode(vtkDistributedDataFilter::ASSIGN_TO_ONE_REGION); }
|
|
void SetBoundaryModeToAssignToAllIntersectingRegions()
|
|
{ this->SetBoundaryMode(
|
|
vtkDistributedDataFilter::ASSIGN_TO_ALL_INTERSECTING_REGIONS);
|
|
}
|
|
void SetBoundaryModeToSplitBoundaryCells()
|
|
{ this->SetBoundaryMode(vtkDistributedDataFilter::SPLIT_BOUNDARY_CELLS); }
|
|
int GetBoundaryMode();
|
|
|
|
// Description:
|
|
// Ensure previous filters don't send up ghost cells
|
|
virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
|
|
|
|
// Description:
|
|
// This class does a great deal of all-to-all communication
|
|
// when exchanging portions of data sets and building new sub
|
|
// grids.
|
|
// By default it will do fast communication. It can instead
|
|
// use communication routines that use the least possible
|
|
// amount of memory, but these are slower. Set this option
|
|
// ON to choose these latter routines.
|
|
|
|
vtkBooleanMacro(UseMinimalMemory, int);
|
|
vtkGetMacro(UseMinimalMemory, int);
|
|
vtkSetMacro(UseMinimalMemory, int);
|
|
|
|
|
|
// Description:
|
|
// Turn on collection of timing data
|
|
|
|
vtkBooleanMacro(Timing, int);
|
|
vtkSetMacro(Timing, int);
|
|
vtkGetMacro(Timing, int);
|
|
|
|
// Description:
|
|
// Consider the MTime of the KdTree.
|
|
unsigned long GetMTime();
|
|
|
|
protected:
|
|
vtkDistributedDataFilter();
|
|
~vtkDistributedDataFilter();
|
|
|
|
// Description:
|
|
// Another way to set ClipCells and IncludeAllIntersectingCells.
|
|
// AssignBoundaryCellsToOneRegion turns off both ClipCells and
|
|
// IncludeAllIntersectingCells. Each cell will be included in
|
|
// exactly one process' output unstructured grid.
|
|
|
|
void AssignBoundaryCellsToOneRegionOn();
|
|
void AssignBoundaryCellsToOneRegionOff();
|
|
void SetAssignBoundaryCellsToOneRegion(int val);
|
|
|
|
// Description:
|
|
// Another way to set ClipCells and IncludeAllIntersectingCells.
|
|
// AssignBoundaryCellsToAllIntersectingRegions turns off ClipCells
|
|
// turns on IncludeAllIntersectingCells. A cell will be included
|
|
// in the output unstructured grid built for every region that it
|
|
// intersects. If a cell intersects two process' spatial regions,
|
|
// both processes will have that cell in their output grid.
|
|
|
|
void AssignBoundaryCellsToAllIntersectingRegionsOn();
|
|
void AssignBoundaryCellsToAllIntersectingRegionsOff();
|
|
void SetAssignBoundaryCellsToAllIntersectingRegions(int val);
|
|
|
|
// Description:
|
|
// Another way to set ClipCells and IncludeAllIntersectingCells.
|
|
// DivideBoundaryCells turns on both ClipCells and
|
|
// IncludeAllIntersectingCells. A cell that straddles a processor
|
|
// boundary will be split along the boundary, with each process
|
|
// getting the portion of the cell that lies in it's spatial region.
|
|
|
|
void DivideBoundaryCellsOn();
|
|
void DivideBoundaryCellsOff();
|
|
void SetDivideBoundaryCells(int val);
|
|
|
|
// Description:
|
|
// Build a vtkUnstructuredGrid for a spatial region from the
|
|
// data distributed across processes. Execute() must be called
|
|
// by all processes, or it will hang.
|
|
|
|
virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
|
|
void SingleProcessExecute(vtkDataSet *input, vtkUnstructuredGrid *output);
|
|
virtual int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
|
|
virtual int FillInputPortInformation(int port, vtkInformation *info);
|
|
|
|
private:
|
|
|
|
//BTX
|
|
enum{
|
|
DeleteNo = 0,
|
|
DeleteYes = 1
|
|
};
|
|
|
|
enum{
|
|
DuplicateCellsNo = 0,
|
|
DuplicateCellsYes = 1
|
|
};
|
|
|
|
enum{
|
|
GhostCellsNo = 0,
|
|
GhostCellsYes = 1
|
|
};
|
|
|
|
enum{
|
|
UnsetGhostLevel = 99
|
|
};
|
|
//ETX
|
|
int PartitionDataAndAssignToProcesses(vtkDataSet *set);
|
|
vtkUnstructuredGrid *RedistributeDataSet(vtkDataSet *set, vtkDataSet *input);
|
|
int ClipGridCells(vtkUnstructuredGrid *grid);
|
|
vtkUnstructuredGrid * AcquireGhostCells(vtkUnstructuredGrid *grid);
|
|
|
|
void ComputeMyRegionBounds();
|
|
|
|
int CheckFieldArrayTypes(vtkDataSet *set);
|
|
|
|
vtkDataSet *TestFixTooFewInputFiles(vtkDataSet *input);
|
|
|
|
vtkUnstructuredGrid *MPIRedistribute(vtkDataSet *in, vtkDataSet *input);
|
|
|
|
vtkIdList **GetCellIdsForProcess(int proc, int *nlists);
|
|
|
|
void SetUpPairWiseExchange();
|
|
void FreeIntArrays(vtkIntArray **ar);
|
|
vtkIntArray *ExchangeCounts(int myCount, int tag);
|
|
vtkIntArray **ExchangeIntArrays(vtkIntArray **arIn,
|
|
int deleteSendArrays, int tag);
|
|
vtkFloatArray **ExchangeFloatArrays(vtkFloatArray **myArray,
|
|
int deleteSendArrays, int tag);
|
|
vtkUnstructuredGrid *ExchangeMergeSubGrids(vtkIdList **cellIds, int deleteCellIds,
|
|
vtkDataSet *myGrid, int deleteMyGrid,
|
|
int filterOutDuplicateCells, int ghostCellFlag, int tag);
|
|
vtkUnstructuredGrid *ExchangeMergeSubGrids(vtkIdList ***cellIds, int *numLists,
|
|
int deleteCellIds,
|
|
vtkDataSet *myGrid, int deleteMyGrid,
|
|
int filterOutDuplicateCells, int ghostCellFlag, int tag);
|
|
vtkIntArray *ExchangeCountsLean(int myCount, int tag);
|
|
vtkIntArray **ExchangeIntArraysLean(vtkIntArray **arIn,
|
|
int deleteSendArrays, int tag);
|
|
vtkFloatArray **ExchangeFloatArraysLean(vtkFloatArray **myArray,
|
|
int deleteSendArrays, int tag);
|
|
vtkUnstructuredGrid *ExchangeMergeSubGridsLean(
|
|
vtkIdList ***cellIds, int *numLists,
|
|
int deleteCellIds,
|
|
vtkDataSet *myGrid, int deleteMyGrid,
|
|
int filterOutDuplicateCells, int ghostCellFlag, int tag);
|
|
vtkIntArray *ExchangeCountsFast(int myCount, int tag);
|
|
vtkIntArray **ExchangeIntArraysFast(vtkIntArray **arIn,
|
|
int deleteSendArrays, int tag);
|
|
vtkFloatArray **ExchangeFloatArraysFast(vtkFloatArray **myArray,
|
|
int deleteSendArrays, int tag);
|
|
vtkUnstructuredGrid *ExchangeMergeSubGridsFast(
|
|
vtkIdList ***cellIds, int *numLists,
|
|
int deleteCellIds,
|
|
vtkDataSet *myGrid, int deleteMyGrid,
|
|
int filterOutDuplicateCells, int ghostCellFlag, int tag);
|
|
|
|
|
|
char *MarshallDataSet(vtkUnstructuredGrid *extractedGrid, int &size);
|
|
vtkUnstructuredGrid *UnMarshallDataSet(char *buf, int size);
|
|
|
|
void ClipCellsToSpatialRegion(vtkUnstructuredGrid *grid);
|
|
|
|
void ClipWithVtkClipDataSet(vtkUnstructuredGrid *grid, double *bounds,
|
|
vtkUnstructuredGrid **outside, vtkUnstructuredGrid **inside);
|
|
void ClipWithBoxClipDataSet(vtkUnstructuredGrid *grid, double *bounds,
|
|
vtkUnstructuredGrid **outside, vtkUnstructuredGrid **inside);
|
|
|
|
const char *GetGlobalNodeIdArrayName(vtkDataSet *set);
|
|
int *GetGlobalNodeIds(vtkDataSet *set);
|
|
|
|
const char *GetGlobalElementIdArrayName(vtkDataSet *set);
|
|
int *GetGlobalElementIds(vtkDataSet *set);
|
|
|
|
int AssignGlobalNodeIds(vtkUnstructuredGrid *grid);
|
|
int AssignGlobalElementIds(vtkDataSet *in);
|
|
|
|
vtkIntArray **FindGlobalPointIds(vtkFloatArray **ptarray,
|
|
vtkIntArray *ids, vtkUnstructuredGrid *grid, int &numUniqueMissingPoints);
|
|
|
|
int InMySpatialRegion(float x, float y, float z);
|
|
int InMySpatialRegion(double x, double y, double z);
|
|
int StrictlyInsideMyBounds(float x, float y, float z);
|
|
int StrictlyInsideMyBounds(double x, double y, double z);
|
|
|
|
vtkIntArray **GetGhostPointIds(int ghostLevel, vtkUnstructuredGrid *grid,
|
|
int AddCellsIAlreadyHave);
|
|
vtkIntArray **MakeProcessLists(vtkIntArray **pointIds,
|
|
vtkDistributedDataFilterSTLCloak *procs);
|
|
vtkUnstructuredGrid *AddGhostCellsUniqueCellAssignment(
|
|
vtkUnstructuredGrid *myGrid,
|
|
vtkDistributedDataFilterSTLCloak *globalToLocalMap);
|
|
vtkUnstructuredGrid *AddGhostCellsDuplicateCellAssignment(
|
|
vtkUnstructuredGrid *myGrid,
|
|
vtkDistributedDataFilterSTLCloak *globalToLocalMap);
|
|
vtkIdList **BuildRequestedGrids( vtkIntArray **globalPtIds,
|
|
vtkUnstructuredGrid *grid,
|
|
vtkDistributedDataFilterSTLCloak *ptIdMap);
|
|
vtkUnstructuredGrid *SetMergeGhostGrid(
|
|
vtkUnstructuredGrid *ghostCellGrid,
|
|
vtkUnstructuredGrid *incomingGhostCells,
|
|
int ghostLevel, vtkDistributedDataFilterSTLCloak *idMap);
|
|
|
|
vtkUnstructuredGrid *ExtractCells(vtkIdList *list,
|
|
int deleteCellLists, vtkDataSet *in, vtkModelMetadata *mmd);
|
|
vtkUnstructuredGrid *ExtractCells(vtkIdList **lists, int nlists,
|
|
int deleteCellLists, vtkDataSet *in, vtkModelMetadata *mmd);
|
|
vtkUnstructuredGrid *ExtractZeroCellGrid(vtkDataSet *in,
|
|
vtkModelMetadata *mmd);
|
|
|
|
void AddMetadata(vtkUnstructuredGrid *grid, vtkModelMetadata *mmd);
|
|
|
|
static int GlobalPointIdIsUsed(vtkUnstructuredGrid *grid,
|
|
int ptId, vtkDistributedDataFilterSTLCloak *globalToLocal);
|
|
|
|
static int LocalPointIdIsUsed(vtkUnstructuredGrid *grid, int ptId);
|
|
static int FindId(vtkIntArray *ids, int gid, int startLoc);
|
|
static vtkIntArray *AddPointAndCells(int gid, int localId,
|
|
vtkUnstructuredGrid *grid, int *gidCells, vtkIntArray *ids);
|
|
|
|
static void AddConstantUnsignedCharPointArray(vtkUnstructuredGrid *grid,
|
|
const char *arrayName, unsigned char val);
|
|
static void AddConstantUnsignedCharCellArray(vtkUnstructuredGrid *grid,
|
|
const char *arrayName, unsigned char val);
|
|
static void RemoveRemoteCellsFromList(vtkIdList *cellList, int *gidCells,
|
|
int *remoteCells, int nRemoteCells);
|
|
static vtkUnstructuredGrid *MergeGrids(vtkDataSet **sets, int nsets,
|
|
int deleteDataSets,
|
|
const char *globalNodeIdArrayName, float pointMergeTolerance,
|
|
const char *globalCellIdArrayName);
|
|
|
|
static void FreeIdLists(vtkIdList**lists, int nlists);
|
|
static vtkIdType GetIdListSize(vtkIdList**lists, int nlists);
|
|
static int HasMetadata(vtkDataSet *s);
|
|
|
|
vtkPKdTree *Kdtree;
|
|
vtkMultiProcessController *Controller;
|
|
|
|
int NumProcesses;
|
|
int MyId;
|
|
|
|
int *Target;
|
|
int *Source;
|
|
|
|
int NumConvexSubRegions;
|
|
double *ConvexSubRegionBounds;
|
|
|
|
int GhostLevel;
|
|
|
|
char *GlobalElementIdArrayName;
|
|
char *GlobalNodeIdArrayName;
|
|
|
|
int RetainKdtree;
|
|
int IncludeAllIntersectingCells;
|
|
int ClipCells;
|
|
int AssignBoundaryCellsToOneRegion;
|
|
int AssignBoundaryCellsToAllIntersectingRegions;
|
|
int DivideBoundaryCells;
|
|
|
|
int Timing;
|
|
|
|
int NextProgressStep;
|
|
double ProgressIncrement;
|
|
|
|
int UseMinimalMemory;
|
|
|
|
vtkDistributedDataFilter(const vtkDistributedDataFilter&); // Not implemented
|
|
void operator=(const vtkDistributedDataFilter&); // Not implemented
|
|
};
|
|
#endif
|
|
|