Actual source code: metis.c

  1: #include <../src/mat/impls/adj/mpi/mpiadj.h>
  2: #include <petsc/private/matmetisimpl.h>
  3: #include <metis.h>

  5: PETSC_EXTERN PetscErrorCode MatMeshToCellGraph_METIS(Mat mesh, PetscInt ncommonnodes, Mat *dual)
  6: {
  7:   PetscInt   *newxadj, *newadjncy;
  8:   PetscInt    numflag = 0;
  9:   Mat_MPIAdj *adj     = (Mat_MPIAdj *)mesh->data, *newadj;
 10:   PetscBool   flg;
 11:   MPI_Comm    comm;
 12:   PetscMPIInt size;

 14:   PetscFunctionBegin;
 15:   PetscCall(PetscObjectTypeCompare((PetscObject)mesh, MATMPIADJ, &flg));
 16:   PetscCall(PetscObjectGetComm((PetscObject)mesh, &comm));
 17:   PetscCheck(flg, comm, PETSC_ERR_SUP, "Must use MPIAdj matrix type");

 19:   PetscCallMPI(MPI_Comm_size(comm, &size));
 20:   PetscCheck(size == 1, comm, PETSC_ERR_WRONG_MPI_SIZE, "MatMeshToCellGraph_METIS() requires a sequential matrix (communicator size must be 1)");

 22:   {
 23:     idx_t ne = mesh->rmap->N;
 24:     idx_t nn = mesh->cmap->N;

 26:     PetscCallMETIS(METIS_MeshToDual, &ne, &nn, (idx_t *)adj->i, (idx_t *)adj->j, (idx_t *)&ncommonnodes, (idx_t *)&numflag, (idx_t **)&newxadj, (idx_t **)&newadjncy);
 27:   }

 29:   for (PetscInt i = 0; i < mesh->rmap->N; i++) PetscCall(PetscSortInt(newxadj[i + 1] - newxadj[i], newadjncy + newxadj[i]));

 31:   PetscCall(MatCreateMPIAdj(PetscObjectComm((PetscObject)mesh), mesh->rmap->n, mesh->rmap->N, newxadj, newadjncy, NULL, dual));
 32:   newadj = (Mat_MPIAdj *)(*dual)->data;

 34:   newadj->freeaijwithfree = PETSC_TRUE; /* signal the matrix should be freed with system free since space was allocated by METIS */
 35:   PetscFunctionReturn(PETSC_SUCCESS);
 36: }