├── README.md ├── resources ├── ParaViewMetisMeshPartitioner.xml └── MetisMeshPartitioner.xml ├── cmake └── FindMETIS.cmake ├── CMakeLists.txt ├── vtkMetisMeshPartitioner.h └── vtkMetisMeshPartitioner.cxx /README.md: -------------------------------------------------------------------------------- 1 | ParaViewMetisMeshPartitioner 2 | ============================ 3 | 4 | A ParaView plugin that uses metis to partition a VTK mesh -------------------------------------------------------------------------------- /resources/ParaViewMetisMeshPartitioner.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /cmake/FindMETIS.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the METIS graph partitioning library 2 | # Once done, this will define: 3 | # 4 | # METIS_FOUND -- boolean that indicates whether METIS was found 5 | # METIS_INCLUDE_DIRS -- the include path for METIS 6 | # METIS_LIBRARIES -- the METIS libraries to link against 7 | 8 | ## Try to find the include directory 9 | find_path(METIS_INCLUDE_DIRS 10 | NAMES metis.h 11 | PATHS /usr/include /usr/local/include) 12 | 13 | ## Try to find the METIS library 14 | find_library(METIS_LIBRARIES 15 | NAMES metis 16 | PATHS /usr/lib) 17 | 18 | include(FindPackageHandleStandardArgs) 19 | find_package_handle_standard_args( 20 | METIS DEFAULT_MSG METIS_INCLUDE_DIRS METIS_LIBRARIES) 21 | mark_as_advanced(METIS_INCLUDE_DIRS) 22 | mark_as_advanced(METIS_LIBRARIES) 23 | -------------------------------------------------------------------------------- /resources/MetisMeshPartitioner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | This property specifies the unstructured input grid that will 18 | be partitioned. 19 | 20 | 21 | 22 | 28 | 29 | 30 | Sets the number of partitions which to partition the domain. 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(ParaViewMetisMeshPartitioner) 3 | 4 | ## Set path for cmake modules 5 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) 6 | 7 | ## Find ParaView 8 | find_package(ParaView REQUIRED) 9 | include(${PARAVIEW_USE_FILE}) 10 | include(ParaViewBranding) 11 | include(ParaViewPlugins) 12 | 13 | ## Set plugin name and version 14 | set(PLUGIN_NAME ParaViewMetisMeshPartitioner) 15 | set(PLUGIN_VERSION "1.0") 16 | 17 | ## Find METIS 18 | include(FindMETIS REQUIRED) 19 | 20 | ## Set include directories 21 | include_directories( 22 | ${METIS_INCLUDE_DIRS} 23 | ${PARAVIEW_INCLUDE_DIRS} 24 | ${VTK_INCLUDE_DIR} 25 | ) 26 | 27 | ## Set server-manager XML 28 | set(SMXML 29 | resources/MetisMeshPartitioner.xml 30 | ) 31 | 32 | ## Set server-manager sources 33 | set(SMSRC 34 | vtkMetisMeshPartitioner.cxx 35 | ) 36 | 37 | ## Set the GUI resource XML files 38 | set(GUIXML 39 | resources/ParaViewMetisMeshPartitioner.xml 40 | ) 41 | 42 | ## Set required libraries 43 | set(RequiredLibs 44 | ${METIS_LIBRARIES} 45 | ${VTK_LIBRARIES} 46 | ) 47 | 48 | ## Compile the paraview plugin 49 | add_paraview_plugin( 50 | ${PLUGIN_NAME} 51 | ${PLUGIN_VERSION} 52 | GUI_RESOURCE_FILES ${GUIXML} 53 | SERVER_MANAGER_XML ${SMXML} 54 | SERVER_MANAGER_SOURCES ${SMSRC} 55 | ) 56 | target_link_libraries(${PLUGIN_NAME} ${RequiredLibs}) 57 | -------------------------------------------------------------------------------- /vtkMetisMeshPartitioner.h: -------------------------------------------------------------------------------- 1 | /*========================================================================= 2 | 3 | Program: Visualization Toolkit 4 | Module: vtkCosmoDensityProfile.h 5 | 6 | Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 | All rights reserved. 8 | See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 | 10 | This software is distributed WITHOUT ANY WARRANTY; without even 11 | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 | PURPOSE. See the above copyright notice for more information. 13 | 14 | =========================================================================*/ 15 | // .NAME vtkMetisMeshPartitioner.h -- Mesh partitioner based on METIS. 16 | // 17 | // .SECTION Description 18 | // A concrete instance of vtkPointSetAlgorithm that provides 19 | // functionality for partitioning a VTK dataset. 20 | // 21 | // .SECTION Caveats 22 | // In the current implementation, mixed element grids are not supported 23 | // 24 | // .SECTION See Also 25 | // vtkPointSetAlgorithm 26 | 27 | #ifndef VTKMETISMESHPARTITIONER_H_ 28 | #define VTKMETISMESHPARTITIONER_H_ 29 | 30 | #include "vtkPointSetAlgorithm.h" 31 | 32 | class VTK_EXPORT vtkMetisMeshPartitioner : public vtkPointSetAlgorithm 33 | { 34 | public: 35 | static vtkMetisMeshPartitioner* New(); 36 | vtkTypeMacro(vtkMetisMeshPartitioner,vtkPointSetAlgorithm); 37 | void PrintSelf(ostream& os, vtkIndent indent); 38 | 39 | // Description: 40 | // Get/Set NumberOfPartitions property 41 | vtkGetMacro(NumberOfPartitions,int); 42 | vtkSetMacro(NumberOfPartitions,int); 43 | 44 | protected: 45 | vtkMetisMeshPartitioner(); 46 | virtual ~vtkMetisMeshPartitioner(); 47 | 48 | // Standard pipeline operations 49 | virtual int RequestData( vtkInformation *request, 50 | vtkInformationVector **inputVector, 51 | vtkInformationVector *outputVector ); 52 | 53 | // Class ivars 54 | int NumberOfPartitions; // The total number of partitions requested by the user 55 | 56 | private: 57 | vtkMetisMeshPartitioner(const vtkMetisMeshPartitioner&); // Not implemented 58 | void operator=(const vtkMetisMeshPartitioner&); // Not implemented 59 | }; 60 | 61 | #endif /* VTKMETISMESHPARTITIONER_H_ */ 62 | -------------------------------------------------------------------------------- /vtkMetisMeshPartitioner.cxx: -------------------------------------------------------------------------------- 1 | /*========================================================================= 2 | 3 | Program: Visualization Toolkit 4 | Module: vtkCosmoDensityProfile.h 5 | 6 | Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 | All rights reserved. 8 | See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 | 10 | This software is distributed WITHOUT ANY WARRANTY; without even 11 | the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 | PURPOSE. See the above copyright notice for more information. 13 | 14 | =========================================================================*/ 15 | #include "vtkMetisMeshPartitioner.h" 16 | 17 | // VTK includes 18 | #include "vtkAlgorithm.h" 19 | #include "vtkCellData.h" 20 | #include "vtkDataObject.h" 21 | #include "vtkIdList.h" 22 | #include "vtkInformation.h" 23 | #include "vtkInformationVector.h" 24 | #include "vtkNew.h" 25 | #include "vtkObjectFactory.h" 26 | #include "vtkPolyData.h" 27 | #include "vtkStructuredGrid.h" 28 | #include "vtkUnstructuredGrid.h" 29 | 30 | // C/C++ includes 31 | #include 32 | #include 33 | 34 | #include "metis.h" 35 | 36 | namespace { // private namespace 37 | 38 | template 39 | void Partition(T* data, idx_t nparts) 40 | { 41 | // STEP 1: Setup metis data-structures 42 | idx_t ne = data->GetNumberOfCells(); 43 | idx_t nn = data->GetNumberOfPoints(); 44 | 45 | // METIS mesh data-structure (see METIS manual Section 5.6) 46 | std::vector< idx_t > eptr; 47 | eptr.resize( ne+1 ); 48 | std::vector< idx_t > eind; 49 | 50 | // vectors used for weighted partitioning 51 | idx_t *vwgt = NULL; 52 | idx_t *vsize = NULL; 53 | real_t *tpwgts = NULL; 54 | 55 | // Return values 56 | idx_t objval = 0; // stores edgecut or total communication volume upon 57 | // successful completion. 58 | 59 | std::vector< idx_t > epart; // the element partition vector 60 | epart.resize( ne ); 61 | std::vector< idx_t > npart; // the node partition vector 62 | npart.resize( nn ); 63 | 64 | // STEP 2: Setup the metis options vector 65 | idx_t options[METIS_NOPTIONS]; 66 | METIS_SetDefaultOptions(options); 67 | options[METIS_OPTION_NUMBERING] = 0; 68 | if( nparts > 8 ) 69 | { 70 | options[METIS_OPTION_PTYPE]=METIS_PTYPE_KWAY; 71 | } 72 | else 73 | { 74 | options[METIS_OPTION_PTYPE]=METIS_PTYPE_RB; 75 | } 76 | 77 | // STEP 3: Convert unstructured grid to METIS mesh 78 | eptr[0] = 0; 79 | vtkIdList *cellIds = vtkIdList::New(); 80 | for(vtkIdType cellIdx=0; cellIdx < data->GetNumberOfCells(); ++cellIdx) 81 | { 82 | cellIds->Reset(); 83 | data->GetCellPoints(cellIdx,cellIds); 84 | 85 | for(vtkIdType nodeIdx=0; nodeIdx < cellIds->GetNumberOfIds(); ++nodeIdx ) 86 | { 87 | eind.push_back( cellIds->GetId(nodeIdx) ); 88 | } // END for all cell nodes 89 | 90 | eptr[cellIdx+1] = eind.size(); 91 | } // END for all grid cells 92 | cellIds->Delete(); 93 | 94 | // STEP 4: Partition METIS mesh 95 | int rc = METIS_PartMeshNodal( 96 | &ne, &nn, &eptr[0],&eind[0], 97 | vwgt,vsize,&nparts,tpwgts,options, 98 | &objval,&epart[0],&npart[0]); 99 | 100 | // STEP 5: Add output array 101 | vtkNew partitionIds; 102 | partitionIds->SetName("PartitionID"); 103 | partitionIds->SetNumberOfValues(data->GetNumberOfCells()); 104 | for(vtkIdType cellIdx=0; cellIdx < data->GetNumberOfCells(); ++cellIdx) 105 | { 106 | partitionIds->SetValue(cellIdx, epart[ cellIdx ]); 107 | } 108 | data->GetCellData()->AddArray( partitionIds.GetPointer() ); 109 | } 110 | 111 | } // end of private namespace 112 | 113 | //------------------------------------------------------------------------------ 114 | vtkStandardNewMacro(vtkMetisMeshPartitioner); 115 | 116 | //------------------------------------------------------------------------------ 117 | vtkMetisMeshPartitioner::vtkMetisMeshPartitioner() 118 | { 119 | this->NumberOfPartitions = 5; 120 | } 121 | 122 | //------------------------------------------------------------------------------ 123 | vtkMetisMeshPartitioner::~vtkMetisMeshPartitioner() 124 | { 125 | } 126 | 127 | //------------------------------------------------------------------------------ 128 | void vtkMetisMeshPartitioner::PrintSelf(ostream& os, vtkIndent indent) 129 | { 130 | this->Superclass::PrintSelf(os,indent); 131 | } 132 | 133 | //------------------------------------------------------------------------------ 134 | int vtkMetisMeshPartitioner::RequestData( 135 | vtkInformation* vtkNotUsed(request), 136 | vtkInformationVector **inputVector, 137 | vtkInformationVector *outputVector) 138 | { 139 | // STEP 0: Get input object 140 | vtkInformation *input = inputVector[0]->GetInformationObject( 0 ); 141 | assert("pre: input information object is NULL!" && (input != NULL) ); 142 | vtkDataObject *inputData = input->Get( vtkDataObject::DATA_OBJECT() ); 143 | assert("pre: input grid is NULL!" && (inputData != NULL) ); 144 | 145 | // STEP 1: Get output object 146 | vtkInformation *output = outputVector->GetInformationObject( 0 ); 147 | assert("pre: output information object is NULL!" && (output != NULL) ); 148 | vtkDataObject *outputData = output->Get(vtkDataObject::DATA_OBJECT() ); 149 | 150 | // STEP 2: Shallow copy input object to output 151 | outputData->ShallowCopy( inputData ); 152 | 153 | // STEP 3: Short-circuit here if we are not partitioning 154 | if( this->NumberOfPartitions < 2 ) 155 | { 156 | return 1; 157 | } 158 | 159 | if(vtkUnstructuredGrid::SafeDownCast(outputData)) 160 | { 161 | Partition(vtkUnstructuredGrid::SafeDownCast(outputData), this->NumberOfPartitions); 162 | } 163 | else if(vtkPolyData::SafeDownCast(outputData)) 164 | { 165 | Partition(vtkPolyData::SafeDownCast(outputData), this->NumberOfPartitions); 166 | } 167 | else if(vtkStructuredGrid::SafeDownCast(outputData)) 168 | { 169 | Partition(vtkUnstructuredGrid::SafeDownCast(outputData), this->NumberOfPartitions); 170 | } 171 | else 172 | { 173 | vtkErrorMacro(<<"Unsupported data type"); 174 | return 0; 175 | } 176 | return 1; 177 | } 178 | --------------------------------------------------------------------------------