vtkStructuredGridPartitioner.cxx 6.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*=========================================================================

 Program:   Visualization Toolkit
 Module:    vtkStructuredGridPartitioner.cxx

 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.

 =========================================================================*/
#include "vtkStructuredGridPartitioner.h"
#include "vtkObjectFactory.h"
#include "vtkIndent.h"
#include "vtkExtentRCBPartitioner.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredData.h"
#include "vtkStructuredExtent.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
24 25
#include "vtkMultiBlockDataSet.h"
#include "vtkPoints.h"
George Zagaris's avatar
George Zagaris committed
26
#include "vtkStreamingDemandDrivenPipeline.h"
27 28 29 30 31 32 33 34 35 36

#include <cassert>

vtkStandardNewMacro( vtkStructuredGridPartitioner );

//------------------------------------------------------------------------------
vtkStructuredGridPartitioner::vtkStructuredGridPartitioner()
{
  this->NumberOfPartitions  = 2;
  this->NumberOfGhostLayers = 0;
37
  this->DuplicateNodes      = 1;
38 39
  this->SetNumberOfInputPorts(1);
  this->SetNumberOfOutputPorts(1);
40 41 42
}

//------------------------------------------------------------------------------
43
vtkStructuredGridPartitioner::~vtkStructuredGridPartitioner() = default;
44 45 46 47 48 49

//------------------------------------------------------------------------------
void vtkStructuredGridPartitioner::PrintSelf(
    std::ostream &oss, vtkIndent indent )
{
  this->Superclass::PrintSelf( oss, indent );
50 51
  oss << "NumberOfPartitions: " << this->NumberOfPartitions << std::endl;
  oss << "NumberOfGhostLayers: " << this->NumberOfGhostLayers << std::endl;
52
  oss << "DuplicateNodes: " << this->DuplicateNodes << std::endl;
53 54 55 56 57 58 59 60 61 62 63
}

//------------------------------------------------------------------------------
int vtkStructuredGridPartitioner::FillInputPortInformation(
    int vtkNotUsed(port), vtkInformation *info )
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),"vtkStructuredGrid");
  return 1;
}

//------------------------------------------------------------------------------
64 65
int vtkStructuredGridPartitioner::FillOutputPortInformation(
    int vtkNotUsed(port), vtkInformation *info )
66 67 68 69 70
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(),"vtkMultiBlockDataSet");
  return 1;
}

71 72 73 74
//------------------------------------------------------------------------------
vtkPoints* vtkStructuredGridPartitioner::ExtractSubGridPoints(
    vtkStructuredGrid *wholeGrid, int subext[6] )
{
75
  assert("pre: whole grid is nullptr" && (wholeGrid != nullptr) );
76

77
  int numNodes    = vtkStructuredData::GetNumberOfPoints( subext );
78 79 80 81 82 83 84 85
  vtkPoints *pnts = vtkPoints::New();
  pnts->SetDataTypeToDouble();
  pnts->SetNumberOfPoints( numNodes );

  int ijk[3];
  double p[3];
  int dataDescription = vtkStructuredData::GetDataDescriptionFromExtent(subext);
  for( int i=subext[0]; i <= subext[1]; ++i )
86
  {
87
    for( int j=subext[2]; j <= subext[3]; ++j )
88
    {
89
      for( int k=subext[4]; k <= subext[5]; ++k )
90
      {
91 92 93 94 95 96 97 98 99
        wholeGrid->GetPoint(i,j,k,p,false);

        ijk[0]=i; ijk[1]=j; ijk[2]=k;
        vtkIdType pntIdx =
            vtkStructuredData::ComputePointIdForExtent(
                subext,ijk,dataDescription);
        assert("pre: point index is out-of-bounds!" &&
                (pntIdx >= 0) && (pntIdx < numNodes) );
        pnts->SetPoint(pntIdx,p);
100 101 102
      } // END for all k
    } // END for all j
  } // END for all i
103 104 105
  return( pnts );
}

106 107 108 109 110 111
//------------------------------------------------------------------------------
int vtkStructuredGridPartitioner::RequestData(
    vtkInformation* vtkNotUsed(request),
    vtkInformationVector** inputVector,vtkInformationVector* outputVector )
{
  // STEP 0: Get input object
112
  vtkInformation *input = inputVector[0]->GetInformationObject( 0 );
113
  assert("pre: input information object is nullptr" && (input != nullptr) );
114 115
  vtkStructuredGrid *grd =
      vtkStructuredGrid::SafeDownCast(input->Get(vtkDataObject::DATA_OBJECT()));
116 117

  // STEP 1: Get output object
118
  vtkInformation *output = outputVector->GetInformationObject( 0 );
119
  assert("pre: output information object is nullptr" && (output != nullptr) );
120 121 122
  vtkMultiBlockDataSet *multiblock =
      vtkMultiBlockDataSet::SafeDownCast(
          output->Get( vtkDataObject::DATA_OBJECT() ) );
123
  assert("pre: multi-block grid is nullptr" && (multiblock != nullptr) );
124 125

  // STEP 2: Get the global extent
126 127
  int extent[6];
  grd->GetExtent( extent );
128 129

  // STEP 3: Setup extent partitioner
130
  vtkExtentRCBPartitioner *extentPartitioner = vtkExtentRCBPartitioner::New();
131
  assert("pre: extent partitioner is nullptr" && (extentPartitioner != nullptr) );
132 133 134 135
  extentPartitioner->SetGlobalExtent( extent );
  extentPartitioner->SetNumberOfPartitions( this->NumberOfPartitions );
  extentPartitioner->SetNumberOfGhostLayers( this->NumberOfGhostLayers );

136
  if(this->DuplicateNodes == 1)
137
  {
138
    extentPartitioner->DuplicateNodesOn();
139
  }
140
  else
141
  {
142
    extentPartitioner->DuplicateNodesOff();
143
  }
144

145 146 147 148 149 150 151
  // STEP 4: Partition
  extentPartitioner->Partition();

  // STEP 5: Extract partitions in a multi-block
  multiblock->SetNumberOfBlocks( extentPartitioner->GetNumExtents() );

  // Set the whole extent of the grid
George Zagaris's avatar
George Zagaris committed
152 153
  multiblock->GetInformation()->Set(
      vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
154 155 156 157

  int subext[6];
  unsigned int blockIdx = 0;
  for( ; blockIdx < multiblock->GetNumberOfBlocks(); ++blockIdx )
158
  {
159 160 161 162 163 164
    extentPartitioner->GetPartitionExtent( blockIdx, subext );

    vtkStructuredGrid *subgrid = vtkStructuredGrid::New();
    subgrid->SetExtent( subext );

    vtkPoints *points = this->ExtractSubGridPoints( grd, subext );
165
    assert("pre: subgrid points are nullptr" && (points != nullptr) );
166 167 168 169
    subgrid->SetPoints( points );
    points->Delete();

    vtkInformation *metadata = multiblock->GetMetaData( blockIdx );
170
    assert( "pre: metadata is nullptr" && (metadata != nullptr) );
171 172 173 174
    metadata->Set( vtkDataObject::PIECE_EXTENT(), subext, 6);

    multiblock->SetBlock( blockIdx, subgrid );
    subgrid->Delete();
175
  } // END for all blocks
176

177
  extentPartitioner->Delete();
178 179 180
  return 1;
}