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*/ 116989cf23SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 124f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1328f4e0baSStefano Zampini 14f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 15b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 16b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 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; 4575d48cdbSStefano 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 { 16575d48cdbSStefano Zampini Mat PT; 16675d48cdbSStefano Zampini MatISPtAP ptap; 16775d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 16875d48cdbSStefano Zampini PetscContainer c; 16975d48cdbSStefano Zampini const PetscInt *garray; 17075d48cdbSStefano Zampini PetscInt ibs,N,dc; 17175d48cdbSStefano Zampini MPI_Comm comm; 17275d48cdbSStefano Zampini PetscErrorCode ierr; 17375d48cdbSStefano Zampini 17475d48cdbSStefano Zampini PetscFunctionBegin; 17575d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 17675d48cdbSStefano Zampini ierr = MatCreate(comm,C);CHKERRQ(ierr); 17775d48cdbSStefano Zampini ierr = MatSetType(*C,MATIS);CHKERRQ(ierr); 17875d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 17975d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 18075d48cdbSStefano Zampini ierr = MatSetSizes(*C,dc,dc,N,N);CHKERRQ(ierr); 18175d48cdbSStefano Zampini /* Not sure about this 18275d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18375d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18475d48cdbSStefano Zampini */ 18575d48cdbSStefano Zampini 18675d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 18775d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 18875d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 18975d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 19075d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(*C),"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19175d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19275d48cdbSStefano Zampini ptap->fill = fill; 19375d48cdbSStefano Zampini 19475d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 19575d48cdbSStefano Zampini 19675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 19775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 19875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 19975d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 20075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20175d48cdbSStefano Zampini 20275d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 20575d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 20675d48cdbSStefano Zampini 20775d48cdbSStefano Zampini Crl2g = NULL; 20875d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 20975d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 21075d48cdbSStefano Zampini PetscInt N1,ibs1; 21175d48cdbSStefano Zampini 21275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21575d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 21675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21775d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 21875d48cdbSStefano Zampini const PetscInt *i1,*i2; 21975d48cdbSStefano Zampini 22075d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22175d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 22275d48cdbSStefano Zampini ierr = PetscMemcmp(i1,i2,N*sizeof(*i1),&lsame);CHKERRQ(ierr); 22375d48cdbSStefano Zampini } 22475d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 22575d48cdbSStefano Zampini if (same) { 22675d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 22775d48cdbSStefano Zampini } else { 22875d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 22975d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 23075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23175d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23275d48cdbSStefano Zampini } 23375d48cdbSStefano Zampini } 23475d48cdbSStefano Zampini /* Not sure about this 23575d48cdbSStefano Zampini if (!Crl2g) { 23675d48cdbSStefano Zampini ierr = MatGetBlockSize(*C,&ibs);CHKERRQ(ierr); 23775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 23875d48cdbSStefano Zampini } 23975d48cdbSStefano Zampini */ 24075d48cdbSStefano Zampini ierr = MatSetLocalToGlobalMapping(*C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24375d48cdbSStefano Zampini 24475d48cdbSStefano Zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 24575d48cdbSStefano Zampini PetscFunctionReturn(0); 24675d48cdbSStefano Zampini } 24775d48cdbSStefano Zampini 24875d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 24975d48cdbSStefano Zampini { 25075d48cdbSStefano Zampini PetscErrorCode ierr; 25175d48cdbSStefano Zampini 25275d48cdbSStefano Zampini PetscFunctionBegin; 25375d48cdbSStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 25475d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25575d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 25675d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25775d48cdbSStefano Zampini } 25875d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 25975d48cdbSStefano Zampini ierr = ((*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 26075d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26175d48cdbSStefano Zampini PetscFunctionReturn(0); 26275d48cdbSStefano Zampini } 26375d48cdbSStefano Zampini 2645b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2655b003df0Sstefano_zampini { 2665b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2675b003df0Sstefano_zampini PetscInt i; 2685b003df0Sstefano_zampini PetscErrorCode ierr; 2695b003df0Sstefano_zampini 270ab4d48faSStefano Zampini PetscFunctionBegin; 2715b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2725b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2735b003df0Sstefano_zampini } 2745b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2755b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2765b003df0Sstefano_zampini } 2775b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 2785b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 2795b003df0Sstefano_zampini PetscFunctionReturn(0); 2805b003df0Sstefano_zampini } 281a72627d2SStefano Zampini 2826989cf23SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2836989cf23SStefano Zampini { 2846989cf23SStefano Zampini Mat_MPIAIJ *aij = (Mat_MPIAIJ*)A->data; 2856989cf23SStefano Zampini Mat_SeqAIJ *diag = (Mat_SeqAIJ*)(aij->A->data); 2866989cf23SStefano Zampini Mat_SeqAIJ *offd = (Mat_SeqAIJ*)(aij->B->data); 2876989cf23SStefano Zampini Mat lA; 2886989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2896989cf23SStefano Zampini IS is; 2906989cf23SStefano Zampini MPI_Comm comm; 2916989cf23SStefano Zampini void *ptrs[2]; 2926989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 2936989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 2946989cf23SStefano Zampini PetscInt *di,*dj,*oi,*oj; 2956989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 296e363d98aSStefano Zampini PetscInt lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 2976989cf23SStefano Zampini PetscErrorCode ierr; 2986989cf23SStefano Zampini 299ab4d48faSStefano Zampini PetscFunctionBegin; 3006989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 3016989cf23SStefano Zampini if (!aij->garray) SETERRQ(comm,PETSC_ERR_SUP,"garray not present"); 3026989cf23SStefano Zampini 3036989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 3046989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 3056989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 3066989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 3076989cf23SStefano Zampini di = diag->i; 3086989cf23SStefano Zampini dj = diag->j; 3096989cf23SStefano Zampini dd = diag->a; 3106989cf23SStefano Zampini oc = aij->B->cmap->n; 3116989cf23SStefano Zampini oi = offd->i; 3126989cf23SStefano Zampini oj = offd->j; 3136989cf23SStefano Zampini od = offd->a; 3146989cf23SStefano Zampini nnz = diag->i[dr] + offd->i[dr]; 3156989cf23SStefano Zampini 3166989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 3176989cf23SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 3186989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3196989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 320e363d98aSStefano Zampini if (dr) { 3216989cf23SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 3226989cf23SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 3236989cf23SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = aij->garray[i]; 3246989cf23SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 325e363d98aSStefano Zampini lc = dc+oc; 326e363d98aSStefano Zampini } else { 327e363d98aSStefano Zampini ierr = ISCreateGeneral(comm,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 328e363d98aSStefano Zampini lc = 0; 329e363d98aSStefano Zampini } 3306989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3316989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3326989cf23SStefano Zampini 3336989cf23SStefano Zampini /* create MATIS object */ 3346989cf23SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 3356989cf23SStefano Zampini ierr = MatSetSizes(*newmat,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3366989cf23SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 3376989cf23SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 3386989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3396989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3406989cf23SStefano Zampini 3416989cf23SStefano Zampini /* merge local matrices */ 3426989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 3436989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 3446989cf23SStefano Zampini ii = aux; 3456989cf23SStefano Zampini jj = aux+dr+1; 3466989cf23SStefano Zampini aa = data; 3476989cf23SStefano Zampini *ii = *(di++) + *(oi++); 3486989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 3496989cf23SStefano Zampini { 3506989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 3516989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 3526989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 3536989cf23SStefano Zampini } 3546989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 3556989cf23SStefano Zampini ii = aux; 3566989cf23SStefano Zampini jj = aux+dr+1; 3576989cf23SStefano Zampini aa = data; 358e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 3596989cf23SStefano Zampini 3606989cf23SStefano Zampini /* create containers to destroy the data */ 3616989cf23SStefano Zampini ptrs[0] = aux; 3626989cf23SStefano Zampini ptrs[1] = data; 3636989cf23SStefano Zampini for (i=0; i<2; i++) { 3646989cf23SStefano Zampini PetscContainer c; 3656989cf23SStefano Zampini 3666989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 3676989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 368b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 3696989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 3706989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 3716989cf23SStefano Zampini } 3726989cf23SStefano Zampini 3736989cf23SStefano Zampini /* finalize matrix */ 3746989cf23SStefano Zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 3756989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3766989cf23SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3776989cf23SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3786989cf23SStefano Zampini PetscFunctionReturn(0); 3796989cf23SStefano Zampini } 3806989cf23SStefano Zampini 381cf0a3239SStefano Zampini /*@ 3823d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 383cf0a3239SStefano Zampini 384cf0a3239SStefano Zampini Collective on MPI_Comm 385cf0a3239SStefano Zampini 386cf0a3239SStefano Zampini Input Parameters: 387cf0a3239SStefano Zampini + A - the matrix 388cf0a3239SStefano Zampini 389cf0a3239SStefano Zampini Level: advanced 390cf0a3239SStefano Zampini 39195452b02SPatrick Sanan Notes: 39295452b02SPatrick Sanan This function does not need to be called by the user. 393cf0a3239SStefano Zampini 394cf0a3239SStefano Zampini .keywords: matrix 395cf0a3239SStefano Zampini 396cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 397cf0a3239SStefano Zampini @*/ 398cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 399cf0a3239SStefano Zampini { 4007fa8f2d3SStefano Zampini PetscErrorCode ierr; 4017fa8f2d3SStefano Zampini 4027fa8f2d3SStefano Zampini PetscFunctionBegin; 403cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 404cf0a3239SStefano Zampini PetscValidType(A,1); 405cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 4067fa8f2d3SStefano Zampini PetscFunctionReturn(0); 4077fa8f2d3SStefano Zampini } 4087fa8f2d3SStefano Zampini 4095e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 4105e3038f0Sstefano_zampini { 4115e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 4125e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 4135e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 4145e3038f0Sstefano_zampini MPI_Comm comm; 4155b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 4165b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 4179e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 4185e3038f0Sstefano_zampini PetscErrorCode ierr; 4195e3038f0Sstefano_zampini 420ab4d48faSStefano Zampini PetscFunctionBegin; 4215e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 4225e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 4235e3038f0Sstefano_zampini rnest = NULL; 4245e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 4255e3038f0Sstefano_zampini PetscBool ismatis,isnest; 4265e3038f0Sstefano_zampini 4275e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 4285e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 4295e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4305e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 4315e3038f0Sstefano_zampini if (isnest) { 4325e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 4335e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 4345e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 4355e3038f0Sstefano_zampini } 4365e3038f0Sstefano_zampini } 4375e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 4385b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 4399e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 4405e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 4419e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 4425e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 4435e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4445e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 4455e3038f0Sstefano_zampini PetscBool ismatis; 4469e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 4475e3038f0Sstefano_zampini 4485e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 4495e3038f0Sstefano_zampini if (!nest[i][j]) continue; 4505e3038f0Sstefano_zampini 4515e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 4529e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 4539e7b2b25Sstefano_zampini if (istrans[ij]) { 4549e7b2b25Sstefano_zampini Mat T,lT; 4559e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 4569e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 4579e7b2b25Sstefano_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); 4589e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 4599e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 4609e7b2b25Sstefano_zampini } else { 4615e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 4625e3038f0Sstefano_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); 4639e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 4649e7b2b25Sstefano_zampini } 4655e3038f0Sstefano_zampini 4665e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 4675e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 4689e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 4695e3038f0Sstefano_zampini if (!l1 || !l2) continue; 4705e3038f0Sstefano_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); 4715e3038f0Sstefano_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); 4725e3038f0Sstefano_zampini lr[i] = l1; 4735e3038f0Sstefano_zampini lc[j] = l2; 4745e3038f0Sstefano_zampini 4755e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 4765e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 4775e3038f0Sstefano_zampini } 4785e3038f0Sstefano_zampini } 4795e3038f0Sstefano_zampini 4805e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 4815e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 4825e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4835e3038f0Sstefano_zampini rl2g = NULL; 4845e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 4855e3038f0Sstefano_zampini PetscInt n1,n2; 4865e3038f0Sstefano_zampini 4875e3038f0Sstefano_zampini if (!nest[i][j]) continue; 4889e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 4899e7b2b25Sstefano_zampini Mat T; 4909e7b2b25Sstefano_zampini 4919e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 4929e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 4939e7b2b25Sstefano_zampini } else { 4945e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 4959e7b2b25Sstefano_zampini } 4965e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 4975e3038f0Sstefano_zampini if (!n1) continue; 4985e3038f0Sstefano_zampini if (!rl2g) { 4995e3038f0Sstefano_zampini rl2g = cl2g; 5005e3038f0Sstefano_zampini } else { 5015e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 5025e3038f0Sstefano_zampini PetscBool same; 5035e3038f0Sstefano_zampini 5045e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 5055e3038f0Sstefano_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); 5065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 5075e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 5085e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 5095e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 5105e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 5115e3038f0Sstefano_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); 5125e3038f0Sstefano_zampini } 5135e3038f0Sstefano_zampini } 5145e3038f0Sstefano_zampini } 5155e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 5165e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 5175e3038f0Sstefano_zampini rl2g = NULL; 5185e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 5195e3038f0Sstefano_zampini PetscInt n1,n2; 5205e3038f0Sstefano_zampini 5215e3038f0Sstefano_zampini if (!nest[j][i]) continue; 5229e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 5239e7b2b25Sstefano_zampini Mat T; 5249e7b2b25Sstefano_zampini 5259e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 5269e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 5279e7b2b25Sstefano_zampini } else { 5285e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 5299e7b2b25Sstefano_zampini } 5305e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 5315e3038f0Sstefano_zampini if (!n1) continue; 5325e3038f0Sstefano_zampini if (!rl2g) { 5335e3038f0Sstefano_zampini rl2g = cl2g; 5345e3038f0Sstefano_zampini } else { 5355e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 5365e3038f0Sstefano_zampini PetscBool same; 5375e3038f0Sstefano_zampini 5385e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 5395e3038f0Sstefano_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); 5405e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 5415e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 5425e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 5435e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 5445e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 5455e3038f0Sstefano_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); 5465e3038f0Sstefano_zampini } 5475e3038f0Sstefano_zampini } 5485e3038f0Sstefano_zampini } 5495e3038f0Sstefano_zampini #endif 5505e3038f0Sstefano_zampini 5515e3038f0Sstefano_zampini B = NULL; 5525e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 5535b003df0Sstefano_zampini PetscInt stl; 5545b003df0Sstefano_zampini 5555e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 5565e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 5575e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 5585b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 5595e3038f0Sstefano_zampini Mat usedmat; 5605e3038f0Sstefano_zampini Mat_IS *matis; 5615e3038f0Sstefano_zampini const PetscInt *idxs; 5625e3038f0Sstefano_zampini 5635e3038f0Sstefano_zampini /* local IS for local NEST */ 5645b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 5655e3038f0Sstefano_zampini 5665e3038f0Sstefano_zampini /* l2gmap */ 5675e3038f0Sstefano_zampini j = 0; 5685e3038f0Sstefano_zampini usedmat = nest[i][j]; 5699e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 5709e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 5719e7b2b25Sstefano_zampini 5729e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 5739e7b2b25Sstefano_zampini Mat T; 5749e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 5759e7b2b25Sstefano_zampini usedmat = T; 5769e7b2b25Sstefano_zampini } 57782d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 5785e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 5795e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 5809e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 5819e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 5829e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 5839e7b2b25Sstefano_zampini } else { 5845e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 5855e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 5869e7b2b25Sstefano_zampini } 5875e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 5885e3038f0Sstefano_zampini stl += lr[i]; 5895e3038f0Sstefano_zampini } 5905e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 5915e3038f0Sstefano_zampini 5925e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 5935e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 5945e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 5955b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 5965e3038f0Sstefano_zampini Mat usedmat; 5975e3038f0Sstefano_zampini Mat_IS *matis; 5985e3038f0Sstefano_zampini const PetscInt *idxs; 5995e3038f0Sstefano_zampini 6005e3038f0Sstefano_zampini /* local IS for local NEST */ 6015b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 6025e3038f0Sstefano_zampini 6035e3038f0Sstefano_zampini /* l2gmap */ 6045e3038f0Sstefano_zampini j = 0; 6055e3038f0Sstefano_zampini usedmat = nest[j][i]; 6069e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 6079e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 6089e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 6099e7b2b25Sstefano_zampini Mat T; 6109e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 6119e7b2b25Sstefano_zampini usedmat = T; 6129e7b2b25Sstefano_zampini } 61382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 6145e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 6155e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 6169e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 6179e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 6189e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 6199e7b2b25Sstefano_zampini } else { 6205e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 6215e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 6229e7b2b25Sstefano_zampini } 6235e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 6245e3038f0Sstefano_zampini stl += lc[i]; 6255e3038f0Sstefano_zampini } 6265e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 6275e3038f0Sstefano_zampini 6285e3038f0Sstefano_zampini /* Create MATIS */ 6295e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 6305e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 6315e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 6325e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 6335e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 6345e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 6355e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6365e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6375e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 6389e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 6399e7b2b25Sstefano_zampini if (istrans[i]) { 6409e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 6419e7b2b25Sstefano_zampini } 6429e7b2b25Sstefano_zampini } 6435e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 6445e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 6455e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6465e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6475e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 6485e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 6495e3038f0Sstefano_zampini } else { 6505e3038f0Sstefano_zampini *newmat = B; 6515e3038f0Sstefano_zampini } 6525e3038f0Sstefano_zampini } else { 6535e3038f0Sstefano_zampini if (lreuse) { 6545e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 6555e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 6565e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 6575e3038f0Sstefano_zampini if (snest[i*nc+j]) { 6585e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 6599e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 6609e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 6619e7b2b25Sstefano_zampini } 6625e3038f0Sstefano_zampini } 6635e3038f0Sstefano_zampini } 6645e3038f0Sstefano_zampini } 6655e3038f0Sstefano_zampini } else { 6665b003df0Sstefano_zampini PetscInt stl; 6675b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 6685b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 6695b003df0Sstefano_zampini stl += lr[i]; 6705e3038f0Sstefano_zampini } 6715b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 6725b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 6735b003df0Sstefano_zampini stl += lc[i]; 6745e3038f0Sstefano_zampini } 6755e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 676ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 6779e7b2b25Sstefano_zampini if (istrans[i]) { 6789e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 6799e7b2b25Sstefano_zampini } 680ab4d48faSStefano Zampini } 6815e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 6825e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 6835e3038f0Sstefano_zampini } 6845e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6855e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6865e3038f0Sstefano_zampini } 6875e3038f0Sstefano_zampini 6885b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 6895b003df0Sstefano_zampini convert = PETSC_FALSE; 6905b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 6915b003df0Sstefano_zampini if (convert) { 6925b003df0Sstefano_zampini Mat M; 6935b003df0Sstefano_zampini MatISLocalFields lf; 6945b003df0Sstefano_zampini PetscContainer c; 6955b003df0Sstefano_zampini 6965b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 6975b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 6985b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 6995b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 7005b003df0Sstefano_zampini 7015b003df0Sstefano_zampini /* attach local fields to the matrix */ 7025b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 7035b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 7045b003df0Sstefano_zampini for (i=0;i<nr;i++) { 7055b003df0Sstefano_zampini PetscInt n,st; 7065b003df0Sstefano_zampini 7075b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 7085b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 7095b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 7105b003df0Sstefano_zampini } 7115b003df0Sstefano_zampini for (i=0;i<nc;i++) { 7125b003df0Sstefano_zampini PetscInt n,st; 7135b003df0Sstefano_zampini 7145b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 7155b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 7165b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 7175b003df0Sstefano_zampini } 7185b003df0Sstefano_zampini lf->nr = nr; 7195b003df0Sstefano_zampini lf->nc = nc; 7205b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 7215b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 7225b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 7235b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 7245b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 7255b003df0Sstefano_zampini } 7265b003df0Sstefano_zampini 7275e3038f0Sstefano_zampini /* Free workspace */ 7285e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 7295e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 7305e3038f0Sstefano_zampini } 7315e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 7325e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 7335e3038f0Sstefano_zampini } 7349e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 7355b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 7365e3038f0Sstefano_zampini PetscFunctionReturn(0); 7375e3038f0Sstefano_zampini } 7385e3038f0Sstefano_zampini 739ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 740ad219c80Sstefano_zampini { 741ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 742ad219c80Sstefano_zampini Vec ll,rr; 743ad219c80Sstefano_zampini const PetscScalar *Y,*X; 744ad219c80Sstefano_zampini PetscScalar *x,*y; 745ad219c80Sstefano_zampini PetscErrorCode ierr; 746ad219c80Sstefano_zampini 747ad219c80Sstefano_zampini PetscFunctionBegin; 748ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 749ad219c80Sstefano_zampini if (l) { 750ad219c80Sstefano_zampini ll = matis->y; 751ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 752ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 753ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 754ad219c80Sstefano_zampini } else { 755ad219c80Sstefano_zampini ll = NULL; 756ad219c80Sstefano_zampini } 757ad219c80Sstefano_zampini if (r) { 758ad219c80Sstefano_zampini rr = matis->x; 759ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 760ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 761ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 762ad219c80Sstefano_zampini } else { 763ad219c80Sstefano_zampini rr = NULL; 764ad219c80Sstefano_zampini } 765ad219c80Sstefano_zampini if (ll) { 766ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 767ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 768ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 769ad219c80Sstefano_zampini } 770ad219c80Sstefano_zampini if (rr) { 771ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 772ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 773ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 774ad219c80Sstefano_zampini } 775ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 776ad219c80Sstefano_zampini PetscFunctionReturn(0); 777ad219c80Sstefano_zampini } 778ad219c80Sstefano_zampini 7797fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 7807fa8f2d3SStefano Zampini { 7817fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 7827fa8f2d3SStefano Zampini MatInfo info; 7837fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 7847fa8f2d3SStefano Zampini PetscInt bs; 7857fa8f2d3SStefano Zampini PetscErrorCode ierr; 7867fa8f2d3SStefano Zampini 7877fa8f2d3SStefano Zampini PetscFunctionBegin; 7887fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 7897fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 7907fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 7917fa8f2d3SStefano Zampini isend[0] = info.nz_used; 7927fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 7937fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 7947fa8f2d3SStefano Zampini isend[3] = info.memory; 7957fa8f2d3SStefano Zampini isend[4] = info.mallocs; 7967fa8f2d3SStefano Zampini } else { 7977fa8f2d3SStefano Zampini isend[0] = 0.; 7987fa8f2d3SStefano Zampini isend[1] = 0.; 7997fa8f2d3SStefano Zampini isend[2] = 0.; 8007fa8f2d3SStefano Zampini isend[3] = 0.; 8017fa8f2d3SStefano Zampini isend[4] = 0.; 8027fa8f2d3SStefano Zampini } 8037fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 8047fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 8057fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 8067fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 8077fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 8087fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 8097fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 8107fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 8117fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 8127fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 8137fa8f2d3SStefano Zampini 8147fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 8157fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 8167fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 8177fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 8187fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 8197fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 8207fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 8217fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 8227fa8f2d3SStefano Zampini 8237fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 8247fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 8257fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 8267fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 8277fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 8287fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 829d7f69cd0SStefano Zampini } 830d7f69cd0SStefano Zampini ginfo->block_size = bs; 831d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 832d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 833d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 8345e3038f0Sstefano_zampini PetscFunctionReturn(0); 8355e3038f0Sstefano_zampini } 8365e3038f0Sstefano_zampini 837d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 838d7f69cd0SStefano Zampini { 839d7f69cd0SStefano Zampini Mat C,lC,lA; 840d7f69cd0SStefano Zampini PetscErrorCode ierr; 841d7f69cd0SStefano Zampini 842d7f69cd0SStefano Zampini PetscFunctionBegin; 843cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 844cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 845d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 846d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 847d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 848d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 849d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 850d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 851cf37664fSBarry Smith } else { 852cf37664fSBarry Smith C = *B; 853d7f69cd0SStefano Zampini } 854d7f69cd0SStefano Zampini 855d7f69cd0SStefano Zampini /* perform local transposition */ 856d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 857d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 858d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 859d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 860d7f69cd0SStefano Zampini 861cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 862d7f69cd0SStefano Zampini *B = C; 863d7f69cd0SStefano Zampini } else { 864d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 865d7f69cd0SStefano Zampini } 8667aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8677aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 868d7f69cd0SStefano Zampini PetscFunctionReturn(0); 869d7f69cd0SStefano Zampini } 870d7f69cd0SStefano Zampini 8713fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 8723fd1c9e7SStefano Zampini { 8733fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 8743fd1c9e7SStefano Zampini PetscErrorCode ierr; 8753fd1c9e7SStefano Zampini 8763fd1c9e7SStefano Zampini PetscFunctionBegin; 8774b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 8783fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8793fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8803fd1c9e7SStefano Zampini } 8813fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 8823fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 8833fd1c9e7SStefano Zampini PetscFunctionReturn(0); 8843fd1c9e7SStefano Zampini } 8853fd1c9e7SStefano Zampini 8863fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 8873fd1c9e7SStefano Zampini { 8884b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 8893fd1c9e7SStefano Zampini PetscErrorCode ierr; 8903fd1c9e7SStefano Zampini 8913fd1c9e7SStefano Zampini PetscFunctionBegin; 8924b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 8933fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 8943fd1c9e7SStefano Zampini PetscFunctionReturn(0); 8953fd1c9e7SStefano Zampini } 8963fd1c9e7SStefano Zampini 897f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 898f26d0771SStefano Zampini { 899f26d0771SStefano Zampini PetscErrorCode ierr; 900f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 901f26d0771SStefano Zampini 902f26d0771SStefano Zampini PetscFunctionBegin; 903f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 904f26d0771SStefano 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); 905f26d0771SStefano Zampini #endif 906f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 907f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 908b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 909f26d0771SStefano Zampini PetscFunctionReturn(0); 910f26d0771SStefano Zampini } 911f26d0771SStefano Zampini 912f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 913f26d0771SStefano Zampini { 914f26d0771SStefano Zampini PetscErrorCode ierr; 915f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 916f26d0771SStefano Zampini 917f26d0771SStefano Zampini PetscFunctionBegin; 918f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 919f26d0771SStefano 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); 920f26d0771SStefano Zampini #endif 921f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 922f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 923b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 924f26d0771SStefano Zampini PetscFunctionReturn(0); 925f26d0771SStefano Zampini } 926f26d0771SStefano Zampini 927f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 928a8116848SStefano Zampini { 929a8116848SStefano Zampini PetscInt *owners = map->range; 930a8116848SStefano Zampini PetscInt n = map->n; 931a8116848SStefano Zampini PetscSF sf; 932a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 933a8116848SStefano Zampini PetscSFNode *ridxs; 934a8116848SStefano Zampini PetscMPIInt rank; 935a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 936a8116848SStefano Zampini PetscErrorCode ierr; 937a8116848SStefano Zampini 938a8116848SStefano Zampini PetscFunctionBegin; 939fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 940a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 941a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 942a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 943a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 944a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 945a8116848SStefano Zampini for (r = 0; r < N; ++r) { 946a8116848SStefano Zampini const PetscInt idx = idxs[r]; 947a8116848SStefano 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); 948a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 949a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 950a8116848SStefano Zampini } 951a8116848SStefano Zampini ridxs[r].rank = p; 952a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 953a8116848SStefano Zampini } 954a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 955a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 956a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 957a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 958f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 959a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 960f0ae7da4SStefano Zampini 961f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 962a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 963a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 964a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 965a8116848SStefano Zampini start -= cum; 966a8116848SStefano Zampini cum = 0; 967a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 968a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 969a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 970a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 971a8116848SStefano Zampini } 972a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 973a8116848SStefano Zampini /* Compress and put in indices */ 974a8116848SStefano Zampini for (r = 0; r < n; ++r) 975a8116848SStefano Zampini if (lidxs[r] >= 0) { 976a8116848SStefano Zampini if (work) work[len] = work[r]; 977a8116848SStefano Zampini lidxs[len++] = r; 978a8116848SStefano Zampini } 979a8116848SStefano Zampini if (on) *on = len; 980a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 981a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 982a8116848SStefano Zampini PetscFunctionReturn(0); 983a8116848SStefano Zampini } 984a8116848SStefano Zampini 9857dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 986a8116848SStefano Zampini { 987a8116848SStefano Zampini Mat locmat,newlocmat; 988a8116848SStefano Zampini Mat_IS *newmatis; 989a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 990a8116848SStefano Zampini Vec rtest,ltest; 991a8116848SStefano Zampini const PetscScalar *array; 992a8116848SStefano Zampini #endif 993a8116848SStefano Zampini const PetscInt *idxs; 994a8116848SStefano Zampini PetscInt i,m,n; 995a8116848SStefano Zampini PetscErrorCode ierr; 996a8116848SStefano Zampini 997a8116848SStefano Zampini PetscFunctionBegin; 998a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 999a8116848SStefano Zampini PetscBool ismatis; 1000a8116848SStefano Zampini 1001a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1002a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1003a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1004a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1005a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1006a8116848SStefano Zampini } 1007a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1008a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1009a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1010a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1011a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1012a8116848SStefano Zampini for (i=0;i<n;i++) { 1013a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1014a8116848SStefano Zampini } 1015a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1016a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1017a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1018a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1019a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1020fd479f66SMatthew 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])); 1021a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1022a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1023a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1024a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1025a8116848SStefano Zampini for (i=0;i<n;i++) { 1026a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1027a8116848SStefano Zampini } 1028a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1029a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1030a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1031a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1032a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1033fd479f66SMatthew 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])); 1034a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1035a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1036a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1037a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1038a8116848SStefano Zampini #endif 1039a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1040a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1041a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1042a8116848SStefano Zampini IS is; 1043a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1044306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 104594342113SStefano Zampini PetscBool cong; 1046a8116848SStefano Zampini MPI_Comm comm; 1047a8116848SStefano Zampini 1048a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1049306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1050306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1051306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1052306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1053306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1054a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1055a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1056a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1057a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1058a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1059306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1060a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1061a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1062f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1063a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 10643d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 10653d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1066a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1067a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1068a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1069a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1070a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 10713d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1072a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1073a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 10743d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1075a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1076a8116848SStefano Zampini lidxs[newloc] = i; 1077a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1078a8116848SStefano Zampini } 1079a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1080a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1081306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1082a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1083a8116848SStefano Zampini /* local is to extract local submatrix */ 1084a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1085a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 108694342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 108794342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1088a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1089a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1090a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1091a8116848SStefano Zampini } else { 1092a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1093a8116848SStefano Zampini 1094a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1095a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1096f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1097a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 10983d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1099a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1100a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1101a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1102a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1103a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 11043d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1105a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1106a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 11073d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1108a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1109a8116848SStefano Zampini lidxs[newloc] = i; 1110a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1111a8116848SStefano Zampini } 1112a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1113a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1114306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1115a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1116a8116848SStefano Zampini /* local is to extract local submatrix */ 1117a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1118a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1119a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1120a8116848SStefano Zampini } 1121a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1122a8116848SStefano Zampini } else { 1123a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1124a8116848SStefano Zampini } 1125a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1126a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 11277dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1128a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1129a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1130a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1131a8116848SStefano Zampini } 1132a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1133a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1134a8116848SStefano Zampini PetscFunctionReturn(0); 1135a8116848SStefano Zampini } 1136a8116848SStefano Zampini 1137a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 11382b404112SStefano Zampini { 11392b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 11402b404112SStefano Zampini PetscBool ismatis; 11412b404112SStefano Zampini PetscErrorCode ierr; 11422b404112SStefano Zampini 11432b404112SStefano Zampini PetscFunctionBegin; 11442b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 11452b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 11462b404112SStefano Zampini b = (Mat_IS*)B->data; 11472b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1148cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 11492b404112SStefano Zampini PetscFunctionReturn(0); 11502b404112SStefano Zampini } 11512b404112SStefano Zampini 1152a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 11536bd84002SStefano Zampini { 1154527b2640SStefano Zampini Vec v; 1155527b2640SStefano Zampini const PetscScalar *array; 1156527b2640SStefano Zampini PetscInt i,n; 11576bd84002SStefano Zampini PetscErrorCode ierr; 11586bd84002SStefano Zampini 11596bd84002SStefano Zampini PetscFunctionBegin; 1160527b2640SStefano Zampini *missing = PETSC_FALSE; 1161527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1162527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1163527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1164527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1165527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1166527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1167527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1168527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1169527b2640SStefano Zampini if (d) { 1170527b2640SStefano Zampini *d = -1; 1171527b2640SStefano Zampini if (*missing) { 1172527b2640SStefano Zampini PetscInt rstart; 1173527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1174527b2640SStefano Zampini *d = i+rstart; 1175527b2640SStefano Zampini } 1176527b2640SStefano Zampini } 11776bd84002SStefano Zampini PetscFunctionReturn(0); 11786bd84002SStefano Zampini } 11796bd84002SStefano Zampini 1180cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 118128f4e0baSStefano Zampini { 118228f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 118328f4e0baSStefano Zampini const PetscInt *gidxs; 11844f2d7cafSStefano Zampini PetscInt nleaves; 118528f4e0baSStefano Zampini PetscErrorCode ierr; 118628f4e0baSStefano Zampini 118728f4e0baSStefano Zampini PetscFunctionBegin; 11884f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 118975d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 119075d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 119128f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 11923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 11934f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 11944f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 11953bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 11964f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1197a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 11983d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1199a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1200a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 12013d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1202a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 12033d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1204a8116848SStefano Zampini } else { 1205a8116848SStefano Zampini matis->csf = matis->sf; 1206a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1207a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1208a8116848SStefano Zampini } 120928f4e0baSStefano Zampini PetscFunctionReturn(0); 121028f4e0baSStefano Zampini } 12112e1947a5SStefano Zampini 1212eb82efa4SStefano Zampini /*@ 121375d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 121475d48cdbSStefano Zampini 121575d48cdbSStefano Zampini Collective on MPI_Comm 121675d48cdbSStefano Zampini 121775d48cdbSStefano Zampini Input Parameters: 121875d48cdbSStefano Zampini + A - the matrix 121975d48cdbSStefano Zampini - store - the boolean flag 122075d48cdbSStefano Zampini 122175d48cdbSStefano Zampini Level: advanced 122275d48cdbSStefano Zampini 122375d48cdbSStefano Zampini Notes: 122475d48cdbSStefano Zampini 122575d48cdbSStefano Zampini .keywords: matrix 122675d48cdbSStefano Zampini 122775d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 122875d48cdbSStefano Zampini @*/ 122975d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 123075d48cdbSStefano Zampini { 123175d48cdbSStefano Zampini PetscErrorCode ierr; 123275d48cdbSStefano Zampini 123375d48cdbSStefano Zampini PetscFunctionBegin; 123475d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 123575d48cdbSStefano Zampini PetscValidType(A,1); 123675d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 123775d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 123875d48cdbSStefano Zampini PetscFunctionReturn(0); 123975d48cdbSStefano Zampini } 124075d48cdbSStefano Zampini 124175d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 124275d48cdbSStefano Zampini { 124375d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 124475d48cdbSStefano Zampini PetscErrorCode ierr; 124575d48cdbSStefano Zampini 124675d48cdbSStefano Zampini PetscFunctionBegin; 124775d48cdbSStefano Zampini matis->storel2l = store; 124875d48cdbSStefano Zampini if (!store) { 124975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 125075d48cdbSStefano Zampini } 125175d48cdbSStefano Zampini PetscFunctionReturn(0); 125275d48cdbSStefano Zampini } 125375d48cdbSStefano Zampini 125475d48cdbSStefano Zampini /*@ 1255a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1256a88811baSStefano Zampini 1257a88811baSStefano Zampini Collective on MPI_Comm 1258a88811baSStefano Zampini 1259a88811baSStefano Zampini Input Parameters: 1260a88811baSStefano Zampini + B - the matrix 1261a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1262a88811baSStefano Zampini (same value is used for all local rows) 1263a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1264a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1265a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1266a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1267a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1268a88811baSStefano Zampini the diagonal entry even if it is zero. 1269a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1270a88811baSStefano Zampini submatrix (same value is used for all local rows). 1271a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1272a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1273a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1274a88811baSStefano Zampini structure. The size of this array is equal to the number 1275a88811baSStefano Zampini of local rows, i.e 'm'. 1276a88811baSStefano Zampini 1277a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1278a88811baSStefano Zampini 1279a88811baSStefano Zampini Level: intermediate 1280a88811baSStefano Zampini 128195452b02SPatrick Sanan Notes: 128295452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1283a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1284a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1285a88811baSStefano Zampini 1286a88811baSStefano Zampini .keywords: matrix 1287a88811baSStefano Zampini 12883c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1289a88811baSStefano Zampini @*/ 12902e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 12912e1947a5SStefano Zampini { 12922e1947a5SStefano Zampini PetscErrorCode ierr; 12932e1947a5SStefano Zampini 12942e1947a5SStefano Zampini PetscFunctionBegin; 12952e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 12962e1947a5SStefano Zampini PetscValidType(B,1); 12972e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 12982e1947a5SStefano Zampini PetscFunctionReturn(0); 12992e1947a5SStefano Zampini } 13002e1947a5SStefano Zampini 1301844bd0d7SStefano Zampini /* this is used by DMDA */ 1302844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 13032e1947a5SStefano Zampini { 13042e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 130528f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 13062e1947a5SStefano Zampini PetscErrorCode ierr; 13072e1947a5SStefano Zampini 13082e1947a5SStefano Zampini PetscFunctionBegin; 13096c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1310cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 13114f2d7cafSStefano Zampini 13124f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 13134f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 13144f2d7cafSStefano Zampini 13154f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 13164f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 13174f2d7cafSStefano Zampini 131828f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 131928f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 132028f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 132128f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13224f2d7cafSStefano Zampini 13234f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 132428f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 13250f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 13260f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 13270f2f62c7SStefano Zampini #endif 13284f2d7cafSStefano Zampini 13294f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 133028f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 13314f2d7cafSStefano Zampini 13324f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 133328f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 13340f2f62c7SStefano Zampini 13350f2f62c7SStefano Zampini /* for other matrix types */ 13360f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 13372e1947a5SStefano Zampini PetscFunctionReturn(0); 13382e1947a5SStefano Zampini } 1339b4319ba4SBarry Smith 13403927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 13413927de2eSStefano Zampini { 13423927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 13433927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1344ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 13453927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 13463927de2eSStefano Zampini PetscInt lrows,lcols; 13473927de2eSStefano Zampini PetscInt local_rows,local_cols; 13483927de2eSStefano Zampini PetscMPIInt nsubdomains; 13493927de2eSStefano Zampini PetscBool isdense,issbaij; 13503927de2eSStefano Zampini PetscErrorCode ierr; 13513927de2eSStefano Zampini 13523927de2eSStefano Zampini PetscFunctionBegin; 13533927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 13543927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 13553927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 13563927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 13573927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 13583927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1359ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1360ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 13617230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1362ecf5a873SStefano Zampini } else { 1363ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1364ecf5a873SStefano Zampini } 1365ecf5a873SStefano Zampini 13663927de2eSStefano Zampini if (issbaij) { 13673927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 13683927de2eSStefano Zampini } 13693927de2eSStefano Zampini /* 1370ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 13713927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 13723927de2eSStefano Zampini */ 1373cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 13743927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 13753927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 13763927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 13773927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 13783927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 13793927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 13803927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 13813927de2eSStefano Zampini row_ownership[j] = i; 13823927de2eSStefano Zampini } 13833927de2eSStefano Zampini } 13847230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 13853927de2eSStefano Zampini 13863927de2eSStefano Zampini /* 13873927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 13883927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 13893927de2eSStefano Zampini */ 13903927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 13913927de2eSStefano Zampini /* preallocation as a MATAIJ */ 13923927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 13933927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 139412dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 139512dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1396ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 13973927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 13983927de2eSStefano Zampini my_dnz[i] += 1; 13993927de2eSStefano Zampini } else { /* offdiag block */ 14003927de2eSStefano Zampini my_onz[i] += 1; 14013927de2eSStefano Zampini } 14023927de2eSStefano Zampini } 14033927de2eSStefano Zampini } 1404bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1405bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1406bb1015c3SStefano Zampini PetscBool done; 1407bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1408938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1409bb1015c3SStefano Zampini jptr = jj; 1410bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1411bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1412bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1413bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1414bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1415bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1416bb1015c3SStefano Zampini my_dnz[i] += 1; 1417bb1015c3SStefano Zampini } else { /* offdiag block */ 1418bb1015c3SStefano Zampini my_onz[i] += 1; 1419bb1015c3SStefano Zampini } 1420bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1421bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1422bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1423bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1424bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1425bb1015c3SStefano Zampini } else { 1426bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1427bb1015c3SStefano Zampini } 1428bb1015c3SStefano Zampini } 1429bb1015c3SStefano Zampini } 1430bb1015c3SStefano Zampini } 1431bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1432938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1433bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 14343927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 14353927de2eSStefano Zampini const PetscInt *cols; 1436ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 14373927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 14383927de2eSStefano Zampini for (j=0;j<ncols;j++) { 14393927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1440ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 14413927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 14423927de2eSStefano Zampini my_dnz[i] += 1; 14433927de2eSStefano Zampini } else { /* offdiag block */ 14443927de2eSStefano Zampini my_onz[i] += 1; 14453927de2eSStefano Zampini } 14463927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1447d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 14483927de2eSStefano Zampini owner = row_ownership[index_col]; 14493927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1450d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 14513927de2eSStefano Zampini } else { 1452d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 14533927de2eSStefano Zampini } 14543927de2eSStefano Zampini } 14553927de2eSStefano Zampini } 14563927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 14573927de2eSStefano Zampini } 14583927de2eSStefano Zampini } 1459ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 14607230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1461ecf5a873SStefano Zampini } 14624f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 14633927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1464ecf5a873SStefano Zampini 1465ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 14663927de2eSStefano Zampini if (maxreduce) { 14673927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 14683927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1469bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 14703927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 14713927de2eSStefano Zampini } else { 14723927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 14733927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1474bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 14753927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 14763927de2eSStefano Zampini } 14773927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 14783927de2eSStefano Zampini 14793927de2eSStefano Zampini /* Resize preallocation if overestimated */ 14803927de2eSStefano Zampini for (i=0;i<lrows;i++) { 14813927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 14823927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 14833927de2eSStefano Zampini } 14841670daf9Sstefano_zampini 14851670daf9Sstefano_zampini /* Set preallocation */ 1486268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 14873927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 14883927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 14893927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 14903927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 14913927de2eSStefano Zampini } 1492268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 14933927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 14943927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 14953927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 14963927de2eSStefano Zampini if (issbaij) { 14973927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 14983927de2eSStefano Zampini } 1499*9be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 15003927de2eSStefano Zampini PetscFunctionReturn(0); 15013927de2eSStefano Zampini } 15023927de2eSStefano Zampini 15037230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1504b7ce53b6SStefano Zampini { 1505b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1506d9a9e74cSStefano Zampini Mat local_mat; 1507b7ce53b6SStefano Zampini /* info on mat */ 15083cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1509b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1510b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1511b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1512b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1513b9ed4604SStefano Zampini #endif 15147c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1515b7ce53b6SStefano Zampini /* values insertion */ 1516b7ce53b6SStefano Zampini PetscScalar *array; 1517b7ce53b6SStefano Zampini /* work */ 1518b7ce53b6SStefano Zampini PetscErrorCode ierr; 1519b7ce53b6SStefano Zampini 1520b7ce53b6SStefano Zampini PetscFunctionBegin; 1521b7ce53b6SStefano Zampini /* get info from mat */ 15227c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 15237c03b4e8SStefano Zampini if (nsubdomains == 1) { 15241670daf9Sstefano_zampini Mat B; 15251670daf9Sstefano_zampini IS rows,cols; 1526acdf38a7Sstefano_zampini IS irows,icols; 15271670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 15281670daf9Sstefano_zampini 15291670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 15301670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 15311670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 15321670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 1533acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1534acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1535acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1536acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1537268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 1538268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1539acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1540acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 15416104e0f1Sstefano_zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 15427dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1543acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1544acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1545acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 15467c03b4e8SStefano Zampini PetscFunctionReturn(0); 15477c03b4e8SStefano Zampini } 1548b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1549b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 15503cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1551b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1552b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 15534099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1554b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1555b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1556b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1557b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1558b9ed4604SStefano Zampini lb[0] = isseqdense; 1559b9ed4604SStefano Zampini lb[1] = isseqaij; 1560b9ed4604SStefano Zampini lb[2] = isseqbaij; 1561b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1562b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1563b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1564b9ed4604SStefano Zampini #endif 1565b7ce53b6SStefano Zampini 1566b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 15673927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 15683cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 1569b9ed4604SStefano Zampini if (!isseqsbaij) { 1570b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1571b9ed4604SStefano Zampini } else { 1572b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1573b9ed4604SStefano Zampini } 1574d59cf9ebSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 15753927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1576b7ce53b6SStefano Zampini } else { 15773cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1578b7ce53b6SStefano Zampini /* some checks */ 1579b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1580b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 15813cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 15826c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 15836c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 15846c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 15856c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 15866c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1587b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1588b7ce53b6SStefano Zampini } 1589d9a9e74cSStefano Zampini 1590b9ed4604SStefano Zampini if (isseqsbaij) { 1591d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1592d9a9e74cSStefano Zampini } else { 1593d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1594d9a9e74cSStefano Zampini local_mat = matis->A; 1595d9a9e74cSStefano Zampini } 1596686e3a49SStefano Zampini 1597b7ce53b6SStefano Zampini /* Set values */ 1598ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1599b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 160065066ba5SStefano Zampini PetscInt i,*dummy; 1601ecf5a873SStefano Zampini 160265066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 160365066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 1604b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1605d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 160665066ba5SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 1607d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 160865066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 1609686e3a49SStefano Zampini } else if (isseqaij) { 1610ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1611686e3a49SStefano Zampini PetscBool done; 1612686e3a49SStefano Zampini 1613d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1614938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1615d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1616686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1617ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1618686e3a49SStefano Zampini } 1619d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1620938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1621d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1622686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1623ecf5a873SStefano Zampini PetscInt i; 1624c0962df8SStefano Zampini 1625686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1626686e3a49SStefano Zampini PetscInt j; 1627ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1628686e3a49SStefano Zampini 1629ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1630ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1631ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1632686e3a49SStefano Zampini } 1633b7ce53b6SStefano Zampini } 1634b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1635d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1636b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1637b9ed4604SStefano Zampini if (isseqdense) { 1638b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1639b7ce53b6SStefano Zampini } 1640b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1641b7ce53b6SStefano Zampini } 1642b7ce53b6SStefano Zampini 1643b7ce53b6SStefano Zampini /*@ 1644b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1645b7ce53b6SStefano Zampini 1646b7ce53b6SStefano Zampini Input Parameter: 1647b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1648b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1649b7ce53b6SStefano Zampini 1650b7ce53b6SStefano Zampini Output Parameter: 1651b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1652b7ce53b6SStefano Zampini 1653b7ce53b6SStefano Zampini Level: developer 1654b7ce53b6SStefano Zampini 165595452b02SPatrick Sanan Notes: 165695452b02SPatrick Sanan mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1657b7ce53b6SStefano Zampini 1658b7ce53b6SStefano Zampini .seealso: MATIS 1659b7ce53b6SStefano Zampini @*/ 1660b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1661b7ce53b6SStefano Zampini { 1662b7ce53b6SStefano Zampini PetscErrorCode ierr; 1663b7ce53b6SStefano Zampini 1664b7ce53b6SStefano Zampini PetscFunctionBegin; 1665b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1666b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1667b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1668b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1669b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1670b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 16716c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1672b7ce53b6SStefano Zampini } 1673b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1674b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1675b7ce53b6SStefano Zampini } 1676b7ce53b6SStefano Zampini 1677ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1678ad6194a2SStefano Zampini { 1679ad6194a2SStefano Zampini PetscErrorCode ierr; 1680ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1681ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1682ad6194a2SStefano Zampini Mat B,localmat; 1683ad6194a2SStefano Zampini 1684ad6194a2SStefano Zampini PetscFunctionBegin; 1685ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1686ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1687ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1688e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1689ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1690ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1691b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1692b0f2910eSStefano Zampini if (matis->sf) { 1693b0f2910eSStefano Zampini Mat_IS *bmatis = (Mat_IS*)(B->data); 1694b0f2910eSStefano Zampini 1695b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->sf);CHKERRQ(ierr); 1696b0f2910eSStefano Zampini bmatis->sf = matis->sf; 1697b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&bmatis->sf_rootdata,matis->sf->nleaves,&bmatis->sf_leafdata);CHKERRQ(ierr); 1698b0f2910eSStefano Zampini if (matis->sf != matis->csf) { 1699b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->csf);CHKERRQ(ierr); 1700b0f2910eSStefano Zampini bmatis->csf = matis->csf; 1701b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&bmatis->csf_rootdata,matis->csf->nleaves,&bmatis->csf_leafdata);CHKERRQ(ierr); 1702b0f2910eSStefano Zampini } else { 1703b0f2910eSStefano Zampini bmatis->csf = bmatis->sf; 1704b0f2910eSStefano Zampini bmatis->csf_leafdata = bmatis->sf_leafdata; 1705b0f2910eSStefano Zampini bmatis->csf_rootdata = bmatis->sf_rootdata; 1706b0f2910eSStefano Zampini } 1707b0f2910eSStefano Zampini } 1708ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1709ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1710ad6194a2SStefano Zampini *newmat = B; 1711ad6194a2SStefano Zampini PetscFunctionReturn(0); 1712ad6194a2SStefano Zampini } 1713ad6194a2SStefano Zampini 1714a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 171569796d55SStefano Zampini { 171669796d55SStefano Zampini PetscErrorCode ierr; 171769796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 171869796d55SStefano Zampini PetscBool local_sym; 171969796d55SStefano Zampini 172069796d55SStefano Zampini PetscFunctionBegin; 172169796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1722b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 172369796d55SStefano Zampini PetscFunctionReturn(0); 172469796d55SStefano Zampini } 172569796d55SStefano Zampini 1726a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 172769796d55SStefano Zampini { 172869796d55SStefano Zampini PetscErrorCode ierr; 172969796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 173069796d55SStefano Zampini PetscBool local_sym; 173169796d55SStefano Zampini 173269796d55SStefano Zampini PetscFunctionBegin; 173369796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1734b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 173569796d55SStefano Zampini PetscFunctionReturn(0); 173669796d55SStefano Zampini } 173769796d55SStefano Zampini 173845471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 173945471136SStefano Zampini { 174045471136SStefano Zampini PetscErrorCode ierr; 174145471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 174245471136SStefano Zampini PetscBool local_sym; 174345471136SStefano Zampini 174445471136SStefano Zampini PetscFunctionBegin; 174545471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 174645471136SStefano Zampini *flg = PETSC_FALSE; 174745471136SStefano Zampini PetscFunctionReturn(0); 174845471136SStefano Zampini } 174945471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 175045471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 175145471136SStefano Zampini PetscFunctionReturn(0); 175245471136SStefano Zampini } 175345471136SStefano Zampini 1754a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1755b4319ba4SBarry Smith { 1756dfbe8321SBarry Smith PetscErrorCode ierr; 1757b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1758b4319ba4SBarry Smith 1759b4319ba4SBarry Smith PetscFunctionBegin; 17606bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1761e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1762e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 17636bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 17646bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 17653fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1766a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1767a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1768a8116848SStefano Zampini if (b->sf != b->csf) { 1769a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1770a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1771a8116848SStefano Zampini } 177228f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 177328f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1774bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1775dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1776bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1777b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1778b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 17792e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1780cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 178175d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 1782b4319ba4SBarry Smith PetscFunctionReturn(0); 1783b4319ba4SBarry Smith } 1784b4319ba4SBarry Smith 1785a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1786b4319ba4SBarry Smith { 1787dfbe8321SBarry Smith PetscErrorCode ierr; 1788b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1789b4319ba4SBarry Smith PetscScalar zero = 0.0; 1790b4319ba4SBarry Smith 1791b4319ba4SBarry Smith PetscFunctionBegin; 1792b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1793e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1794e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1795b4319ba4SBarry Smith 1796b4319ba4SBarry Smith /* multiply the local matrix */ 1797b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1798b4319ba4SBarry Smith 1799b4319ba4SBarry Smith /* scatter product back into global memory */ 18002dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1801e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1802e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1803b4319ba4SBarry Smith PetscFunctionReturn(0); 1804b4319ba4SBarry Smith } 1805b4319ba4SBarry Smith 1806a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 18072e74eeadSLisandro Dalcin { 1808650997f4SStefano Zampini Vec temp_vec; 18092e74eeadSLisandro Dalcin PetscErrorCode ierr; 18102e74eeadSLisandro Dalcin 18112e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1812650997f4SStefano Zampini if (v3 != v2) { 1813650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1814650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1815650997f4SStefano Zampini } else { 1816650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1817650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1818650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1819650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1820650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1821650997f4SStefano Zampini } 18222e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18232e74eeadSLisandro Dalcin } 18242e74eeadSLisandro Dalcin 1825a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 18262e74eeadSLisandro Dalcin { 18272e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 18282e74eeadSLisandro Dalcin PetscErrorCode ierr; 18292e74eeadSLisandro Dalcin 1830e176bc59SStefano Zampini PetscFunctionBegin; 18312e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1832e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1833e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18342e74eeadSLisandro Dalcin 18352e74eeadSLisandro Dalcin /* multiply the local matrix */ 1836e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 18372e74eeadSLisandro Dalcin 18382e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1839e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1840e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1841e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18422e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18432e74eeadSLisandro Dalcin } 18442e74eeadSLisandro Dalcin 1845a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 18462e74eeadSLisandro Dalcin { 1847650997f4SStefano Zampini Vec temp_vec; 18482e74eeadSLisandro Dalcin PetscErrorCode ierr; 18492e74eeadSLisandro Dalcin 18502e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1851650997f4SStefano Zampini if (v3 != v2) { 1852650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1853650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1854650997f4SStefano Zampini } else { 1855650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1856650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1857650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1858650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1859650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1860650997f4SStefano Zampini } 18612e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18622e74eeadSLisandro Dalcin } 18632e74eeadSLisandro Dalcin 1864a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1865b4319ba4SBarry Smith { 1866b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1867dfbe8321SBarry Smith PetscErrorCode ierr; 1868b4319ba4SBarry Smith PetscViewer sviewer; 1869ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1870b4319ba4SBarry Smith 1871b4319ba4SBarry Smith PetscFunctionBegin; 1872ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1873ee2491ecSStefano Zampini if (isascii) { 1874ee2491ecSStefano Zampini PetscViewerFormat format; 1875ee2491ecSStefano Zampini 1876ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1877ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1878ee2491ecSStefano Zampini } 1879ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 18803f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1881b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 18823f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 18836e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1884b4319ba4SBarry Smith PetscFunctionReturn(0); 1885b4319ba4SBarry Smith } 1886b4319ba4SBarry Smith 1887a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1888b4319ba4SBarry Smith { 1889dfbe8321SBarry Smith PetscErrorCode ierr; 1890e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1891b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1892b4319ba4SBarry Smith IS from,to; 1893e176bc59SStefano Zampini Vec cglobal,rglobal; 1894b4319ba4SBarry Smith 1895b4319ba4SBarry Smith PetscFunctionBegin; 1896784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1897e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 18983bbff08aSStefano Zampini /* Destroy any previous data */ 189970cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 190070cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 19013fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1902e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1903e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 19041c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 1905872cf891SStefano Zampini if (is->csf != is->sf) { 1906872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 1907872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 1908872cf891SStefano Zampini } 190928f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 191028f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 19113bbff08aSStefano Zampini 19123bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1913fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1914fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1915e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1916e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1917e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1918e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 19196625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 19206625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 19216625354bSStefano Zampini PetscBool same,gsame; 19226625354bSStefano Zampini 19236625354bSStefano Zampini same = PETSC_FALSE; 19246625354bSStefano Zampini if (nr == nc && cbs == rbs) { 19256625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 19266625354bSStefano Zampini 19276625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 19286625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 19296625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 19306625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 19316625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 19326625354bSStefano Zampini } 19336625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 19346625354bSStefano Zampini if (gsame) cmapping = rmapping; 19356625354bSStefano Zampini } 19366625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 19376625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 19386625354bSStefano Zampini 19396625354bSStefano Zampini /* Create the local matrix A */ 1940f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1941e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1942e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1943e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1944ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1945ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1946b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1947c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 1948c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 1949b4319ba4SBarry Smith 1950f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1951b4319ba4SBarry Smith /* Create the local work vectors */ 19523bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1953b4319ba4SBarry Smith 1954e176bc59SStefano Zampini /* setup the global to local scatters */ 1955e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1956e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1957784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1958e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1959e176bc59SStefano Zampini if (rmapping != cmapping) { 1960e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1961e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1962e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1963e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1964e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1965e176bc59SStefano Zampini } else { 1966e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1967e176bc59SStefano Zampini is->cctx = is->rctx; 1968e176bc59SStefano Zampini } 19693fd1c9e7SStefano Zampini 19703fd1c9e7SStefano Zampini /* interface counter vector (local) */ 19713fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 19723fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 19733fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19743fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19753fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19763fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19773fd1c9e7SStefano Zampini 19783fd1c9e7SStefano Zampini /* free workspace */ 1979e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1980e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 19816bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 19826bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1983f26d0771SStefano Zampini } 198448ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1985b4319ba4SBarry Smith PetscFunctionReturn(0); 1986b4319ba4SBarry Smith } 1987b4319ba4SBarry Smith 1988a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 19892e74eeadSLisandro Dalcin { 19902e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 19912e74eeadSLisandro Dalcin PetscErrorCode ierr; 199297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 199397563a80SStefano Zampini PetscInt i,zm,zn; 199497563a80SStefano Zampini #endif 1995f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 19962e74eeadSLisandro Dalcin 19972e74eeadSLisandro Dalcin PetscFunctionBegin; 19982e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1999f26d0771SStefano 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); 200097563a80SStefano Zampini /* count negative indices */ 200197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 200297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 20032e74eeadSLisandro Dalcin #endif 200497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 200597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 200697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 200797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 200897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 200997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2010b4f971dfSStefano 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"); 2011b4f971dfSStefano 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"); 201297563a80SStefano Zampini #endif 20132e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 20142e74eeadSLisandro Dalcin PetscFunctionReturn(0); 20152e74eeadSLisandro Dalcin } 20162e74eeadSLisandro Dalcin 2017a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 201897563a80SStefano Zampini { 201997563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 202097563a80SStefano Zampini PetscErrorCode ierr; 202197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 202297563a80SStefano Zampini PetscInt i,zm,zn; 202397563a80SStefano Zampini #endif 2024f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 202597563a80SStefano Zampini 202697563a80SStefano Zampini PetscFunctionBegin; 202797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2028f26d0771SStefano 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); 202997563a80SStefano Zampini /* count negative indices */ 203097563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 203197563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 203297563a80SStefano Zampini #endif 203397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 203497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 203597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 203697563a80SStefano Zampini /* count negative indices (should be the same as before) */ 203797563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 203897563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2039b4f971dfSStefano 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"); 2040b4f971dfSStefano 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"); 204197563a80SStefano Zampini #endif 2042d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 204397563a80SStefano Zampini PetscFunctionReturn(0); 204497563a80SStefano Zampini } 204597563a80SStefano Zampini 2046a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2047b4319ba4SBarry Smith { 2048dfbe8321SBarry Smith PetscErrorCode ierr; 2049b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2050b4319ba4SBarry Smith 2051b4319ba4SBarry Smith PetscFunctionBegin; 2052b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2053872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2054872cf891SStefano Zampini } else { 2055b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2056872cf891SStefano Zampini } 2057b4319ba4SBarry Smith PetscFunctionReturn(0); 2058b4319ba4SBarry Smith } 2059b4319ba4SBarry Smith 2060a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2061f0006bf2SLisandro Dalcin { 2062f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2063f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2064f0006bf2SLisandro Dalcin 2065f0006bf2SLisandro Dalcin PetscFunctionBegin; 2066b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2067b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2068b4f971dfSStefano Zampini PetscInt ibs,bs; 2069b4f971dfSStefano Zampini 2070b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2071b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2072b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2073b4f971dfSStefano Zampini #endif 2074b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2075b4f971dfSStefano Zampini } else { 2076f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2077b4f971dfSStefano Zampini } 2078f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2079f0006bf2SLisandro Dalcin } 2080f0006bf2SLisandro Dalcin 2081f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2082f0ae7da4SStefano Zampini { 2083f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2084f0ae7da4SStefano Zampini PetscErrorCode ierr; 2085f0ae7da4SStefano Zampini 2086f0ae7da4SStefano Zampini PetscFunctionBegin; 2087f0ae7da4SStefano Zampini if (!n) { 2088f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2089f0ae7da4SStefano Zampini } else { 2090f0ae7da4SStefano Zampini PetscInt i; 2091f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2092f0ae7da4SStefano Zampini 2093f0ae7da4SStefano Zampini if (columns) { 2094f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2095f0ae7da4SStefano Zampini } else { 2096f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2097f0ae7da4SStefano Zampini } 2098f0ae7da4SStefano Zampini if (diag != 0.) { 2099f0ae7da4SStefano Zampini const PetscScalar *array; 2100f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2101f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2102f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2103f0ae7da4SStefano Zampini } 2104f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2105f0ae7da4SStefano Zampini } 2106f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2107f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2108f0ae7da4SStefano Zampini } 2109f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2110f0ae7da4SStefano Zampini } 2111f0ae7da4SStefano Zampini 2112f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 21132e74eeadSLisandro Dalcin { 21146e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 21156e520ac8SStefano Zampini PetscInt nr,nl,len,i; 21166e520ac8SStefano Zampini PetscInt *lrows; 21172e74eeadSLisandro Dalcin PetscErrorCode ierr; 21182e74eeadSLisandro Dalcin 21192e74eeadSLisandro Dalcin PetscFunctionBegin; 2120f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2121f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2122f0ae7da4SStefano Zampini PetscBool cong; 212326b0207aSStefano Zampini 2124f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 212526b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2126268753edSStefano 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"); 2127268753edSStefano 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"); 2128268753edSStefano 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"); 2129f0ae7da4SStefano Zampini } 2130f0ae7da4SStefano Zampini #endif 21316e520ac8SStefano Zampini /* get locally owned rows */ 2132f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 21336e520ac8SStefano Zampini /* fix right hand side if needed */ 21346e520ac8SStefano Zampini if (x && b) { 21356e520ac8SStefano Zampini const PetscScalar *xx; 21366e520ac8SStefano Zampini PetscScalar *bb; 21376e520ac8SStefano Zampini 21386e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 21396e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 21406e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 21416e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 21426e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 21432e74eeadSLisandro Dalcin } 21446e520ac8SStefano Zampini /* get rows associated to the local matrices */ 21453d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 21466e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 21476e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 21486e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 21496e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 21506e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 21516e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 21526e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 21536e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 21546e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2155f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 21566e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 21572e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21582e74eeadSLisandro Dalcin } 21592e74eeadSLisandro Dalcin 2160f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2161b4319ba4SBarry Smith { 2162dfbe8321SBarry Smith PetscErrorCode ierr; 2163b4319ba4SBarry Smith 2164b4319ba4SBarry Smith PetscFunctionBegin; 2165f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2166f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2167f0ae7da4SStefano Zampini } 21682205254eSKarl Rupp 2169f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2170f0ae7da4SStefano Zampini { 2171f0ae7da4SStefano Zampini PetscErrorCode ierr; 2172f0ae7da4SStefano Zampini 2173f0ae7da4SStefano Zampini PetscFunctionBegin; 2174f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2175b4319ba4SBarry Smith PetscFunctionReturn(0); 2176b4319ba4SBarry Smith } 2177b4319ba4SBarry Smith 2178a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2179b4319ba4SBarry Smith { 2180b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2181dfbe8321SBarry Smith PetscErrorCode ierr; 2182b4319ba4SBarry Smith 2183b4319ba4SBarry Smith PetscFunctionBegin; 2184b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2185b4319ba4SBarry Smith PetscFunctionReturn(0); 2186b4319ba4SBarry Smith } 2187b4319ba4SBarry Smith 2188a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2189b4319ba4SBarry Smith { 2190b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2191dfbe8321SBarry Smith PetscErrorCode ierr; 2192b4319ba4SBarry Smith 2193b4319ba4SBarry Smith PetscFunctionBegin; 2194b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2195872cf891SStefano Zampini /* fix for local empty rows/cols */ 2196872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2197872cf891SStefano Zampini Mat newlA; 2198872cf891SStefano Zampini ISLocalToGlobalMapping l2g; 2199872cf891SStefano Zampini IS tis; 2200872cf891SStefano Zampini const PetscScalar *v; 2201872cf891SStefano Zampini PetscInt i,n,cf,*loce,*locf; 2202872cf891SStefano Zampini PetscBool sym; 2203872cf891SStefano Zampini 2204872cf891SStefano Zampini ierr = MatGetRowMaxAbs(is->A,is->y,NULL);CHKERRQ(ierr); 2205872cf891SStefano Zampini ierr = MatIsSymmetric(is->A,PETSC_SMALL,&sym);CHKERRQ(ierr); 2206872cf891SStefano Zampini if (!sym) SETERRQ(PetscObjectComm((PetscObject)is->A),PETSC_ERR_SUP,"Not yet implemented for unsymmetric case"); 2207872cf891SStefano Zampini ierr = VecGetLocalSize(is->y,&n);CHKERRQ(ierr); 2208872cf891SStefano Zampini ierr = PetscMalloc1(n,&loce);CHKERRQ(ierr); 2209872cf891SStefano Zampini ierr = PetscMalloc1(n,&locf);CHKERRQ(ierr); 2210872cf891SStefano Zampini ierr = VecGetArrayRead(is->y,&v);CHKERRQ(ierr); 2211872cf891SStefano Zampini for (i=0,cf=0;i<n;i++) { 2212872cf891SStefano Zampini if (v[i] == 0.0) { 2213872cf891SStefano Zampini loce[i] = -1; 2214872cf891SStefano Zampini } else { 2215872cf891SStefano Zampini loce[i] = cf; 2216872cf891SStefano Zampini locf[cf++] = i; 2217872cf891SStefano Zampini } 2218872cf891SStefano Zampini } 2219872cf891SStefano Zampini ierr = VecRestoreArrayRead(is->y,&v);CHKERRQ(ierr); 2220872cf891SStefano Zampini /* extract valid submatrix */ 2221872cf891SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A),cf,locf,PETSC_USE_POINTER,&tis);CHKERRQ(ierr); 2222e5b89577SStefano Zampini ierr = MatCreateSubMatrix(is->A,tis,tis,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2223872cf891SStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2224872cf891SStefano Zampini /* attach local l2g map for successive calls of MatSetValues */ 2225872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)is->A),1,n,loce,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 2226872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,l2g,l2g);CHKERRQ(ierr); 2227872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2228872cf891SStefano Zampini /* attach new global l2g map */ 2229872cf891SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,cf,locf,locf);CHKERRQ(ierr); 2230872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,cf,locf,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 2231872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,l2g,l2g);CHKERRQ(ierr); 2232872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2233872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2234872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2235872cf891SStefano Zampini } 2236872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2237b4319ba4SBarry Smith PetscFunctionReturn(0); 2238b4319ba4SBarry Smith } 2239b4319ba4SBarry Smith 2240a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2241b4319ba4SBarry Smith { 2242b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2243b4319ba4SBarry Smith 2244b4319ba4SBarry Smith PetscFunctionBegin; 2245b4319ba4SBarry Smith *local = is->A; 2246b4319ba4SBarry Smith PetscFunctionReturn(0); 2247b4319ba4SBarry Smith } 2248b4319ba4SBarry Smith 22493b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 22503b3b1effSJed Brown { 22513b3b1effSJed Brown PetscFunctionBegin; 22523b3b1effSJed Brown *local = NULL; 22533b3b1effSJed Brown PetscFunctionReturn(0); 22543b3b1effSJed Brown } 22553b3b1effSJed Brown 2256b4319ba4SBarry Smith /*@ 2257b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2258b4319ba4SBarry Smith 2259b4319ba4SBarry Smith Input Parameter: 2260b4319ba4SBarry Smith . mat - the matrix 2261b4319ba4SBarry Smith 2262b4319ba4SBarry Smith Output Parameter: 2263eb82efa4SStefano Zampini . local - the local matrix 2264b4319ba4SBarry Smith 2265b4319ba4SBarry Smith Level: advanced 2266b4319ba4SBarry Smith 2267b4319ba4SBarry Smith Notes: 2268b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2269b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2270b4319ba4SBarry Smith of the MatSetValues() operation. 2271b4319ba4SBarry Smith 22723b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 227396a6f129SJed Brown 2274b4319ba4SBarry Smith .seealso: MATIS 2275b4319ba4SBarry Smith @*/ 22767087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2277b4319ba4SBarry Smith { 22784ac538c5SBarry Smith PetscErrorCode ierr; 2279b4319ba4SBarry Smith 2280b4319ba4SBarry Smith PetscFunctionBegin; 22810700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2282b4319ba4SBarry Smith PetscValidPointer(local,2); 22834ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2284b4319ba4SBarry Smith PetscFunctionReturn(0); 2285b4319ba4SBarry Smith } 2286b4319ba4SBarry Smith 22873b3b1effSJed Brown /*@ 22883b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 22893b3b1effSJed Brown 22903b3b1effSJed Brown Input Parameter: 22913b3b1effSJed Brown . mat - the matrix 22923b3b1effSJed Brown 22933b3b1effSJed Brown Output Parameter: 22943b3b1effSJed Brown . local - the local matrix 22953b3b1effSJed Brown 22963b3b1effSJed Brown Level: advanced 22973b3b1effSJed Brown 22983b3b1effSJed Brown .seealso: MATIS 22993b3b1effSJed Brown @*/ 23003b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 23013b3b1effSJed Brown { 23023b3b1effSJed Brown PetscErrorCode ierr; 23033b3b1effSJed Brown 23043b3b1effSJed Brown PetscFunctionBegin; 23053b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 23063b3b1effSJed Brown PetscValidPointer(local,2); 23073b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 23083b3b1effSJed Brown PetscFunctionReturn(0); 23093b3b1effSJed Brown } 23103b3b1effSJed Brown 2311a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 23123b03a366Sstefano_zampini { 23133b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 23143b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 23153b03a366Sstefano_zampini PetscErrorCode ierr; 23163b03a366Sstefano_zampini 23173b03a366Sstefano_zampini PetscFunctionBegin; 23184e4c7dbeSStefano Zampini if (is->A) { 23193b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 23203b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2321f0ae7da4SStefano 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); 23224e4c7dbeSStefano Zampini } 23233b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 23243b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 23253b03a366Sstefano_zampini is->A = local; 23263b03a366Sstefano_zampini PetscFunctionReturn(0); 23273b03a366Sstefano_zampini } 23283b03a366Sstefano_zampini 23293b03a366Sstefano_zampini /*@ 2330eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 23313b03a366Sstefano_zampini 23323b03a366Sstefano_zampini Input Parameter: 23333b03a366Sstefano_zampini . mat - the matrix 2334eb82efa4SStefano Zampini . local - the local matrix 23353b03a366Sstefano_zampini 23363b03a366Sstefano_zampini Output Parameter: 23373b03a366Sstefano_zampini 23383b03a366Sstefano_zampini Level: advanced 23393b03a366Sstefano_zampini 23403b03a366Sstefano_zampini Notes: 23413b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 23423b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 23433b03a366Sstefano_zampini 23443b03a366Sstefano_zampini .seealso: MATIS 23453b03a366Sstefano_zampini @*/ 23463b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 23473b03a366Sstefano_zampini { 23483b03a366Sstefano_zampini PetscErrorCode ierr; 23493b03a366Sstefano_zampini 23503b03a366Sstefano_zampini PetscFunctionBegin; 23513b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2352b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 23533b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 23543b03a366Sstefano_zampini PetscFunctionReturn(0); 23553b03a366Sstefano_zampini } 23563b03a366Sstefano_zampini 2357a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 23586726f965SBarry Smith { 23596726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 23606726f965SBarry Smith PetscErrorCode ierr; 23616726f965SBarry Smith 23626726f965SBarry Smith PetscFunctionBegin; 23636726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 23646726f965SBarry Smith PetscFunctionReturn(0); 23656726f965SBarry Smith } 23666726f965SBarry Smith 2367a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 23682e74eeadSLisandro Dalcin { 23692e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23702e74eeadSLisandro Dalcin PetscErrorCode ierr; 23712e74eeadSLisandro Dalcin 23722e74eeadSLisandro Dalcin PetscFunctionBegin; 23732e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 23742e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23752e74eeadSLisandro Dalcin } 23762e74eeadSLisandro Dalcin 2377a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 23782e74eeadSLisandro Dalcin { 23792e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23802e74eeadSLisandro Dalcin PetscErrorCode ierr; 23812e74eeadSLisandro Dalcin 23822e74eeadSLisandro Dalcin PetscFunctionBegin; 23832e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2384e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 23852e74eeadSLisandro Dalcin 23862e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 23872e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2388e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2389e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23902e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23912e74eeadSLisandro Dalcin } 23922e74eeadSLisandro Dalcin 2393a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 23946726f965SBarry Smith { 23956726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 23966726f965SBarry Smith PetscErrorCode ierr; 23976726f965SBarry Smith 23986726f965SBarry Smith PetscFunctionBegin; 23994e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 24006726f965SBarry Smith PetscFunctionReturn(0); 24016726f965SBarry Smith } 24026726f965SBarry Smith 2403f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2404f26d0771SStefano Zampini { 2405f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2406f26d0771SStefano Zampini Mat_IS *x; 2407f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2408f26d0771SStefano Zampini PetscBool ismatis; 2409f26d0771SStefano Zampini #endif 2410f26d0771SStefano Zampini PetscErrorCode ierr; 2411f26d0771SStefano Zampini 2412f26d0771SStefano Zampini PetscFunctionBegin; 2413f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2414f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2415f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2416f26d0771SStefano Zampini #endif 2417f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2418f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2419f26d0771SStefano Zampini PetscFunctionReturn(0); 2420f26d0771SStefano Zampini } 2421f26d0771SStefano Zampini 2422f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2423f26d0771SStefano Zampini { 2424f26d0771SStefano Zampini Mat lA; 2425f26d0771SStefano Zampini Mat_IS *matis; 2426f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2427f26d0771SStefano Zampini IS is; 2428f26d0771SStefano Zampini const PetscInt *rg,*rl; 2429f26d0771SStefano Zampini PetscInt nrg; 2430f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2431f26d0771SStefano Zampini PetscErrorCode ierr; 2432f26d0771SStefano Zampini 2433f26d0771SStefano Zampini PetscFunctionBegin; 2434f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2435f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2436f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2437f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2438f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2439f0ae7da4SStefano 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 than maximum possible %D",i,rl[i],nrg); 2440f26d0771SStefano Zampini #endif 2441f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2442f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2443f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2444f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2445f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2446f26d0771SStefano Zampini #else 2447f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2448f26d0771SStefano Zampini #endif 2449f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2450f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2451f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2452f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2453f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2454f26d0771SStefano Zampini /* compute new l2g map for columns */ 2455f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2456f26d0771SStefano Zampini const PetscInt *cg,*cl; 2457f26d0771SStefano Zampini PetscInt ncg; 2458f26d0771SStefano Zampini PetscInt ncl; 2459f26d0771SStefano Zampini 2460f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2461f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2462f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2463f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2464f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2465f0ae7da4SStefano 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 than maximum possible %D",i,cl[i],ncg); 2466f26d0771SStefano Zampini #endif 2467f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2468f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2469f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2470f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2471f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2472f26d0771SStefano Zampini #else 2473f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2474f26d0771SStefano Zampini #endif 2475f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2476f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2477f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2478f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2479f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2480f26d0771SStefano Zampini } else { 2481f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2482f26d0771SStefano Zampini cl2g = rl2g; 2483f26d0771SStefano Zampini } 2484f26d0771SStefano Zampini /* create the MATIS submatrix */ 2485f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2486f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2487f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2488f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2489b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2490f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2491f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2492f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2493f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2494f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2495f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2496f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2497f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2498f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2499f26d0771SStefano Zampini /* remove unsupported ops */ 2500f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2501f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2502f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2503f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2504f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2505f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2506f26d0771SStefano Zampini PetscFunctionReturn(0); 2507f26d0771SStefano Zampini } 2508f26d0771SStefano Zampini 2509872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 2510872cf891SStefano Zampini { 2511872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 2512872cf891SStefano Zampini PetscErrorCode ierr; 2513872cf891SStefano Zampini 2514872cf891SStefano Zampini PetscFunctionBegin; 2515872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 2516872cf891SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)A); 2517872cf891SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns",NULL,a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 251875d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 2519872cf891SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 2520872cf891SStefano Zampini PetscFunctionReturn(0); 2521872cf891SStefano Zampini } 2522872cf891SStefano Zampini 2523284134d9SBarry Smith /*@ 25243c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2525284134d9SBarry Smith process but not across processes. 2526284134d9SBarry Smith 2527284134d9SBarry Smith Input Parameters: 2528284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2529e176bc59SStefano Zampini . bs - block size of the matrix 2530df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2531e176bc59SStefano Zampini . rmap - local to global map for rows 2532e176bc59SStefano Zampini - cmap - local to global map for cols 2533284134d9SBarry Smith 2534284134d9SBarry Smith Output Parameter: 2535284134d9SBarry Smith . A - the resulting matrix 2536284134d9SBarry Smith 25378e6c10adSSatish Balay Level: advanced 25388e6c10adSSatish Balay 253995452b02SPatrick Sanan Notes: 254095452b02SPatrick Sanan See MATIS for more details. 25416fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 25426fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 25433c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2544284134d9SBarry Smith 2545284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2546284134d9SBarry Smith @*/ 2547e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2548284134d9SBarry Smith { 2549284134d9SBarry Smith PetscErrorCode ierr; 2550284134d9SBarry Smith 2551284134d9SBarry Smith PetscFunctionBegin; 25526fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2553284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 2554284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 25556fdf41d1SStefano Zampini if (bs > 0) { 2556284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 25576fdf41d1SStefano Zampini } 2558284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2559e176bc59SStefano Zampini if (rmap && cmap) { 2560e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2561e176bc59SStefano Zampini } else if (!rmap) { 2562e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2563e176bc59SStefano Zampini } else { 2564e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2565e176bc59SStefano Zampini } 2566284134d9SBarry Smith PetscFunctionReturn(0); 2567284134d9SBarry Smith } 2568284134d9SBarry Smith 2569b4319ba4SBarry Smith /*MC 2570f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2571b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2572b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2573b4319ba4SBarry Smith product is handled "implicitly". 2574b4319ba4SBarry Smith 2575b4319ba4SBarry Smith Operations Provided: 25766726f965SBarry Smith + MatMult() 25772e74eeadSLisandro Dalcin . MatMultAdd() 25782e74eeadSLisandro Dalcin . MatMultTranspose() 25792e74eeadSLisandro Dalcin . MatMultTransposeAdd() 25806726f965SBarry Smith . MatZeroEntries() 25816726f965SBarry Smith . MatSetOption() 25822e74eeadSLisandro Dalcin . MatZeroRows() 25832e74eeadSLisandro Dalcin . MatSetValues() 258497563a80SStefano Zampini . MatSetValuesBlocked() 25856726f965SBarry Smith . MatSetValuesLocal() 258697563a80SStefano Zampini . MatSetValuesBlockedLocal() 25872e74eeadSLisandro Dalcin . MatScale() 25882e74eeadSLisandro Dalcin . MatGetDiagonal() 25892b404112SStefano Zampini . MatMissingDiagonal() 25902b404112SStefano Zampini . MatDuplicate() 25912b404112SStefano Zampini . MatCopy() 2592f26d0771SStefano Zampini . MatAXPY() 25937dae84e0SHong Zhang . MatCreateSubMatrix() 2594f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2595d7f69cd0SStefano Zampini . MatTranspose() 259675d48cdbSStefano Zampini . MatPtAP() (with P of AIJ type) 25976726f965SBarry Smith - MatSetLocalToGlobalMapping() 2598b4319ba4SBarry Smith 2599b4319ba4SBarry Smith Options Database Keys: 260075d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 260175d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 260275d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 2603b4319ba4SBarry Smith 260495452b02SPatrick Sanan Notes: 260595452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 2606b4319ba4SBarry Smith 2607b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2608b4319ba4SBarry Smith 2609b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2610eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2611b4319ba4SBarry Smith 2612b4319ba4SBarry Smith Level: advanced 2613b4319ba4SBarry Smith 2614f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2615b4319ba4SBarry Smith 2616b4319ba4SBarry Smith M*/ 2617b4319ba4SBarry Smith 26188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2619b4319ba4SBarry Smith { 2620dfbe8321SBarry Smith PetscErrorCode ierr; 2621b4319ba4SBarry Smith Mat_IS *b; 2622b4319ba4SBarry Smith 2623b4319ba4SBarry Smith PetscFunctionBegin; 2624b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2625b4319ba4SBarry Smith A->data = (void*)b; 2626b4319ba4SBarry Smith 2627e176bc59SStefano Zampini /* matrix ops */ 2628e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2629b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 26302e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 26312e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 26322e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2633b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2634b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 26352e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 263698921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2637b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2638f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 26392e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2640f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2641b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2642b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2643b4319ba4SBarry Smith A->ops->view = MatView_IS; 26446726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 26452e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 26462e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 26476726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 264869796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 264969796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 265045471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2651ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 26526bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 26532b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2654659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 26557dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 2656f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 26573fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 26583fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2659d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 26607fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 2661ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 2662872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 2663b4319ba4SBarry Smith 2664b7ce53b6SStefano Zampini /* special MATIS functions */ 2665bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 26663b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 2667bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2668b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 26692e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2670cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 267175d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 267217667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2673b4319ba4SBarry Smith PetscFunctionReturn(0); 2674b4319ba4SBarry Smith } 2675