1b4319ba4SBarry Smith /* 2b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 3b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 4b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 5b4319ba4SBarry Smith product is handled "implicitly". 6b4319ba4SBarry Smith 7b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 8b4319ba4SBarry Smith */ 9b4319ba4SBarry Smith 10c6db04a5SJed Brown #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 114f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1228f4e0baSStefano Zampini 13f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 14b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 15b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 168546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat); 17f26d0771SStefano Zampini 1875d48cdbSStefano Zampini static PetscErrorCode MatISContainerDestroyPtAP_Private(void *ptr) 1975d48cdbSStefano Zampini { 2075d48cdbSStefano Zampini MatISPtAP ptap = (MatISPtAP)ptr; 2175d48cdbSStefano Zampini PetscErrorCode ierr; 2275d48cdbSStefano Zampini 2375d48cdbSStefano Zampini PetscFunctionBegin; 2475d48cdbSStefano Zampini ierr = MatDestroySubMatrices(ptap->ris1 ? 2 : 1,&ptap->lP);CHKERRQ(ierr); 2575d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis0);CHKERRQ(ierr); 2675d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis1);CHKERRQ(ierr); 2775d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris0);CHKERRQ(ierr); 2875d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 2975d48cdbSStefano Zampini ierr = PetscFree(ptap);CHKERRQ(ierr); 3075d48cdbSStefano Zampini PetscFunctionReturn(0); 3175d48cdbSStefano Zampini } 3275d48cdbSStefano Zampini 3375d48cdbSStefano Zampini static PetscErrorCode MatPtAPNumeric_IS_XAIJ(Mat A, Mat P, Mat C) 3475d48cdbSStefano Zampini { 3575d48cdbSStefano Zampini MatISPtAP ptap; 3675d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3775d48cdbSStefano Zampini Mat lA,lC; 3875d48cdbSStefano Zampini MatReuse reuse; 3975d48cdbSStefano Zampini IS ris[2],cis[2]; 4075d48cdbSStefano Zampini PetscContainer c; 4175d48cdbSStefano Zampini PetscInt n; 4275d48cdbSStefano Zampini PetscErrorCode ierr; 4375d48cdbSStefano Zampini 4475d48cdbSStefano Zampini PetscFunctionBegin; 456afe12f5SStefano Zampini ierr = PetscObjectQuery((PetscObject)C,"_MatIS_PtAP",(PetscObject*)&c);CHKERRQ(ierr); 4675d48cdbSStefano Zampini if (!c) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing PtAP information"); 4775d48cdbSStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&ptap);CHKERRQ(ierr); 4875d48cdbSStefano Zampini ris[0] = ptap->ris0; 4975d48cdbSStefano Zampini ris[1] = ptap->ris1; 5075d48cdbSStefano Zampini cis[0] = ptap->cis0; 5175d48cdbSStefano Zampini cis[1] = ptap->cis1; 5275d48cdbSStefano Zampini n = ptap->ris1 ? 2 : 1; 5375d48cdbSStefano Zampini reuse = ptap->lP ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX; 5475d48cdbSStefano Zampini ierr = MatCreateSubMatrices(P,n,ris,cis,reuse,&ptap->lP);CHKERRQ(ierr); 5575d48cdbSStefano Zampini 5675d48cdbSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 5775d48cdbSStefano Zampini ierr = MatISGetLocalMat(C,&lC);CHKERRQ(ierr); 5875d48cdbSStefano Zampini if (ptap->ris1) { /* unsymmetric A mapping */ 5975d48cdbSStefano Zampini Mat lPt; 6075d48cdbSStefano Zampini 6175d48cdbSStefano Zampini ierr = MatTranspose(ptap->lP[1],MAT_INITIAL_MATRIX,&lPt);CHKERRQ(ierr); 6275d48cdbSStefano Zampini ierr = MatMatMatMult(lPt,lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6375d48cdbSStefano Zampini if (matis->storel2l) { 6475d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",(PetscObject)lPt);CHKERRQ(ierr); 6575d48cdbSStefano Zampini } 6675d48cdbSStefano Zampini ierr = MatDestroy(&lPt);CHKERRQ(ierr); 6775d48cdbSStefano Zampini } else { 6875d48cdbSStefano Zampini ierr = MatPtAP(lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6975d48cdbSStefano Zampini if (matis->storel2l) { 7075d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(C),"_MatIS_PtAP_l2l",(PetscObject)ptap->lP[0]);CHKERRQ(ierr); 7175d48cdbSStefano Zampini } 7275d48cdbSStefano Zampini } 7375d48cdbSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7475d48cdbSStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 7575d48cdbSStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 7675d48cdbSStefano Zampini } 7775d48cdbSStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7875d48cdbSStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7975d48cdbSStefano Zampini PetscFunctionReturn(0); 8075d48cdbSStefano Zampini } 8175d48cdbSStefano Zampini 8275d48cdbSStefano Zampini static PetscErrorCode MatGetNonzeroColumnsLocal_Private(Mat PT,IS *cis) 8375d48cdbSStefano Zampini { 8475d48cdbSStefano Zampini Mat Po,Pd; 8575d48cdbSStefano Zampini IS zd,zo; 8675d48cdbSStefano Zampini const PetscInt *garray; 8775d48cdbSStefano Zampini PetscInt *aux,i,bs; 8875d48cdbSStefano Zampini PetscInt dc,stc,oc,ctd,cto; 8975d48cdbSStefano Zampini PetscBool ismpiaij,ismpibaij,isseqaij,isseqbaij; 9075d48cdbSStefano Zampini MPI_Comm comm; 9175d48cdbSStefano Zampini PetscErrorCode ierr; 9275d48cdbSStefano Zampini 9375d48cdbSStefano Zampini PetscFunctionBegin; 9475d48cdbSStefano Zampini PetscValidHeaderSpecific(PT,MAT_CLASSID,1); 9575d48cdbSStefano Zampini PetscValidPointer(cis,2); 9675d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)PT,&comm);CHKERRQ(ierr); 9775d48cdbSStefano Zampini bs = 1; 9875d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 9975d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 10004637862SRichard Tran Mills ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 10175d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 10275d48cdbSStefano Zampini if (isseqaij || isseqbaij) { 10375d48cdbSStefano Zampini Pd = PT; 10475d48cdbSStefano Zampini Po = NULL; 10575d48cdbSStefano Zampini garray = NULL; 10675d48cdbSStefano Zampini } else if (ismpiaij) { 10775d48cdbSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10875d48cdbSStefano Zampini } else if (ismpibaij) { 10975d48cdbSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 11075d48cdbSStefano Zampini ierr = MatGetBlockSize(PT,&bs);CHKERRQ(ierr); 11175d48cdbSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(PT))->type_name); 11275d48cdbSStefano Zampini 11375d48cdbSStefano Zampini /* identify any null columns in Pd or Po */ 11422f7620eSStefano Zampini /* We use a tolerance comparison since it may happen that, with geometric multigrid, 11522f7620eSStefano Zampini some of the columns are not really zero, but very close to */ 11675d48cdbSStefano Zampini zo = zd = NULL; 11775d48cdbSStefano Zampini if (Po) { 11822f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Po,PETSC_TRUE,PETSC_SMALL,&zo);CHKERRQ(ierr); 11975d48cdbSStefano Zampini } 12022f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Pd,PETSC_TRUE,PETSC_SMALL,&zd);CHKERRQ(ierr); 12175d48cdbSStefano Zampini 12275d48cdbSStefano Zampini ierr = MatGetLocalSize(PT,NULL,&dc);CHKERRQ(ierr); 12375d48cdbSStefano Zampini ierr = MatGetOwnershipRangeColumn(PT,&stc,NULL);CHKERRQ(ierr); 12475d48cdbSStefano Zampini if (Po) { ierr = MatGetLocalSize(Po,NULL,&oc);CHKERRQ(ierr); } 12575d48cdbSStefano Zampini else oc = 0; 12675d48cdbSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 12775d48cdbSStefano Zampini if (zd) { 12875d48cdbSStefano Zampini const PetscInt *idxs; 12975d48cdbSStefano Zampini PetscInt nz; 13075d48cdbSStefano Zampini 13175d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 13275d48cdbSStefano Zampini ierr = ISSetBlockSize(zd,bs);CHKERRQ(ierr); 13375d48cdbSStefano Zampini ierr = ISGetLocalSize(zd,&nz);CHKERRQ(ierr); 13475d48cdbSStefano Zampini ierr = ISGetIndices(zd,&idxs);CHKERRQ(ierr); 13575d48cdbSStefano Zampini ctd = nz/bs; 13675d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = (idxs[bs*i]+stc)/bs; 13775d48cdbSStefano Zampini ierr = ISRestoreIndices(zd,&idxs);CHKERRQ(ierr); 13875d48cdbSStefano Zampini } else { 13975d48cdbSStefano Zampini ctd = dc/bs; 14075d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = i+stc/bs; 14175d48cdbSStefano Zampini } 14275d48cdbSStefano Zampini if (zo) { 14375d48cdbSStefano Zampini const PetscInt *idxs; 14475d48cdbSStefano Zampini PetscInt nz; 14575d48cdbSStefano Zampini 14675d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 14775d48cdbSStefano Zampini ierr = ISSetBlockSize(zo,bs);CHKERRQ(ierr); 14875d48cdbSStefano Zampini ierr = ISGetLocalSize(zo,&nz);CHKERRQ(ierr); 14975d48cdbSStefano Zampini ierr = ISGetIndices(zo,&idxs);CHKERRQ(ierr); 15075d48cdbSStefano Zampini cto = nz/bs; 15175d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[idxs[bs*i]/bs]; 15275d48cdbSStefano Zampini ierr = ISRestoreIndices(zo,&idxs);CHKERRQ(ierr); 15375d48cdbSStefano Zampini } else { 15475d48cdbSStefano Zampini cto = oc/bs; 15575d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[i]; 15675d48cdbSStefano Zampini } 15775d48cdbSStefano Zampini ierr = ISCreateBlock(comm,bs,ctd+cto,aux,PETSC_OWN_POINTER,cis);CHKERRQ(ierr); 15875d48cdbSStefano Zampini ierr = ISDestroy(&zd);CHKERRQ(ierr); 15975d48cdbSStefano Zampini ierr = ISDestroy(&zo);CHKERRQ(ierr); 16075d48cdbSStefano Zampini PetscFunctionReturn(0); 16175d48cdbSStefano Zampini } 16275d48cdbSStefano Zampini 16375d48cdbSStefano Zampini static PetscErrorCode MatPtAPSymbolic_IS_XAIJ(Mat A,Mat P,PetscReal fill,Mat *C) 16475d48cdbSStefano Zampini { 1658546b261SStefano Zampini Mat PT,lA; 16675d48cdbSStefano Zampini MatISPtAP ptap; 16775d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 16875d48cdbSStefano Zampini PetscContainer c; 1698546b261SStefano Zampini MatType lmtype; 17075d48cdbSStefano Zampini const PetscInt *garray; 17175d48cdbSStefano Zampini PetscInt ibs,N,dc; 17275d48cdbSStefano Zampini MPI_Comm comm; 17375d48cdbSStefano Zampini PetscErrorCode ierr; 17475d48cdbSStefano Zampini 17575d48cdbSStefano Zampini PetscFunctionBegin; 17675d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 17775d48cdbSStefano Zampini ierr = MatCreate(comm,C);CHKERRQ(ierr); 17875d48cdbSStefano Zampini ierr = MatSetType(*C,MATIS);CHKERRQ(ierr); 1798546b261SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1808546b261SStefano Zampini ierr = MatGetType(lA,&lmtype);CHKERRQ(ierr); 1818546b261SStefano Zampini ierr = MatISSetLocalMatType(*C,lmtype);CHKERRQ(ierr); 18275d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 18375d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 18475d48cdbSStefano Zampini ierr = MatSetSizes(*C,dc,dc,N,N);CHKERRQ(ierr); 18575d48cdbSStefano Zampini /* Not sure about this 18675d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18775d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18875d48cdbSStefano Zampini */ 18975d48cdbSStefano Zampini 19075d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 19175d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 19275d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 19375d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 19475d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(*C),"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19575d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ptap->fill = fill; 19775d48cdbSStefano Zampini 19875d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 19975d48cdbSStefano Zampini 20075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 20175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20575d48cdbSStefano Zampini 20675d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20775d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 20975d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 21075d48cdbSStefano Zampini 21175d48cdbSStefano Zampini Crl2g = NULL; 21275d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 21375d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 21475d48cdbSStefano Zampini PetscInt N1,ibs1; 21575d48cdbSStefano Zampini 21675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21975d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22175d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 22275d48cdbSStefano Zampini const PetscInt *i1,*i2; 22375d48cdbSStefano Zampini 22475d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22575d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 22675d48cdbSStefano Zampini ierr = PetscMemcmp(i1,i2,N*sizeof(*i1),&lsame);CHKERRQ(ierr); 22775d48cdbSStefano Zampini } 22875d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 22975d48cdbSStefano Zampini if (same) { 23075d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 23175d48cdbSStefano Zampini } else { 23275d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 23375d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 23475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23575d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23675d48cdbSStefano Zampini } 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini /* Not sure about this 23975d48cdbSStefano Zampini if (!Crl2g) { 24075d48cdbSStefano Zampini ierr = MatGetBlockSize(*C,&ibs);CHKERRQ(ierr); 24175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 24275d48cdbSStefano Zampini } 24375d48cdbSStefano Zampini */ 24475d48cdbSStefano Zampini ierr = MatSetLocalToGlobalMapping(*C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24775d48cdbSStefano Zampini 24875d48cdbSStefano Zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 24975d48cdbSStefano Zampini PetscFunctionReturn(0); 25075d48cdbSStefano Zampini } 25175d48cdbSStefano Zampini 25275d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 25375d48cdbSStefano Zampini { 25475d48cdbSStefano Zampini PetscErrorCode ierr; 25575d48cdbSStefano Zampini 25675d48cdbSStefano Zampini PetscFunctionBegin; 25775d48cdbSStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 25875d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25975d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 26075d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 26175d48cdbSStefano Zampini } 26275d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26375d48cdbSStefano Zampini ierr = ((*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 26475d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26575d48cdbSStefano Zampini PetscFunctionReturn(0); 26675d48cdbSStefano Zampini } 26775d48cdbSStefano Zampini 2685b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2695b003df0Sstefano_zampini { 2705b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2715b003df0Sstefano_zampini PetscInt i; 2725b003df0Sstefano_zampini PetscErrorCode ierr; 2735b003df0Sstefano_zampini 274ab4d48faSStefano Zampini PetscFunctionBegin; 2755b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2765b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2775b003df0Sstefano_zampini } 2785b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2795b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2805b003df0Sstefano_zampini } 2815b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 2825b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 2835b003df0Sstefano_zampini PetscFunctionReturn(0); 2845b003df0Sstefano_zampini } 285a72627d2SStefano Zampini 286c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2876989cf23SStefano Zampini { 288c9225affSStefano Zampini Mat B,lB; 289c9225affSStefano Zampini PetscErrorCode ierr; 290c9225affSStefano Zampini 291c9225affSStefano Zampini PetscFunctionBegin; 292c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 293c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 294c9225affSStefano Zampini PetscInt bs; 295c9225affSStefano Zampini IS is; 296c9225affSStefano Zampini 297c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 298c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 299c9225affSStefano Zampini if (bs > 1) { 300c9225affSStefano Zampini IS is2; 301c9225affSStefano Zampini PetscInt i,*aux; 302c9225affSStefano Zampini 303c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 304c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 305c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 306c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 307c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 308c9225affSStefano Zampini is = is2; 309c9225affSStefano Zampini } 310c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 311c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 312c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 313c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 314c9225affSStefano Zampini if (bs > 1) { 315c9225affSStefano Zampini IS is2; 316c9225affSStefano Zampini PetscInt i,*aux; 317c9225affSStefano Zampini 318c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 319c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 320c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 321c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 322c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 323c9225affSStefano Zampini is = is2; 324c9225affSStefano Zampini } 325c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 326c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 327c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 328c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 329c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 330c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 331c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 332c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 333c9225affSStefano Zampini } else { 334c9225affSStefano Zampini B = *newmat; 335c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 336c9225affSStefano Zampini lB = A; 337c9225affSStefano Zampini } 338c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 339c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 340c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 341c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 343c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 344c9225affSStefano Zampini } 345c9225affSStefano Zampini PetscFunctionReturn(0); 346c9225affSStefano Zampini } 347c9225affSStefano Zampini 348c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 349c9225affSStefano Zampini { 350c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 351c9225affSStefano Zampini PetscScalar *aa; 352c9225affSStefano Zampini const PetscInt *ii,*jj; 353c9225affSStefano Zampini PetscInt i,n,m; 354fabe8965SStefano Zampini PetscInt *ecount,**eneighs; 355c9225affSStefano Zampini PetscBool flg; 356c9225affSStefano Zampini PetscErrorCode ierr; 357c9225affSStefano Zampini 358c9225affSStefano Zampini PetscFunctionBegin; 359c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 360c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 361fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 362c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 363c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 364c9225affSStefano Zampini for (i=0;i<n;i++) { 365fabe8965SStefano Zampini if (ecount[i] > 1) { 366c9225affSStefano Zampini PetscInt j; 367c9225affSStefano Zampini 368c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 369c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 370fabe8965SStefano Zampini PetscReal scal = 0.0; 371c9225affSStefano Zampini 372c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 373c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 374c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 375c9225affSStefano Zampini } 376c9225affSStefano Zampini } 377fabe8965SStefano Zampini if (scal) aa[j] /= scal; 378c9225affSStefano Zampini } 379c9225affSStefano Zampini } 380c9225affSStefano Zampini } 381fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 382c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 383c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 384c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 385c9225affSStefano Zampini PetscFunctionReturn(0); 386c9225affSStefano Zampini } 387c9225affSStefano Zampini 388fabe8965SStefano Zampini typedef enum {MAT_IS_DISASSEMBLE_L2G_NATURAL,MAT_IS_DISASSEMBLE_L2G_MAT, MAT_IS_DISASSEMBLE_L2G_ND} MatISDisassemblel2gType; 389fabe8965SStefano Zampini 390c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 391c9225affSStefano Zampini { 392fabe8965SStefano Zampini Mat Ad,Ao; 393fabe8965SStefano Zampini IS is,ndmap,ndsub; 394c9225affSStefano Zampini MPI_Comm comm; 395fabe8965SStefano Zampini const PetscInt *garray,*ndmapi; 396fabe8965SStefano Zampini PetscInt bs,i,cnt,nl,*ncount,*ndmapc; 397fabe8965SStefano Zampini PetscBool ismpiaij,ismpibaij; 398fabe8965SStefano Zampini const char *const MatISDisassemblel2gTypes[] = {"NATURAL","MAT","ND","MatISDisassemblel2gType","MAT_IS_DISASSEMBLE_L2G_",0}; 399fabe8965SStefano Zampini MatISDisassemblel2gType mode = MAT_IS_DISASSEMBLE_L2G_NATURAL; 400fabe8965SStefano Zampini MatPartitioning part; 401fabe8965SStefano Zampini PetscSF sf; 402c9225affSStefano Zampini PetscErrorCode ierr; 403c9225affSStefano Zampini 404c9225affSStefano Zampini PetscFunctionBegin; 405fabe8965SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MatIS l2g disassembling options","Mat");CHKERRQ(ierr); 406fabe8965SStefano Zampini ierr = PetscOptionsEnum("-mat_is_disassemble_l2g_type","Type of local-to-global mapping to be used for disassembling","MatISDisassemblel2gType",MatISDisassemblel2gTypes,(PetscEnum)mode,(PetscEnum*)&mode,NULL);CHKERRQ(ierr); 407fabe8965SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 408fabe8965SStefano Zampini if (mode == MAT_IS_DISASSEMBLE_L2G_MAT) { 409c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 410c9225affSStefano Zampini PetscFunctionReturn(0); 411c9225affSStefano Zampini } 412c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 413c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 414c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 415c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 416fabe8965SStefano Zampini switch (mode) { 417fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_ND: 418fabe8965SStefano Zampini ierr = MatPartitioningCreate(comm,&part);CHKERRQ(ierr); 419fabe8965SStefano Zampini ierr = MatPartitioningSetAdjacency(part,A);CHKERRQ(ierr); 420fabe8965SStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)part,((PetscObject)A)->prefix);CHKERRQ(ierr); 421fabe8965SStefano Zampini ierr = MatPartitioningSetFromOptions(part);CHKERRQ(ierr); 422fabe8965SStefano Zampini ierr = MatPartitioningApplyND(part,&ndmap);CHKERRQ(ierr); 423fabe8965SStefano Zampini ierr = MatPartitioningDestroy(&part);CHKERRQ(ierr); 424fabe8965SStefano Zampini ierr = ISBuildTwoSided(ndmap,NULL,&ndsub);CHKERRQ(ierr); 425fabe8965SStefano Zampini ierr = MatMPIAIJSetUseScalableIncreaseOverlap(A,PETSC_TRUE);CHKERRQ(ierr); 426fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,1,&ndsub,1);CHKERRQ(ierr); 427fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ndsub,l2g);CHKERRQ(ierr); 428fabe8965SStefano Zampini 429fabe8965SStefano Zampini /* it may happen that a separator node is not properly shared */ 430fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(*l2g,&nl,&ncount,NULL);CHKERRQ(ierr); 431fabe8965SStefano Zampini ierr = PetscSFCreate(comm,&sf);CHKERRQ(ierr); 432fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(*l2g,&garray);CHKERRQ(ierr); 433fabe8965SStefano Zampini ierr = PetscSFSetGraphLayout(sf,A->rmap,nl,NULL,PETSC_OWN_POINTER,garray);CHKERRQ(ierr); 434fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(*l2g,&garray);CHKERRQ(ierr); 435fabe8965SStefano Zampini ierr = PetscCalloc1(A->rmap->n,&ndmapc);CHKERRQ(ierr); 436fabe8965SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 437fabe8965SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 438fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(*l2g,NULL,&ncount,NULL);CHKERRQ(ierr); 439fabe8965SStefano Zampini ierr = ISGetIndices(ndmap,&ndmapi);CHKERRQ(ierr); 440fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 441fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) 442fabe8965SStefano Zampini cnt++; 443fabe8965SStefano Zampini 444fabe8965SStefano Zampini ierr = MPIU_Allreduce(&cnt,&i,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 445fabe8965SStefano Zampini if (i) { /* we detected isolated separator nodes */ 446fabe8965SStefano Zampini Mat A2,A3; 447fabe8965SStefano Zampini IS *workis,is2; 448fabe8965SStefano Zampini PetscScalar *vals; 449fabe8965SStefano Zampini PetscInt gcnt = i,*dnz,*onz,j,*lndmapi; 450fabe8965SStefano Zampini ISLocalToGlobalMapping ll2g; 451fabe8965SStefano Zampini PetscBool flg; 452fabe8965SStefano Zampini const PetscInt *ii,*jj; 453fabe8965SStefano Zampini 454fabe8965SStefano Zampini /* communicate global id of separators */ 455fabe8965SStefano Zampini ierr = MatPreallocateInitialize(comm,A->rmap->n,A->cmap->n,dnz,onz);CHKERRQ(ierr); 456fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 457fabe8965SStefano Zampini dnz[i] = ndmapi[i] < 0 ? i + A->rmap->rstart : -1; 458fabe8965SStefano Zampini 459fabe8965SStefano Zampini ierr = PetscMalloc1(nl,&lndmapi);CHKERRQ(ierr); 460fabe8965SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 461fabe8965SStefano Zampini 462fabe8965SStefano Zampini /* compute adjacency of isolated separators node */ 463fabe8965SStefano Zampini ierr = PetscMalloc1(gcnt,&workis);CHKERRQ(ierr); 464fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) { 465fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 466fabe8965SStefano Zampini ierr = ISCreateStride(comm,1,i+A->rmap->rstart,1,&workis[cnt++]);CHKERRQ(ierr); 467fabe8965SStefano Zampini } 468fabe8965SStefano Zampini } 469fabe8965SStefano Zampini for (i = cnt; i < gcnt; i++) { 470fabe8965SStefano Zampini ierr = ISCreateStride(comm,0,0,1,&workis[i]);CHKERRQ(ierr); 471fabe8965SStefano Zampini } 472fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 473fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"ISOLATED");CHKERRQ(ierr); 474fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 475fabe8965SStefano Zampini } 476fabe8965SStefano Zampini 477fabe8965SStefano Zampini /* no communications since all the ISes correspond to locally owned rows */ 478fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,gcnt,workis,1);CHKERRQ(ierr); 479fabe8965SStefano Zampini 480fabe8965SStefano Zampini /* end communicate global id of separators */ 481fabe8965SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 482fabe8965SStefano Zampini 483fabe8965SStefano Zampini /* communicate new layers : create a matrix and transpose it */ 484fabe8965SStefano Zampini ierr = PetscMemzero(dnz,A->rmap->n*sizeof(*dnz));CHKERRQ(ierr); 485fabe8965SStefano Zampini ierr = PetscMemzero(onz,A->rmap->n*sizeof(*onz));CHKERRQ(ierr); 486fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) { 487fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 488fabe8965SStefano Zampini const PetscInt* idxs; 489fabe8965SStefano Zampini PetscInt s; 490fabe8965SStefano Zampini 491fabe8965SStefano Zampini ierr = ISGetLocalSize(workis[j],&s);CHKERRQ(ierr); 492fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 493fabe8965SStefano Zampini ierr = MatPreallocateSet(i+A->rmap->rstart,s,idxs,dnz,onz);CHKERRQ(ierr); 494fabe8965SStefano Zampini j++; 495fabe8965SStefano Zampini } 496fabe8965SStefano Zampini } 497fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 498fabe8965SStefano Zampini 499fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 500fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"EXTENDED");CHKERRQ(ierr); 501fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 502fabe8965SStefano Zampini } 503fabe8965SStefano Zampini 504fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) j = PetscMax(j,dnz[i]+onz[i]); 505fabe8965SStefano Zampini ierr = PetscMalloc1(j,&vals);CHKERRQ(ierr); 506fabe8965SStefano Zampini for (i = 0; i < j; i++) vals[i] = 1.0; 507fabe8965SStefano Zampini 508fabe8965SStefano Zampini ierr = MatCreate(comm,&A2);CHKERRQ(ierr); 509fabe8965SStefano Zampini ierr = MatSetType(A2,MATMPIAIJ);CHKERRQ(ierr); 510fabe8965SStefano Zampini ierr = MatSetSizes(A2,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 511fabe8965SStefano Zampini ierr = MatMPIAIJSetPreallocation(A2,0,dnz,0,onz);CHKERRQ(ierr); 512fabe8965SStefano Zampini ierr = MatSetOption(A2,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 513fabe8965SStefano Zampini for (i = 0, j = 0; i < A2->rmap->n; i++) { 514fabe8965SStefano Zampini PetscInt row = i+A2->rmap->rstart,s = dnz[i] + onz[i]; 515fabe8965SStefano Zampini const PetscInt* idxs; 516fabe8965SStefano Zampini 517fabe8965SStefano Zampini if (s) { 518fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 519fabe8965SStefano Zampini ierr = MatSetValues(A2,1,&row,s,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 520fabe8965SStefano Zampini ierr = ISRestoreIndices(workis[j],&idxs);CHKERRQ(ierr); 521fabe8965SStefano Zampini j++; 522fabe8965SStefano Zampini } 523fabe8965SStefano Zampini } 524fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 525fabe8965SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 526fabe8965SStefano Zampini ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 527fabe8965SStefano Zampini ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 528fabe8965SStefano Zampini ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 529fabe8965SStefano Zampini 530fabe8965SStefano Zampini /* extract submatrix corresponding to the coupling "owned separators" x "isolated separators" */ 531fabe8965SStefano Zampini for (i = 0, j = 0; i < nl; i++) 532fabe8965SStefano Zampini if (lndmapi[i] >= 0) lndmapi[j++] = lndmapi[i]; 533fabe8965SStefano Zampini ierr = ISCreateGeneral(comm,j,lndmapi,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 534fabe8965SStefano Zampini ierr = MatMPIAIJGetLocalMatCondensed(A2,MAT_INITIAL_MATRIX,&is,NULL,&A3);CHKERRQ(ierr); 535fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 536fabe8965SStefano Zampini ierr = MatDestroy(&A2);CHKERRQ(ierr); 537fabe8965SStefano Zampini 538fabe8965SStefano Zampini /* extend local to global map to include connected isolated separators */ 539fabe8965SStefano Zampini ierr = PetscObjectQuery((PetscObject)A3,"_petsc_GetLocalMatCondensed_iscol",(PetscObject*)&is);CHKERRQ(ierr); 540fabe8965SStefano Zampini if (!is) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing column map"); 541fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&ll2g);CHKERRQ(ierr); 542fabe8965SStefano Zampini ierr = MatGetRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 543fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 544fabe8965SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,ii[i],jj,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 545fabe8965SStefano Zampini ierr = MatRestoreRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 546fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 547fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ll2g,is,&is2);CHKERRQ(ierr); 548fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 549fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ll2g);CHKERRQ(ierr); 550fabe8965SStefano Zampini 551fabe8965SStefano Zampini /* add new nodes to the local-to-global map */ 552fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(l2g);CHKERRQ(ierr); 553fabe8965SStefano Zampini ierr = ISExpand(ndsub,is2,&is);CHKERRQ(ierr); 554fabe8965SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 555fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 556fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 557fabe8965SStefano Zampini 558fabe8965SStefano Zampini ierr = MatDestroy(&A3);CHKERRQ(ierr); 559fabe8965SStefano Zampini ierr = PetscFree(lndmapi);CHKERRQ(ierr); 560fabe8965SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 561fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 562fabe8965SStefano Zampini ierr = ISDestroy(&workis[i]);CHKERRQ(ierr); 563fabe8965SStefano Zampini } 564fabe8965SStefano Zampini ierr = PetscFree(workis);CHKERRQ(ierr); 565fabe8965SStefano Zampini } 566fabe8965SStefano Zampini ierr = ISRestoreIndices(ndmap,&ndmapi);CHKERRQ(ierr); 567fabe8965SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 568fabe8965SStefano Zampini ierr = PetscFree(ndmapc);CHKERRQ(ierr); 569fabe8965SStefano Zampini ierr = ISDestroy(&ndmap);CHKERRQ(ierr); 570fabe8965SStefano Zampini ierr = ISDestroy(&ndsub);CHKERRQ(ierr); 571fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(*l2g,bs);CHKERRQ(ierr); 572fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingViewFromOptions(*l2g,NULL,"-matis_nd_l2g_view");CHKERRQ(ierr); 573fabe8965SStefano Zampini break; 574fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_NATURAL: 575fabe8965SStefano Zampini if (ismpiaij) { 576fabe8965SStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 577fabe8965SStefano Zampini } else if (ismpibaij) { 578fabe8965SStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 579c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 580c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 581c9225affSStefano Zampini if (A->rmap->n) { 582fabe8965SStefano Zampini PetscInt dc,oc,stc,*aux; 583c9225affSStefano Zampini 584c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 585c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 586c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 587c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 588c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 589c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 590c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 591c9225affSStefano Zampini } else { 592c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 593c9225affSStefano Zampini } 594c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 595c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 596fabe8965SStefano Zampini break; 597fabe8965SStefano Zampini default: 598fabe8965SStefano Zampini SETERRQ1(comm,PETSC_ERR_ARG_WRONG,"Unsupported l2g disassembling type %D",mode); 599c9225affSStefano Zampini } 600c9225affSStefano Zampini PetscFunctionReturn(0); 601c9225affSStefano Zampini } 602c9225affSStefano Zampini 603c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 604c9225affSStefano Zampini { 605c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 6066989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 6076989cf23SStefano Zampini IS is; 6086989cf23SStefano Zampini MPI_Comm comm; 6096989cf23SStefano Zampini void *ptrs[2]; 6106989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 611c9225affSStefano Zampini const PetscInt *garray; 6126989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 613c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 614c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 6156989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 616c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 617c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 618c9225affSStefano Zampini PetscMPIInt size; 6196989cf23SStefano Zampini PetscErrorCode ierr; 6206989cf23SStefano Zampini 621ab4d48faSStefano Zampini PetscFunctionBegin; 6226989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 623c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 624c9225affSStefano Zampini if (size == 1) { 625c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 626c9225affSStefano Zampini PetscFunctionReturn(0); 627c9225affSStefano Zampini } 628c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 629c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 630c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 631c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 632c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 633c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 634c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 635c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 636c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 637c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 638c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 639c9225affSStefano Zampini } 640c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 641c9225affSStefano Zampini Mat *newlA, lA; 642c9225affSStefano Zampini IS rows, cols; 643c9225affSStefano Zampini const PetscInt *ridx, *cidx; 644c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 645c9225affSStefano Zampini 646c9225affSStefano Zampini if (!B) B = *newmat; 647c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 648c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 649c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 650c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 651c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 652c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 653c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 654c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 655c9225affSStefano Zampini if (rl2g != cl2g) { 656c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 657c9225affSStefano Zampini } else { 658c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 659c9225affSStefano Zampini cols = rows; 660c9225affSStefano Zampini } 661c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 662c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 663c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 664c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 665c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 666c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 667c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 668c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 669c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 670c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 671c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 672c9225affSStefano Zampini } 673c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 674c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 675c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 676c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 677c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 678c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 679c9225affSStefano Zampini else *newmat = B; 680c9225affSStefano Zampini PetscFunctionReturn(0); 681c9225affSStefano Zampini } 682c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 683c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 684c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 685c9225affSStefano Zampini if (ismpiaij) { 686c9225affSStefano Zampini bs = 1; 687c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 688c9225affSStefano Zampini } else if (ismpibaij) { 689c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 690c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 691c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 692c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 693c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 694c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 695c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 696c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 6976989cf23SStefano Zampini 6986989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 6996989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 7006989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 7016989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 702c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 703c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 704c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 705c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 706c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 707c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 708c9225affSStefano Zampini /* store original pointers to be restored later */ 709c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 7106989cf23SStefano Zampini 7116989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 712c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 713c9225affSStefano Zampini if (bs > 1) { 714c9225affSStefano Zampini IS is2; 715c9225affSStefano Zampini 716c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 717c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 718c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 719c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 720c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 721c9225affSStefano Zampini is = is2; 722c9225affSStefano Zampini } 7236989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 7246989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 725e363d98aSStefano Zampini if (dr) { 726c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 727c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 728c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 729c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 730e363d98aSStefano Zampini lc = dc+oc; 731e363d98aSStefano Zampini } else { 732c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 733e363d98aSStefano Zampini lc = 0; 734e363d98aSStefano Zampini } 7356989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 7366989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 7376989cf23SStefano Zampini 7386989cf23SStefano Zampini /* create MATIS object */ 739c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 740c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 741c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 742c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 743c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 7446989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7456989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7466989cf23SStefano Zampini 7476989cf23SStefano Zampini /* merge local matrices */ 7486989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 7496989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 7506989cf23SStefano Zampini ii = aux; 7516989cf23SStefano Zampini jj = aux+dr+1; 7526989cf23SStefano Zampini aa = data; 7536989cf23SStefano Zampini *ii = *(di++) + *(oi++); 7546989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 7556989cf23SStefano Zampini { 7566989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 7576989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 7586989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 7596989cf23SStefano Zampini } 7606989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 761c9225affSStefano Zampini 762c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 763c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 764c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 765c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 766c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 767c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 768c9225affSStefano Zampini 7696989cf23SStefano Zampini ii = aux; 7706989cf23SStefano Zampini jj = aux+dr+1; 7716989cf23SStefano Zampini aa = data; 772e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 7736989cf23SStefano Zampini 7746989cf23SStefano Zampini /* create containers to destroy the data */ 7756989cf23SStefano Zampini ptrs[0] = aux; 7766989cf23SStefano Zampini ptrs[1] = data; 7776989cf23SStefano Zampini for (i=0; i<2; i++) { 7786989cf23SStefano Zampini PetscContainer c; 7796989cf23SStefano Zampini 7806989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 7816989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 782b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 7836989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 7846989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 7856989cf23SStefano Zampini } 786c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 787c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 788c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 789c9225affSStefano Zampini } 7906989cf23SStefano Zampini 7916989cf23SStefano Zampini /* finalize matrix */ 792c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 7936989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 794c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 795c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 796c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 797c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 798c9225affSStefano Zampini } else *newmat = B; 7996989cf23SStefano Zampini PetscFunctionReturn(0); 8006989cf23SStefano Zampini } 8016989cf23SStefano Zampini 802cf0a3239SStefano Zampini /*@ 8033d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 804cf0a3239SStefano Zampini 8058546b261SStefano Zampini Collective on Mat 806cf0a3239SStefano Zampini 807cf0a3239SStefano Zampini Input Parameters: 808cf0a3239SStefano Zampini + A - the matrix 809cf0a3239SStefano Zampini 810cf0a3239SStefano Zampini Level: advanced 811cf0a3239SStefano Zampini 81295452b02SPatrick Sanan Notes: 81395452b02SPatrick Sanan This function does not need to be called by the user. 814cf0a3239SStefano Zampini 815cf0a3239SStefano Zampini .keywords: matrix 816cf0a3239SStefano Zampini 817cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 818cf0a3239SStefano Zampini @*/ 819cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 820cf0a3239SStefano Zampini { 8217fa8f2d3SStefano Zampini PetscErrorCode ierr; 8227fa8f2d3SStefano Zampini 8237fa8f2d3SStefano Zampini PetscFunctionBegin; 824cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 825cf0a3239SStefano Zampini PetscValidType(A,1); 826cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 8277fa8f2d3SStefano Zampini PetscFunctionReturn(0); 8287fa8f2d3SStefano Zampini } 8297fa8f2d3SStefano Zampini 8305e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 8315e3038f0Sstefano_zampini { 8325e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 8335e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 8345e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 8355e3038f0Sstefano_zampini MPI_Comm comm; 8365b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 8375b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 8389e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 8395e3038f0Sstefano_zampini PetscErrorCode ierr; 8405e3038f0Sstefano_zampini 841ab4d48faSStefano Zampini PetscFunctionBegin; 8425e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 8435e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 8445e3038f0Sstefano_zampini rnest = NULL; 8455e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 8465e3038f0Sstefano_zampini PetscBool ismatis,isnest; 8475e3038f0Sstefano_zampini 8485e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 8495e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 8505e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 8515e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 8525e3038f0Sstefano_zampini if (isnest) { 8535e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 8545e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 8555e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 8565e3038f0Sstefano_zampini } 8575e3038f0Sstefano_zampini } 8585e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 8595b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 8609e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 8615e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 8629e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 8635e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 8645e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8655e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8665e3038f0Sstefano_zampini PetscBool ismatis; 8679e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 8685e3038f0Sstefano_zampini 8695e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 8705e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8715e3038f0Sstefano_zampini 8725e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 8739e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 8749e7b2b25Sstefano_zampini if (istrans[ij]) { 8759e7b2b25Sstefano_zampini Mat T,lT; 8769e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8779e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 8789e7b2b25Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) (transposed) is not of type MATIS",i,j); 8799e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 8809e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 8819e7b2b25Sstefano_zampini } else { 8825e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 8835e3038f0Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) is not of type MATIS",i,j); 8849e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 8859e7b2b25Sstefano_zampini } 8865e3038f0Sstefano_zampini 8875e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 8885e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 8899e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 8905e3038f0Sstefano_zampini if (!l1 || !l2) continue; 8915e3038f0Sstefano_zampini if (lr[i] && l1 != lr[i]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lr[i],l1); 8925e3038f0Sstefano_zampini if (lc[j] && l2 != lc[j]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lc[j],l2); 8935e3038f0Sstefano_zampini lr[i] = l1; 8945e3038f0Sstefano_zampini lc[j] = l2; 8955e3038f0Sstefano_zampini 8965e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 8975e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 8985e3038f0Sstefano_zampini } 8995e3038f0Sstefano_zampini } 9005e3038f0Sstefano_zampini 9015e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 9025e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 9035e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 9045e3038f0Sstefano_zampini rl2g = NULL; 9055e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 9065e3038f0Sstefano_zampini PetscInt n1,n2; 9075e3038f0Sstefano_zampini 9085e3038f0Sstefano_zampini if (!nest[i][j]) continue; 9099e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9109e7b2b25Sstefano_zampini Mat T; 9119e7b2b25Sstefano_zampini 9129e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 9139e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 9149e7b2b25Sstefano_zampini } else { 9155e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 9169e7b2b25Sstefano_zampini } 9175e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9185e3038f0Sstefano_zampini if (!n1) continue; 9195e3038f0Sstefano_zampini if (!rl2g) { 9205e3038f0Sstefano_zampini rl2g = cl2g; 9215e3038f0Sstefano_zampini } else { 9225e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9235e3038f0Sstefano_zampini PetscBool same; 9245e3038f0Sstefano_zampini 9255e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9265e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap size %D != %D",i,j,n1,n2); 9275e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9285e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 9295e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 9305e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9315e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9325e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap",i,j); 9335e3038f0Sstefano_zampini } 9345e3038f0Sstefano_zampini } 9355e3038f0Sstefano_zampini } 9365e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 9375e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 9385e3038f0Sstefano_zampini rl2g = NULL; 9395e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 9405e3038f0Sstefano_zampini PetscInt n1,n2; 9415e3038f0Sstefano_zampini 9425e3038f0Sstefano_zampini if (!nest[j][i]) continue; 9439e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 9449e7b2b25Sstefano_zampini Mat T; 9459e7b2b25Sstefano_zampini 9469e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 9479e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 9489e7b2b25Sstefano_zampini } else { 9495e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 9509e7b2b25Sstefano_zampini } 9515e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9525e3038f0Sstefano_zampini if (!n1) continue; 9535e3038f0Sstefano_zampini if (!rl2g) { 9545e3038f0Sstefano_zampini rl2g = cl2g; 9555e3038f0Sstefano_zampini } else { 9565e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9575e3038f0Sstefano_zampini PetscBool same; 9585e3038f0Sstefano_zampini 9595e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9605e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap size %D != %D",j,i,n1,n2); 9615e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9625e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 9635e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 9645e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9655e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9665e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap",j,i); 9675e3038f0Sstefano_zampini } 9685e3038f0Sstefano_zampini } 9695e3038f0Sstefano_zampini } 9705e3038f0Sstefano_zampini #endif 9715e3038f0Sstefano_zampini 9725e3038f0Sstefano_zampini B = NULL; 9735e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 9745b003df0Sstefano_zampini PetscInt stl; 9755b003df0Sstefano_zampini 9765e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 9775e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 9785e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9795b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9805e3038f0Sstefano_zampini Mat usedmat; 9815e3038f0Sstefano_zampini Mat_IS *matis; 9825e3038f0Sstefano_zampini const PetscInt *idxs; 9835e3038f0Sstefano_zampini 9845e3038f0Sstefano_zampini /* local IS for local NEST */ 9855b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9865e3038f0Sstefano_zampini 9875e3038f0Sstefano_zampini /* l2gmap */ 9885e3038f0Sstefano_zampini j = 0; 9895e3038f0Sstefano_zampini usedmat = nest[i][j]; 9909e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 9919e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 9929e7b2b25Sstefano_zampini 9939e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9949e7b2b25Sstefano_zampini Mat T; 9959e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 9969e7b2b25Sstefano_zampini usedmat = T; 9979e7b2b25Sstefano_zampini } 99882d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 9995e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10005e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 10019e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10029e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10039e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10049e7b2b25Sstefano_zampini } else { 10055e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10065e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10079e7b2b25Sstefano_zampini } 10085e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 10095e3038f0Sstefano_zampini stl += lr[i]; 10105e3038f0Sstefano_zampini } 10115e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 10125e3038f0Sstefano_zampini 10135e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 10145e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 10155e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 10165b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10175e3038f0Sstefano_zampini Mat usedmat; 10185e3038f0Sstefano_zampini Mat_IS *matis; 10195e3038f0Sstefano_zampini const PetscInt *idxs; 10205e3038f0Sstefano_zampini 10215e3038f0Sstefano_zampini /* local IS for local NEST */ 10225b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10235e3038f0Sstefano_zampini 10245e3038f0Sstefano_zampini /* l2gmap */ 10255e3038f0Sstefano_zampini j = 0; 10265e3038f0Sstefano_zampini usedmat = nest[j][i]; 10279e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 10289e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 10299e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10309e7b2b25Sstefano_zampini Mat T; 10319e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 10329e7b2b25Sstefano_zampini usedmat = T; 10339e7b2b25Sstefano_zampini } 103482d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 10355e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10365e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 10379e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10389e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10399e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10409e7b2b25Sstefano_zampini } else { 10415e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10425e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10439e7b2b25Sstefano_zampini } 10445e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 10455e3038f0Sstefano_zampini stl += lc[i]; 10465e3038f0Sstefano_zampini } 10475e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 10485e3038f0Sstefano_zampini 10495e3038f0Sstefano_zampini /* Create MATIS */ 10505e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 10515e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 10525e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 10535e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 10545e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 10558546b261SStefano Zampini ierr = MatISSetLocalMatType(B,MATNEST);CHKERRQ(ierr); 10568546b261SStefano Zampini { /* hack : avoid setup of scatters */ 10578546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10588546b261SStefano Zampini matis->islocalref = PETSC_TRUE; 10598546b261SStefano Zampini } 10605e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 10615e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 10625e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 10635e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 10648546b261SStefano Zampini ierr = MatNestSetVecType(lA,VECNEST);CHKERRQ(ierr); 10659e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 10669e7b2b25Sstefano_zampini if (istrans[i]) { 10679e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10689e7b2b25Sstefano_zampini } 10699e7b2b25Sstefano_zampini } 10705e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 10715e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10728546b261SStefano Zampini { /* hack : setup of scatters done here */ 10738546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10748546b261SStefano Zampini 10758546b261SStefano Zampini matis->islocalref = PETSC_FALSE; 10768546b261SStefano Zampini ierr = MatISSetUpScatters_Private(B);CHKERRQ(ierr); 10778546b261SStefano Zampini } 10785e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10795e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10805e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 10815e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 10825e3038f0Sstefano_zampini } else { 10835e3038f0Sstefano_zampini *newmat = B; 10845e3038f0Sstefano_zampini } 10855e3038f0Sstefano_zampini } else { 10865e3038f0Sstefano_zampini if (lreuse) { 10875e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10885e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10895e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 10905e3038f0Sstefano_zampini if (snest[i*nc+j]) { 10915e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 10929e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10939e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 10949e7b2b25Sstefano_zampini } 10955e3038f0Sstefano_zampini } 10965e3038f0Sstefano_zampini } 10975e3038f0Sstefano_zampini } 10985e3038f0Sstefano_zampini } else { 10995b003df0Sstefano_zampini PetscInt stl; 11005b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 11015b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 11025b003df0Sstefano_zampini stl += lr[i]; 11035e3038f0Sstefano_zampini } 11045b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 11055b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 11065b003df0Sstefano_zampini stl += lc[i]; 11075e3038f0Sstefano_zampini } 11085e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 1109ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 11109e7b2b25Sstefano_zampini if (istrans[i]) { 11119e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 11129e7b2b25Sstefano_zampini } 1113ab4d48faSStefano Zampini } 11145e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 11155e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 11165e3038f0Sstefano_zampini } 11175e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11185e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11195e3038f0Sstefano_zampini } 11205e3038f0Sstefano_zampini 11215b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 11225b003df0Sstefano_zampini convert = PETSC_FALSE; 11235b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 11245b003df0Sstefano_zampini if (convert) { 11255b003df0Sstefano_zampini Mat M; 11265b003df0Sstefano_zampini MatISLocalFields lf; 11275b003df0Sstefano_zampini PetscContainer c; 11285b003df0Sstefano_zampini 11295b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 11305b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 11315b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 11325b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 11335b003df0Sstefano_zampini 11345b003df0Sstefano_zampini /* attach local fields to the matrix */ 11355b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 11365b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 11375b003df0Sstefano_zampini for (i=0;i<nr;i++) { 11385b003df0Sstefano_zampini PetscInt n,st; 11395b003df0Sstefano_zampini 11405b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 11415b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 11425b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 11435b003df0Sstefano_zampini } 11445b003df0Sstefano_zampini for (i=0;i<nc;i++) { 11455b003df0Sstefano_zampini PetscInt n,st; 11465b003df0Sstefano_zampini 11475b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 11485b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 11495b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 11505b003df0Sstefano_zampini } 11515b003df0Sstefano_zampini lf->nr = nr; 11525b003df0Sstefano_zampini lf->nc = nc; 11535b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 11545b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 11555b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 11565b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 11575b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 11585b003df0Sstefano_zampini } 11595b003df0Sstefano_zampini 11605e3038f0Sstefano_zampini /* Free workspace */ 11615e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 11625e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 11635e3038f0Sstefano_zampini } 11645e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 11655e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 11665e3038f0Sstefano_zampini } 11679e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 11685b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 11695e3038f0Sstefano_zampini PetscFunctionReturn(0); 11705e3038f0Sstefano_zampini } 11715e3038f0Sstefano_zampini 1172ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1173ad219c80Sstefano_zampini { 1174ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1175ad219c80Sstefano_zampini Vec ll,rr; 1176ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1177ad219c80Sstefano_zampini PetscScalar *x,*y; 1178ad219c80Sstefano_zampini PetscErrorCode ierr; 1179ad219c80Sstefano_zampini 1180ad219c80Sstefano_zampini PetscFunctionBegin; 1181ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 1182ad219c80Sstefano_zampini if (l) { 1183ad219c80Sstefano_zampini ll = matis->y; 1184ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1185ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1186ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1187ad219c80Sstefano_zampini } else { 1188ad219c80Sstefano_zampini ll = NULL; 1189ad219c80Sstefano_zampini } 1190ad219c80Sstefano_zampini if (r) { 1191ad219c80Sstefano_zampini rr = matis->x; 1192ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1193ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1194ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1195ad219c80Sstefano_zampini } else { 1196ad219c80Sstefano_zampini rr = NULL; 1197ad219c80Sstefano_zampini } 1198ad219c80Sstefano_zampini if (ll) { 1199ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1200ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1201ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1202ad219c80Sstefano_zampini } 1203ad219c80Sstefano_zampini if (rr) { 1204ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1205ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1206ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1207ad219c80Sstefano_zampini } 1208ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1209ad219c80Sstefano_zampini PetscFunctionReturn(0); 1210ad219c80Sstefano_zampini } 1211ad219c80Sstefano_zampini 12127fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 12137fa8f2d3SStefano Zampini { 12147fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 12157fa8f2d3SStefano Zampini MatInfo info; 12167fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 12177fa8f2d3SStefano Zampini PetscInt bs; 12187fa8f2d3SStefano Zampini PetscErrorCode ierr; 12197fa8f2d3SStefano Zampini 12207fa8f2d3SStefano Zampini PetscFunctionBegin; 12217fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 12227fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 12237fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 12247fa8f2d3SStefano Zampini isend[0] = info.nz_used; 12257fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 12267fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 12277fa8f2d3SStefano Zampini isend[3] = info.memory; 12287fa8f2d3SStefano Zampini isend[4] = info.mallocs; 12297fa8f2d3SStefano Zampini } else { 12307fa8f2d3SStefano Zampini isend[0] = 0.; 12317fa8f2d3SStefano Zampini isend[1] = 0.; 12327fa8f2d3SStefano Zampini isend[2] = 0.; 12337fa8f2d3SStefano Zampini isend[3] = 0.; 12347fa8f2d3SStefano Zampini isend[4] = 0.; 12357fa8f2d3SStefano Zampini } 12367fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 12377fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 12387fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 12397fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 12407fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 12417fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 12427fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 12437fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 12447fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 12457fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12467fa8f2d3SStefano Zampini 12477fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12487fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12497fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12507fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12517fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12527fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 12537fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 12547fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12557fa8f2d3SStefano Zampini 12567fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12577fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12587fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12597fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12607fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12617fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 1262d7f69cd0SStefano Zampini } 1263d7f69cd0SStefano Zampini ginfo->block_size = bs; 1264d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 1265d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 1266d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 12675e3038f0Sstefano_zampini PetscFunctionReturn(0); 12685e3038f0Sstefano_zampini } 12695e3038f0Sstefano_zampini 1270d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1271d7f69cd0SStefano Zampini { 1272d7f69cd0SStefano Zampini Mat C,lC,lA; 1273d7f69cd0SStefano Zampini PetscErrorCode ierr; 1274d7f69cd0SStefano Zampini 1275d7f69cd0SStefano Zampini PetscFunctionBegin; 1276cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1277cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1278d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1279d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1280d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1281d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1282d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1283d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1284cf37664fSBarry Smith } else { 1285cf37664fSBarry Smith C = *B; 1286d7f69cd0SStefano Zampini } 1287d7f69cd0SStefano Zampini 1288d7f69cd0SStefano Zampini /* perform local transposition */ 1289d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1290d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1291d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1292d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1293d7f69cd0SStefano Zampini 1294cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1295d7f69cd0SStefano Zampini *B = C; 1296d7f69cd0SStefano Zampini } else { 1297d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1298d7f69cd0SStefano Zampini } 12997aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13007aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1301d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1302d7f69cd0SStefano Zampini } 1303d7f69cd0SStefano Zampini 13043fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 13053fd1c9e7SStefano Zampini { 13063fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 13073fd1c9e7SStefano Zampini PetscErrorCode ierr; 13083fd1c9e7SStefano Zampini 13093fd1c9e7SStefano Zampini PetscFunctionBegin; 13104b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 13113fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13123fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13133fd1c9e7SStefano Zampini } 13143fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 13153fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 13163fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13173fd1c9e7SStefano Zampini } 13183fd1c9e7SStefano Zampini 13193fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 13203fd1c9e7SStefano Zampini { 13214b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 13223fd1c9e7SStefano Zampini PetscErrorCode ierr; 13233fd1c9e7SStefano Zampini 13243fd1c9e7SStefano Zampini PetscFunctionBegin; 13254b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 13263fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 13273fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13283fd1c9e7SStefano Zampini } 13293fd1c9e7SStefano Zampini 1330f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1331f26d0771SStefano Zampini { 1332f26d0771SStefano Zampini PetscErrorCode ierr; 1333f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1334f26d0771SStefano Zampini 1335f26d0771SStefano Zampini PetscFunctionBegin; 1336f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1337f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1338f26d0771SStefano Zampini #endif 1339f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1340f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1341b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1342f26d0771SStefano Zampini PetscFunctionReturn(0); 1343f26d0771SStefano Zampini } 1344f26d0771SStefano Zampini 1345f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1346f26d0771SStefano Zampini { 1347f26d0771SStefano Zampini PetscErrorCode ierr; 1348f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1349f26d0771SStefano Zampini 1350f26d0771SStefano Zampini PetscFunctionBegin; 1351f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1352f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1353f26d0771SStefano Zampini #endif 1354f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1355f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1356b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1357f26d0771SStefano Zampini PetscFunctionReturn(0); 1358f26d0771SStefano Zampini } 1359f26d0771SStefano Zampini 1360f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 1361a8116848SStefano Zampini { 1362a8116848SStefano Zampini PetscInt *owners = map->range; 1363a8116848SStefano Zampini PetscInt n = map->n; 1364a8116848SStefano Zampini PetscSF sf; 1365a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 1366a8116848SStefano Zampini PetscSFNode *ridxs; 1367a8116848SStefano Zampini PetscMPIInt rank; 1368a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 1369a8116848SStefano Zampini PetscErrorCode ierr; 1370a8116848SStefano Zampini 1371a8116848SStefano Zampini PetscFunctionBegin; 1372fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 1373a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 1374a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 1375a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 1376a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 1377a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 1378a8116848SStefano Zampini for (r = 0; r < N; ++r) { 1379a8116848SStefano Zampini const PetscInt idx = idxs[r]; 1380a8116848SStefano Zampini if (idx < 0 || map->N <= idx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Index %D out of range [0,%D)",idx,map->N); 1381a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 1382a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 1383a8116848SStefano Zampini } 1384a8116848SStefano Zampini ridxs[r].rank = p; 1385a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 1386a8116848SStefano Zampini } 1387a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 1388a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 1389a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1390a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1391f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 1392a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 1393f0ae7da4SStefano Zampini 1394f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1395a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 1396a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 1397a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1398a8116848SStefano Zampini start -= cum; 1399a8116848SStefano Zampini cum = 0; 1400a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 1401a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1402a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1403a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 1404a8116848SStefano Zampini } 1405a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1406a8116848SStefano Zampini /* Compress and put in indices */ 1407a8116848SStefano Zampini for (r = 0; r < n; ++r) 1408a8116848SStefano Zampini if (lidxs[r] >= 0) { 1409a8116848SStefano Zampini if (work) work[len] = work[r]; 1410a8116848SStefano Zampini lidxs[len++] = r; 1411a8116848SStefano Zampini } 1412a8116848SStefano Zampini if (on) *on = len; 1413a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 1414a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 1415a8116848SStefano Zampini PetscFunctionReturn(0); 1416a8116848SStefano Zampini } 1417a8116848SStefano Zampini 14187dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1419a8116848SStefano Zampini { 1420a8116848SStefano Zampini Mat locmat,newlocmat; 1421a8116848SStefano Zampini Mat_IS *newmatis; 1422a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1423a8116848SStefano Zampini Vec rtest,ltest; 1424a8116848SStefano Zampini const PetscScalar *array; 1425a8116848SStefano Zampini #endif 1426a8116848SStefano Zampini const PetscInt *idxs; 1427a8116848SStefano Zampini PetscInt i,m,n; 1428a8116848SStefano Zampini PetscErrorCode ierr; 1429a8116848SStefano Zampini 1430a8116848SStefano Zampini PetscFunctionBegin; 1431a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1432a8116848SStefano Zampini PetscBool ismatis; 1433a8116848SStefano Zampini 1434a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1435a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1436a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1437a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1438a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1439a8116848SStefano Zampini } 1440a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1441a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1442a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1443a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1444a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1445a8116848SStefano Zampini for (i=0;i<n;i++) { 1446a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1447a8116848SStefano Zampini } 1448a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1449a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1450a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1451a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1452a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1453fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Irow may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1454a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1455a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1456a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1457a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1458a8116848SStefano Zampini for (i=0;i<n;i++) { 1459a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1460a8116848SStefano Zampini } 1461a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1462a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1463a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1464a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1465a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1466fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Icol may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1467a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1468a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1469a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1470a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1471a8116848SStefano Zampini #endif 1472a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1473a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1474a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1475a8116848SStefano Zampini IS is; 1476a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1477306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 147894342113SStefano Zampini PetscBool cong; 1479a8116848SStefano Zampini MPI_Comm comm; 1480a8116848SStefano Zampini 1481a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1482306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1483306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1484306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1485306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1486306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1487a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1488a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1489a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1490a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1491a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1492306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1493a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1494a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1495f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1496a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 14973d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 14983d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1499a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1500a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1501a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1502a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1503a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 15043d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1505a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1506a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 15073d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1508a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1509a8116848SStefano Zampini lidxs[newloc] = i; 1510a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1511a8116848SStefano Zampini } 1512a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1513a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1514306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1515a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1516a8116848SStefano Zampini /* local is to extract local submatrix */ 1517a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1518a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 151994342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 152094342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1521a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1522a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1523a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1524a8116848SStefano Zampini } else { 1525a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1526a8116848SStefano Zampini 1527a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1528a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1529f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1530a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 15313d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1532a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1533a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1534a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1535a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1536a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 15373d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1538a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1539a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 15403d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1541a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1542a8116848SStefano Zampini lidxs[newloc] = i; 1543a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1544a8116848SStefano Zampini } 1545a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1546a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1547306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1548a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1549a8116848SStefano Zampini /* local is to extract local submatrix */ 1550a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1551a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1552a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1553a8116848SStefano Zampini } 1554a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1555a8116848SStefano Zampini } else { 1556a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1557a8116848SStefano Zampini } 1558a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1559a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 15607dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1561a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1562a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1563a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1564a8116848SStefano Zampini } 1565a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1566a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1567a8116848SStefano Zampini PetscFunctionReturn(0); 1568a8116848SStefano Zampini } 1569a8116848SStefano Zampini 1570a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 15712b404112SStefano Zampini { 15722b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 15732b404112SStefano Zampini PetscBool ismatis; 15742b404112SStefano Zampini PetscErrorCode ierr; 15752b404112SStefano Zampini 15762b404112SStefano Zampini PetscFunctionBegin; 15772b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 15782b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 15792b404112SStefano Zampini b = (Mat_IS*)B->data; 15802b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1581cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 15822b404112SStefano Zampini PetscFunctionReturn(0); 15832b404112SStefano Zampini } 15842b404112SStefano Zampini 1585a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 15866bd84002SStefano Zampini { 1587527b2640SStefano Zampini Vec v; 1588527b2640SStefano Zampini const PetscScalar *array; 1589527b2640SStefano Zampini PetscInt i,n; 15906bd84002SStefano Zampini PetscErrorCode ierr; 15916bd84002SStefano Zampini 15926bd84002SStefano Zampini PetscFunctionBegin; 1593527b2640SStefano Zampini *missing = PETSC_FALSE; 1594527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1595527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1596527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1597527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1598527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1599527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1600527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1601527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1602527b2640SStefano Zampini if (d) { 1603527b2640SStefano Zampini *d = -1; 1604527b2640SStefano Zampini if (*missing) { 1605527b2640SStefano Zampini PetscInt rstart; 1606527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1607527b2640SStefano Zampini *d = i+rstart; 1608527b2640SStefano Zampini } 1609527b2640SStefano Zampini } 16106bd84002SStefano Zampini PetscFunctionReturn(0); 16116bd84002SStefano Zampini } 16126bd84002SStefano Zampini 1613cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 161428f4e0baSStefano Zampini { 161528f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 161628f4e0baSStefano Zampini const PetscInt *gidxs; 16174f2d7cafSStefano Zampini PetscInt nleaves; 161828f4e0baSStefano Zampini PetscErrorCode ierr; 161928f4e0baSStefano Zampini 162028f4e0baSStefano Zampini PetscFunctionBegin; 16214f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 162275d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 162375d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 162428f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 16253bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 16264f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 16274f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 16283bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 16294f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1630a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 16313d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1632a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1633a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 16343d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1635a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 16363d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1637a8116848SStefano Zampini } else { 1638a8116848SStefano Zampini matis->csf = matis->sf; 1639a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1640a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1641a8116848SStefano Zampini } 164228f4e0baSStefano Zampini PetscFunctionReturn(0); 164328f4e0baSStefano Zampini } 16442e1947a5SStefano Zampini 1645eb82efa4SStefano Zampini /*@ 164675d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 164775d48cdbSStefano Zampini 164875d48cdbSStefano Zampini Collective on MPI_Comm 164975d48cdbSStefano Zampini 165075d48cdbSStefano Zampini Input Parameters: 165175d48cdbSStefano Zampini + A - the matrix 165275d48cdbSStefano Zampini - store - the boolean flag 165375d48cdbSStefano Zampini 165475d48cdbSStefano Zampini Level: advanced 165575d48cdbSStefano Zampini 165675d48cdbSStefano Zampini Notes: 165775d48cdbSStefano Zampini 165875d48cdbSStefano Zampini .keywords: matrix 165975d48cdbSStefano Zampini 166075d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 166175d48cdbSStefano Zampini @*/ 166275d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 166375d48cdbSStefano Zampini { 166475d48cdbSStefano Zampini PetscErrorCode ierr; 166575d48cdbSStefano Zampini 166675d48cdbSStefano Zampini PetscFunctionBegin; 166775d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 166875d48cdbSStefano Zampini PetscValidType(A,1); 166975d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 167075d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 167175d48cdbSStefano Zampini PetscFunctionReturn(0); 167275d48cdbSStefano Zampini } 167375d48cdbSStefano Zampini 167475d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 167575d48cdbSStefano Zampini { 167675d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 167775d48cdbSStefano Zampini PetscErrorCode ierr; 167875d48cdbSStefano Zampini 167975d48cdbSStefano Zampini PetscFunctionBegin; 168075d48cdbSStefano Zampini matis->storel2l = store; 168175d48cdbSStefano Zampini if (!store) { 168275d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 168375d48cdbSStefano Zampini } 168475d48cdbSStefano Zampini PetscFunctionReturn(0); 168575d48cdbSStefano Zampini } 168675d48cdbSStefano Zampini 168775d48cdbSStefano Zampini /*@ 1688f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1689f03112d0SStefano Zampini 1690f03112d0SStefano Zampini Collective on MPI_Comm 1691f03112d0SStefano Zampini 1692f03112d0SStefano Zampini Input Parameters: 1693f03112d0SStefano Zampini + A - the matrix 1694f03112d0SStefano Zampini - fix - the boolean flag 1695f03112d0SStefano Zampini 1696f03112d0SStefano Zampini Level: advanced 1697f03112d0SStefano Zampini 1698f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1699f03112d0SStefano Zampini 1700f03112d0SStefano Zampini .keywords: matrix 1701f03112d0SStefano Zampini 1702f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1703f03112d0SStefano Zampini @*/ 1704f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1705f03112d0SStefano Zampini { 1706f03112d0SStefano Zampini PetscErrorCode ierr; 1707f03112d0SStefano Zampini 1708f03112d0SStefano Zampini PetscFunctionBegin; 1709f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1710f03112d0SStefano Zampini PetscValidType(A,1); 1711f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1712f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1713f03112d0SStefano Zampini PetscFunctionReturn(0); 1714f03112d0SStefano Zampini } 1715f03112d0SStefano Zampini 1716f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1717f03112d0SStefano Zampini { 1718f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1719f03112d0SStefano Zampini 1720f03112d0SStefano Zampini PetscFunctionBegin; 1721f03112d0SStefano Zampini matis->locempty = fix; 1722f03112d0SStefano Zampini PetscFunctionReturn(0); 1723f03112d0SStefano Zampini } 1724f03112d0SStefano Zampini 1725f03112d0SStefano Zampini /*@ 1726a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1727a88811baSStefano Zampini 1728a88811baSStefano Zampini Collective on MPI_Comm 1729a88811baSStefano Zampini 1730a88811baSStefano Zampini Input Parameters: 1731a88811baSStefano Zampini + B - the matrix 1732a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1733a88811baSStefano Zampini (same value is used for all local rows) 1734a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1735a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1736a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1737a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1738a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1739a88811baSStefano Zampini the diagonal entry even if it is zero. 1740a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1741a88811baSStefano Zampini submatrix (same value is used for all local rows). 1742a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1743a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1744a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1745a88811baSStefano Zampini structure. The size of this array is equal to the number 1746a88811baSStefano Zampini of local rows, i.e 'm'. 1747a88811baSStefano Zampini 1748a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1749a88811baSStefano Zampini 1750a88811baSStefano Zampini Level: intermediate 1751a88811baSStefano Zampini 175295452b02SPatrick Sanan Notes: 175395452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1754a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1755a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1756a88811baSStefano Zampini 1757a88811baSStefano Zampini .keywords: matrix 1758a88811baSStefano Zampini 17593c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1760a88811baSStefano Zampini @*/ 17612e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 17622e1947a5SStefano Zampini { 17632e1947a5SStefano Zampini PetscErrorCode ierr; 17642e1947a5SStefano Zampini 17652e1947a5SStefano Zampini PetscFunctionBegin; 17662e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 17672e1947a5SStefano Zampini PetscValidType(B,1); 17682e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 17692e1947a5SStefano Zampini PetscFunctionReturn(0); 17702e1947a5SStefano Zampini } 17712e1947a5SStefano Zampini 1772844bd0d7SStefano Zampini /* this is used by DMDA */ 1773844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 17742e1947a5SStefano Zampini { 17752e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 177628f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 17772e1947a5SStefano Zampini PetscErrorCode ierr; 17782e1947a5SStefano Zampini 17792e1947a5SStefano Zampini PetscFunctionBegin; 17806c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1781cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 17824f2d7cafSStefano Zampini 17834f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 17844f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 17854f2d7cafSStefano Zampini 17864f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 17874f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 17884f2d7cafSStefano Zampini 178928f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 179028f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 179128f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 179228f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17934f2d7cafSStefano Zampini 17944f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 179528f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 17960f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 17970f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 17980f2f62c7SStefano Zampini #endif 17994f2d7cafSStefano Zampini 18004f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 180128f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 18024f2d7cafSStefano Zampini 180300a59248SStefano Zampini nlocalcols /= bs; 180400a59248SStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols - i); 180528f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 18060f2f62c7SStefano Zampini 18070f2f62c7SStefano Zampini /* for other matrix types */ 18080f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 18092e1947a5SStefano Zampini PetscFunctionReturn(0); 18102e1947a5SStefano Zampini } 1811b4319ba4SBarry Smith 18123927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 18133927de2eSStefano Zampini { 18143927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 18153927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1816ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 18173927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 18183927de2eSStefano Zampini PetscInt lrows,lcols; 18193927de2eSStefano Zampini PetscInt local_rows,local_cols; 1820f03112d0SStefano Zampini PetscMPIInt size; 18213927de2eSStefano Zampini PetscBool isdense,issbaij; 18223927de2eSStefano Zampini PetscErrorCode ierr; 18233927de2eSStefano Zampini 18243927de2eSStefano Zampini PetscFunctionBegin; 1825f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 18263927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 18273927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 18283927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 18293927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 18303927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1831ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1832ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 18337230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1834ecf5a873SStefano Zampini } else { 1835ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1836ecf5a873SStefano Zampini } 1837ecf5a873SStefano Zampini 18383927de2eSStefano Zampini if (issbaij) { 18393927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 18403927de2eSStefano Zampini } 18413927de2eSStefano Zampini /* 1842ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 18433927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 18443927de2eSStefano Zampini */ 1845cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 18463927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 18473927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 18483927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 18493927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 18503927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1851f03112d0SStefano Zampini for (i=0;i<size;i++) { 18523927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 18533927de2eSStefano Zampini row_ownership[j] = i; 18543927de2eSStefano Zampini } 18553927de2eSStefano Zampini } 18567230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 18573927de2eSStefano Zampini 18583927de2eSStefano Zampini /* 18593927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 18603927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 18613927de2eSStefano Zampini */ 18623927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 18633927de2eSStefano Zampini /* preallocation as a MATAIJ */ 18643927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 18653927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 186612dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 186712dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1868ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 18693927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 18703927de2eSStefano Zampini my_dnz[i] += 1; 18713927de2eSStefano Zampini } else { /* offdiag block */ 18723927de2eSStefano Zampini my_onz[i] += 1; 18733927de2eSStefano Zampini } 18743927de2eSStefano Zampini } 18753927de2eSStefano Zampini } 1876bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1877bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1878bb1015c3SStefano Zampini PetscBool done; 1879bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1880938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1881bb1015c3SStefano Zampini jptr = jj; 1882bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1883bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1884bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1885bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1886bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1887bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1888bb1015c3SStefano Zampini my_dnz[i] += 1; 1889bb1015c3SStefano Zampini } else { /* offdiag block */ 1890bb1015c3SStefano Zampini my_onz[i] += 1; 1891bb1015c3SStefano Zampini } 1892bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1893bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1894bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1895bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1896bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1897bb1015c3SStefano Zampini } else { 1898bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1899bb1015c3SStefano Zampini } 1900bb1015c3SStefano Zampini } 1901bb1015c3SStefano Zampini } 1902bb1015c3SStefano Zampini } 1903bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1904938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1905bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 19063927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 19073927de2eSStefano Zampini const PetscInt *cols; 1908ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 19093927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 19103927de2eSStefano Zampini for (j=0;j<ncols;j++) { 19113927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1912ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 19133927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 19143927de2eSStefano Zampini my_dnz[i] += 1; 19153927de2eSStefano Zampini } else { /* offdiag block */ 19163927de2eSStefano Zampini my_onz[i] += 1; 19173927de2eSStefano Zampini } 19183927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1919d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 19203927de2eSStefano Zampini owner = row_ownership[index_col]; 19213927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1922d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 19233927de2eSStefano Zampini } else { 1924d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 19253927de2eSStefano Zampini } 19263927de2eSStefano Zampini } 19273927de2eSStefano Zampini } 19283927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 19293927de2eSStefano Zampini } 19303927de2eSStefano Zampini } 1931ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 19327230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1933ecf5a873SStefano Zampini } 19344f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 19353927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1936ecf5a873SStefano Zampini 1937ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 19383927de2eSStefano Zampini if (maxreduce) { 19393927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 19403927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1941bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 19423927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 19433927de2eSStefano Zampini } else { 19443927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 19453927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1946bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 19473927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 19483927de2eSStefano Zampini } 19493927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 19503927de2eSStefano Zampini 19513927de2eSStefano Zampini /* Resize preallocation if overestimated */ 19523927de2eSStefano Zampini for (i=0;i<lrows;i++) { 19533927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 19543927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 19553927de2eSStefano Zampini } 19561670daf9Sstefano_zampini 19571670daf9Sstefano_zampini /* Set preallocation */ 1958268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 19593927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 196053b44cf5SStefano Zampini for (i=0;i<lrows;i+=bs) { 196153b44cf5SStefano Zampini PetscInt b, d = dnz[i],o = onz[i]; 196253b44cf5SStefano Zampini 196353b44cf5SStefano Zampini for (b=1;b<bs;b++) { 196453b44cf5SStefano Zampini d = PetscMax(d,dnz[i+b]); 196553b44cf5SStefano Zampini o = PetscMax(o,onz[i+b]); 196653b44cf5SStefano Zampini } 196753b44cf5SStefano Zampini dnz[i/bs] = PetscMin(d/bs + d%bs,lcols/bs); 196853b44cf5SStefano Zampini onz[i/bs] = PetscMin(o/bs + o%bs,(cols-lcols)/bs); 19693927de2eSStefano Zampini } 1970268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 19713927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 19723927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 19733927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 19743927de2eSStefano Zampini if (issbaij) { 19753927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 19763927de2eSStefano Zampini } 19779be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19783927de2eSStefano Zampini PetscFunctionReturn(0); 19793927de2eSStefano Zampini } 19803927de2eSStefano Zampini 1981487b449aSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_IS_XAIJ(Mat mat, MatType mtype, MatReuse reuse, Mat *M) 1982b7ce53b6SStefano Zampini { 1983b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1984487b449aSStefano Zampini Mat local_mat,MT; 198553b44cf5SStefano Zampini PetscInt rbs,cbs,rows,cols,lrows,lcols; 1986b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1987b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1988b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1989b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1990b9ed4604SStefano Zampini #endif 1991f03112d0SStefano Zampini PetscMPIInt size; 1992b7ce53b6SStefano Zampini PetscScalar *array; 1993b7ce53b6SStefano Zampini PetscErrorCode ierr; 1994b7ce53b6SStefano Zampini 1995b7ce53b6SStefano Zampini PetscFunctionBegin; 1996f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1997f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 19981670daf9Sstefano_zampini Mat B; 199953b44cf5SStefano Zampini IS irows = NULL,icols = NULL; 2000487b449aSStefano Zampini PetscInt rbs,cbs; 20011670daf9Sstefano_zampini 2002487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2003487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 200453b44cf5SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { /* check if l2g maps are one-to-one */ 200553b44cf5SStefano Zampini IS rows,cols; 200653b44cf5SStefano Zampini const PetscInt *ridxs,*cidxs; 200753b44cf5SStefano Zampini PetscInt i,nw,*work; 200853b44cf5SStefano Zampini 200953b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 201053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&nw);CHKERRQ(ierr); 201153b44cf5SStefano Zampini nw = nw/rbs; 201253b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 201353b44cf5SStefano Zampini for (i=0;i<nw;i++) work[ridxs[i]] += 1; 201453b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 201553b44cf5SStefano Zampini if (i == nw) { 201653b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,nw,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 2017acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 201853b44cf5SStefano Zampini ierr = ISInvertPermutation(rows,PETSC_DECIDE,&irows);CHKERRQ(ierr); 2019acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 202053b44cf5SStefano Zampini } 202153b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 202253b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 202353b44cf5SStefano Zampini if (irows && mat->rmap->mapping != mat->cmap->mapping) { 202453b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 202553b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->cmap->mapping,&nw);CHKERRQ(ierr); 202653b44cf5SStefano Zampini nw = nw/cbs; 202753b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 202853b44cf5SStefano Zampini for (i=0;i<nw;i++) work[cidxs[i]] += 1; 202953b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 203053b44cf5SStefano Zampini if (i == nw) { 203153b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,nw,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 203253b44cf5SStefano Zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 203353b44cf5SStefano Zampini ierr = ISInvertPermutation(cols,PETSC_DECIDE,&icols);CHKERRQ(ierr); 203453b44cf5SStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 203553b44cf5SStefano Zampini } 203653b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 203753b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 203853b44cf5SStefano Zampini } else if (irows) { 203953b44cf5SStefano Zampini ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); 204053b44cf5SStefano Zampini icols = irows; 204153b44cf5SStefano Zampini } 204253b44cf5SStefano Zampini } else { 204353b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject*)&irows);CHKERRQ(ierr); 204453b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject*)&icols);CHKERRQ(ierr); 204553b44cf5SStefano Zampini if (irows) { ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); } 204653b44cf5SStefano Zampini if (icols) { ierr = PetscObjectReference((PetscObject)icols);CHKERRQ(ierr); } 204753b44cf5SStefano Zampini } 204853b44cf5SStefano Zampini if (!irows || !icols) { 204953b44cf5SStefano Zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 205053b44cf5SStefano Zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 205153b44cf5SStefano Zampini goto general_assembly; 205253b44cf5SStefano Zampini } 2053487b449aSStefano Zampini ierr = MatConvert(matis->A,(rbs == cbs && rbs > 1) ? MATSEQBAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 2054487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 20557dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 205653b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject)irows);CHKERRQ(ierr); 205753b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject)icols);CHKERRQ(ierr); 2058487b449aSStefano Zampini } else { 2059487b449aSStefano Zampini Mat C; 2060487b449aSStefano Zampini 2061487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 2062487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 2063487b449aSStefano Zampini } 2064acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2065acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 2066acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 20677c03b4e8SStefano Zampini PetscFunctionReturn(0); 20687c03b4e8SStefano Zampini } 206953b44cf5SStefano Zampini general_assembly: 2070b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 207153b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 207253b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 20733cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 2074b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 2075b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 20764099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 2077b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 2078b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 2079b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 2080b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 2081b9ed4604SStefano Zampini lb[0] = isseqdense; 2082b9ed4604SStefano Zampini lb[1] = isseqaij; 2083b9ed4604SStefano Zampini lb[2] = isseqbaij; 2084b9ed4604SStefano Zampini lb[3] = isseqsbaij; 2085b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 2086b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 2087b9ed4604SStefano Zampini #endif 2088b7ce53b6SStefano Zampini 2089487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2090487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 2091487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 2092487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 209353b44cf5SStefano Zampini ierr = MatSetBlockSizes(MT,rbs,cbs);CHKERRQ(ierr); 2094487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 2095b7ce53b6SStefano Zampini } else { 209653b44cf5SStefano Zampini PetscInt mrbs,mcbs,mrows,mcols,mlrows,mlcols; 2097487b449aSStefano Zampini 2098b7ce53b6SStefano Zampini /* some checks */ 2099487b449aSStefano Zampini MT = *M; 210053b44cf5SStefano Zampini ierr = MatGetBlockSizes(MT,&mrbs,&mcbs);CHKERRQ(ierr); 2101487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 2102487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 21036c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 21046c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 21056c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 21066c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 210753b44cf5SStefano Zampini if (mrbs != rbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong row block size (%d != %d)",rbs,mrbs); 210853b44cf5SStefano Zampini if (mcbs != cbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong col block size (%d != %d)",cbs,mcbs); 2109487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 2110b7ce53b6SStefano Zampini } 2111d9a9e74cSStefano Zampini 21128546b261SStefano Zampini if (isseqsbaij || isseqbaij) { 21138546b261SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 21148546b261SStefano Zampini isseqaij = PETSC_TRUE; 2115d9a9e74cSStefano Zampini } else { 2116d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 2117d9a9e74cSStefano Zampini local_mat = matis->A; 2118d9a9e74cSStefano Zampini } 2119686e3a49SStefano Zampini 2120b7ce53b6SStefano Zampini /* Set values */ 2121487b449aSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2122b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 212365066ba5SStefano Zampini PetscInt i,*dummy; 2124ecf5a873SStefano Zampini 212565066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 212665066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 2127487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 2128d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 2129487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 2130d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 213165066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 2132686e3a49SStefano Zampini } else if (isseqaij) { 21336afe12f5SStefano Zampini const PetscInt *blocks; 21346afe12f5SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy, nb; 2135686e3a49SStefano Zampini PetscBool done; 2136686e3a49SStefano Zampini 2137d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2138938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 2139d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 21406afe12f5SStefano Zampini ierr = MatGetVariableBlockSizes(local_mat,&nb,&blocks);CHKERRQ(ierr); 21416afe12f5SStefano Zampini if (nb) { /* speed up assembly for special blocked matrices (used by BDDC) */ 21426afe12f5SStefano Zampini PetscInt sum; 21436afe12f5SStefano Zampini 21446afe12f5SStefano Zampini for (i=0,sum=0;i<nb;i++) sum += blocks[i]; 21456afe12f5SStefano Zampini if (sum == nvtxs) { 21466afe12f5SStefano Zampini PetscInt r; 21476afe12f5SStefano Zampini 21486afe12f5SStefano Zampini for (i=0,r=0;i<nb;i++) { 21496afe12f5SStefano Zampini if (blocks[i] != xadj[r+1] - xadj[r]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid block sizes prescribed for block %D: expected %D, got %D",i,blocks[i],xadj[r+1] - xadj[r]); 21506afe12f5SStefano Zampini ierr = MatSetValuesLocal(MT,blocks[i],adjncy+xadj[r],blocks[i],adjncy+xadj[r],array+xadj[r],ADD_VALUES);CHKERRQ(ierr); 21516afe12f5SStefano Zampini r += blocks[i]; 21526afe12f5SStefano Zampini } 21536afe12f5SStefano Zampini } else { 2154686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 2155487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 2156686e3a49SStefano Zampini } 21576afe12f5SStefano Zampini } 21586afe12f5SStefano Zampini } else { 21596afe12f5SStefano Zampini for (i=0;i<nvtxs;i++) { 21606afe12f5SStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 21616afe12f5SStefano Zampini } 21626afe12f5SStefano Zampini } 2163d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2164938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 2165d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 2166686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 2167ecf5a873SStefano Zampini PetscInt i; 2168c0962df8SStefano Zampini 2169686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 2170686e3a49SStefano Zampini PetscInt j; 2171ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 2172686e3a49SStefano Zampini 2173ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 2174487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 2175ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 2176686e3a49SStefano Zampini } 2177b7ce53b6SStefano Zampini } 2178487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2179d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 2180487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2181b9ed4604SStefano Zampini if (isseqdense) { 2182487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 2183487b449aSStefano Zampini } 2184487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 2185487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 2186487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 2187487b449aSStefano Zampini *M = MT; 2188b7ce53b6SStefano Zampini } 2189b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2190b7ce53b6SStefano Zampini } 2191b7ce53b6SStefano Zampini 2192b7ce53b6SStefano Zampini /*@ 2193b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 2194b7ce53b6SStefano Zampini 2195b7ce53b6SStefano Zampini Input Parameter: 2196b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 2197b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 2198b7ce53b6SStefano Zampini 2199b7ce53b6SStefano Zampini Output Parameter: 2200b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 2201b7ce53b6SStefano Zampini 2202b7ce53b6SStefano Zampini Level: developer 2203b7ce53b6SStefano Zampini 220495452b02SPatrick Sanan Notes: 2205487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 2206b7ce53b6SStefano Zampini 2207487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2208b7ce53b6SStefano Zampini @*/ 2209b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2210b7ce53b6SStefano Zampini { 2211b7ce53b6SStefano Zampini PetscErrorCode ierr; 2212b7ce53b6SStefano Zampini 2213b7ce53b6SStefano Zampini PetscFunctionBegin; 2214b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2215b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2216b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2217487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2218b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2219b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 22206c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2221b7ce53b6SStefano Zampini } 2222487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2223b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2224b7ce53b6SStefano Zampini } 2225b7ce53b6SStefano Zampini 2226ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2227ad6194a2SStefano Zampini { 2228ad6194a2SStefano Zampini PetscErrorCode ierr; 2229ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2230c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2231ad6194a2SStefano Zampini Mat B,localmat; 2232ad6194a2SStefano Zampini 2233ad6194a2SStefano Zampini PetscFunctionBegin; 2234c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2235c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2236ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2237ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 22388546b261SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 22398546b261SStefano Zampini ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 22408546b261SStefano Zampini ierr = MatSetBlockSize(B,rbs == cbs ? rbs : 1);CHKERRQ(ierr); 22418546b261SStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 22428546b261SStefano Zampini ierr = MatISSetLocalMatType(B,matis->lmattype);CHKERRQ(ierr); 22438546b261SStefano Zampini ierr = MatSetLocalToGlobalMapping(B,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2244ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2245ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2246b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2247b0f2910eSStefano Zampini if (matis->sf) { 2248b0f2910eSStefano Zampini Mat_IS *bmatis = (Mat_IS*)(B->data); 2249b0f2910eSStefano Zampini 2250b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->sf);CHKERRQ(ierr); 2251b0f2910eSStefano Zampini bmatis->sf = matis->sf; 2252b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&bmatis->sf_rootdata,matis->sf->nleaves,&bmatis->sf_leafdata);CHKERRQ(ierr); 2253b0f2910eSStefano Zampini if (matis->sf != matis->csf) { 2254b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->csf);CHKERRQ(ierr); 2255b0f2910eSStefano Zampini bmatis->csf = matis->csf; 2256b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&bmatis->csf_rootdata,matis->csf->nleaves,&bmatis->csf_leafdata);CHKERRQ(ierr); 2257b0f2910eSStefano Zampini } else { 2258b0f2910eSStefano Zampini bmatis->csf = bmatis->sf; 2259b0f2910eSStefano Zampini bmatis->csf_leafdata = bmatis->sf_leafdata; 2260b0f2910eSStefano Zampini bmatis->csf_rootdata = bmatis->sf_rootdata; 2261b0f2910eSStefano Zampini } 2262b0f2910eSStefano Zampini } 2263ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2264ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2265ad6194a2SStefano Zampini *newmat = B; 2266ad6194a2SStefano Zampini PetscFunctionReturn(0); 2267ad6194a2SStefano Zampini } 2268ad6194a2SStefano Zampini 2269a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 227069796d55SStefano Zampini { 227169796d55SStefano Zampini PetscErrorCode ierr; 227269796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 227369796d55SStefano Zampini PetscBool local_sym; 227469796d55SStefano Zampini 227569796d55SStefano Zampini PetscFunctionBegin; 227669796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2277b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 227869796d55SStefano Zampini PetscFunctionReturn(0); 227969796d55SStefano Zampini } 228069796d55SStefano Zampini 2281a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 228269796d55SStefano Zampini { 228369796d55SStefano Zampini PetscErrorCode ierr; 228469796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 228569796d55SStefano Zampini PetscBool local_sym; 228669796d55SStefano Zampini 228769796d55SStefano Zampini PetscFunctionBegin; 228869796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2289b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 229069796d55SStefano Zampini PetscFunctionReturn(0); 229169796d55SStefano Zampini } 229269796d55SStefano Zampini 229345471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 229445471136SStefano Zampini { 229545471136SStefano Zampini PetscErrorCode ierr; 229645471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 229745471136SStefano Zampini PetscBool local_sym; 229845471136SStefano Zampini 229945471136SStefano Zampini PetscFunctionBegin; 230045471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 230145471136SStefano Zampini *flg = PETSC_FALSE; 230245471136SStefano Zampini PetscFunctionReturn(0); 230345471136SStefano Zampini } 230445471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 230545471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 230645471136SStefano Zampini PetscFunctionReturn(0); 230745471136SStefano Zampini } 230845471136SStefano Zampini 2309a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2310b4319ba4SBarry Smith { 2311dfbe8321SBarry Smith PetscErrorCode ierr; 2312b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2313b4319ba4SBarry Smith 2314b4319ba4SBarry Smith PetscFunctionBegin; 23158546b261SStefano Zampini ierr = PetscFree(b->lmattype);CHKERRQ(ierr); 23166bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2317e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2318e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 23196bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 23206bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 23213fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2322a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2323a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2324a8116848SStefano Zampini if (b->sf != b->csf) { 2325a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2326a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2327f03112d0SStefano Zampini } else b->csf = NULL; 232828f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 232928f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2330bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2331dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 23328546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",NULL);CHKERRQ(ierr); 2333bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2334b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2335b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 23362e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 2337cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 233875d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2339f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2340487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2341487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2342487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2343487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2344487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2345487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2346487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2347b4319ba4SBarry Smith PetscFunctionReturn(0); 2348b4319ba4SBarry Smith } 2349b4319ba4SBarry Smith 2350a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2351b4319ba4SBarry Smith { 2352dfbe8321SBarry Smith PetscErrorCode ierr; 2353b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2354b4319ba4SBarry Smith PetscScalar zero = 0.0; 2355b4319ba4SBarry Smith 2356b4319ba4SBarry Smith PetscFunctionBegin; 2357b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2358e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2359e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2360b4319ba4SBarry Smith 2361b4319ba4SBarry Smith /* multiply the local matrix */ 2362b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2363b4319ba4SBarry Smith 2364b4319ba4SBarry Smith /* scatter product back into global memory */ 23652dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2366e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2367e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2368b4319ba4SBarry Smith PetscFunctionReturn(0); 2369b4319ba4SBarry Smith } 2370b4319ba4SBarry Smith 2371a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23722e74eeadSLisandro Dalcin { 2373650997f4SStefano Zampini Vec temp_vec; 23742e74eeadSLisandro Dalcin PetscErrorCode ierr; 23752e74eeadSLisandro Dalcin 23762e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2377650997f4SStefano Zampini if (v3 != v2) { 2378650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2379650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2380650997f4SStefano Zampini } else { 2381650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2382650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2383650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2384650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2385650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2386650997f4SStefano Zampini } 23872e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23882e74eeadSLisandro Dalcin } 23892e74eeadSLisandro Dalcin 2390a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 23912e74eeadSLisandro Dalcin { 23922e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23932e74eeadSLisandro Dalcin PetscErrorCode ierr; 23942e74eeadSLisandro Dalcin 2395e176bc59SStefano Zampini PetscFunctionBegin; 23962e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2397e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2398e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23992e74eeadSLisandro Dalcin 24002e74eeadSLisandro Dalcin /* multiply the local matrix */ 2401e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 24022e74eeadSLisandro Dalcin 24032e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2404e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2405e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2406e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24072e74eeadSLisandro Dalcin PetscFunctionReturn(0); 24082e74eeadSLisandro Dalcin } 24092e74eeadSLisandro Dalcin 2410a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 24112e74eeadSLisandro Dalcin { 2412650997f4SStefano Zampini Vec temp_vec; 24132e74eeadSLisandro Dalcin PetscErrorCode ierr; 24142e74eeadSLisandro Dalcin 24152e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2416650997f4SStefano Zampini if (v3 != v2) { 2417650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2418650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2419650997f4SStefano Zampini } else { 2420650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2421650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2422650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2423650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2424650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2425650997f4SStefano Zampini } 24262e74eeadSLisandro Dalcin PetscFunctionReturn(0); 24272e74eeadSLisandro Dalcin } 24282e74eeadSLisandro Dalcin 2429a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2430b4319ba4SBarry Smith { 2431b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2432dfbe8321SBarry Smith PetscErrorCode ierr; 2433b4319ba4SBarry Smith PetscViewer sviewer; 2434ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2435b4319ba4SBarry Smith 2436b4319ba4SBarry Smith PetscFunctionBegin; 2437ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2438ee2491ecSStefano Zampini if (isascii) { 2439ee2491ecSStefano Zampini PetscViewerFormat format; 2440ee2491ecSStefano Zampini 2441ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2442ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2443ee2491ecSStefano Zampini } 2444ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 24453f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2446b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 24473f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 24486e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2449b4319ba4SBarry Smith PetscFunctionReturn(0); 2450b4319ba4SBarry Smith } 2451b4319ba4SBarry Smith 24528546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat A) 2453b4319ba4SBarry Smith { 2454e176bc59SStefano Zampini Vec cglobal,rglobal; 24558546b261SStefano Zampini IS from; 24568546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 24578546b261SStefano Zampini const PetscInt *garray; 24588546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 24598546b261SStefano Zampini PetscBool iscuda; 24608546b261SStefano Zampini PetscErrorCode ierr; 2461b4319ba4SBarry Smith 2462b4319ba4SBarry Smith PetscFunctionBegin; 24638546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nr);CHKERRQ(ierr); 24648546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->rmap->mapping,&rbs);CHKERRQ(ierr); 24658546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&nc);CHKERRQ(ierr); 24668546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->cmap->mapping,&cbs);CHKERRQ(ierr); 246770cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 246870cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 24693fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2470e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2471e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 24728546b261SStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 24738546b261SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)is->y,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 24748546b261SStefano Zampini if (iscuda) { 24758546b261SStefano Zampini ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 24768546b261SStefano Zampini ierr = PetscStrallocpy(VECCUDA,&A->defaultvectype);CHKERRQ(ierr); 24778546b261SStefano Zampini } 24788546b261SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 24798546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 24808546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 2481*35928de7SBarry Smith ierr = VecScatterCreateWithData(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 24828546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 24838546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24848546b261SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 24858546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 24868546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 2487*35928de7SBarry Smith ierr = VecScatterCreateWithData(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 24888546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 24898546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24908546b261SStefano Zampini } else { 24918546b261SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 24928546b261SStefano Zampini is->cctx = is->rctx; 24938546b261SStefano Zampini } 24948546b261SStefano Zampini /* interface counter vector (local) */ 24958546b261SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 24968546b261SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 24978546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24988546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24998546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 25008546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 25018546b261SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 25028546b261SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 25038546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 25048546b261SStefano Zampini PetscFunctionReturn(0); 25058546b261SStefano Zampini } 25068546b261SStefano Zampini 25078546b261SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 25088546b261SStefano Zampini { 25098546b261SStefano Zampini PetscErrorCode ierr; 25108546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 25118546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 25128546b261SStefano Zampini 25138546b261SStefano Zampini PetscFunctionBegin; 25148546b261SStefano Zampini PetscCheckSameComm(A,1,rmapping,2); 25158546b261SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 25161c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2517872cf891SStefano Zampini if (is->csf != is->sf) { 2518872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2519872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2520f03112d0SStefano Zampini } else is->csf = NULL; 252128f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 252228f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 25233bbff08aSStefano Zampini 25243bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2525fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2526fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2527e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2528e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2529e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2530e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 25316625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 25326625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 25336625354bSStefano Zampini PetscBool same,gsame; 25346625354bSStefano Zampini 25356625354bSStefano Zampini same = PETSC_FALSE; 25366625354bSStefano Zampini if (nr == nc && cbs == rbs) { 25376625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 25386625354bSStefano Zampini 25396625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 25406625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 25416625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 25426625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 25436625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 25446625354bSStefano Zampini } 25456625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 25466625354bSStefano Zampini if (gsame) cmapping = rmapping; 25476625354bSStefano Zampini } 254853b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 254953b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 25506625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 25516625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 25526625354bSStefano Zampini 25536625354bSStefano Zampini /* Create the local matrix A */ 2554f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 25558546b261SStefano Zampini ierr = MatSetType(is->A,is->lmattype);CHKERRQ(ierr); 2556e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2557e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 25588546b261SStefano Zampini ierr = MatSetOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 25598546b261SStefano Zampini ierr = MatAppendOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2560c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2561c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2562b4319ba4SBarry Smith 2563f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 25648546b261SStefano Zampini ierr = MatISSetUpScatters_Private(A);CHKERRQ(ierr); 2565f26d0771SStefano Zampini } 256648ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2567b4319ba4SBarry Smith PetscFunctionReturn(0); 2568b4319ba4SBarry Smith } 2569b4319ba4SBarry Smith 2570a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 25712e74eeadSLisandro Dalcin { 25722e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 25732e74eeadSLisandro Dalcin PetscErrorCode ierr; 257497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 257597563a80SStefano Zampini PetscInt i,zm,zn; 257697563a80SStefano Zampini #endif 2577f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 25782e74eeadSLisandro Dalcin 25792e74eeadSLisandro Dalcin PetscFunctionBegin; 25802e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2581f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 258297563a80SStefano Zampini /* count negative indices */ 258397563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 258497563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 25852e74eeadSLisandro Dalcin #endif 258697563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 258797563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 258897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 258997563a80SStefano Zampini /* count negative indices (should be the same as before) */ 259097563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 259197563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2592b4f971dfSStefano Zampini if (!is->A->rmap->mapping && zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 2593b4f971dfSStefano Zampini if (!is->A->cmap->mapping && zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 259497563a80SStefano Zampini #endif 25952e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 25962e74eeadSLisandro Dalcin PetscFunctionReturn(0); 25972e74eeadSLisandro Dalcin } 25982e74eeadSLisandro Dalcin 2599a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 260097563a80SStefano Zampini { 260197563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 260297563a80SStefano Zampini PetscErrorCode ierr; 260397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 260497563a80SStefano Zampini PetscInt i,zm,zn; 260597563a80SStefano Zampini #endif 2606f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 260797563a80SStefano Zampini 260897563a80SStefano Zampini PetscFunctionBegin; 260997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2610f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 261197563a80SStefano Zampini /* count negative indices */ 261297563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 261397563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 261497563a80SStefano Zampini #endif 261597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 261697563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 261797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 261897563a80SStefano Zampini /* count negative indices (should be the same as before) */ 261997563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 262097563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2621b4f971dfSStefano Zampini if (!is->A->rmap->mapping && zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 2622b4f971dfSStefano Zampini if (!is->A->cmap->mapping && zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 262397563a80SStefano Zampini #endif 2624d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 262597563a80SStefano Zampini PetscFunctionReturn(0); 262697563a80SStefano Zampini } 262797563a80SStefano Zampini 2628a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2629b4319ba4SBarry Smith { 2630dfbe8321SBarry Smith PetscErrorCode ierr; 2631b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2632b4319ba4SBarry Smith 2633b4319ba4SBarry Smith PetscFunctionBegin; 2634b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2635872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2636872cf891SStefano Zampini } else { 2637b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2638872cf891SStefano Zampini } 2639b4319ba4SBarry Smith PetscFunctionReturn(0); 2640b4319ba4SBarry Smith } 2641b4319ba4SBarry Smith 2642a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2643f0006bf2SLisandro Dalcin { 2644f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2645f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2646f0006bf2SLisandro Dalcin 2647f0006bf2SLisandro Dalcin PetscFunctionBegin; 2648b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2649b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2650b4f971dfSStefano Zampini PetscInt ibs,bs; 2651b4f971dfSStefano Zampini 2652b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2653b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2654b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2655b4f971dfSStefano Zampini #endif 2656b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2657b4f971dfSStefano Zampini } else { 2658f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2659b4f971dfSStefano Zampini } 2660f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2661f0006bf2SLisandro Dalcin } 2662f0006bf2SLisandro Dalcin 2663f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2664f0ae7da4SStefano Zampini { 2665f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2666f0ae7da4SStefano Zampini PetscErrorCode ierr; 2667f0ae7da4SStefano Zampini 2668f0ae7da4SStefano Zampini PetscFunctionBegin; 2669f0ae7da4SStefano Zampini if (!n) { 2670f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2671f0ae7da4SStefano Zampini } else { 2672f0ae7da4SStefano Zampini PetscInt i; 2673f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2674f0ae7da4SStefano Zampini 2675f0ae7da4SStefano Zampini if (columns) { 2676f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2677f0ae7da4SStefano Zampini } else { 2678f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2679f0ae7da4SStefano Zampini } 2680f0ae7da4SStefano Zampini if (diag != 0.) { 2681f0ae7da4SStefano Zampini const PetscScalar *array; 2682f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2683f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2684f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2685f0ae7da4SStefano Zampini } 2686f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2687f0ae7da4SStefano Zampini } 2688f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2689f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2690f0ae7da4SStefano Zampini } 2691f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2692f0ae7da4SStefano Zampini } 2693f0ae7da4SStefano Zampini 2694f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 26952e74eeadSLisandro Dalcin { 26966e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 26976e520ac8SStefano Zampini PetscInt nr,nl,len,i; 26986e520ac8SStefano Zampini PetscInt *lrows; 26992e74eeadSLisandro Dalcin PetscErrorCode ierr; 27002e74eeadSLisandro Dalcin 27012e74eeadSLisandro Dalcin PetscFunctionBegin; 2702f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2703f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2704f0ae7da4SStefano Zampini PetscBool cong; 270526b0207aSStefano Zampini 2706f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 270726b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2708268753edSStefano Zampini if (!cong && columns) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Columns can be zeroed if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 2709268753edSStefano Zampini if (!cong && diag != 0.) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Nonzero diagonal value supported if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 2710268753edSStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent, and the l2g maps be the same"); 2711f0ae7da4SStefano Zampini } 2712f0ae7da4SStefano Zampini #endif 27136e520ac8SStefano Zampini /* get locally owned rows */ 2714f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 27156e520ac8SStefano Zampini /* fix right hand side if needed */ 27166e520ac8SStefano Zampini if (x && b) { 27176e520ac8SStefano Zampini const PetscScalar *xx; 27186e520ac8SStefano Zampini PetscScalar *bb; 27196e520ac8SStefano Zampini 27206e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 27216e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 27226e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 27236e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 27246e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 27252e74eeadSLisandro Dalcin } 27266e520ac8SStefano Zampini /* get rows associated to the local matrices */ 27273d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 27286e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 27296e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 27306e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 27316e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 27326e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 27336e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 27346e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 27356e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 27366e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2737f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 27386e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 27392e74eeadSLisandro Dalcin PetscFunctionReturn(0); 27402e74eeadSLisandro Dalcin } 27412e74eeadSLisandro Dalcin 2742f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2743b4319ba4SBarry Smith { 2744dfbe8321SBarry Smith PetscErrorCode ierr; 2745b4319ba4SBarry Smith 2746b4319ba4SBarry Smith PetscFunctionBegin; 2747f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2748f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2749f0ae7da4SStefano Zampini } 27502205254eSKarl Rupp 2751f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2752f0ae7da4SStefano Zampini { 2753f0ae7da4SStefano Zampini PetscErrorCode ierr; 2754f0ae7da4SStefano Zampini 2755f0ae7da4SStefano Zampini PetscFunctionBegin; 2756f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2757b4319ba4SBarry Smith PetscFunctionReturn(0); 2758b4319ba4SBarry Smith } 2759b4319ba4SBarry Smith 2760a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2761b4319ba4SBarry Smith { 2762b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2763dfbe8321SBarry Smith PetscErrorCode ierr; 2764b4319ba4SBarry Smith 2765b4319ba4SBarry Smith PetscFunctionBegin; 2766b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2767b4319ba4SBarry Smith PetscFunctionReturn(0); 2768b4319ba4SBarry Smith } 2769b4319ba4SBarry Smith 2770a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2771b4319ba4SBarry Smith { 2772b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2773dfbe8321SBarry Smith PetscErrorCode ierr; 2774b4319ba4SBarry Smith 2775b4319ba4SBarry Smith PetscFunctionBegin; 2776b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2777872cf891SStefano Zampini /* fix for local empty rows/cols */ 2778872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2779872cf891SStefano Zampini Mat newlA; 2780f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2781f03112d0SStefano Zampini IS nzr,nzc; 2782f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2783f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2784872cf891SStefano Zampini 2785f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2786f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2787f03112d0SStefano Zampini if (!nzr) { 2788f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2789872cf891SStefano Zampini } 2790f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2791f03112d0SStefano Zampini if (!nzc) { 2792f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2793872cf891SStefano Zampini } 2794f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2795f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2796f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2797f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2798f03112d0SStefano Zampini IS is1,is2; 2799f03112d0SStefano Zampini 2800f03112d0SStefano Zampini /* need new global l2g map */ 2801f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2802f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2803f03112d0SStefano Zampini 2804872cf891SStefano Zampini /* extract valid submatrix */ 2805f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2806f03112d0SStefano Zampini 2807f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2808f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2809f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2810f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2811872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 281272ed36d8SStefano Zampini if (is->A->rmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 281372ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 281472ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 281572ed36d8SStefano Zampini 281672ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->rmap->mapping,&nl);CHKERRQ(ierr); 281772ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 281872ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 281972ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 282072ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 282172ed36d8SStefano Zampini if (j != nr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nr); 282272ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 282372ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 282472ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 282572ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->rmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 282672ed36d8SStefano Zampini } 2827f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2828f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2829f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 283072ed36d8SStefano Zampini 2831f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2832f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2833f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2834f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 283572ed36d8SStefano Zampini if (is->A->cmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 283672ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 283772ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 283872ed36d8SStefano Zampini 283972ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->cmap->mapping,&nl);CHKERRQ(ierr); 284072ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 284172ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 284272ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 284372ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 284472ed36d8SStefano Zampini if (j != nc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nc); 284572ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 284672ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 284772ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 284872ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->cmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 284972ed36d8SStefano Zampini } 2850f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2851f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2852f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 285372ed36d8SStefano Zampini 2854f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 285572ed36d8SStefano Zampini 2856f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2857f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2858f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2859f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2860f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2861f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2862f03112d0SStefano Zampini newlA = is->A; 2863f03112d0SStefano Zampini } 2864f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2865f03112d0SStefano Zampini if (newl2g) { 2866f03112d0SStefano Zampini IS gnzr,gnzc; 2867f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2868f03112d0SStefano Zampini 2869f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2870f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2871f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2872f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2873f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2874f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2875f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2876f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2877f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2878f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2879f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2880f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2881f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2882f03112d0SStefano Zampini } 2883872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2884872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2885f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2886f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2887872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2888f03112d0SStefano Zampini } 2889b4319ba4SBarry Smith PetscFunctionReturn(0); 2890b4319ba4SBarry Smith } 2891b4319ba4SBarry Smith 2892a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2893b4319ba4SBarry Smith { 2894b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2895b4319ba4SBarry Smith 2896b4319ba4SBarry Smith PetscFunctionBegin; 2897b4319ba4SBarry Smith *local = is->A; 2898b4319ba4SBarry Smith PetscFunctionReturn(0); 2899b4319ba4SBarry Smith } 2900b4319ba4SBarry Smith 29013b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 29023b3b1effSJed Brown { 29033b3b1effSJed Brown PetscFunctionBegin; 29043b3b1effSJed Brown *local = NULL; 29053b3b1effSJed Brown PetscFunctionReturn(0); 29063b3b1effSJed Brown } 29073b3b1effSJed Brown 2908b4319ba4SBarry Smith /*@ 2909b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2910b4319ba4SBarry Smith 2911b4319ba4SBarry Smith Input Parameter: 2912b4319ba4SBarry Smith . mat - the matrix 2913b4319ba4SBarry Smith 2914b4319ba4SBarry Smith Output Parameter: 2915eb82efa4SStefano Zampini . local - the local matrix 2916b4319ba4SBarry Smith 2917b4319ba4SBarry Smith Level: advanced 2918b4319ba4SBarry Smith 2919b4319ba4SBarry Smith Notes: 2920b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2921b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2922b4319ba4SBarry Smith of the MatSetValues() operation. 2923b4319ba4SBarry Smith 29243b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 292596a6f129SJed Brown 2926b4319ba4SBarry Smith .seealso: MATIS 2927b4319ba4SBarry Smith @*/ 29287087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2929b4319ba4SBarry Smith { 29304ac538c5SBarry Smith PetscErrorCode ierr; 2931b4319ba4SBarry Smith 2932b4319ba4SBarry Smith PetscFunctionBegin; 29330700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2934b4319ba4SBarry Smith PetscValidPointer(local,2); 29354ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2936b4319ba4SBarry Smith PetscFunctionReturn(0); 2937b4319ba4SBarry Smith } 2938b4319ba4SBarry Smith 29393b3b1effSJed Brown /*@ 29403b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 29413b3b1effSJed Brown 29423b3b1effSJed Brown Input Parameter: 29433b3b1effSJed Brown . mat - the matrix 29443b3b1effSJed Brown 29453b3b1effSJed Brown Output Parameter: 29463b3b1effSJed Brown . local - the local matrix 29473b3b1effSJed Brown 29483b3b1effSJed Brown Level: advanced 29493b3b1effSJed Brown 29503b3b1effSJed Brown .seealso: MATIS 29513b3b1effSJed Brown @*/ 29523b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 29533b3b1effSJed Brown { 29543b3b1effSJed Brown PetscErrorCode ierr; 29553b3b1effSJed Brown 29563b3b1effSJed Brown PetscFunctionBegin; 29573b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29583b3b1effSJed Brown PetscValidPointer(local,2); 29593b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 29603b3b1effSJed Brown PetscFunctionReturn(0); 29613b3b1effSJed Brown } 29623b3b1effSJed Brown 29638546b261SStefano Zampini static PetscErrorCode MatISSetLocalMatType_IS(Mat mat,MatType mtype) 29648546b261SStefano Zampini { 29658546b261SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 29668546b261SStefano Zampini PetscErrorCode ierr; 29678546b261SStefano Zampini 29688546b261SStefano Zampini PetscFunctionBegin; 29698546b261SStefano Zampini if (is->A) { 29708546b261SStefano Zampini ierr = MatSetType(is->A,mtype);CHKERRQ(ierr); 29718546b261SStefano Zampini } 29728546b261SStefano Zampini ierr = PetscFree(is->lmattype);CHKERRQ(ierr); 29738546b261SStefano Zampini ierr = PetscStrallocpy(mtype,&is->lmattype);CHKERRQ(ierr); 29748546b261SStefano Zampini PetscFunctionReturn(0); 29758546b261SStefano Zampini } 29768546b261SStefano Zampini 29778546b261SStefano Zampini /*@ 29788546b261SStefano Zampini MatISSetLocalMatType - Specifies the type of local matrix 29798546b261SStefano Zampini 29808546b261SStefano Zampini Input Parameter: 29818546b261SStefano Zampini . mat - the matrix 29828546b261SStefano Zampini . mtype - the local matrix type 29838546b261SStefano Zampini 29848546b261SStefano Zampini Output Parameter: 29858546b261SStefano Zampini 29868546b261SStefano Zampini Level: advanced 29878546b261SStefano Zampini 29888546b261SStefano Zampini .seealso: MATIS, MatSetType(), MatType 29898546b261SStefano Zampini @*/ 29908546b261SStefano Zampini PetscErrorCode MatISSetLocalMatType(Mat mat,MatType mtype) 29918546b261SStefano Zampini { 29928546b261SStefano Zampini PetscErrorCode ierr; 29938546b261SStefano Zampini 29948546b261SStefano Zampini PetscFunctionBegin; 29958546b261SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29968546b261SStefano Zampini ierr = PetscUseMethod(mat,"MatISSetLocalMatType_C",(Mat,MatType),(mat,mtype));CHKERRQ(ierr); 29978546b261SStefano Zampini PetscFunctionReturn(0); 29988546b261SStefano Zampini } 29998546b261SStefano Zampini 3000a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 30013b03a366Sstefano_zampini { 30023b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 30033b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 30043b03a366Sstefano_zampini PetscErrorCode ierr; 30058546b261SStefano Zampini MatType mtype,otype; 30068546b261SStefano Zampini PetscBool sametype = PETSC_TRUE; 30073b03a366Sstefano_zampini 30083b03a366Sstefano_zampini PetscFunctionBegin; 30094e4c7dbeSStefano Zampini if (is->A) { 30103b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 30113b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 3012f0ae7da4SStefano Zampini if (orows != nrows || ocols != ncols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local MATIS matrix should be of size %Dx%D (you passed a %Dx%D matrix)",orows,ocols,nrows,ncols); 30138546b261SStefano Zampini ierr = MatGetType(local,&mtype);CHKERRQ(ierr); 30148546b261SStefano Zampini ierr = MatGetType(is->A,&otype);CHKERRQ(ierr); 30158546b261SStefano Zampini ierr = PetscStrcmp(mtype,otype,&sametype);CHKERRQ(ierr); 30164e4c7dbeSStefano Zampini } 30173b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 30183b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 30193b03a366Sstefano_zampini is->A = local; 30208546b261SStefano Zampini ierr = MatGetType(is->A,&mtype);CHKERRQ(ierr); 30218546b261SStefano Zampini ierr = MatISSetLocalMatType(mat,mtype);CHKERRQ(ierr); 30228546b261SStefano Zampini if (!sametype && !is->islocalref) { 30238546b261SStefano Zampini ierr = MatISSetUpScatters_Private(mat);CHKERRQ(ierr); 30248546b261SStefano Zampini } 30253b03a366Sstefano_zampini PetscFunctionReturn(0); 30263b03a366Sstefano_zampini } 30273b03a366Sstefano_zampini 30283b03a366Sstefano_zampini /*@ 3029eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 30303b03a366Sstefano_zampini 30318546b261SStefano Zampini Collective on Mat 30328546b261SStefano Zampini 30333b03a366Sstefano_zampini Input Parameter: 30343b03a366Sstefano_zampini . mat - the matrix 3035eb82efa4SStefano Zampini . local - the local matrix 30363b03a366Sstefano_zampini 30373b03a366Sstefano_zampini Output Parameter: 30383b03a366Sstefano_zampini 30393b03a366Sstefano_zampini Level: advanced 30403b03a366Sstefano_zampini 30413b03a366Sstefano_zampini Notes: 30423b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 30433b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 30443b03a366Sstefano_zampini 30453b03a366Sstefano_zampini .seealso: MATIS 30463b03a366Sstefano_zampini @*/ 30473b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 30483b03a366Sstefano_zampini { 30493b03a366Sstefano_zampini PetscErrorCode ierr; 30503b03a366Sstefano_zampini 30513b03a366Sstefano_zampini PetscFunctionBegin; 30523b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3053b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 30543b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 30553b03a366Sstefano_zampini PetscFunctionReturn(0); 30563b03a366Sstefano_zampini } 30573b03a366Sstefano_zampini 3058a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 30596726f965SBarry Smith { 30606726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30616726f965SBarry Smith PetscErrorCode ierr; 30626726f965SBarry Smith 30636726f965SBarry Smith PetscFunctionBegin; 30646726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 30656726f965SBarry Smith PetscFunctionReturn(0); 30666726f965SBarry Smith } 30676726f965SBarry Smith 3068a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 30692e74eeadSLisandro Dalcin { 30702e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30712e74eeadSLisandro Dalcin PetscErrorCode ierr; 30722e74eeadSLisandro Dalcin 30732e74eeadSLisandro Dalcin PetscFunctionBegin; 30742e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 30752e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30762e74eeadSLisandro Dalcin } 30772e74eeadSLisandro Dalcin 3078a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 30792e74eeadSLisandro Dalcin { 30802e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30812e74eeadSLisandro Dalcin PetscErrorCode ierr; 30822e74eeadSLisandro Dalcin 30832e74eeadSLisandro Dalcin PetscFunctionBegin; 30842e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 3085e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 30862e74eeadSLisandro Dalcin 30872e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 30882e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 3089e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3090e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 30912e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30922e74eeadSLisandro Dalcin } 30932e74eeadSLisandro Dalcin 3094a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 30956726f965SBarry Smith { 30966726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30976726f965SBarry Smith PetscErrorCode ierr; 30986726f965SBarry Smith 30996726f965SBarry Smith PetscFunctionBegin; 31004e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 31016726f965SBarry Smith PetscFunctionReturn(0); 31026726f965SBarry Smith } 31036726f965SBarry Smith 3104f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 3105f26d0771SStefano Zampini { 3106f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 3107f26d0771SStefano Zampini Mat_IS *x; 3108f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3109f26d0771SStefano Zampini PetscBool ismatis; 3110f26d0771SStefano Zampini #endif 3111f26d0771SStefano Zampini PetscErrorCode ierr; 3112f26d0771SStefano Zampini 3113f26d0771SStefano Zampini PetscFunctionBegin; 3114f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3115f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 3116f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 3117f26d0771SStefano Zampini #endif 3118f26d0771SStefano Zampini x = (Mat_IS*)X->data; 3119f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 3120f26d0771SStefano Zampini PetscFunctionReturn(0); 3121f26d0771SStefano Zampini } 3122f26d0771SStefano Zampini 3123f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 3124f26d0771SStefano Zampini { 3125f26d0771SStefano Zampini Mat lA; 3126f26d0771SStefano Zampini Mat_IS *matis; 3127f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 3128f26d0771SStefano Zampini IS is; 3129f26d0771SStefano Zampini const PetscInt *rg,*rl; 3130f26d0771SStefano Zampini PetscInt nrg; 3131f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 3132f26d0771SStefano Zampini PetscErrorCode ierr; 3133f26d0771SStefano Zampini 3134f26d0771SStefano Zampini PetscFunctionBegin; 3135f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3136f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3137f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3138f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 3139f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3140249c8a71SStefano Zampini for (i=0;i<nrl;i++) if (rl[i]>=nrg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row index %D -> %D greater then maximum possible %D",i,rl[i],nrg); 3141f26d0771SStefano Zampini #endif 3142f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3143f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3144f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3145f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3146f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 3147f26d0771SStefano Zampini #else 3148f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3149f26d0771SStefano Zampini #endif 3150f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3151f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3152f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3153f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3154f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3155f26d0771SStefano Zampini /* compute new l2g map for columns */ 3156f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 3157f26d0771SStefano Zampini const PetscInt *cg,*cl; 3158f26d0771SStefano Zampini PetscInt ncg; 3159f26d0771SStefano Zampini PetscInt ncl; 3160f26d0771SStefano Zampini 3161f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3162f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3163f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3164f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 3165f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3166249c8a71SStefano Zampini for (i=0;i<ncl;i++) if (cl[i]>=ncg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local column index %D -> %D greater then maximum possible %D",i,cl[i],ncg); 3167f26d0771SStefano Zampini #endif 3168f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3169f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3170f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3171f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3172f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 3173f26d0771SStefano Zampini #else 3174f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3175f26d0771SStefano Zampini #endif 3176f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3177f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3178f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3179f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3180f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3181f26d0771SStefano Zampini } else { 3182f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3183f26d0771SStefano Zampini cl2g = rl2g; 3184f26d0771SStefano Zampini } 3185f26d0771SStefano Zampini /* create the MATIS submatrix */ 3186f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3187f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3188f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3189f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3190b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3191f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3192f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3193f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3194f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3195f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3196f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3197f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3198f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3199f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3200f26d0771SStefano Zampini /* remove unsupported ops */ 3201f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3202f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3203f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3204f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3205f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3206f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3207f26d0771SStefano Zampini PetscFunctionReturn(0); 3208f26d0771SStefano Zampini } 3209f26d0771SStefano Zampini 3210872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3211872cf891SStefano Zampini { 3212872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 32138546b261SStefano Zampini char type[256]; 32148546b261SStefano Zampini PetscBool flg; 3215872cf891SStefano Zampini PetscErrorCode ierr; 3216872cf891SStefano Zampini 3217872cf891SStefano Zampini PetscFunctionBegin; 3218872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3219f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 322075d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 32218546b261SStefano Zampini ierr = PetscOptionsFList("-matis_localmat_type","Matrix type","MatISSetLocalMatType",MatList,a->lmattype,type,256,&flg);CHKERRQ(ierr); 32228546b261SStefano Zampini if (flg) { 32238546b261SStefano Zampini ierr = MatISSetLocalMatType(A,type);CHKERRQ(ierr); 32248546b261SStefano Zampini } 32258546b261SStefano Zampini if (a->A) { 32268546b261SStefano Zampini ierr = MatSetFromOptions(a->A);CHKERRQ(ierr); 32278546b261SStefano Zampini } 32280af67c1bSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 3229872cf891SStefano Zampini PetscFunctionReturn(0); 3230872cf891SStefano Zampini } 3231872cf891SStefano Zampini 3232284134d9SBarry Smith /*@ 32333c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3234284134d9SBarry Smith process but not across processes. 3235284134d9SBarry Smith 3236284134d9SBarry Smith Input Parameters: 3237284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3238e176bc59SStefano Zampini . bs - block size of the matrix 3239df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3240e176bc59SStefano Zampini . rmap - local to global map for rows 3241e176bc59SStefano Zampini - cmap - local to global map for cols 3242284134d9SBarry Smith 3243284134d9SBarry Smith Output Parameter: 3244284134d9SBarry Smith . A - the resulting matrix 3245284134d9SBarry Smith 32468e6c10adSSatish Balay Level: advanced 32478e6c10adSSatish Balay 324895452b02SPatrick Sanan Notes: 324995452b02SPatrick Sanan See MATIS for more details. 32506fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 32516fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 32523c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 3253284134d9SBarry Smith 3254284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3255284134d9SBarry Smith @*/ 3256e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3257284134d9SBarry Smith { 3258284134d9SBarry Smith PetscErrorCode ierr; 3259284134d9SBarry Smith 3260284134d9SBarry Smith PetscFunctionBegin; 32616fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 3262284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3263284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 32646fdf41d1SStefano Zampini if (bs > 0) { 3265284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 32666fdf41d1SStefano Zampini } 3267284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3268e176bc59SStefano Zampini if (rmap && cmap) { 3269e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3270e176bc59SStefano Zampini } else if (!rmap) { 3271e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 3272e176bc59SStefano Zampini } else { 3273e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 3274e176bc59SStefano Zampini } 3275284134d9SBarry Smith PetscFunctionReturn(0); 3276284134d9SBarry Smith } 3277284134d9SBarry Smith 3278b4319ba4SBarry Smith /*MC 3279f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3280b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 3281b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 3282b4319ba4SBarry Smith product is handled "implicitly". 3283b4319ba4SBarry Smith 3284b4319ba4SBarry Smith Operations Provided: 32856726f965SBarry Smith + MatMult() 32862e74eeadSLisandro Dalcin . MatMultAdd() 32872e74eeadSLisandro Dalcin . MatMultTranspose() 32882e74eeadSLisandro Dalcin . MatMultTransposeAdd() 32896726f965SBarry Smith . MatZeroEntries() 32906726f965SBarry Smith . MatSetOption() 32912e74eeadSLisandro Dalcin . MatZeroRows() 32922e74eeadSLisandro Dalcin . MatSetValues() 329397563a80SStefano Zampini . MatSetValuesBlocked() 32946726f965SBarry Smith . MatSetValuesLocal() 329597563a80SStefano Zampini . MatSetValuesBlockedLocal() 32962e74eeadSLisandro Dalcin . MatScale() 32972e74eeadSLisandro Dalcin . MatGetDiagonal() 32982b404112SStefano Zampini . MatMissingDiagonal() 32992b404112SStefano Zampini . MatDuplicate() 33002b404112SStefano Zampini . MatCopy() 3301f26d0771SStefano Zampini . MatAXPY() 33027dae84e0SHong Zhang . MatCreateSubMatrix() 3303f26d0771SStefano Zampini . MatGetLocalSubMatrix() 3304d7f69cd0SStefano Zampini . MatTranspose() 330575d48cdbSStefano Zampini . MatPtAP() (with P of AIJ type) 33066726f965SBarry Smith - MatSetLocalToGlobalMapping() 3307b4319ba4SBarry Smith 3308b4319ba4SBarry Smith Options Database Keys: 330975d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 331075d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 331175d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3312b4319ba4SBarry Smith 331395452b02SPatrick Sanan Notes: 331495452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3315b4319ba4SBarry Smith 3316b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3317b4319ba4SBarry Smith 3318b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3319eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3320b4319ba4SBarry Smith 3321b4319ba4SBarry Smith Level: advanced 3322b4319ba4SBarry Smith 3323f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3324b4319ba4SBarry Smith 3325b4319ba4SBarry Smith M*/ 3326b4319ba4SBarry Smith 33278cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3328b4319ba4SBarry Smith { 3329dfbe8321SBarry Smith PetscErrorCode ierr; 3330b4319ba4SBarry Smith Mat_IS *b; 3331b4319ba4SBarry Smith 3332b4319ba4SBarry Smith PetscFunctionBegin; 3333b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 33348546b261SStefano Zampini ierr = PetscStrallocpy(MATAIJ,&b->lmattype);CHKERRQ(ierr); 3335b4319ba4SBarry Smith A->data = (void*)b; 3336b4319ba4SBarry Smith 3337e176bc59SStefano Zampini /* matrix ops */ 3338e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3339b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 33402e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 33412e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 33422e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3343b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3344b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 33452e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 334698921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3347b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3348f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 33492e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3350f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3351b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3352b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3353b4319ba4SBarry Smith A->ops->view = MatView_IS; 33546726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 33552e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 33562e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 33576726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 335869796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 335969796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 336045471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3361ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 33626bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 33632b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3364659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 33657dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3366f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 33673fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 33683fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3369d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 33707fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3371ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3372872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3373b4319ba4SBarry Smith 3374b7ce53b6SStefano Zampini /* special MATIS functions */ 33758546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",MatISSetLocalMatType_IS);CHKERRQ(ierr); 3376bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 33773b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3378bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3379487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 33802e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 3381cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 338275d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3383f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3384487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3385487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3386487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3387487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3388487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3389487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3390487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 339117667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3392b4319ba4SBarry Smith PetscFunctionReturn(0); 3393b4319ba4SBarry Smith } 3394