/*$Id: sorder.c,v 1.90 2001/06/21 21:17:30 bsmith Exp $*/ /* Provides the code that allows PETSc users to register their own sequential matrix Ordering routines. */ #include "src/mat/matimpl.h" #include "petscsys.h" PetscFList MatOrderingList = 0; PetscTruth MatOrderingRegisterAllCalled = PETSC_FALSE; EXTERN int MatOrdering_Flow_SeqAIJ(Mat,MatOrderingType,IS *,IS *); #undef __FUNCT__ #define __FUNCT__ "MatOrdering_Flow" int MatOrdering_Flow(Mat mat,MatOrderingType type,IS *irow,IS *icol) { PetscFunctionBegin; SETERRQ(PETSC_ERR_SUP,"Cannot do default flow ordering for matrix type"); #if !defined(PETSC_USE_DEBUG) PetscFunctionReturn(0); #endif } EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatOrdering_Natural" int MatOrdering_Natural(Mat mat,MatOrderingType type,IS *irow,IS *icol) { int n,ierr,i,*ii; PetscTruth done; MPI_Comm comm; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); ierr = MatGetRowIJ(mat,0,PETSC_FALSE,&n,PETSC_NULL,PETSC_NULL,&done);CHKERRQ(ierr); ierr = MatRestoreRowIJ(mat,0,PETSC_FALSE,&n,PETSC_NULL,PETSC_NULL,&done);CHKERRQ(ierr); if (done) { /* matrix may be "compressed" in symbolic factorization, due to i-nodes or block storage */ /* We actually create general index sets because this avoids mallocs to to obtain the indices in the MatSolve() routines. ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,irow);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,icol);CHKERRQ(ierr); */ ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); for (i=0; iassembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); ierr = PetscTypeCompare((PetscObject)mat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); ierr = PetscTypeCompare((PetscObject)mat,MATMPIDENSE,&ismpidense);CHKERRQ(ierr); if (isseqdense || ismpidense) { ierr = MatGetLocalSize(mat,&m,PETSC_NULL);CHKERRQ(ierr); /* Dense matrices only give natural ordering */ ierr = ISCreateStride(PETSC_COMM_SELF,0,m,1,cperm);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,0,m,1,rperm);CHKERRQ(ierr); ierr = ISSetIdentity(*cperm);CHKERRQ(ierr); ierr = ISSetIdentity(*rperm);CHKERRQ(ierr); ierr = ISSetPermutation(*rperm);CHKERRQ(ierr); ierr = ISSetPermutation(*cperm);CHKERRQ(ierr); PetscFunctionReturn(0); } if (!mat->M) { /* matrix has zero rows */ ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,cperm);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,rperm);CHKERRQ(ierr); ierr = ISSetIdentity(*cperm);CHKERRQ(ierr); ierr = ISSetIdentity(*rperm);CHKERRQ(ierr); ierr = ISSetPermutation(*rperm);CHKERRQ(ierr); ierr = ISSetPermutation(*cperm);CHKERRQ(ierr); PetscFunctionReturn(0); } if (!MatOrderingRegisterAllCalled) { ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr); } ierr = PetscLogEventBegin(MAT_GetOrdering,mat,0,0,0);CHKERRQ(ierr); ierr = PetscFListFind(mat->comm,MatOrderingList,type,(void (**)(void)) &r);CHKERRQ(ierr); if (!r) {SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Unknown or unregistered type: %s",type);} ierr = (*r)(mat,type,rperm,cperm);CHKERRQ(ierr); ierr = ISSetPermutation(*rperm);CHKERRQ(ierr); ierr = ISSetPermutation(*cperm);CHKERRQ(ierr); /* Adjust for inode (reduced matrix ordering) only if row permutation is smaller then matrix size */ ierr = MatGetLocalSize(mat,&mmat,&nmat);CHKERRQ(ierr); ierr = ISGetLocalSize(*rperm,&mis);CHKERRQ(ierr); if (mmat > mis) { ierr = MatAdjustForInodes(mat,rperm,cperm);CHKERRQ(ierr); } ierr = PetscLogEventEnd(MAT_GetOrdering,mat,0,0,0);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_ordering_draw",&flg);CHKERRQ(ierr); if (flg) { Mat tmat; ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); } ierr = MatPermute(mat,*rperm,*cperm,&tmat);CHKERRQ(ierr); ierr = MatView(tmat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); if (flg) { ierr = PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); } ierr = MatDestroy(tmat);CHKERRQ(ierr); } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatGetOrderingList" int MatGetOrderingList(PetscFList *list) { PetscFunctionBegin; *list = MatOrderingList; PetscFunctionReturn(0); }