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; 2315*b89f26deSStefano Zampini ierr = PetscFree(b->bdiag);CHKERRQ(ierr); 23168546b261SStefano Zampini ierr = PetscFree(b->lmattype);CHKERRQ(ierr); 23176bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2318e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2319e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 23206bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 23216bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 23223fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2323a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2324a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2325a8116848SStefano Zampini if (b->sf != b->csf) { 2326a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2327a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2328f03112d0SStefano Zampini } else b->csf = NULL; 232928f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 233028f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2331bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2332dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 23338546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",NULL);CHKERRQ(ierr); 2334bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2335b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2336b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 23372e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 2338cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 233975d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2340f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2341487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2342487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2343487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2344487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2345487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2346487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2347487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2348b4319ba4SBarry Smith PetscFunctionReturn(0); 2349b4319ba4SBarry Smith } 2350b4319ba4SBarry Smith 2351a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2352b4319ba4SBarry Smith { 2353dfbe8321SBarry Smith PetscErrorCode ierr; 2354b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2355b4319ba4SBarry Smith PetscScalar zero = 0.0; 2356b4319ba4SBarry Smith 2357b4319ba4SBarry Smith PetscFunctionBegin; 2358b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2359e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2360e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2361b4319ba4SBarry Smith 2362b4319ba4SBarry Smith /* multiply the local matrix */ 2363b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2364b4319ba4SBarry Smith 2365b4319ba4SBarry Smith /* scatter product back into global memory */ 23662dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2367e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2368e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2369b4319ba4SBarry Smith PetscFunctionReturn(0); 2370b4319ba4SBarry Smith } 2371b4319ba4SBarry Smith 2372a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23732e74eeadSLisandro Dalcin { 2374650997f4SStefano Zampini Vec temp_vec; 23752e74eeadSLisandro Dalcin PetscErrorCode ierr; 23762e74eeadSLisandro Dalcin 23772e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2378650997f4SStefano Zampini if (v3 != v2) { 2379650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2380650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2381650997f4SStefano Zampini } else { 2382650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2383650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2384650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2385650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2386650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2387650997f4SStefano Zampini } 23882e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23892e74eeadSLisandro Dalcin } 23902e74eeadSLisandro Dalcin 2391a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 23922e74eeadSLisandro Dalcin { 23932e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23942e74eeadSLisandro Dalcin PetscErrorCode ierr; 23952e74eeadSLisandro Dalcin 2396e176bc59SStefano Zampini PetscFunctionBegin; 23972e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2398e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2399e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24002e74eeadSLisandro Dalcin 24012e74eeadSLisandro Dalcin /* multiply the local matrix */ 2402e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 24032e74eeadSLisandro Dalcin 24042e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2405e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2406e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2407e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24082e74eeadSLisandro Dalcin PetscFunctionReturn(0); 24092e74eeadSLisandro Dalcin } 24102e74eeadSLisandro Dalcin 2411a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 24122e74eeadSLisandro Dalcin { 2413650997f4SStefano Zampini Vec temp_vec; 24142e74eeadSLisandro Dalcin PetscErrorCode ierr; 24152e74eeadSLisandro Dalcin 24162e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2417650997f4SStefano Zampini if (v3 != v2) { 2418650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2419650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2420650997f4SStefano Zampini } else { 2421650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2422650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2423650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2424650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2425650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2426650997f4SStefano Zampini } 24272e74eeadSLisandro Dalcin PetscFunctionReturn(0); 24282e74eeadSLisandro Dalcin } 24292e74eeadSLisandro Dalcin 2430a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2431b4319ba4SBarry Smith { 2432b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2433dfbe8321SBarry Smith PetscErrorCode ierr; 2434b4319ba4SBarry Smith PetscViewer sviewer; 2435ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2436b4319ba4SBarry Smith 2437b4319ba4SBarry Smith PetscFunctionBegin; 2438ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2439ee2491ecSStefano Zampini if (isascii) { 2440ee2491ecSStefano Zampini PetscViewerFormat format; 2441ee2491ecSStefano Zampini 2442ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2443ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2444ee2491ecSStefano Zampini } 2445ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 24463f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2447b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 24483f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 24496e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2450b4319ba4SBarry Smith PetscFunctionReturn(0); 2451b4319ba4SBarry Smith } 2452b4319ba4SBarry Smith 2453*b89f26deSStefano Zampini static PetscErrorCode MatInvertBlockDiagonal_IS(Mat mat,const PetscScalar **values) 2454*b89f26deSStefano Zampini { 2455*b89f26deSStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 2456*b89f26deSStefano Zampini MPI_Datatype nodeType; 2457*b89f26deSStefano Zampini const PetscScalar *lv; 2458*b89f26deSStefano Zampini PetscInt bs; 2459*b89f26deSStefano Zampini PetscErrorCode ierr; 2460*b89f26deSStefano Zampini 2461*b89f26deSStefano Zampini PetscFunctionBegin; 2462*b89f26deSStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2463*b89f26deSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 2464*b89f26deSStefano Zampini ierr = MatInvertBlockDiagonal(is->A,&lv);CHKERRQ(ierr); 2465*b89f26deSStefano Zampini if (!is->bdiag) { 2466*b89f26deSStefano Zampini ierr = PetscMalloc1(bs*mat->rmap->n,&is->bdiag);CHKERRQ(ierr); 2467*b89f26deSStefano Zampini } 2468*b89f26deSStefano Zampini ierr = MPI_Type_contiguous(bs,MPIU_SCALAR,&nodeType);CHKERRQ(ierr); 2469*b89f26deSStefano Zampini ierr = MPI_Type_commit(&nodeType);CHKERRQ(ierr); 2470*b89f26deSStefano Zampini ierr = PetscSFReduceBegin(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2471*b89f26deSStefano Zampini ierr = PetscSFReduceEnd(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2472*b89f26deSStefano Zampini ierr = MPI_Type_free(&nodeType);CHKERRQ(ierr); 2473*b89f26deSStefano Zampini if (values) *values = is->bdiag; 2474*b89f26deSStefano Zampini PetscFunctionReturn(0); 2475*b89f26deSStefano Zampini } 2476*b89f26deSStefano Zampini 24778546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat A) 2478b4319ba4SBarry Smith { 2479e176bc59SStefano Zampini Vec cglobal,rglobal; 24808546b261SStefano Zampini IS from; 24818546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2482*b89f26deSStefano Zampini PetscScalar sum; 24838546b261SStefano Zampini const PetscInt *garray; 24848546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 24858546b261SStefano Zampini PetscBool iscuda; 24868546b261SStefano Zampini PetscErrorCode ierr; 2487b4319ba4SBarry Smith 2488b4319ba4SBarry Smith PetscFunctionBegin; 24898546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nr);CHKERRQ(ierr); 24908546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->rmap->mapping,&rbs);CHKERRQ(ierr); 24918546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&nc);CHKERRQ(ierr); 24928546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->cmap->mapping,&cbs);CHKERRQ(ierr); 249370cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 249470cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 24953fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2496e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2497e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 24988546b261SStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 24998546b261SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)is->y,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 25008546b261SStefano Zampini if (iscuda) { 25018546b261SStefano Zampini ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 25028546b261SStefano Zampini ierr = PetscStrallocpy(VECCUDA,&A->defaultvectype);CHKERRQ(ierr); 25038546b261SStefano Zampini } 25048546b261SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 25058546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 25068546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 250735928de7SBarry Smith ierr = VecScatterCreateWithData(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 25088546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 25098546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 25108546b261SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 25118546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 25128546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 251335928de7SBarry Smith ierr = VecScatterCreateWithData(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 25148546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 25158546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 25168546b261SStefano Zampini } else { 25178546b261SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 25188546b261SStefano Zampini is->cctx = is->rctx; 25198546b261SStefano Zampini } 2520*b89f26deSStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 2521*b89f26deSStefano Zampini 25228546b261SStefano Zampini /* interface counter vector (local) */ 25238546b261SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 25248546b261SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 25258546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25268546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25278546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 25288546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2529*b89f26deSStefano Zampini 2530*b89f26deSStefano Zampini /* special functions for block-diagonal matrices */ 2531*b89f26deSStefano Zampini ierr = VecSum(rglobal,&sum);CHKERRQ(ierr); 2532*b89f26deSStefano Zampini if ((PetscInt)(PetscRealPart(sum)) == A->rmap->N && A->rmap->N == A->cmap->N && A->rmap->mapping == A->cmap->mapping) { 2533*b89f26deSStefano Zampini A->ops->invertblockdiagonal = MatInvertBlockDiagonal_IS; 2534*b89f26deSStefano Zampini } else { 2535*b89f26deSStefano Zampini A->ops->invertblockdiagonal = NULL; 2536*b89f26deSStefano Zampini } 2537*b89f26deSStefano Zampini 25388546b261SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 25398546b261SStefano Zampini PetscFunctionReturn(0); 25408546b261SStefano Zampini } 25418546b261SStefano Zampini 25428546b261SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 25438546b261SStefano Zampini { 25448546b261SStefano Zampini PetscErrorCode ierr; 25458546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 25468546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 25478546b261SStefano Zampini 25488546b261SStefano Zampini PetscFunctionBegin; 25498546b261SStefano Zampini PetscCheckSameComm(A,1,rmapping,2); 25508546b261SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 25511c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2552872cf891SStefano Zampini if (is->csf != is->sf) { 2553872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2554872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2555f03112d0SStefano Zampini } else is->csf = NULL; 255628f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 255728f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 2558*b89f26deSStefano Zampini ierr = PetscFree(is->bdiag);CHKERRQ(ierr); 25593bbff08aSStefano Zampini 25603bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2561fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2562fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2563e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2564e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2565e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2566e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 25676625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 25686625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 25696625354bSStefano Zampini PetscBool same,gsame; 25706625354bSStefano Zampini 25716625354bSStefano Zampini same = PETSC_FALSE; 25726625354bSStefano Zampini if (nr == nc && cbs == rbs) { 25736625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 25746625354bSStefano Zampini 25756625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 25766625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 25776625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 25786625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 25796625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 25806625354bSStefano Zampini } 25816625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 25826625354bSStefano Zampini if (gsame) cmapping = rmapping; 25836625354bSStefano Zampini } 258453b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 258553b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 25866625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 25876625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 25886625354bSStefano Zampini 25896625354bSStefano Zampini /* Create the local matrix A */ 2590f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 25918546b261SStefano Zampini ierr = MatSetType(is->A,is->lmattype);CHKERRQ(ierr); 2592e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2593e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 25948546b261SStefano Zampini ierr = MatSetOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 25958546b261SStefano Zampini ierr = MatAppendOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2596c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2597c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2598b4319ba4SBarry Smith 2599f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 26008546b261SStefano Zampini ierr = MatISSetUpScatters_Private(A);CHKERRQ(ierr); 2601f26d0771SStefano Zampini } 260248ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2603b4319ba4SBarry Smith PetscFunctionReturn(0); 2604b4319ba4SBarry Smith } 2605b4319ba4SBarry Smith 2606a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 26072e74eeadSLisandro Dalcin { 26082e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 26092e74eeadSLisandro Dalcin PetscErrorCode ierr; 261097563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 261197563a80SStefano Zampini PetscInt i,zm,zn; 261297563a80SStefano Zampini #endif 2613f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 26142e74eeadSLisandro Dalcin 26152e74eeadSLisandro Dalcin PetscFunctionBegin; 26162e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2617f26d0771SStefano 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); 261897563a80SStefano Zampini /* count negative indices */ 261997563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 262097563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 26212e74eeadSLisandro Dalcin #endif 262297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 262397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 262497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 262597563a80SStefano Zampini /* count negative indices (should be the same as before) */ 262697563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 262797563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2628b4f971dfSStefano 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"); 2629b4f971dfSStefano 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"); 263097563a80SStefano Zampini #endif 26312e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 26322e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26332e74eeadSLisandro Dalcin } 26342e74eeadSLisandro Dalcin 2635a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 263697563a80SStefano Zampini { 263797563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 263897563a80SStefano Zampini PetscErrorCode ierr; 263997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 264097563a80SStefano Zampini PetscInt i,zm,zn; 264197563a80SStefano Zampini #endif 2642f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 264397563a80SStefano Zampini 264497563a80SStefano Zampini PetscFunctionBegin; 264597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2646f26d0771SStefano 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); 264797563a80SStefano Zampini /* count negative indices */ 264897563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 264997563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 265097563a80SStefano Zampini #endif 265197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 265297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 265397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 265497563a80SStefano Zampini /* count negative indices (should be the same as before) */ 265597563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 265697563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2657b4f971dfSStefano 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"); 2658b4f971dfSStefano 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"); 265997563a80SStefano Zampini #endif 2660d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 266197563a80SStefano Zampini PetscFunctionReturn(0); 266297563a80SStefano Zampini } 266397563a80SStefano Zampini 2664a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2665b4319ba4SBarry Smith { 2666dfbe8321SBarry Smith PetscErrorCode ierr; 2667b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2668b4319ba4SBarry Smith 2669b4319ba4SBarry Smith PetscFunctionBegin; 2670b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2671872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2672872cf891SStefano Zampini } else { 2673b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2674872cf891SStefano Zampini } 2675b4319ba4SBarry Smith PetscFunctionReturn(0); 2676b4319ba4SBarry Smith } 2677b4319ba4SBarry Smith 2678a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2679f0006bf2SLisandro Dalcin { 2680f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2681f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2682f0006bf2SLisandro Dalcin 2683f0006bf2SLisandro Dalcin PetscFunctionBegin; 2684b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2685b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2686b4f971dfSStefano Zampini PetscInt ibs,bs; 2687b4f971dfSStefano Zampini 2688b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2689b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2690b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2691b4f971dfSStefano Zampini #endif 2692b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2693b4f971dfSStefano Zampini } else { 2694f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2695b4f971dfSStefano Zampini } 2696f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2697f0006bf2SLisandro Dalcin } 2698f0006bf2SLisandro Dalcin 2699f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2700f0ae7da4SStefano Zampini { 2701f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2702f0ae7da4SStefano Zampini PetscErrorCode ierr; 2703f0ae7da4SStefano Zampini 2704f0ae7da4SStefano Zampini PetscFunctionBegin; 2705f0ae7da4SStefano Zampini if (!n) { 2706f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2707f0ae7da4SStefano Zampini } else { 2708f0ae7da4SStefano Zampini PetscInt i; 2709f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2710f0ae7da4SStefano Zampini 2711f0ae7da4SStefano Zampini if (columns) { 2712f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2713f0ae7da4SStefano Zampini } else { 2714f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2715f0ae7da4SStefano Zampini } 2716f0ae7da4SStefano Zampini if (diag != 0.) { 2717f0ae7da4SStefano Zampini const PetscScalar *array; 2718f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2719f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2720f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2721f0ae7da4SStefano Zampini } 2722f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2723f0ae7da4SStefano Zampini } 2724f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2725f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2726f0ae7da4SStefano Zampini } 2727f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2728f0ae7da4SStefano Zampini } 2729f0ae7da4SStefano Zampini 2730f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 27312e74eeadSLisandro Dalcin { 27326e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 27336e520ac8SStefano Zampini PetscInt nr,nl,len,i; 27346e520ac8SStefano Zampini PetscInt *lrows; 27352e74eeadSLisandro Dalcin PetscErrorCode ierr; 27362e74eeadSLisandro Dalcin 27372e74eeadSLisandro Dalcin PetscFunctionBegin; 2738f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2739f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2740f0ae7da4SStefano Zampini PetscBool cong; 274126b0207aSStefano Zampini 2742f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 274326b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2744268753edSStefano 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"); 2745268753edSStefano 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"); 2746268753edSStefano 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"); 2747f0ae7da4SStefano Zampini } 2748f0ae7da4SStefano Zampini #endif 27496e520ac8SStefano Zampini /* get locally owned rows */ 2750f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 27516e520ac8SStefano Zampini /* fix right hand side if needed */ 27526e520ac8SStefano Zampini if (x && b) { 27536e520ac8SStefano Zampini const PetscScalar *xx; 27546e520ac8SStefano Zampini PetscScalar *bb; 27556e520ac8SStefano Zampini 27566e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 27576e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 27586e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 27596e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 27606e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 27612e74eeadSLisandro Dalcin } 27626e520ac8SStefano Zampini /* get rows associated to the local matrices */ 27633d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 27646e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 27656e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 27666e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 27676e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 27686e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 27696e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 27706e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 27716e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 27726e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2773f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 27746e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 27752e74eeadSLisandro Dalcin PetscFunctionReturn(0); 27762e74eeadSLisandro Dalcin } 27772e74eeadSLisandro Dalcin 2778f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2779b4319ba4SBarry Smith { 2780dfbe8321SBarry Smith PetscErrorCode ierr; 2781b4319ba4SBarry Smith 2782b4319ba4SBarry Smith PetscFunctionBegin; 2783f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2784f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2785f0ae7da4SStefano Zampini } 27862205254eSKarl Rupp 2787f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2788f0ae7da4SStefano Zampini { 2789f0ae7da4SStefano Zampini PetscErrorCode ierr; 2790f0ae7da4SStefano Zampini 2791f0ae7da4SStefano Zampini PetscFunctionBegin; 2792f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2793b4319ba4SBarry Smith PetscFunctionReturn(0); 2794b4319ba4SBarry Smith } 2795b4319ba4SBarry Smith 2796a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2797b4319ba4SBarry Smith { 2798b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2799dfbe8321SBarry Smith PetscErrorCode ierr; 2800b4319ba4SBarry Smith 2801b4319ba4SBarry Smith PetscFunctionBegin; 2802b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2803b4319ba4SBarry Smith PetscFunctionReturn(0); 2804b4319ba4SBarry Smith } 2805b4319ba4SBarry Smith 2806a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2807b4319ba4SBarry Smith { 2808b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2809dfbe8321SBarry Smith PetscErrorCode ierr; 2810b4319ba4SBarry Smith 2811b4319ba4SBarry Smith PetscFunctionBegin; 2812b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2813872cf891SStefano Zampini /* fix for local empty rows/cols */ 2814872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2815872cf891SStefano Zampini Mat newlA; 2816f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2817f03112d0SStefano Zampini IS nzr,nzc; 2818f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2819f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2820872cf891SStefano Zampini 2821f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2822f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2823f03112d0SStefano Zampini if (!nzr) { 2824f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2825872cf891SStefano Zampini } 2826f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2827f03112d0SStefano Zampini if (!nzc) { 2828f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2829872cf891SStefano Zampini } 2830f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2831f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2832f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2833f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2834f03112d0SStefano Zampini IS is1,is2; 2835f03112d0SStefano Zampini 2836f03112d0SStefano Zampini /* need new global l2g map */ 2837f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2838f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2839f03112d0SStefano Zampini 2840872cf891SStefano Zampini /* extract valid submatrix */ 2841f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2842f03112d0SStefano Zampini 2843f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2844f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2845f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2846f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2847872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 284872ed36d8SStefano Zampini if (is->A->rmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 284972ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 285072ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 285172ed36d8SStefano Zampini 285272ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->rmap->mapping,&nl);CHKERRQ(ierr); 285372ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 285472ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 285572ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 285672ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 285772ed36d8SStefano Zampini if (j != nr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nr); 285872ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 285972ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 286072ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 286172ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->rmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 286272ed36d8SStefano Zampini } 2863f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2864f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2865f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 286672ed36d8SStefano Zampini 2867f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2868f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2869f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2870f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 287172ed36d8SStefano Zampini if (is->A->cmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 287272ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 287372ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 287472ed36d8SStefano Zampini 287572ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->cmap->mapping,&nl);CHKERRQ(ierr); 287672ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 287772ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 287872ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 287972ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 288072ed36d8SStefano Zampini if (j != nc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nc); 288172ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 288272ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 288372ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 288472ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->cmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 288572ed36d8SStefano Zampini } 2886f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2887f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2888f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 288972ed36d8SStefano Zampini 2890f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 289172ed36d8SStefano Zampini 2892f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2893f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2894f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2895f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2896f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2897f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2898f03112d0SStefano Zampini newlA = is->A; 2899f03112d0SStefano Zampini } 2900f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2901f03112d0SStefano Zampini if (newl2g) { 2902f03112d0SStefano Zampini IS gnzr,gnzc; 2903f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2904f03112d0SStefano Zampini 2905f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2906f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2907f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2908f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2909f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2910f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2911f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2912f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2913f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2914f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2915f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2916f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2917f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2918f03112d0SStefano Zampini } 2919872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2920872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2921f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2922f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2923872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2924f03112d0SStefano Zampini } 2925b4319ba4SBarry Smith PetscFunctionReturn(0); 2926b4319ba4SBarry Smith } 2927b4319ba4SBarry Smith 2928a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2929b4319ba4SBarry Smith { 2930b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2931b4319ba4SBarry Smith 2932b4319ba4SBarry Smith PetscFunctionBegin; 2933b4319ba4SBarry Smith *local = is->A; 2934b4319ba4SBarry Smith PetscFunctionReturn(0); 2935b4319ba4SBarry Smith } 2936b4319ba4SBarry Smith 29373b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 29383b3b1effSJed Brown { 29393b3b1effSJed Brown PetscFunctionBegin; 29403b3b1effSJed Brown *local = NULL; 29413b3b1effSJed Brown PetscFunctionReturn(0); 29423b3b1effSJed Brown } 29433b3b1effSJed Brown 2944b4319ba4SBarry Smith /*@ 2945b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2946b4319ba4SBarry Smith 2947b4319ba4SBarry Smith Input Parameter: 2948b4319ba4SBarry Smith . mat - the matrix 2949b4319ba4SBarry Smith 2950b4319ba4SBarry Smith Output Parameter: 2951eb82efa4SStefano Zampini . local - the local matrix 2952b4319ba4SBarry Smith 2953b4319ba4SBarry Smith Level: advanced 2954b4319ba4SBarry Smith 2955b4319ba4SBarry Smith Notes: 2956b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2957b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2958b4319ba4SBarry Smith of the MatSetValues() operation. 2959b4319ba4SBarry Smith 29603b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 296196a6f129SJed Brown 2962b4319ba4SBarry Smith .seealso: MATIS 2963b4319ba4SBarry Smith @*/ 29647087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2965b4319ba4SBarry Smith { 29664ac538c5SBarry Smith PetscErrorCode ierr; 2967b4319ba4SBarry Smith 2968b4319ba4SBarry Smith PetscFunctionBegin; 29690700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2970b4319ba4SBarry Smith PetscValidPointer(local,2); 29714ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2972b4319ba4SBarry Smith PetscFunctionReturn(0); 2973b4319ba4SBarry Smith } 2974b4319ba4SBarry Smith 29753b3b1effSJed Brown /*@ 29763b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 29773b3b1effSJed Brown 29783b3b1effSJed Brown Input Parameter: 29793b3b1effSJed Brown . mat - the matrix 29803b3b1effSJed Brown 29813b3b1effSJed Brown Output Parameter: 29823b3b1effSJed Brown . local - the local matrix 29833b3b1effSJed Brown 29843b3b1effSJed Brown Level: advanced 29853b3b1effSJed Brown 29863b3b1effSJed Brown .seealso: MATIS 29873b3b1effSJed Brown @*/ 29883b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 29893b3b1effSJed Brown { 29903b3b1effSJed Brown PetscErrorCode ierr; 29913b3b1effSJed Brown 29923b3b1effSJed Brown PetscFunctionBegin; 29933b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29943b3b1effSJed Brown PetscValidPointer(local,2); 29953b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 29963b3b1effSJed Brown PetscFunctionReturn(0); 29973b3b1effSJed Brown } 29983b3b1effSJed Brown 29998546b261SStefano Zampini static PetscErrorCode MatISSetLocalMatType_IS(Mat mat,MatType mtype) 30008546b261SStefano Zampini { 30018546b261SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 30028546b261SStefano Zampini PetscErrorCode ierr; 30038546b261SStefano Zampini 30048546b261SStefano Zampini PetscFunctionBegin; 30058546b261SStefano Zampini if (is->A) { 30068546b261SStefano Zampini ierr = MatSetType(is->A,mtype);CHKERRQ(ierr); 30078546b261SStefano Zampini } 30088546b261SStefano Zampini ierr = PetscFree(is->lmattype);CHKERRQ(ierr); 30098546b261SStefano Zampini ierr = PetscStrallocpy(mtype,&is->lmattype);CHKERRQ(ierr); 30108546b261SStefano Zampini PetscFunctionReturn(0); 30118546b261SStefano Zampini } 30128546b261SStefano Zampini 30138546b261SStefano Zampini /*@ 30148546b261SStefano Zampini MatISSetLocalMatType - Specifies the type of local matrix 30158546b261SStefano Zampini 30168546b261SStefano Zampini Input Parameter: 30178546b261SStefano Zampini . mat - the matrix 30188546b261SStefano Zampini . mtype - the local matrix type 30198546b261SStefano Zampini 30208546b261SStefano Zampini Output Parameter: 30218546b261SStefano Zampini 30228546b261SStefano Zampini Level: advanced 30238546b261SStefano Zampini 30248546b261SStefano Zampini .seealso: MATIS, MatSetType(), MatType 30258546b261SStefano Zampini @*/ 30268546b261SStefano Zampini PetscErrorCode MatISSetLocalMatType(Mat mat,MatType mtype) 30278546b261SStefano Zampini { 30288546b261SStefano Zampini PetscErrorCode ierr; 30298546b261SStefano Zampini 30308546b261SStefano Zampini PetscFunctionBegin; 30318546b261SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 30328546b261SStefano Zampini ierr = PetscUseMethod(mat,"MatISSetLocalMatType_C",(Mat,MatType),(mat,mtype));CHKERRQ(ierr); 30338546b261SStefano Zampini PetscFunctionReturn(0); 30348546b261SStefano Zampini } 30358546b261SStefano Zampini 3036a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 30373b03a366Sstefano_zampini { 30383b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 30393b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 30403b03a366Sstefano_zampini PetscErrorCode ierr; 30418546b261SStefano Zampini MatType mtype,otype; 30428546b261SStefano Zampini PetscBool sametype = PETSC_TRUE; 30433b03a366Sstefano_zampini 30443b03a366Sstefano_zampini PetscFunctionBegin; 30454e4c7dbeSStefano Zampini if (is->A) { 30463b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 30473b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 3048f0ae7da4SStefano 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); 30498546b261SStefano Zampini ierr = MatGetType(local,&mtype);CHKERRQ(ierr); 30508546b261SStefano Zampini ierr = MatGetType(is->A,&otype);CHKERRQ(ierr); 30518546b261SStefano Zampini ierr = PetscStrcmp(mtype,otype,&sametype);CHKERRQ(ierr); 30524e4c7dbeSStefano Zampini } 30533b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 30543b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 30553b03a366Sstefano_zampini is->A = local; 30568546b261SStefano Zampini ierr = MatGetType(is->A,&mtype);CHKERRQ(ierr); 30578546b261SStefano Zampini ierr = MatISSetLocalMatType(mat,mtype);CHKERRQ(ierr); 30588546b261SStefano Zampini if (!sametype && !is->islocalref) { 30598546b261SStefano Zampini ierr = MatISSetUpScatters_Private(mat);CHKERRQ(ierr); 30608546b261SStefano Zampini } 30613b03a366Sstefano_zampini PetscFunctionReturn(0); 30623b03a366Sstefano_zampini } 30633b03a366Sstefano_zampini 30643b03a366Sstefano_zampini /*@ 3065eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 30663b03a366Sstefano_zampini 30678546b261SStefano Zampini Collective on Mat 30688546b261SStefano Zampini 30693b03a366Sstefano_zampini Input Parameter: 30703b03a366Sstefano_zampini . mat - the matrix 3071eb82efa4SStefano Zampini . local - the local matrix 30723b03a366Sstefano_zampini 30733b03a366Sstefano_zampini Output Parameter: 30743b03a366Sstefano_zampini 30753b03a366Sstefano_zampini Level: advanced 30763b03a366Sstefano_zampini 30773b03a366Sstefano_zampini Notes: 30783b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 30793b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 30803b03a366Sstefano_zampini 30813b03a366Sstefano_zampini .seealso: MATIS 30823b03a366Sstefano_zampini @*/ 30833b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 30843b03a366Sstefano_zampini { 30853b03a366Sstefano_zampini PetscErrorCode ierr; 30863b03a366Sstefano_zampini 30873b03a366Sstefano_zampini PetscFunctionBegin; 30883b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3089b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 30903b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 30913b03a366Sstefano_zampini PetscFunctionReturn(0); 30923b03a366Sstefano_zampini } 30933b03a366Sstefano_zampini 3094a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 30956726f965SBarry Smith { 30966726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30976726f965SBarry Smith PetscErrorCode ierr; 30986726f965SBarry Smith 30996726f965SBarry Smith PetscFunctionBegin; 31006726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 31016726f965SBarry Smith PetscFunctionReturn(0); 31026726f965SBarry Smith } 31036726f965SBarry Smith 3104a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 31052e74eeadSLisandro Dalcin { 31062e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 31072e74eeadSLisandro Dalcin PetscErrorCode ierr; 31082e74eeadSLisandro Dalcin 31092e74eeadSLisandro Dalcin PetscFunctionBegin; 31102e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 31112e74eeadSLisandro Dalcin PetscFunctionReturn(0); 31122e74eeadSLisandro Dalcin } 31132e74eeadSLisandro Dalcin 3114a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 31152e74eeadSLisandro Dalcin { 31162e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 31172e74eeadSLisandro Dalcin PetscErrorCode ierr; 31182e74eeadSLisandro Dalcin 31192e74eeadSLisandro Dalcin PetscFunctionBegin; 31202e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 3121e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 31222e74eeadSLisandro Dalcin 31232e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 31242e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 3125e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3126e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 31272e74eeadSLisandro Dalcin PetscFunctionReturn(0); 31282e74eeadSLisandro Dalcin } 31292e74eeadSLisandro Dalcin 3130a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 31316726f965SBarry Smith { 31326726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 31336726f965SBarry Smith PetscErrorCode ierr; 31346726f965SBarry Smith 31356726f965SBarry Smith PetscFunctionBegin; 31364e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 31376726f965SBarry Smith PetscFunctionReturn(0); 31386726f965SBarry Smith } 31396726f965SBarry Smith 3140f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 3141f26d0771SStefano Zampini { 3142f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 3143f26d0771SStefano Zampini Mat_IS *x; 3144f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3145f26d0771SStefano Zampini PetscBool ismatis; 3146f26d0771SStefano Zampini #endif 3147f26d0771SStefano Zampini PetscErrorCode ierr; 3148f26d0771SStefano Zampini 3149f26d0771SStefano Zampini PetscFunctionBegin; 3150f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3151f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 3152f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 3153f26d0771SStefano Zampini #endif 3154f26d0771SStefano Zampini x = (Mat_IS*)X->data; 3155f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 3156f26d0771SStefano Zampini PetscFunctionReturn(0); 3157f26d0771SStefano Zampini } 3158f26d0771SStefano Zampini 3159f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 3160f26d0771SStefano Zampini { 3161f26d0771SStefano Zampini Mat lA; 3162f26d0771SStefano Zampini Mat_IS *matis; 3163f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 3164f26d0771SStefano Zampini IS is; 3165f26d0771SStefano Zampini const PetscInt *rg,*rl; 3166f26d0771SStefano Zampini PetscInt nrg; 3167f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 3168f26d0771SStefano Zampini PetscErrorCode ierr; 3169f26d0771SStefano Zampini 3170f26d0771SStefano Zampini PetscFunctionBegin; 3171f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3172f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3173f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3174f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 3175f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3176249c8a71SStefano 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); 3177f26d0771SStefano Zampini #endif 3178f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3179f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3180f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3181f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3182f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 3183f26d0771SStefano Zampini #else 3184f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3185f26d0771SStefano Zampini #endif 3186f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3187f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3188f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3189f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3190f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3191f26d0771SStefano Zampini /* compute new l2g map for columns */ 3192f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 3193f26d0771SStefano Zampini const PetscInt *cg,*cl; 3194f26d0771SStefano Zampini PetscInt ncg; 3195f26d0771SStefano Zampini PetscInt ncl; 3196f26d0771SStefano Zampini 3197f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3198f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3199f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3200f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 3201f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3202249c8a71SStefano 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); 3203f26d0771SStefano Zampini #endif 3204f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3205f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3206f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3207f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3208f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 3209f26d0771SStefano Zampini #else 3210f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3211f26d0771SStefano Zampini #endif 3212f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3213f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3214f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3215f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3216f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3217f26d0771SStefano Zampini } else { 3218f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3219f26d0771SStefano Zampini cl2g = rl2g; 3220f26d0771SStefano Zampini } 3221f26d0771SStefano Zampini /* create the MATIS submatrix */ 3222f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3223f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3224f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3225f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3226b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3227f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3228f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3229f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3230f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3231f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3232f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3233f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3234f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3235f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3236f26d0771SStefano Zampini /* remove unsupported ops */ 3237f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3238f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3239f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3240f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3241f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3242f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3243f26d0771SStefano Zampini PetscFunctionReturn(0); 3244f26d0771SStefano Zampini } 3245f26d0771SStefano Zampini 3246872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3247872cf891SStefano Zampini { 3248872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 32498546b261SStefano Zampini char type[256]; 32508546b261SStefano Zampini PetscBool flg; 3251872cf891SStefano Zampini PetscErrorCode ierr; 3252872cf891SStefano Zampini 3253872cf891SStefano Zampini PetscFunctionBegin; 3254872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3255f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 325675d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 32578546b261SStefano Zampini ierr = PetscOptionsFList("-matis_localmat_type","Matrix type","MatISSetLocalMatType",MatList,a->lmattype,type,256,&flg);CHKERRQ(ierr); 32588546b261SStefano Zampini if (flg) { 32598546b261SStefano Zampini ierr = MatISSetLocalMatType(A,type);CHKERRQ(ierr); 32608546b261SStefano Zampini } 32618546b261SStefano Zampini if (a->A) { 32628546b261SStefano Zampini ierr = MatSetFromOptions(a->A);CHKERRQ(ierr); 32638546b261SStefano Zampini } 32640af67c1bSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 3265872cf891SStefano Zampini PetscFunctionReturn(0); 3266872cf891SStefano Zampini } 3267872cf891SStefano Zampini 3268284134d9SBarry Smith /*@ 32693c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3270284134d9SBarry Smith process but not across processes. 3271284134d9SBarry Smith 3272284134d9SBarry Smith Input Parameters: 3273284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3274e176bc59SStefano Zampini . bs - block size of the matrix 3275df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3276e176bc59SStefano Zampini . rmap - local to global map for rows 3277e176bc59SStefano Zampini - cmap - local to global map for cols 3278284134d9SBarry Smith 3279284134d9SBarry Smith Output Parameter: 3280284134d9SBarry Smith . A - the resulting matrix 3281284134d9SBarry Smith 32828e6c10adSSatish Balay Level: advanced 32838e6c10adSSatish Balay 328495452b02SPatrick Sanan Notes: 328595452b02SPatrick Sanan See MATIS for more details. 32866fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 32876fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 32883c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 3289284134d9SBarry Smith 3290284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3291284134d9SBarry Smith @*/ 3292e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3293284134d9SBarry Smith { 3294284134d9SBarry Smith PetscErrorCode ierr; 3295284134d9SBarry Smith 3296284134d9SBarry Smith PetscFunctionBegin; 32976fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 3298284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3299284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 33006fdf41d1SStefano Zampini if (bs > 0) { 3301284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 33026fdf41d1SStefano Zampini } 3303284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3304e176bc59SStefano Zampini if (rmap && cmap) { 3305e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3306e176bc59SStefano Zampini } else if (!rmap) { 3307e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 3308e176bc59SStefano Zampini } else { 3309e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 3310e176bc59SStefano Zampini } 3311284134d9SBarry Smith PetscFunctionReturn(0); 3312284134d9SBarry Smith } 3313284134d9SBarry Smith 3314b4319ba4SBarry Smith /*MC 3315f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3316*b89f26deSStefano Zampini This stores the matrices in globally unassembled form. Each processor assembles only its local Neumann problem and the parallel matrix vector 3317b4319ba4SBarry Smith product is handled "implicitly". 3318b4319ba4SBarry Smith 3319b4319ba4SBarry Smith Options Database Keys: 332075d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 332175d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 332275d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3323b4319ba4SBarry Smith 332495452b02SPatrick Sanan Notes: 332595452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3326b4319ba4SBarry Smith 3327b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3328b4319ba4SBarry Smith 3329b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3330eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3331b4319ba4SBarry Smith 3332b4319ba4SBarry Smith Level: advanced 3333b4319ba4SBarry Smith 3334f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3335b4319ba4SBarry Smith 3336b4319ba4SBarry Smith M*/ 3337b4319ba4SBarry Smith 33388cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3339b4319ba4SBarry Smith { 3340dfbe8321SBarry Smith PetscErrorCode ierr; 3341b4319ba4SBarry Smith Mat_IS *b; 3342b4319ba4SBarry Smith 3343b4319ba4SBarry Smith PetscFunctionBegin; 3344b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 33458546b261SStefano Zampini ierr = PetscStrallocpy(MATAIJ,&b->lmattype);CHKERRQ(ierr); 3346b4319ba4SBarry Smith A->data = (void*)b; 3347b4319ba4SBarry Smith 3348e176bc59SStefano Zampini /* matrix ops */ 3349e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3350b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 33512e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 33522e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 33532e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3354b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3355b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 33562e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 335798921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3358b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3359f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 33602e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3361f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3362b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3363b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3364b4319ba4SBarry Smith A->ops->view = MatView_IS; 33656726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 33662e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 33672e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 33686726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 336969796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 337069796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 337145471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3372ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 33736bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 33742b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3375659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 33767dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3377f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 33783fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 33793fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3380d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 33817fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3382ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3383872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3384b4319ba4SBarry Smith 3385b7ce53b6SStefano Zampini /* special MATIS functions */ 33868546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",MatISSetLocalMatType_IS);CHKERRQ(ierr); 3387bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 33883b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3389bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3390487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 33912e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 3392cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 339375d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3394f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3395487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3396487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3397487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3398487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3399487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3400487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3401487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 340217667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3403b4319ba4SBarry Smith PetscFunctionReturn(0); 3404b4319ba4SBarry Smith } 3405