170034214SMatthew G. Knepley #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 270034214SMatthew G. Knepley 377623264SMatthew G. Knepley PetscClassId PETSCPARTITIONER_CLASSID = 0; 477623264SMatthew G. Knepley 577623264SMatthew G. Knepley PetscFunctionList PetscPartitionerList = NULL; 677623264SMatthew G. Knepley PetscBool PetscPartitionerRegisterAllCalled = PETSC_FALSE; 777623264SMatthew G. Knepley 877623264SMatthew G. Knepley PetscBool ChacoPartitionercite = PETSC_FALSE; 977623264SMatthew G. Knepley const char ChacoPartitionerCitation[] = "@inproceedings{Chaco95,\n" 1077623264SMatthew G. Knepley " author = {Bruce Hendrickson and Robert Leland},\n" 1177623264SMatthew G. Knepley " title = {A multilevel algorithm for partitioning graphs},\n" 1277623264SMatthew G. Knepley " booktitle = {Supercomputing '95: Proceedings of the 1995 ACM/IEEE Conference on Supercomputing (CDROM)}," 1377623264SMatthew G. Knepley " isbn = {0-89791-816-9},\n" 1477623264SMatthew G. Knepley " pages = {28},\n" 1577623264SMatthew G. Knepley " doi = {http://doi.acm.org/10.1145/224170.224228},\n" 1677623264SMatthew G. Knepley " publisher = {ACM Press},\n" 1777623264SMatthew G. Knepley " address = {New York},\n" 1877623264SMatthew G. Knepley " year = {1995}\n}\n"; 1977623264SMatthew G. Knepley 2077623264SMatthew G. Knepley PetscBool ParMetisPartitionercite = PETSC_FALSE; 2177623264SMatthew G. Knepley const char ParMetisPartitionerCitation[] = "@article{KarypisKumar98,\n" 2277623264SMatthew G. Knepley " author = {George Karypis and Vipin Kumar},\n" 2377623264SMatthew G. Knepley " title = {A Parallel Algorithm for Multilevel Graph Partitioning and Sparse Matrix Ordering},\n" 2477623264SMatthew G. Knepley " journal = {Journal of Parallel and Distributed Computing},\n" 2577623264SMatthew G. Knepley " volume = {48},\n" 2677623264SMatthew G. Knepley " pages = {71--85},\n" 2777623264SMatthew G. Knepley " year = {1998}\n}\n"; 2877623264SMatthew G. Knepley 2970034214SMatthew G. Knepley #undef __FUNCT__ 3070034214SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateNeighborCSR" 3170034214SMatthew G. Knepley PetscErrorCode DMPlexCreateNeighborCSR(DM dm, PetscInt cellHeight, PetscInt *numVertices, PetscInt **offsets, PetscInt **adjacency) 3270034214SMatthew G. Knepley { 3370034214SMatthew G. Knepley const PetscInt maxFaceCases = 30; 3470034214SMatthew G. Knepley PetscInt numFaceCases = 0; 3570034214SMatthew G. Knepley PetscInt numFaceVertices[30]; /* maxFaceCases, C89 sucks sucks sucks */ 3670034214SMatthew G. Knepley PetscInt *off, *adj; 3770034214SMatthew G. Knepley PetscInt *neighborCells = NULL; 3870034214SMatthew G. Knepley PetscInt dim, cellDim, depth = 0, faceDepth, cStart, cEnd, c, numCells, cell; 3970034214SMatthew G. Knepley PetscErrorCode ierr; 4070034214SMatthew G. Knepley 4170034214SMatthew G. Knepley PetscFunctionBegin; 4270034214SMatthew G. Knepley /* For parallel partitioning, I think you have to communicate supports */ 43c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4470034214SMatthew G. Knepley cellDim = dim - cellHeight; 4570034214SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4670034214SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 4770034214SMatthew G. Knepley if (cEnd - cStart == 0) { 4870034214SMatthew G. Knepley if (numVertices) *numVertices = 0; 4970034214SMatthew G. Knepley if (offsets) *offsets = NULL; 5070034214SMatthew G. Knepley if (adjacency) *adjacency = NULL; 5170034214SMatthew G. Knepley PetscFunctionReturn(0); 5270034214SMatthew G. Knepley } 5370034214SMatthew G. Knepley numCells = cEnd - cStart; 5470034214SMatthew G. Knepley faceDepth = depth - cellHeight; 5570034214SMatthew G. Knepley if (dim == depth) { 5670034214SMatthew G. Knepley PetscInt f, fStart, fEnd; 5770034214SMatthew G. Knepley 5870034214SMatthew G. Knepley ierr = PetscCalloc1(numCells+1, &off);CHKERRQ(ierr); 5970034214SMatthew G. Knepley /* Count neighboring cells */ 6070034214SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight+1, &fStart, &fEnd);CHKERRQ(ierr); 6170034214SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 6270034214SMatthew G. Knepley const PetscInt *support; 6370034214SMatthew G. Knepley PetscInt supportSize; 6470034214SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6570034214SMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6670034214SMatthew G. Knepley if (supportSize == 2) { 679ffc88e4SToby Isaac PetscInt numChildren; 689ffc88e4SToby Isaac 699ffc88e4SToby Isaac ierr = DMPlexGetTreeChildren(dm,f,&numChildren,NULL);CHKERRQ(ierr); 709ffc88e4SToby Isaac if (!numChildren) { 7170034214SMatthew G. Knepley ++off[support[0]-cStart+1]; 7270034214SMatthew G. Knepley ++off[support[1]-cStart+1]; 7370034214SMatthew G. Knepley } 7470034214SMatthew G. Knepley } 759ffc88e4SToby Isaac } 7670034214SMatthew G. Knepley /* Prefix sum */ 7770034214SMatthew G. Knepley for (c = 1; c <= numCells; ++c) off[c] += off[c-1]; 7870034214SMatthew G. Knepley if (adjacency) { 7970034214SMatthew G. Knepley PetscInt *tmp; 8070034214SMatthew G. Knepley 8170034214SMatthew G. Knepley ierr = PetscMalloc1(off[numCells], &adj);CHKERRQ(ierr); 8270034214SMatthew G. Knepley ierr = PetscMalloc1((numCells+1), &tmp);CHKERRQ(ierr); 8370034214SMatthew G. Knepley ierr = PetscMemcpy(tmp, off, (numCells+1) * sizeof(PetscInt));CHKERRQ(ierr); 8470034214SMatthew G. Knepley /* Get neighboring cells */ 8570034214SMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 8670034214SMatthew G. Knepley const PetscInt *support; 8770034214SMatthew G. Knepley PetscInt supportSize; 8870034214SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 8970034214SMatthew G. Knepley ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 9070034214SMatthew G. Knepley if (supportSize == 2) { 919ffc88e4SToby Isaac PetscInt numChildren; 929ffc88e4SToby Isaac 939ffc88e4SToby Isaac ierr = DMPlexGetTreeChildren(dm,f,&numChildren,NULL);CHKERRQ(ierr); 949ffc88e4SToby Isaac if (!numChildren) { 9570034214SMatthew G. Knepley adj[tmp[support[0]-cStart]++] = support[1]; 9670034214SMatthew G. Knepley adj[tmp[support[1]-cStart]++] = support[0]; 9770034214SMatthew G. Knepley } 9870034214SMatthew G. Knepley } 999ffc88e4SToby Isaac } 10070034214SMatthew G. Knepley #if defined(PETSC_USE_DEBUG) 10170034214SMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) if (tmp[c] != off[c+1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Offset %d != %d for cell %d", tmp[c], off[c], c+cStart); 10270034214SMatthew G. Knepley #endif 10370034214SMatthew G. Knepley ierr = PetscFree(tmp);CHKERRQ(ierr); 10470034214SMatthew G. Knepley } 10570034214SMatthew G. Knepley if (numVertices) *numVertices = numCells; 10670034214SMatthew G. Knepley if (offsets) *offsets = off; 10770034214SMatthew G. Knepley if (adjacency) *adjacency = adj; 10870034214SMatthew G. Knepley PetscFunctionReturn(0); 10970034214SMatthew G. Knepley } 11070034214SMatthew G. Knepley /* Setup face recognition */ 11170034214SMatthew G. Knepley if (faceDepth == 1) { 11270034214SMatthew G. Knepley PetscInt cornersSeen[30] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Could use PetscBT */ 11370034214SMatthew G. Knepley 11470034214SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 11570034214SMatthew G. Knepley PetscInt corners; 11670034214SMatthew G. Knepley 11770034214SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &corners);CHKERRQ(ierr); 11870034214SMatthew G. Knepley if (!cornersSeen[corners]) { 11970034214SMatthew G. Knepley PetscInt nFV; 12070034214SMatthew G. Knepley 12170034214SMatthew G. Knepley if (numFaceCases >= maxFaceCases) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Exceeded maximum number of face recognition cases"); 12270034214SMatthew G. Knepley cornersSeen[corners] = 1; 12370034214SMatthew G. Knepley 12470034214SMatthew G. Knepley ierr = DMPlexGetNumFaceVertices(dm, cellDim, corners, &nFV);CHKERRQ(ierr); 12570034214SMatthew G. Knepley 12670034214SMatthew G. Knepley numFaceVertices[numFaceCases++] = nFV; 12770034214SMatthew G. Knepley } 12870034214SMatthew G. Knepley } 12970034214SMatthew G. Knepley } 13070034214SMatthew G. Knepley ierr = PetscCalloc1(numCells+1, &off);CHKERRQ(ierr); 13170034214SMatthew G. Knepley /* Count neighboring cells */ 13270034214SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 13370034214SMatthew G. Knepley PetscInt numNeighbors = PETSC_DETERMINE, n; 13470034214SMatthew G. Knepley 1358b0b4c70SToby Isaac ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &numNeighbors, &neighborCells);CHKERRQ(ierr); 13670034214SMatthew G. Knepley /* Get meet with each cell, and check with recognizer (could optimize to check each pair only once) */ 13770034214SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 13870034214SMatthew G. Knepley PetscInt cellPair[2]; 13970034214SMatthew G. Knepley PetscBool found = faceDepth > 1 ? PETSC_TRUE : PETSC_FALSE; 14070034214SMatthew G. Knepley PetscInt meetSize = 0; 14170034214SMatthew G. Knepley const PetscInt *meet = NULL; 14270034214SMatthew G. Knepley 14370034214SMatthew G. Knepley cellPair[0] = cell; cellPair[1] = neighborCells[n]; 14470034214SMatthew G. Knepley if (cellPair[0] == cellPair[1]) continue; 14570034214SMatthew G. Knepley if (!found) { 14670034214SMatthew G. Knepley ierr = DMPlexGetMeet(dm, 2, cellPair, &meetSize, &meet);CHKERRQ(ierr); 14770034214SMatthew G. Knepley if (meetSize) { 14870034214SMatthew G. Knepley PetscInt f; 14970034214SMatthew G. Knepley 15070034214SMatthew G. Knepley for (f = 0; f < numFaceCases; ++f) { 15170034214SMatthew G. Knepley if (numFaceVertices[f] == meetSize) { 15270034214SMatthew G. Knepley found = PETSC_TRUE; 15370034214SMatthew G. Knepley break; 15470034214SMatthew G. Knepley } 15570034214SMatthew G. Knepley } 15670034214SMatthew G. Knepley } 15770034214SMatthew G. Knepley ierr = DMPlexRestoreMeet(dm, 2, cellPair, &meetSize, &meet);CHKERRQ(ierr); 15870034214SMatthew G. Knepley } 15970034214SMatthew G. Knepley if (found) ++off[cell-cStart+1]; 16070034214SMatthew G. Knepley } 16170034214SMatthew G. Knepley } 16270034214SMatthew G. Knepley /* Prefix sum */ 16370034214SMatthew G. Knepley for (cell = 1; cell <= numCells; ++cell) off[cell] += off[cell-1]; 16470034214SMatthew G. Knepley 16570034214SMatthew G. Knepley if (adjacency) { 16670034214SMatthew G. Knepley ierr = PetscMalloc1(off[numCells], &adj);CHKERRQ(ierr); 16770034214SMatthew G. Knepley /* Get neighboring cells */ 16870034214SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 16970034214SMatthew G. Knepley PetscInt numNeighbors = PETSC_DETERMINE, n; 17070034214SMatthew G. Knepley PetscInt cellOffset = 0; 17170034214SMatthew G. Knepley 1728b0b4c70SToby Isaac ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &numNeighbors, &neighborCells);CHKERRQ(ierr); 17370034214SMatthew G. Knepley /* Get meet with each cell, and check with recognizer (could optimize to check each pair only once) */ 17470034214SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 17570034214SMatthew G. Knepley PetscInt cellPair[2]; 17670034214SMatthew G. Knepley PetscBool found = faceDepth > 1 ? PETSC_TRUE : PETSC_FALSE; 17770034214SMatthew G. Knepley PetscInt meetSize = 0; 17870034214SMatthew G. Knepley const PetscInt *meet = NULL; 17970034214SMatthew G. Knepley 18070034214SMatthew G. Knepley cellPair[0] = cell; cellPair[1] = neighborCells[n]; 18170034214SMatthew G. Knepley if (cellPair[0] == cellPair[1]) continue; 18270034214SMatthew G. Knepley if (!found) { 18370034214SMatthew G. Knepley ierr = DMPlexGetMeet(dm, 2, cellPair, &meetSize, &meet);CHKERRQ(ierr); 18470034214SMatthew G. Knepley if (meetSize) { 18570034214SMatthew G. Knepley PetscInt f; 18670034214SMatthew G. Knepley 18770034214SMatthew G. Knepley for (f = 0; f < numFaceCases; ++f) { 18870034214SMatthew G. Knepley if (numFaceVertices[f] == meetSize) { 18970034214SMatthew G. Knepley found = PETSC_TRUE; 19070034214SMatthew G. Knepley break; 19170034214SMatthew G. Knepley } 19270034214SMatthew G. Knepley } 19370034214SMatthew G. Knepley } 19470034214SMatthew G. Knepley ierr = DMPlexRestoreMeet(dm, 2, cellPair, &meetSize, &meet);CHKERRQ(ierr); 19570034214SMatthew G. Knepley } 19670034214SMatthew G. Knepley if (found) { 19770034214SMatthew G. Knepley adj[off[cell-cStart]+cellOffset] = neighborCells[n]; 19870034214SMatthew G. Knepley ++cellOffset; 19970034214SMatthew G. Knepley } 20070034214SMatthew G. Knepley } 20170034214SMatthew G. Knepley } 20270034214SMatthew G. Knepley } 20370034214SMatthew G. Knepley ierr = PetscFree(neighborCells);CHKERRQ(ierr); 20470034214SMatthew G. Knepley if (numVertices) *numVertices = numCells; 20570034214SMatthew G. Knepley if (offsets) *offsets = off; 20670034214SMatthew G. Knepley if (adjacency) *adjacency = adj; 20770034214SMatthew G. Knepley PetscFunctionReturn(0); 20870034214SMatthew G. Knepley } 20970034214SMatthew G. Knepley 21077623264SMatthew G. Knepley #undef __FUNCT__ 21177623264SMatthew G. Knepley #define __FUNCT__ "DMPlexEnlargePartition" 21277623264SMatthew G. Knepley /* Expand the partition by BFS on the adjacency graph */ 21377623264SMatthew G. Knepley PetscErrorCode DMPlexEnlargePartition(DM dm, const PetscInt start[], const PetscInt adjacency[], PetscSection origPartSection, IS origPartition, PetscSection partSection, IS *partition) 21477623264SMatthew G. Knepley { 21577623264SMatthew G. Knepley PetscHashI h; 21677623264SMatthew G. Knepley const PetscInt *points; 21777623264SMatthew G. Knepley PetscInt **tmpPoints, *newPoints, totPoints = 0; 21877623264SMatthew G. Knepley PetscInt pStart, pEnd, part, q; 21977623264SMatthew G. Knepley PetscBool useCone; 22077623264SMatthew G. Knepley PetscErrorCode ierr; 22177623264SMatthew G. Knepley 22277623264SMatthew G. Knepley PetscFunctionBegin; 22377623264SMatthew G. Knepley PetscHashICreate(h); 22477623264SMatthew G. Knepley ierr = PetscSectionGetChart(origPartSection, &pStart, &pEnd);CHKERRQ(ierr); 22577623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, pStart, pEnd);CHKERRQ(ierr); 22677623264SMatthew G. Knepley ierr = ISGetIndices(origPartition, &points);CHKERRQ(ierr); 22777623264SMatthew G. Knepley ierr = PetscMalloc1((pEnd - pStart), &tmpPoints);CHKERRQ(ierr); 22877623264SMatthew G. Knepley ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 22977623264SMatthew G. Knepley ierr = DMPlexSetAdjacencyUseCone(dm, PETSC_TRUE);CHKERRQ(ierr); 23077623264SMatthew G. Knepley for (part = pStart; part < pEnd; ++part) { 23177623264SMatthew G. Knepley PetscInt *adj = NULL; 23277623264SMatthew G. Knepley PetscInt numPoints, nP, numNewPoints, off, p, n = 0; 23377623264SMatthew G. Knepley 23477623264SMatthew G. Knepley PetscHashIClear(h); 23577623264SMatthew G. Knepley ierr = PetscSectionGetDof(origPartSection, part, &numPoints);CHKERRQ(ierr); 23677623264SMatthew G. Knepley ierr = PetscSectionGetOffset(origPartSection, part, &off);CHKERRQ(ierr); 23777623264SMatthew G. Knepley /* Add all existing points to h */ 23877623264SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 23977623264SMatthew G. Knepley const PetscInt point = points[off+p]; 24077623264SMatthew G. Knepley PetscHashIAdd(h, point, 1); 24177623264SMatthew G. Knepley } 24277623264SMatthew G. Knepley PetscHashISize(h, nP); 24377623264SMatthew G. Knepley if (nP != numPoints) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Invalid partition has %d points, but only %d were unique", numPoints, nP); 24477623264SMatthew G. Knepley /* Add all points in next BFS level */ 24577623264SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 24677623264SMatthew G. Knepley const PetscInt point = points[off+p]; 24777623264SMatthew G. Knepley PetscInt adjSize = PETSC_DETERMINE, a; 24877623264SMatthew G. Knepley 24977623264SMatthew G. Knepley ierr = DMPlexGetAdjacency(dm, point, &adjSize, &adj);CHKERRQ(ierr); 25077623264SMatthew G. Knepley for (a = 0; a < adjSize; ++a) PetscHashIAdd(h, adj[a], 1); 25177623264SMatthew G. Knepley } 25277623264SMatthew G. Knepley PetscHashISize(h, numNewPoints); 25377623264SMatthew G. Knepley ierr = PetscSectionSetDof(partSection, part, numNewPoints);CHKERRQ(ierr); 25477623264SMatthew G. Knepley ierr = PetscMalloc1(numNewPoints, &tmpPoints[part]);CHKERRQ(ierr); 25577623264SMatthew G. Knepley ierr = PetscHashIGetKeys(h, &n, tmpPoints[part]);CHKERRQ(ierr); 25677623264SMatthew G. Knepley ierr = PetscFree(adj);CHKERRQ(ierr); 25777623264SMatthew G. Knepley totPoints += numNewPoints; 25877623264SMatthew G. Knepley } 25977623264SMatthew G. Knepley ierr = DMPlexSetAdjacencyUseCone(dm, useCone);CHKERRQ(ierr); 26077623264SMatthew G. Knepley ierr = ISRestoreIndices(origPartition, &points);CHKERRQ(ierr); 26177623264SMatthew G. Knepley PetscHashIDestroy(h); 26277623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 26377623264SMatthew G. Knepley ierr = PetscMalloc1(totPoints, &newPoints);CHKERRQ(ierr); 26477623264SMatthew G. Knepley for (part = pStart, q = 0; part < pEnd; ++part) { 26577623264SMatthew G. Knepley PetscInt numPoints, p; 26677623264SMatthew G. Knepley 26777623264SMatthew G. Knepley ierr = PetscSectionGetDof(partSection, part, &numPoints);CHKERRQ(ierr); 26877623264SMatthew G. Knepley for (p = 0; p < numPoints; ++p, ++q) newPoints[q] = tmpPoints[part][p]; 26977623264SMatthew G. Knepley ierr = PetscFree(tmpPoints[part]);CHKERRQ(ierr); 27077623264SMatthew G. Knepley } 27177623264SMatthew G. Knepley ierr = PetscFree(tmpPoints);CHKERRQ(ierr); 27277623264SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), totPoints, newPoints, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 27377623264SMatthew G. Knepley PetscFunctionReturn(0); 27477623264SMatthew G. Knepley } 27577623264SMatthew G. Knepley 27677623264SMatthew G. Knepley #undef __FUNCT__ 27777623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerRegister" 27877623264SMatthew G. Knepley /*@C 27977623264SMatthew G. Knepley PetscPartitionerRegister - Adds a new PetscPartitioner implementation 28077623264SMatthew G. Knepley 28177623264SMatthew G. Knepley Not Collective 28277623264SMatthew G. Knepley 28377623264SMatthew G. Knepley Input Parameters: 28477623264SMatthew G. Knepley + name - The name of a new user-defined creation routine 28577623264SMatthew G. Knepley - create_func - The creation routine itself 28677623264SMatthew G. Knepley 28777623264SMatthew G. Knepley Notes: 28877623264SMatthew G. Knepley PetscPartitionerRegister() may be called multiple times to add several user-defined PetscPartitioners 28977623264SMatthew G. Knepley 29077623264SMatthew G. Knepley Sample usage: 29177623264SMatthew G. Knepley .vb 29277623264SMatthew G. Knepley PetscPartitionerRegister("my_part", MyPetscPartitionerCreate); 29377623264SMatthew G. Knepley .ve 29477623264SMatthew G. Knepley 29577623264SMatthew G. Knepley Then, your PetscPartitioner type can be chosen with the procedural interface via 29677623264SMatthew G. Knepley .vb 29777623264SMatthew G. Knepley PetscPartitionerCreate(MPI_Comm, PetscPartitioner *); 29877623264SMatthew G. Knepley PetscPartitionerSetType(PetscPartitioner, "my_part"); 29977623264SMatthew G. Knepley .ve 30077623264SMatthew G. Knepley or at runtime via the option 30177623264SMatthew G. Knepley .vb 30277623264SMatthew G. Knepley -petscpartitioner_type my_part 30377623264SMatthew G. Knepley .ve 30477623264SMatthew G. Knepley 30577623264SMatthew G. Knepley Level: advanced 30677623264SMatthew G. Knepley 30777623264SMatthew G. Knepley .keywords: PetscPartitioner, register 30877623264SMatthew G. Knepley .seealso: PetscPartitionerRegisterAll(), PetscPartitionerRegisterDestroy() 30977623264SMatthew G. Knepley 31077623264SMatthew G. Knepley @*/ 31177623264SMatthew G. Knepley PetscErrorCode PetscPartitionerRegister(const char sname[], PetscErrorCode (*function)(PetscPartitioner)) 31277623264SMatthew G. Knepley { 31377623264SMatthew G. Knepley PetscErrorCode ierr; 31477623264SMatthew G. Knepley 31577623264SMatthew G. Knepley PetscFunctionBegin; 31677623264SMatthew G. Knepley ierr = PetscFunctionListAdd(&PetscPartitionerList, sname, function);CHKERRQ(ierr); 31777623264SMatthew G. Knepley PetscFunctionReturn(0); 31877623264SMatthew G. Knepley } 31977623264SMatthew G. Knepley 32077623264SMatthew G. Knepley #undef __FUNCT__ 32177623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerSetType" 32277623264SMatthew G. Knepley /*@C 32377623264SMatthew G. Knepley PetscPartitionerSetType - Builds a particular PetscPartitioner 32477623264SMatthew G. Knepley 32577623264SMatthew G. Knepley Collective on PetscPartitioner 32677623264SMatthew G. Knepley 32777623264SMatthew G. Knepley Input Parameters: 32877623264SMatthew G. Knepley + part - The PetscPartitioner object 32977623264SMatthew G. Knepley - name - The kind of partitioner 33077623264SMatthew G. Knepley 33177623264SMatthew G. Knepley Options Database Key: 33277623264SMatthew G. Knepley . -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types 33377623264SMatthew G. Knepley 33477623264SMatthew G. Knepley Level: intermediate 33577623264SMatthew G. Knepley 33677623264SMatthew G. Knepley .keywords: PetscPartitioner, set, type 33777623264SMatthew G. Knepley .seealso: PetscPartitionerGetType(), PetscPartitionerCreate() 33877623264SMatthew G. Knepley @*/ 33977623264SMatthew G. Knepley PetscErrorCode PetscPartitionerSetType(PetscPartitioner part, PetscPartitionerType name) 34077623264SMatthew G. Knepley { 34177623264SMatthew G. Knepley PetscErrorCode (*r)(PetscPartitioner); 34277623264SMatthew G. Knepley PetscBool match; 34377623264SMatthew G. Knepley PetscErrorCode ierr; 34477623264SMatthew G. Knepley 34577623264SMatthew G. Knepley PetscFunctionBegin; 34677623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 34777623264SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) part, name, &match);CHKERRQ(ierr); 34877623264SMatthew G. Knepley if (match) PetscFunctionReturn(0); 34977623264SMatthew G. Knepley 35077623264SMatthew G. Knepley if (!PetscPartitionerRegisterAllCalled) {ierr = PetscPartitionerRegisterAll();CHKERRQ(ierr);} 35177623264SMatthew G. Knepley ierr = PetscFunctionListFind(PetscPartitionerList, name, &r);CHKERRQ(ierr); 35277623264SMatthew G. Knepley if (!r) SETERRQ1(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscPartitioner type: %s", name); 35377623264SMatthew G. Knepley 35477623264SMatthew G. Knepley if (part->ops->destroy) { 35577623264SMatthew G. Knepley ierr = (*part->ops->destroy)(part);CHKERRQ(ierr); 35677623264SMatthew G. Knepley part->ops->destroy = NULL; 35777623264SMatthew G. Knepley } 35877623264SMatthew G. Knepley ierr = (*r)(part);CHKERRQ(ierr); 35977623264SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) part, name);CHKERRQ(ierr); 36077623264SMatthew G. Knepley PetscFunctionReturn(0); 36177623264SMatthew G. Knepley } 36277623264SMatthew G. Knepley 36377623264SMatthew G. Knepley #undef __FUNCT__ 36477623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerGetType" 36577623264SMatthew G. Knepley /*@C 36677623264SMatthew G. Knepley PetscPartitionerGetType - Gets the PetscPartitioner type name (as a string) from the object. 36777623264SMatthew G. Knepley 36877623264SMatthew G. Knepley Not Collective 36977623264SMatthew G. Knepley 37077623264SMatthew G. Knepley Input Parameter: 37177623264SMatthew G. Knepley . part - The PetscPartitioner 37277623264SMatthew G. Knepley 37377623264SMatthew G. Knepley Output Parameter: 37477623264SMatthew G. Knepley . name - The PetscPartitioner type name 37577623264SMatthew G. Knepley 37677623264SMatthew G. Knepley Level: intermediate 37777623264SMatthew G. Knepley 37877623264SMatthew G. Knepley .keywords: PetscPartitioner, get, type, name 37977623264SMatthew G. Knepley .seealso: PetscPartitionerSetType(), PetscPartitionerCreate() 38077623264SMatthew G. Knepley @*/ 38177623264SMatthew G. Knepley PetscErrorCode PetscPartitionerGetType(PetscPartitioner part, PetscPartitionerType *name) 38277623264SMatthew G. Knepley { 38377623264SMatthew G. Knepley PetscErrorCode ierr; 38477623264SMatthew G. Knepley 38577623264SMatthew G. Knepley PetscFunctionBegin; 38677623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 38777623264SMatthew G. Knepley PetscValidPointer(name, 2); 38877623264SMatthew G. Knepley if (!PetscPartitionerRegisterAllCalled) {ierr = PetscPartitionerRegisterAll();CHKERRQ(ierr);} 38977623264SMatthew G. Knepley *name = ((PetscObject) part)->type_name; 39077623264SMatthew G. Knepley PetscFunctionReturn(0); 39177623264SMatthew G. Knepley } 39277623264SMatthew G. Knepley 39377623264SMatthew G. Knepley #undef __FUNCT__ 39477623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView" 39577623264SMatthew G. Knepley /*@C 39677623264SMatthew G. Knepley PetscPartitionerView - Views a PetscPartitioner 39777623264SMatthew G. Knepley 39877623264SMatthew G. Knepley Collective on PetscPartitioner 39977623264SMatthew G. Knepley 40077623264SMatthew G. Knepley Input Parameter: 40177623264SMatthew G. Knepley + part - the PetscPartitioner object to view 40277623264SMatthew G. Knepley - v - the viewer 40377623264SMatthew G. Knepley 40477623264SMatthew G. Knepley Level: developer 40577623264SMatthew G. Knepley 40677623264SMatthew G. Knepley .seealso: PetscPartitionerDestroy() 40777623264SMatthew G. Knepley @*/ 40877623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView(PetscPartitioner part, PetscViewer v) 40977623264SMatthew G. Knepley { 41077623264SMatthew G. Knepley PetscErrorCode ierr; 41177623264SMatthew G. Knepley 41277623264SMatthew G. Knepley PetscFunctionBegin; 41377623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 41477623264SMatthew G. Knepley if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) part), &v);CHKERRQ(ierr);} 41577623264SMatthew G. Knepley if (part->ops->view) {ierr = (*part->ops->view)(part, v);CHKERRQ(ierr);} 41677623264SMatthew G. Knepley PetscFunctionReturn(0); 41777623264SMatthew G. Knepley } 41877623264SMatthew G. Knepley 41977623264SMatthew G. Knepley #undef __FUNCT__ 42077623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerViewFromOptions" 42177623264SMatthew G. Knepley /* 42277623264SMatthew G. Knepley PetscPartitionerViewFromOptions - Processes command line options to determine if/how a PetscPartitioner is to be viewed. 42377623264SMatthew G. Knepley 42477623264SMatthew G. Knepley Collective on PetscPartitioner 42577623264SMatthew G. Knepley 42677623264SMatthew G. Knepley Input Parameters: 42777623264SMatthew G. Knepley + part - the PetscPartitioner 42877623264SMatthew G. Knepley . prefix - prefix to use for viewing, or NULL 42977623264SMatthew G. Knepley - optionname - option to activate viewing 43077623264SMatthew G. Knepley 43177623264SMatthew G. Knepley Level: intermediate 43277623264SMatthew G. Knepley 43377623264SMatthew G. Knepley .keywords: PetscPartitioner, view, options, database 43477623264SMatthew G. Knepley .seealso: VecViewFromOptions(), MatViewFromOptions() 43577623264SMatthew G. Knepley */ 43677623264SMatthew G. Knepley PetscErrorCode PetscPartitionerViewFromOptions(PetscPartitioner part, const char prefix[], const char optionname[]) 43777623264SMatthew G. Knepley { 43877623264SMatthew G. Knepley PetscViewer viewer; 43977623264SMatthew G. Knepley PetscViewerFormat format; 44077623264SMatthew G. Knepley PetscBool flg; 44177623264SMatthew G. Knepley PetscErrorCode ierr; 44277623264SMatthew G. Knepley 44377623264SMatthew G. Knepley PetscFunctionBegin; 44477623264SMatthew G. Knepley if (prefix) {ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) part), prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr);} 44577623264SMatthew G. Knepley else {ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) part), ((PetscObject) part)->prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr);} 44677623264SMatthew G. Knepley if (flg) { 44777623264SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 44877623264SMatthew G. Knepley ierr = PetscPartitionerView(part, viewer);CHKERRQ(ierr); 44977623264SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 45077623264SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 45177623264SMatthew G. Knepley } 45277623264SMatthew G. Knepley PetscFunctionReturn(0); 45377623264SMatthew G. Knepley } 45477623264SMatthew G. Knepley #undef __FUNCT__ 45577623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerSetTypeFromOptions_Internal" 45677623264SMatthew G. Knepley PetscErrorCode PetscPartitionerSetTypeFromOptions_Internal(PetscPartitioner part) 45777623264SMatthew G. Knepley { 45877623264SMatthew G. Knepley const char *defaultType; 45977623264SMatthew G. Knepley char name[256]; 46077623264SMatthew G. Knepley PetscBool flg; 46177623264SMatthew G. Knepley PetscErrorCode ierr; 46277623264SMatthew G. Knepley 46377623264SMatthew G. Knepley PetscFunctionBegin; 46477623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 46577623264SMatthew G. Knepley if (!((PetscObject) part)->type_name) defaultType = PETSCPARTITIONERCHACO; 46677623264SMatthew G. Knepley else defaultType = ((PetscObject) part)->type_name; 46777623264SMatthew G. Knepley if (!PetscPartitionerRegisterAllCalled) {ierr = PetscPartitionerRegisterAll();CHKERRQ(ierr);} 46877623264SMatthew G. Knepley 46977623264SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) part);CHKERRQ(ierr); 47077623264SMatthew G. Knepley ierr = PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, defaultType, name, 256, &flg);CHKERRQ(ierr); 47177623264SMatthew G. Knepley if (flg) { 47277623264SMatthew G. Knepley ierr = PetscPartitionerSetType(part, name);CHKERRQ(ierr); 47377623264SMatthew G. Knepley } else if (!((PetscObject) part)->type_name) { 47477623264SMatthew G. Knepley ierr = PetscPartitionerSetType(part, defaultType);CHKERRQ(ierr); 47577623264SMatthew G. Knepley } 47677623264SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 47777623264SMatthew G. Knepley PetscFunctionReturn(0); 47877623264SMatthew G. Knepley } 47977623264SMatthew G. Knepley 48077623264SMatthew G. Knepley #undef __FUNCT__ 48177623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerSetFromOptions" 48277623264SMatthew G. Knepley /*@ 48377623264SMatthew G. Knepley PetscPartitionerSetFromOptions - sets parameters in a PetscPartitioner from the options database 48477623264SMatthew G. Knepley 48577623264SMatthew G. Knepley Collective on PetscPartitioner 48677623264SMatthew G. Knepley 48777623264SMatthew G. Knepley Input Parameter: 48877623264SMatthew G. Knepley . part - the PetscPartitioner object to set options for 48977623264SMatthew G. Knepley 49077623264SMatthew G. Knepley Level: developer 49177623264SMatthew G. Knepley 49277623264SMatthew G. Knepley .seealso: PetscPartitionerView() 49377623264SMatthew G. Knepley @*/ 49477623264SMatthew G. Knepley PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner part) 49577623264SMatthew G. Knepley { 49677623264SMatthew G. Knepley PetscErrorCode ierr; 49777623264SMatthew G. Knepley 49877623264SMatthew G. Knepley PetscFunctionBegin; 49977623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 50077623264SMatthew G. Knepley ierr = PetscPartitionerSetTypeFromOptions_Internal(part);CHKERRQ(ierr); 50177623264SMatthew G. Knepley 50277623264SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) part);CHKERRQ(ierr); 50377623264SMatthew G. Knepley if (part->ops->setfromoptions) {ierr = (*part->ops->setfromoptions)(part);CHKERRQ(ierr);} 50477623264SMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 50577623264SMatthew G. Knepley ierr = PetscObjectProcessOptionsHandlers((PetscObject) part);CHKERRQ(ierr); 50677623264SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 50777623264SMatthew G. Knepley ierr = PetscPartitionerViewFromOptions(part, NULL, "-petscpartitioner_view");CHKERRQ(ierr); 50877623264SMatthew G. Knepley PetscFunctionReturn(0); 50977623264SMatthew G. Knepley } 51077623264SMatthew G. Knepley 51177623264SMatthew G. Knepley #undef __FUNCT__ 51277623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerSetUp" 51377623264SMatthew G. Knepley /*@C 51477623264SMatthew G. Knepley PetscPartitionerSetUp - Construct data structures for the PetscPartitioner 51577623264SMatthew G. Knepley 51677623264SMatthew G. Knepley Collective on PetscPartitioner 51777623264SMatthew G. Knepley 51877623264SMatthew G. Knepley Input Parameter: 51977623264SMatthew G. Knepley . part - the PetscPartitioner object to setup 52077623264SMatthew G. Knepley 52177623264SMatthew G. Knepley Level: developer 52277623264SMatthew G. Knepley 52377623264SMatthew G. Knepley .seealso: PetscPartitionerView(), PetscPartitionerDestroy() 52477623264SMatthew G. Knepley @*/ 52577623264SMatthew G. Knepley PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part) 52677623264SMatthew G. Knepley { 52777623264SMatthew G. Knepley PetscErrorCode ierr; 52877623264SMatthew G. Knepley 52977623264SMatthew G. Knepley PetscFunctionBegin; 53077623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 53177623264SMatthew G. Knepley if (part->ops->setup) {ierr = (*part->ops->setup)(part);CHKERRQ(ierr);} 53277623264SMatthew G. Knepley PetscFunctionReturn(0); 53377623264SMatthew G. Knepley } 53477623264SMatthew G. Knepley 53577623264SMatthew G. Knepley #undef __FUNCT__ 53677623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerDestroy" 53777623264SMatthew G. Knepley /*@ 53877623264SMatthew G. Knepley PetscPartitionerDestroy - Destroys a PetscPartitioner object 53977623264SMatthew G. Knepley 54077623264SMatthew G. Knepley Collective on PetscPartitioner 54177623264SMatthew G. Knepley 54277623264SMatthew G. Knepley Input Parameter: 54377623264SMatthew G. Knepley . part - the PetscPartitioner object to destroy 54477623264SMatthew G. Knepley 54577623264SMatthew G. Knepley Level: developer 54677623264SMatthew G. Knepley 54777623264SMatthew G. Knepley .seealso: PetscPartitionerView() 54877623264SMatthew G. Knepley @*/ 54977623264SMatthew G. Knepley PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part) 55077623264SMatthew G. Knepley { 55177623264SMatthew G. Knepley PetscErrorCode ierr; 55277623264SMatthew G. Knepley 55377623264SMatthew G. Knepley PetscFunctionBegin; 55477623264SMatthew G. Knepley if (!*part) PetscFunctionReturn(0); 55577623264SMatthew G. Knepley PetscValidHeaderSpecific((*part), PETSCPARTITIONER_CLASSID, 1); 55677623264SMatthew G. Knepley 55777623264SMatthew G. Knepley if (--((PetscObject)(*part))->refct > 0) {*part = 0; PetscFunctionReturn(0);} 55877623264SMatthew G. Knepley ((PetscObject) (*part))->refct = 0; 55977623264SMatthew G. Knepley 56077623264SMatthew G. Knepley if ((*part)->ops->destroy) {ierr = (*(*part)->ops->destroy)(*part);CHKERRQ(ierr);} 56177623264SMatthew G. Knepley ierr = PetscHeaderDestroy(part);CHKERRQ(ierr); 56277623264SMatthew G. Knepley PetscFunctionReturn(0); 56377623264SMatthew G. Knepley } 56477623264SMatthew G. Knepley 56577623264SMatthew G. Knepley #undef __FUNCT__ 56677623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerCreate" 56777623264SMatthew G. Knepley /*@ 56877623264SMatthew G. Knepley PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType(). 56977623264SMatthew G. Knepley 57077623264SMatthew G. Knepley Collective on MPI_Comm 57177623264SMatthew G. Knepley 57277623264SMatthew G. Knepley Input Parameter: 57377623264SMatthew G. Knepley . comm - The communicator for the PetscPartitioner object 57477623264SMatthew G. Knepley 57577623264SMatthew G. Knepley Output Parameter: 57677623264SMatthew G. Knepley . part - The PetscPartitioner object 57777623264SMatthew G. Knepley 57877623264SMatthew G. Knepley Level: beginner 57977623264SMatthew G. Knepley 58077623264SMatthew G. Knepley .seealso: PetscPartitionerSetType(), PETSCPARTITIONERCHACO, PETSCPARTITIONERPARMETIS, PETSCPARTITIONERSHELL 58177623264SMatthew G. Knepley @*/ 58277623264SMatthew G. Knepley PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part) 58377623264SMatthew G. Knepley { 58477623264SMatthew G. Knepley PetscPartitioner p; 58577623264SMatthew G. Knepley PetscErrorCode ierr; 58677623264SMatthew G. Knepley 58777623264SMatthew G. Knepley PetscFunctionBegin; 58877623264SMatthew G. Knepley PetscValidPointer(part, 2); 58977623264SMatthew G. Knepley *part = NULL; 59077623264SMatthew G. Knepley ierr = PetscFVInitializePackage();CHKERRQ(ierr); 59177623264SMatthew G. Knepley 59277623264SMatthew G. Knepley ierr = PetscHeaderCreate(p, _p_PetscPartitioner, struct _PetscPartitionerOps, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView);CHKERRQ(ierr); 59377623264SMatthew G. Knepley ierr = PetscMemzero(p->ops, sizeof(struct _PetscPartitionerOps));CHKERRQ(ierr); 59477623264SMatthew G. Knepley 59577623264SMatthew G. Knepley *part = p; 59677623264SMatthew G. Knepley PetscFunctionReturn(0); 59777623264SMatthew G. Knepley } 59877623264SMatthew G. Knepley 59977623264SMatthew G. Knepley #undef __FUNCT__ 60077623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerPartition" 60177623264SMatthew G. Knepley /*@ 60277623264SMatthew G. Knepley PetscPartitionerPartition - Create a non-overlapping partition of the cells in the mesh 60377623264SMatthew G. Knepley 60477623264SMatthew G. Knepley Collective on DM 60577623264SMatthew G. Knepley 60677623264SMatthew G. Knepley Input Parameters: 60777623264SMatthew G. Knepley + part - The PetscPartitioner 60877623264SMatthew G. Knepley . dm - The mesh DM 60977623264SMatthew G. Knepley - enlarge - Expand each partition with neighbors 61077623264SMatthew G. Knepley 61177623264SMatthew G. Knepley Output Parameters: 61277623264SMatthew G. Knepley + partSection - The PetscSection giving the division of points by partition 61377623264SMatthew G. Knepley . partition - The list of points by partition 61477623264SMatthew G. Knepley . origPartSection - If enlarge is true, the PetscSection giving the division of points before enlarging by partition, otherwise NULL 61577623264SMatthew G. Knepley - origPartition - If enlarge is true, the list of points before enlarging by partition, otherwise NULL 61677623264SMatthew G. Knepley 61777623264SMatthew G. Knepley Note: Instead of cells, points at a given height can be partitioned by calling PetscPartitionerSetPointHeight() 61877623264SMatthew G. Knepley 61977623264SMatthew G. Knepley Level: developer 62077623264SMatthew G. Knepley 62177623264SMatthew G. Knepley .seealso DMPlexDistribute(), PetscPartitionerSetPointHeight(), PetscPartitionerCreate() 622*4b15ede2SMatthew G. Knepley @*/ 62377623264SMatthew G. Knepley PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, DM dm, PetscBool enlarge, PetscSection partSection, IS *partition, PetscSection origPartSection, IS *origPartition) 62477623264SMatthew G. Knepley { 62577623264SMatthew G. Knepley PetscMPIInt size; 62677623264SMatthew G. Knepley PetscErrorCode ierr; 62777623264SMatthew G. Knepley 62877623264SMatthew G. Knepley PetscFunctionBegin; 62977623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 63077623264SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 63177623264SMatthew G. Knepley PetscValidHeaderSpecific(partSection, PETSC_SECTION_CLASSID, 4); 63277623264SMatthew G. Knepley PetscValidPointer(partition, 5); 63377623264SMatthew G. Knepley if (enlarge) {PetscValidHeaderSpecific(origPartSection, PETSC_SECTION_CLASSID, 6);} 63477623264SMatthew G. Knepley if (enlarge) {PetscValidPointer(origPartition, 7);} 63577623264SMatthew G. Knepley ierr = MPI_Comm_size(PetscObjectComm((PetscObject) part), &size);CHKERRQ(ierr); 63677623264SMatthew G. Knepley *origPartition = NULL; 63777623264SMatthew G. Knepley if (size == 1) { 63877623264SMatthew G. Knepley PetscInt *points; 63977623264SMatthew G. Knepley PetscInt cStart, cEnd, c; 64077623264SMatthew G. Knepley 64177623264SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, part->height, &cStart, &cEnd);CHKERRQ(ierr); 64277623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, 0, size);CHKERRQ(ierr); 64377623264SMatthew G. Knepley ierr = PetscSectionSetDof(partSection, 0, cEnd-cStart);CHKERRQ(ierr); 64477623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 64577623264SMatthew G. Knepley ierr = PetscMalloc1(cEnd-cStart, &points);CHKERRQ(ierr); 64677623264SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) points[c] = c; 64777623264SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) part), cEnd-cStart, points, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 64877623264SMatthew G. Knepley PetscFunctionReturn(0); 64977623264SMatthew G. Knepley } 65077623264SMatthew G. Knepley if (part->height == 0) { 65177623264SMatthew G. Knepley PetscInt numVertices; 65277623264SMatthew G. Knepley PetscInt *start = NULL; 65377623264SMatthew G. Knepley PetscInt *adjacency = NULL; 65477623264SMatthew G. Knepley 65577623264SMatthew G. Knepley ierr = DMPlexCreateNeighborCSR(dm, 0, &numVertices, &start, &adjacency);CHKERRQ(ierr); 65677623264SMatthew G. Knepley if (!part->ops->partition) SETERRQ(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_WRONGSTATE, "PetscPartitioner has no type"); 65777623264SMatthew G. Knepley ierr = (*part->ops->partition)(part, dm, size, numVertices, start, adjacency, partSection, partition);CHKERRQ(ierr); 65877623264SMatthew G. Knepley if (enlarge) { 65977623264SMatthew G. Knepley origPartSection = partSection; 66077623264SMatthew G. Knepley *origPartition = *partition; 66177623264SMatthew G. Knepley 66277623264SMatthew G. Knepley ierr = DMPlexEnlargePartition(dm, start, adjacency, origPartSection, *origPartition, partSection, partition);CHKERRQ(ierr); 66377623264SMatthew G. Knepley } 66477623264SMatthew G. Knepley ierr = PetscFree(start);CHKERRQ(ierr); 66577623264SMatthew G. Knepley ierr = PetscFree(adjacency);CHKERRQ(ierr); 66677623264SMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_OUTOFRANGE, "Invalid height %D for points to partition", part->height); 66777623264SMatthew G. Knepley PetscFunctionReturn(0); 66877623264SMatthew G. Knepley } 66977623264SMatthew G. Knepley 67077623264SMatthew G. Knepley #undef __FUNCT__ 67177623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerDestroy_Shell" 67277623264SMatthew G. Knepley PetscErrorCode PetscPartitionerDestroy_Shell(PetscPartitioner part) 67377623264SMatthew G. Knepley { 67477623264SMatthew G. Knepley PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data; 67577623264SMatthew G. Knepley PetscErrorCode ierr; 67677623264SMatthew G. Knepley 67777623264SMatthew G. Knepley PetscFunctionBegin; 67877623264SMatthew G. Knepley ierr = PetscSectionDestroy(&p->section);CHKERRQ(ierr); 67977623264SMatthew G. Knepley ierr = ISDestroy(&p->partition);CHKERRQ(ierr); 68077623264SMatthew G. Knepley ierr = PetscFree(p);CHKERRQ(ierr); 68177623264SMatthew G. Knepley PetscFunctionReturn(0); 68277623264SMatthew G. Knepley } 68377623264SMatthew G. Knepley 68477623264SMatthew G. Knepley #undef __FUNCT__ 68577623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_Shell_Ascii" 68677623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_Shell_Ascii(PetscPartitioner part, PetscViewer viewer) 68777623264SMatthew G. Knepley { 68877623264SMatthew G. Knepley PetscViewerFormat format; 68977623264SMatthew G. Knepley PetscErrorCode ierr; 69077623264SMatthew G. Knepley 69177623264SMatthew G. Knepley PetscFunctionBegin; 69277623264SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 69377623264SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Shell Graph Partitioner:\n");CHKERRQ(ierr); 69477623264SMatthew G. Knepley PetscFunctionReturn(0); 69577623264SMatthew G. Knepley } 69677623264SMatthew G. Knepley 69777623264SMatthew G. Knepley #undef __FUNCT__ 69877623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_Shell" 69977623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_Shell(PetscPartitioner part, PetscViewer viewer) 70077623264SMatthew G. Knepley { 70177623264SMatthew G. Knepley PetscBool iascii; 70277623264SMatthew G. Knepley PetscErrorCode ierr; 70377623264SMatthew G. Knepley 70477623264SMatthew G. Knepley PetscFunctionBegin; 70577623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 70677623264SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 70777623264SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 70877623264SMatthew G. Knepley if (iascii) {ierr = PetscPartitionerView_Shell_Ascii(part, viewer);CHKERRQ(ierr);} 70977623264SMatthew G. Knepley PetscFunctionReturn(0); 71077623264SMatthew G. Knepley } 71177623264SMatthew G. Knepley 71277623264SMatthew G. Knepley #undef __FUNCT__ 71377623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerPartition_Shell" 71477623264SMatthew G. Knepley PetscErrorCode PetscPartitionerPartition_Shell(PetscPartitioner part, DM dm, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection partSection, IS *partition) 71577623264SMatthew G. Knepley { 71677623264SMatthew G. Knepley PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data; 71777623264SMatthew G. Knepley PetscInt np; 71877623264SMatthew G. Knepley PetscErrorCode ierr; 71977623264SMatthew G. Knepley 72077623264SMatthew G. Knepley PetscFunctionBegin; 72177623264SMatthew G. Knepley if (!numVertices) { 72277623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr); 72377623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 72477623264SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) part), 0, NULL, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 72577623264SMatthew G. Knepley PetscFunctionReturn(0); 72677623264SMatthew G. Knepley } 72777623264SMatthew G. Knepley ierr = PetscSectionGetChart(p->section, NULL, &np);CHKERRQ(ierr); 72877623264SMatthew G. Knepley if (nparts != np) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of requested partitions %d != configured partitions %d", nparts, np); 72977623264SMatthew G. Knepley ierr = ISGetLocalSize(p->partition, &np);CHKERRQ(ierr); 73077623264SMatthew G. Knepley if (numVertices != np) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input vertices %d != configured vertices %d", numVertices, np); 73177623264SMatthew G. Knepley partSection = p->section; 73277623264SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) p->section);CHKERRQ(ierr); 73377623264SMatthew G. Knepley *partition = p->partition; 73477623264SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) p->partition);CHKERRQ(ierr); 73577623264SMatthew G. Knepley PetscFunctionReturn(0); 73677623264SMatthew G. Knepley } 73777623264SMatthew G. Knepley 73877623264SMatthew G. Knepley #undef __FUNCT__ 73977623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerInitialize_Shell" 74077623264SMatthew G. Knepley PetscErrorCode PetscPartitionerInitialize_Shell(PetscPartitioner part) 74177623264SMatthew G. Knepley { 74277623264SMatthew G. Knepley PetscFunctionBegin; 74377623264SMatthew G. Knepley part->ops->view = PetscPartitionerView_Shell; 74477623264SMatthew G. Knepley part->ops->destroy = PetscPartitionerDestroy_Shell; 74577623264SMatthew G. Knepley part->ops->partition = PetscPartitionerPartition_Shell; 74677623264SMatthew G. Knepley PetscFunctionReturn(0); 74777623264SMatthew G. Knepley } 74877623264SMatthew G. Knepley 74977623264SMatthew G. Knepley /*MC 75077623264SMatthew G. Knepley PETSCPARTITIONERSHELL = "shell" - A PetscPartitioner object 75177623264SMatthew G. Knepley 75277623264SMatthew G. Knepley Level: intermediate 75377623264SMatthew G. Knepley 75477623264SMatthew G. Knepley .seealso: PetscPartitionerType, PetscPartitionerCreate(), PetscPartitionerSetType() 75577623264SMatthew G. Knepley M*/ 75677623264SMatthew G. Knepley 75777623264SMatthew G. Knepley #undef __FUNCT__ 75877623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerCreate_Shell" 75977623264SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscPartitionerCreate_Shell(PetscPartitioner part) 76077623264SMatthew G. Knepley { 76177623264SMatthew G. Knepley PetscPartitioner_Shell *p; 76277623264SMatthew G. Knepley PetscErrorCode ierr; 76377623264SMatthew G. Knepley 76477623264SMatthew G. Knepley PetscFunctionBegin; 76577623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 76677623264SMatthew G. Knepley ierr = PetscNewLog(part, &p);CHKERRQ(ierr); 76777623264SMatthew G. Knepley part->data = p; 76877623264SMatthew G. Knepley 76977623264SMatthew G. Knepley ierr = PetscPartitionerInitialize_Shell(part);CHKERRQ(ierr); 77077623264SMatthew G. Knepley PetscFunctionReturn(0); 77177623264SMatthew G. Knepley } 77277623264SMatthew G. Knepley 77377623264SMatthew G. Knepley #undef __FUNCT__ 77477623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerDestroy_Chaco" 77577623264SMatthew G. Knepley PetscErrorCode PetscPartitionerDestroy_Chaco(PetscPartitioner part) 77677623264SMatthew G. Knepley { 77777623264SMatthew G. Knepley PetscPartitioner_Chaco *p = (PetscPartitioner_Chaco *) part->data; 77877623264SMatthew G. Knepley PetscErrorCode ierr; 77977623264SMatthew G. Knepley 78077623264SMatthew G. Knepley PetscFunctionBegin; 78177623264SMatthew G. Knepley ierr = PetscFree(p);CHKERRQ(ierr); 78277623264SMatthew G. Knepley PetscFunctionReturn(0); 78377623264SMatthew G. Knepley } 78477623264SMatthew G. Knepley 78577623264SMatthew G. Knepley #undef __FUNCT__ 78677623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_Chaco_Ascii" 78777623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_Chaco_Ascii(PetscPartitioner part, PetscViewer viewer) 78877623264SMatthew G. Knepley { 78977623264SMatthew G. Knepley PetscViewerFormat format; 79077623264SMatthew G. Knepley PetscErrorCode ierr; 79177623264SMatthew G. Knepley 79277623264SMatthew G. Knepley PetscFunctionBegin; 79377623264SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 79477623264SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Chaco Graph Partitioner:\n");CHKERRQ(ierr); 79577623264SMatthew G. Knepley PetscFunctionReturn(0); 79677623264SMatthew G. Knepley } 79777623264SMatthew G. Knepley 79877623264SMatthew G. Knepley #undef __FUNCT__ 79977623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_Chaco" 80077623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_Chaco(PetscPartitioner part, PetscViewer viewer) 80177623264SMatthew G. Knepley { 80277623264SMatthew G. Knepley PetscBool iascii; 80377623264SMatthew G. Knepley PetscErrorCode ierr; 80477623264SMatthew G. Knepley 80577623264SMatthew G. Knepley PetscFunctionBegin; 80677623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 80777623264SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 80877623264SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 80977623264SMatthew G. Knepley if (iascii) {ierr = PetscPartitionerView_Chaco_Ascii(part, viewer);CHKERRQ(ierr);} 81077623264SMatthew G. Knepley PetscFunctionReturn(0); 81177623264SMatthew G. Knepley } 81277623264SMatthew G. Knepley 81370034214SMatthew G. Knepley #if defined(PETSC_HAVE_CHACO) 81470034214SMatthew G. Knepley #if defined(PETSC_HAVE_UNISTD_H) 81570034214SMatthew G. Knepley #include <unistd.h> 81670034214SMatthew G. Knepley #endif 81770034214SMatthew G. Knepley /* Chaco does not have an include file */ 81870034214SMatthew G. Knepley PETSC_EXTERN int interface(int nvtxs, int *start, int *adjacency, int *vwgts, 81970034214SMatthew G. Knepley float *ewgts, float *x, float *y, float *z, char *outassignname, 82070034214SMatthew G. Knepley char *outfilename, short *assignment, int architecture, int ndims_tot, 82170034214SMatthew G. Knepley int mesh_dims[3], double *goal, int global_method, int local_method, 82270034214SMatthew G. Knepley int rqi_flag, int vmax, int ndims, double eigtol, long seed); 82370034214SMatthew G. Knepley 82470034214SMatthew G. Knepley extern int FREE_GRAPH; 82577623264SMatthew G. Knepley #endif 82670034214SMatthew G. Knepley 82770034214SMatthew G. Knepley #undef __FUNCT__ 82877623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerPartition_Chaco" 82977623264SMatthew G. Knepley PetscErrorCode PetscPartitionerPartition_Chaco(PetscPartitioner part, DM dm, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection partSection, IS *partition) 83070034214SMatthew G. Knepley { 83177623264SMatthew G. Knepley #if defined(PETSC_HAVE_CHACO) 83270034214SMatthew G. Knepley enum {DEFAULT_METHOD = 1, INERTIAL_METHOD = 3}; 83370034214SMatthew G. Knepley MPI_Comm comm; 83470034214SMatthew G. Knepley int nvtxs = numVertices; /* number of vertices in full graph */ 83570034214SMatthew G. Knepley int *vwgts = NULL; /* weights for all vertices */ 83670034214SMatthew G. Knepley float *ewgts = NULL; /* weights for all edges */ 83770034214SMatthew G. Knepley float *x = NULL, *y = NULL, *z = NULL; /* coordinates for inertial method */ 83870034214SMatthew G. Knepley char *outassignname = NULL; /* name of assignment output file */ 83970034214SMatthew G. Knepley char *outfilename = NULL; /* output file name */ 84070034214SMatthew G. Knepley int architecture = 1; /* 0 => hypercube, d => d-dimensional mesh */ 84170034214SMatthew G. Knepley int ndims_tot = 0; /* total number of cube dimensions to divide */ 84270034214SMatthew G. Knepley int mesh_dims[3]; /* dimensions of mesh of processors */ 84370034214SMatthew G. Knepley double *goal = NULL; /* desired set sizes for each set */ 84470034214SMatthew G. Knepley int global_method = 1; /* global partitioning algorithm */ 84570034214SMatthew G. Knepley int local_method = 1; /* local partitioning algorithm */ 84670034214SMatthew G. Knepley int rqi_flag = 0; /* should I use RQI/Symmlq eigensolver? */ 84770034214SMatthew G. Knepley int vmax = 200; /* how many vertices to coarsen down to? */ 84870034214SMatthew G. Knepley int ndims = 1; /* number of eigenvectors (2^d sets) */ 84970034214SMatthew G. Knepley double eigtol = 0.001; /* tolerance on eigenvectors */ 85070034214SMatthew G. Knepley long seed = 123636512; /* for random graph mutations */ 85170034214SMatthew G. Knepley short int *assignment; /* Output partition */ 85270034214SMatthew G. Knepley int fd_stdout, fd_pipe[2]; 85370034214SMatthew G. Knepley PetscInt *points; 85470034214SMatthew G. Knepley int i, v, p; 85570034214SMatthew G. Knepley PetscErrorCode ierr; 85670034214SMatthew G. Knepley 85770034214SMatthew G. Knepley PetscFunctionBegin; 85870034214SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 85970034214SMatthew G. Knepley if (!numVertices) { 86077623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr); 86177623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 86270034214SMatthew G. Knepley ierr = ISCreateGeneral(comm, 0, NULL, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 86370034214SMatthew G. Knepley PetscFunctionReturn(0); 86470034214SMatthew G. Knepley } 86570034214SMatthew G. Knepley FREE_GRAPH = 0; /* Do not let Chaco free my memory */ 86670034214SMatthew G. Knepley for (i = 0; i < start[numVertices]; ++i) ++adjacency[i]; 86770034214SMatthew G. Knepley 86870034214SMatthew G. Knepley if (global_method == INERTIAL_METHOD) { 86970034214SMatthew G. Knepley /* manager.createCellCoordinates(nvtxs, &x, &y, &z); */ 87070034214SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "Inertial partitioning not yet supported"); 87170034214SMatthew G. Knepley } 87277623264SMatthew G. Knepley mesh_dims[0] = nparts; 87370034214SMatthew G. Knepley mesh_dims[1] = 1; 87470034214SMatthew G. Knepley mesh_dims[2] = 1; 87570034214SMatthew G. Knepley ierr = PetscMalloc1(nvtxs, &assignment);CHKERRQ(ierr); 87670034214SMatthew G. Knepley /* Chaco outputs to stdout. We redirect this to a buffer. */ 87770034214SMatthew G. Knepley /* TODO: check error codes for UNIX calls */ 87870034214SMatthew G. Knepley #if defined(PETSC_HAVE_UNISTD_H) 87970034214SMatthew G. Knepley { 88070034214SMatthew G. Knepley int piperet; 88170034214SMatthew G. Knepley piperet = pipe(fd_pipe); 88270034214SMatthew G. Knepley if (piperet) SETERRQ(comm,PETSC_ERR_SYS,"Could not create pipe"); 88370034214SMatthew G. Knepley fd_stdout = dup(1); 88470034214SMatthew G. Knepley close(1); 88570034214SMatthew G. Knepley dup2(fd_pipe[1], 1); 88670034214SMatthew G. Knepley } 88770034214SMatthew G. Knepley #endif 88870034214SMatthew G. Knepley ierr = interface(nvtxs, (int*) start, (int*) adjacency, vwgts, ewgts, x, y, z, outassignname, outfilename, 88970034214SMatthew G. Knepley assignment, architecture, ndims_tot, mesh_dims, goal, global_method, local_method, rqi_flag, 89070034214SMatthew G. Knepley vmax, ndims, eigtol, seed); 89170034214SMatthew G. Knepley #if defined(PETSC_HAVE_UNISTD_H) 89270034214SMatthew G. Knepley { 89370034214SMatthew G. Knepley char msgLog[10000]; 89470034214SMatthew G. Knepley int count; 89570034214SMatthew G. Knepley 89670034214SMatthew G. Knepley fflush(stdout); 89770034214SMatthew G. Knepley count = read(fd_pipe[0], msgLog, (10000-1)*sizeof(char)); 89870034214SMatthew G. Knepley if (count < 0) count = 0; 89970034214SMatthew G. Knepley msgLog[count] = 0; 90070034214SMatthew G. Knepley close(1); 90170034214SMatthew G. Knepley dup2(fd_stdout, 1); 90270034214SMatthew G. Knepley close(fd_stdout); 90370034214SMatthew G. Knepley close(fd_pipe[0]); 90470034214SMatthew G. Knepley close(fd_pipe[1]); 90570034214SMatthew G. Knepley if (ierr) SETERRQ1(comm, PETSC_ERR_LIB, "Error in Chaco library: %s", msgLog); 90670034214SMatthew G. Knepley } 90770034214SMatthew G. Knepley #endif 90870034214SMatthew G. Knepley /* Convert to PetscSection+IS */ 90977623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr); 91070034214SMatthew G. Knepley for (v = 0; v < nvtxs; ++v) { 91177623264SMatthew G. Knepley ierr = PetscSectionAddDof(partSection, assignment[v], 1);CHKERRQ(ierr); 91270034214SMatthew G. Knepley } 91377623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 91470034214SMatthew G. Knepley ierr = PetscMalloc1(nvtxs, &points);CHKERRQ(ierr); 91577623264SMatthew G. Knepley for (p = 0, i = 0; p < nparts; ++p) { 91670034214SMatthew G. Knepley for (v = 0; v < nvtxs; ++v) { 91770034214SMatthew G. Knepley if (assignment[v] == p) points[i++] = v; 91870034214SMatthew G. Knepley } 91970034214SMatthew G. Knepley } 92070034214SMatthew G. Knepley if (i != nvtxs) SETERRQ2(comm, PETSC_ERR_PLIB, "Number of points %D should be %D", i, nvtxs); 92170034214SMatthew G. Knepley ierr = ISCreateGeneral(comm, nvtxs, points, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 92270034214SMatthew G. Knepley if (global_method == INERTIAL_METHOD) { 92370034214SMatthew G. Knepley /* manager.destroyCellCoordinates(nvtxs, &x, &y, &z); */ 92470034214SMatthew G. Knepley } 92570034214SMatthew G. Knepley ierr = PetscFree(assignment);CHKERRQ(ierr); 92670034214SMatthew G. Knepley for (i = 0; i < start[numVertices]; ++i) --adjacency[i]; 92770034214SMatthew G. Knepley PetscFunctionReturn(0); 92877623264SMatthew G. Knepley #else 92977623264SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "Mesh partitioning needs external package support.\nPlease reconfigure with --download-chaco."); 93070034214SMatthew G. Knepley #endif 93177623264SMatthew G. Knepley } 93277623264SMatthew G. Knepley 93377623264SMatthew G. Knepley #undef __FUNCT__ 93477623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerInitialize_Chaco" 93577623264SMatthew G. Knepley PetscErrorCode PetscPartitionerInitialize_Chaco(PetscPartitioner part) 93677623264SMatthew G. Knepley { 93777623264SMatthew G. Knepley PetscFunctionBegin; 93877623264SMatthew G. Knepley part->ops->view = PetscPartitionerView_Chaco; 93977623264SMatthew G. Knepley part->ops->destroy = PetscPartitionerDestroy_Chaco; 94077623264SMatthew G. Knepley part->ops->partition = PetscPartitionerPartition_Chaco; 94177623264SMatthew G. Knepley PetscFunctionReturn(0); 94277623264SMatthew G. Knepley } 94377623264SMatthew G. Knepley 94477623264SMatthew G. Knepley /*MC 94577623264SMatthew G. Knepley PETSCPARTITIONERCHACO = "chaco" - A PetscPartitioner object using the Chaco library 94677623264SMatthew G. Knepley 94777623264SMatthew G. Knepley Level: intermediate 94877623264SMatthew G. Knepley 94977623264SMatthew G. Knepley .seealso: PetscPartitionerType, PetscPartitionerCreate(), PetscPartitionerSetType() 95077623264SMatthew G. Knepley M*/ 95177623264SMatthew G. Knepley 95277623264SMatthew G. Knepley #undef __FUNCT__ 95377623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerCreate_Chaco" 95477623264SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscPartitionerCreate_Chaco(PetscPartitioner part) 95577623264SMatthew G. Knepley { 95677623264SMatthew G. Knepley PetscPartitioner_Chaco *p; 95777623264SMatthew G. Knepley PetscErrorCode ierr; 95877623264SMatthew G. Knepley 95977623264SMatthew G. Knepley PetscFunctionBegin; 96077623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 96177623264SMatthew G. Knepley ierr = PetscNewLog(part, &p);CHKERRQ(ierr); 96277623264SMatthew G. Knepley part->data = p; 96377623264SMatthew G. Knepley 96477623264SMatthew G. Knepley ierr = PetscPartitionerInitialize_Chaco(part);CHKERRQ(ierr); 96577623264SMatthew G. Knepley ierr = PetscCitationsRegister(ChacoPartitionerCitation, &ChacoPartitionercite);CHKERRQ(ierr); 96677623264SMatthew G. Knepley PetscFunctionReturn(0); 96777623264SMatthew G. Knepley } 96877623264SMatthew G. Knepley 96977623264SMatthew G. Knepley #undef __FUNCT__ 97077623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerDestroy_ParMetis" 97177623264SMatthew G. Knepley PetscErrorCode PetscPartitionerDestroy_ParMetis(PetscPartitioner part) 97277623264SMatthew G. Knepley { 97377623264SMatthew G. Knepley PetscPartitioner_ParMetis *p = (PetscPartitioner_ParMetis *) part->data; 97477623264SMatthew G. Knepley PetscErrorCode ierr; 97577623264SMatthew G. Knepley 97677623264SMatthew G. Knepley PetscFunctionBegin; 97777623264SMatthew G. Knepley ierr = PetscFree(p);CHKERRQ(ierr); 97877623264SMatthew G. Knepley PetscFunctionReturn(0); 97977623264SMatthew G. Knepley } 98077623264SMatthew G. Knepley 98177623264SMatthew G. Knepley #undef __FUNCT__ 98277623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_ParMetis_Ascii" 98377623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_ParMetis_Ascii(PetscPartitioner part, PetscViewer viewer) 98477623264SMatthew G. Knepley { 98577623264SMatthew G. Knepley PetscViewerFormat format; 98677623264SMatthew G. Knepley PetscErrorCode ierr; 98777623264SMatthew G. Knepley 98877623264SMatthew G. Knepley PetscFunctionBegin; 98977623264SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 99077623264SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "ParMetis Graph Partitioner:\n");CHKERRQ(ierr); 99177623264SMatthew G. Knepley PetscFunctionReturn(0); 99277623264SMatthew G. Knepley } 99377623264SMatthew G. Knepley 99477623264SMatthew G. Knepley #undef __FUNCT__ 99577623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerView_ParMetis" 99677623264SMatthew G. Knepley PetscErrorCode PetscPartitionerView_ParMetis(PetscPartitioner part, PetscViewer viewer) 99777623264SMatthew G. Knepley { 99877623264SMatthew G. Knepley PetscBool iascii; 99977623264SMatthew G. Knepley PetscErrorCode ierr; 100077623264SMatthew G. Knepley 100177623264SMatthew G. Knepley PetscFunctionBegin; 100277623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 100377623264SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 100477623264SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 100577623264SMatthew G. Knepley if (iascii) {ierr = PetscPartitionerView_ParMetis_Ascii(part, viewer);CHKERRQ(ierr);} 100677623264SMatthew G. Knepley PetscFunctionReturn(0); 100777623264SMatthew G. Knepley } 100870034214SMatthew G. Knepley 100970034214SMatthew G. Knepley #if defined(PETSC_HAVE_PARMETIS) 101070034214SMatthew G. Knepley #include <parmetis.h> 101177623264SMatthew G. Knepley #endif 101270034214SMatthew G. Knepley 101370034214SMatthew G. Knepley #undef __FUNCT__ 101477623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerPartition_ParMetis" 101577623264SMatthew G. Knepley PetscErrorCode PetscPartitionerPartition_ParMetis(PetscPartitioner part, DM dm, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection partSection, IS *partition) 101670034214SMatthew G. Knepley { 101777623264SMatthew G. Knepley #if defined(PETSC_HAVE_PARMETIS) 101870034214SMatthew G. Knepley MPI_Comm comm; 101970034214SMatthew G. Knepley PetscInt nvtxs = numVertices; /* The number of vertices in full graph */ 102070034214SMatthew G. Knepley PetscInt *vtxdist; /* Distribution of vertices across processes */ 102170034214SMatthew G. Knepley PetscInt *xadj = start; /* Start of edge list for each vertex */ 102270034214SMatthew G. Knepley PetscInt *adjncy = adjacency; /* Edge lists for all vertices */ 102370034214SMatthew G. Knepley PetscInt *vwgt = NULL; /* Vertex weights */ 102470034214SMatthew G. Knepley PetscInt *adjwgt = NULL; /* Edge weights */ 102570034214SMatthew G. Knepley PetscInt wgtflag = 0; /* Indicates which weights are present */ 102670034214SMatthew G. Knepley PetscInt numflag = 0; /* Indicates initial offset (0 or 1) */ 102770034214SMatthew G. Knepley PetscInt ncon = 1; /* The number of weights per vertex */ 102870034214SMatthew G. Knepley PetscReal *tpwgts; /* The fraction of vertex weights assigned to each partition */ 102970034214SMatthew G. Knepley PetscReal *ubvec; /* The balance intolerance for vertex weights */ 103070034214SMatthew G. Knepley PetscInt options[5]; /* Options */ 103170034214SMatthew G. Knepley /* Outputs */ 103270034214SMatthew G. Knepley PetscInt edgeCut; /* The number of edges cut by the partition */ 103370034214SMatthew G. Knepley PetscInt *assignment, *points; 103477623264SMatthew G. Knepley PetscMPIInt rank, p, v, i; 103570034214SMatthew G. Knepley PetscErrorCode ierr; 103670034214SMatthew G. Knepley 103770034214SMatthew G. Knepley PetscFunctionBegin; 103877623264SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) part, &comm);CHKERRQ(ierr); 103970034214SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 104070034214SMatthew G. Knepley options[0] = 0; /* Use all defaults */ 104170034214SMatthew G. Knepley /* Calculate vertex distribution */ 104270034214SMatthew G. Knepley ierr = PetscMalloc4(nparts+1,&vtxdist,nparts*ncon,&tpwgts,ncon,&ubvec,nvtxs,&assignment);CHKERRQ(ierr); 104370034214SMatthew G. Knepley vtxdist[0] = 0; 104470034214SMatthew G. Knepley ierr = MPI_Allgather(&nvtxs, 1, MPIU_INT, &vtxdist[1], 1, MPIU_INT, comm);CHKERRQ(ierr); 104570034214SMatthew G. Knepley for (p = 2; p <= nparts; ++p) { 104670034214SMatthew G. Knepley vtxdist[p] += vtxdist[p-1]; 104770034214SMatthew G. Knepley } 104870034214SMatthew G. Knepley /* Calculate weights */ 104970034214SMatthew G. Knepley for (p = 0; p < nparts; ++p) { 105070034214SMatthew G. Knepley tpwgts[p] = 1.0/nparts; 105170034214SMatthew G. Knepley } 105270034214SMatthew G. Knepley ubvec[0] = 1.05; 105370034214SMatthew G. Knepley 105470034214SMatthew G. Knepley if (nparts == 1) { 105570034214SMatthew G. Knepley ierr = PetscMemzero(assignment, nvtxs * sizeof(PetscInt)); 105670034214SMatthew G. Knepley } else { 105770034214SMatthew G. Knepley if (vtxdist[1] == vtxdist[nparts]) { 105870034214SMatthew G. Knepley if (!rank) { 105970034214SMatthew G. Knepley PetscStackPush("METIS_PartGraphKway"); 106070034214SMatthew G. Knepley ierr = METIS_PartGraphKway(&nvtxs, &ncon, xadj, adjncy, vwgt, NULL, adjwgt, &nparts, tpwgts, ubvec, NULL, &edgeCut, assignment); 106170034214SMatthew G. Knepley PetscStackPop; 106270034214SMatthew G. Knepley if (ierr != METIS_OK) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in METIS_PartGraphKway()"); 106370034214SMatthew G. Knepley } 106470034214SMatthew G. Knepley } else { 106570034214SMatthew G. Knepley PetscStackPush("ParMETIS_V3_PartKway"); 106670034214SMatthew G. Knepley ierr = ParMETIS_V3_PartKway(vtxdist, xadj, adjncy, vwgt, adjwgt, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgeCut, assignment, &comm); 106770034214SMatthew G. Knepley PetscStackPop; 106870034214SMatthew G. Knepley if (ierr != METIS_OK) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in ParMETIS_V3_PartKway()"); 106970034214SMatthew G. Knepley } 107070034214SMatthew G. Knepley } 107170034214SMatthew G. Knepley /* Convert to PetscSection+IS */ 107277623264SMatthew G. Knepley ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr); 107377623264SMatthew G. Knepley for (v = 0; v < nvtxs; ++v) {ierr = PetscSectionAddDof(partSection, assignment[v], 1);CHKERRQ(ierr);} 107477623264SMatthew G. Knepley ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 107570034214SMatthew G. Knepley ierr = PetscMalloc1(nvtxs, &points);CHKERRQ(ierr); 107677623264SMatthew G. Knepley for (p = 0, i = 0; p < nparts; ++p) { 107770034214SMatthew G. Knepley for (v = 0; v < nvtxs; ++v) { 107870034214SMatthew G. Knepley if (assignment[v] == p) points[i++] = v; 107970034214SMatthew G. Knepley } 108070034214SMatthew G. Knepley } 108170034214SMatthew G. Knepley if (i != nvtxs) SETERRQ2(comm, PETSC_ERR_PLIB, "Number of points %D should be %D", i, nvtxs); 108270034214SMatthew G. Knepley ierr = ISCreateGeneral(comm, nvtxs, points, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 108370034214SMatthew G. Knepley ierr = PetscFree4(vtxdist,tpwgts,ubvec,assignment);CHKERRQ(ierr); 108470034214SMatthew G. Knepley #else 108577623264SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "Mesh partitioning needs external package support.\nPlease reconfigure with --download-parmetis."); 108670034214SMatthew G. Knepley #endif 108777623264SMatthew G. Knepley PetscFunctionReturn(0); 108870034214SMatthew G. Knepley } 108970034214SMatthew G. Knepley 109077623264SMatthew G. Knepley #undef __FUNCT__ 109177623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerInitialize_ParMetis" 109277623264SMatthew G. Knepley PetscErrorCode PetscPartitionerInitialize_ParMetis(PetscPartitioner part) 109377623264SMatthew G. Knepley { 109477623264SMatthew G. Knepley PetscFunctionBegin; 109577623264SMatthew G. Knepley part->ops->view = PetscPartitionerView_ParMetis; 109677623264SMatthew G. Knepley part->ops->destroy = PetscPartitionerDestroy_ParMetis; 109777623264SMatthew G. Knepley part->ops->partition = PetscPartitionerPartition_ParMetis; 109877623264SMatthew G. Knepley PetscFunctionReturn(0); 109977623264SMatthew G. Knepley } 110077623264SMatthew G. Knepley 110177623264SMatthew G. Knepley /*MC 110277623264SMatthew G. Knepley PETSCPARTITIONERPARMETIS = "parmetis" - A PetscPartitioner object using the ParMetis library 110377623264SMatthew G. Knepley 110477623264SMatthew G. Knepley Level: intermediate 110577623264SMatthew G. Knepley 110677623264SMatthew G. Knepley .seealso: PetscPartitionerType, PetscPartitionerCreate(), PetscPartitionerSetType() 110777623264SMatthew G. Knepley M*/ 110877623264SMatthew G. Knepley 110977623264SMatthew G. Knepley #undef __FUNCT__ 111077623264SMatthew G. Knepley #define __FUNCT__ "PetscPartitionerCreate_ParMetis" 111177623264SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscPartitionerCreate_ParMetis(PetscPartitioner part) 111277623264SMatthew G. Knepley { 111377623264SMatthew G. Knepley PetscPartitioner_ParMetis *p; 111477623264SMatthew G. Knepley PetscErrorCode ierr; 111577623264SMatthew G. Knepley 111677623264SMatthew G. Knepley PetscFunctionBegin; 111777623264SMatthew G. Knepley PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 111877623264SMatthew G. Knepley ierr = PetscNewLog(part, &p);CHKERRQ(ierr); 111977623264SMatthew G. Knepley part->data = p; 112077623264SMatthew G. Knepley 112177623264SMatthew G. Knepley ierr = PetscPartitionerInitialize_ParMetis(part);CHKERRQ(ierr); 112277623264SMatthew G. Knepley ierr = PetscCitationsRegister(ParMetisPartitionerCitation, &ParMetisPartitionercite);CHKERRQ(ierr); 112370034214SMatthew G. Knepley PetscFunctionReturn(0); 112470034214SMatthew G. Knepley } 112570034214SMatthew G. Knepley 112670034214SMatthew G. Knepley #undef __FUNCT__ 11279ffc88e4SToby Isaac #define __FUNCT__ "DMPlexMarkTreeClosure" 11289ffc88e4SToby Isaac static PetscErrorCode DMPlexMarkTreeClosure(DM dm, PetscSegBuffer segpart, PetscBT bt, PetscInt point, PetscInt *partSize) 11299ffc88e4SToby Isaac { 11309ffc88e4SToby Isaac PetscInt parent, closureSize, *closure = NULL, i, pStart, pEnd; 11319ffc88e4SToby Isaac PetscErrorCode ierr; 11329ffc88e4SToby Isaac 11339ffc88e4SToby Isaac PetscFunctionBegin; 11349ffc88e4SToby Isaac ierr = DMPlexGetTreeParent(dm,point,&parent,NULL);CHKERRQ(ierr); 11359ffc88e4SToby Isaac if (parent == point) PetscFunctionReturn(0); 11369ffc88e4SToby Isaac ierr = DMPlexGetChart(dm,&pStart,&pEnd);CHKERRQ(ierr); 11379ffc88e4SToby Isaac ierr = DMPlexGetTransitiveClosure(dm,parent,PETSC_TRUE,&closureSize,&closure);CHKERRQ(ierr); 11389ffc88e4SToby Isaac for (i = 0; i < closureSize; i++) { 11399ffc88e4SToby Isaac PetscInt cpoint = closure[2*i]; 11409ffc88e4SToby Isaac 11419ffc88e4SToby Isaac if (!PetscBTLookupSet(bt,cpoint-pStart)) { 11429ffc88e4SToby Isaac PetscInt *PETSC_RESTRICT pt; 11439ffc88e4SToby Isaac (*partSize)++; 11449ffc88e4SToby Isaac ierr = PetscSegBufferGetInts(segpart,1,&pt);CHKERRQ(ierr); 11459ffc88e4SToby Isaac *pt = cpoint; 11469ffc88e4SToby Isaac } 11479ffc88e4SToby Isaac ierr = DMPlexMarkTreeClosure(dm,segpart,bt,cpoint,partSize);CHKERRQ(ierr); 11489ffc88e4SToby Isaac } 11499ffc88e4SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm,parent,PETSC_TRUE,&closureSize,&closure);CHKERRQ(ierr); 11509ffc88e4SToby Isaac PetscFunctionReturn(0); 11519ffc88e4SToby Isaac } 11529ffc88e4SToby Isaac 11539ffc88e4SToby Isaac #undef __FUNCT__ 115470034214SMatthew G. Knepley #define __FUNCT__ "DMPlexCreatePartitionClosure" 115570034214SMatthew G. Knepley PetscErrorCode DMPlexCreatePartitionClosure(DM dm, PetscSection pointSection, IS pointPartition, PetscSection *section, IS *partition) 115670034214SMatthew G. Knepley { 115770034214SMatthew G. Knepley /* const PetscInt height = 0; */ 115870034214SMatthew G. Knepley const PetscInt *partArray; 115970034214SMatthew G. Knepley PetscInt *allPoints, *packPoints; 116070034214SMatthew G. Knepley PetscInt rStart, rEnd, rank, pStart, pEnd, newSize; 116170034214SMatthew G. Knepley PetscErrorCode ierr; 116270034214SMatthew G. Knepley PetscBT bt; 116370034214SMatthew G. Knepley PetscSegBuffer segpack,segpart; 116470034214SMatthew G. Knepley 116570034214SMatthew G. Knepley PetscFunctionBegin; 116670034214SMatthew G. Knepley ierr = PetscSectionGetChart(pointSection, &rStart, &rEnd);CHKERRQ(ierr); 116770034214SMatthew G. Knepley ierr = ISGetIndices(pointPartition, &partArray);CHKERRQ(ierr); 116870034214SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), section);CHKERRQ(ierr); 116970034214SMatthew G. Knepley ierr = PetscSectionSetChart(*section, rStart, rEnd);CHKERRQ(ierr); 117070034214SMatthew G. Knepley ierr = DMPlexGetChart(dm,&pStart,&pEnd);CHKERRQ(ierr); 117170034214SMatthew G. Knepley ierr = PetscBTCreate(pEnd-pStart,&bt);CHKERRQ(ierr); 117270034214SMatthew G. Knepley ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&segpack);CHKERRQ(ierr); 117370034214SMatthew G. Knepley ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&segpart);CHKERRQ(ierr); 117470034214SMatthew G. Knepley for (rank = rStart; rank < rEnd; ++rank) { 117570034214SMatthew G. Knepley PetscInt partSize = 0, numPoints, offset, p, *PETSC_RESTRICT placePoints; 117670034214SMatthew G. Knepley 117770034214SMatthew G. Knepley ierr = PetscSectionGetDof(pointSection, rank, &numPoints);CHKERRQ(ierr); 117870034214SMatthew G. Knepley ierr = PetscSectionGetOffset(pointSection, rank, &offset);CHKERRQ(ierr); 117970034214SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 118070034214SMatthew G. Knepley PetscInt point = partArray[offset+p], closureSize, c; 118170034214SMatthew G. Knepley PetscInt *closure = NULL; 118270034214SMatthew G. Knepley 118370034214SMatthew G. Knepley /* TODO Include support for height > 0 case */ 118470034214SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 118570034214SMatthew G. Knepley for (c=0; c<closureSize; c++) { 118670034214SMatthew G. Knepley PetscInt cpoint = closure[c*2]; 118770034214SMatthew G. Knepley if (!PetscBTLookupSet(bt,cpoint-pStart)) { 118870034214SMatthew G. Knepley PetscInt *PETSC_RESTRICT pt; 118970034214SMatthew G. Knepley partSize++; 119070034214SMatthew G. Knepley ierr = PetscSegBufferGetInts(segpart,1,&pt);CHKERRQ(ierr); 119170034214SMatthew G. Knepley *pt = cpoint; 119270034214SMatthew G. Knepley } 11939ffc88e4SToby Isaac ierr = DMPlexMarkTreeClosure(dm,segpart,bt,cpoint,&partSize);CHKERRQ(ierr); 119470034214SMatthew G. Knepley } 119570034214SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 119670034214SMatthew G. Knepley } 119770034214SMatthew G. Knepley ierr = PetscSectionSetDof(*section, rank, partSize);CHKERRQ(ierr); 119870034214SMatthew G. Knepley ierr = PetscSegBufferGetInts(segpack,partSize,&placePoints);CHKERRQ(ierr); 119970034214SMatthew G. Knepley ierr = PetscSegBufferExtractTo(segpart,placePoints);CHKERRQ(ierr); 120070034214SMatthew G. Knepley ierr = PetscSortInt(partSize,placePoints);CHKERRQ(ierr); 120170034214SMatthew G. Knepley for (p=0; p<partSize; p++) {ierr = PetscBTClear(bt,placePoints[p]-pStart);CHKERRQ(ierr);} 120270034214SMatthew G. Knepley } 120370034214SMatthew G. Knepley ierr = PetscBTDestroy(&bt);CHKERRQ(ierr); 120470034214SMatthew G. Knepley ierr = PetscSegBufferDestroy(&segpart);CHKERRQ(ierr); 120570034214SMatthew G. Knepley 120670034214SMatthew G. Knepley ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 120770034214SMatthew G. Knepley ierr = PetscSectionGetStorageSize(*section, &newSize);CHKERRQ(ierr); 120870034214SMatthew G. Knepley ierr = PetscMalloc1(newSize, &allPoints);CHKERRQ(ierr); 120970034214SMatthew G. Knepley 121070034214SMatthew G. Knepley ierr = PetscSegBufferExtractInPlace(segpack,&packPoints);CHKERRQ(ierr); 121170034214SMatthew G. Knepley for (rank = rStart; rank < rEnd; ++rank) { 121270034214SMatthew G. Knepley PetscInt numPoints, offset; 121370034214SMatthew G. Knepley 121470034214SMatthew G. Knepley ierr = PetscSectionGetDof(*section, rank, &numPoints);CHKERRQ(ierr); 121570034214SMatthew G. Knepley ierr = PetscSectionGetOffset(*section, rank, &offset);CHKERRQ(ierr); 121670034214SMatthew G. Knepley ierr = PetscMemcpy(&allPoints[offset], packPoints, numPoints * sizeof(PetscInt));CHKERRQ(ierr); 121770034214SMatthew G. Knepley packPoints += numPoints; 121870034214SMatthew G. Knepley } 121970034214SMatthew G. Knepley 122070034214SMatthew G. Knepley ierr = PetscSegBufferDestroy(&segpack);CHKERRQ(ierr); 122170034214SMatthew G. Knepley ierr = ISRestoreIndices(pointPartition, &partArray);CHKERRQ(ierr); 122270034214SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), newSize, allPoints, PETSC_OWN_POINTER, partition);CHKERRQ(ierr); 122370034214SMatthew G. Knepley PetscFunctionReturn(0); 122470034214SMatthew G. Knepley } 1225