1b4319ba4SBarry Smith /* 2b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 3b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 4b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 5b4319ba4SBarry Smith product is handled "implicitly". 6b4319ba4SBarry Smith 7b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 8b4319ba4SBarry Smith */ 9b4319ba4SBarry Smith 10c6db04a5SJed Brown #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 114f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1228f4e0baSStefano Zampini 13f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 14b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 15b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 16f26d0771SStefano Zampini 1775d48cdbSStefano Zampini static PetscErrorCode MatISContainerDestroyPtAP_Private(void *ptr) 1875d48cdbSStefano Zampini { 1975d48cdbSStefano Zampini MatISPtAP ptap = (MatISPtAP)ptr; 2075d48cdbSStefano Zampini PetscErrorCode ierr; 2175d48cdbSStefano Zampini 2275d48cdbSStefano Zampini PetscFunctionBegin; 2375d48cdbSStefano Zampini ierr = MatDestroySubMatrices(ptap->ris1 ? 2 : 1,&ptap->lP);CHKERRQ(ierr); 2475d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis0);CHKERRQ(ierr); 2575d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis1);CHKERRQ(ierr); 2675d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris0);CHKERRQ(ierr); 2775d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 2875d48cdbSStefano Zampini ierr = PetscFree(ptap);CHKERRQ(ierr); 2975d48cdbSStefano Zampini PetscFunctionReturn(0); 3075d48cdbSStefano Zampini } 3175d48cdbSStefano Zampini 3275d48cdbSStefano Zampini static PetscErrorCode MatPtAPNumeric_IS_XAIJ(Mat A, Mat P, Mat C) 3375d48cdbSStefano Zampini { 3475d48cdbSStefano Zampini MatISPtAP ptap; 3575d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3675d48cdbSStefano Zampini Mat lA,lC; 3775d48cdbSStefano Zampini MatReuse reuse; 3875d48cdbSStefano Zampini IS ris[2],cis[2]; 3975d48cdbSStefano Zampini PetscContainer c; 4075d48cdbSStefano Zampini PetscInt n; 4175d48cdbSStefano Zampini PetscErrorCode ierr; 4275d48cdbSStefano Zampini 4375d48cdbSStefano Zampini PetscFunctionBegin; 4475d48cdbSStefano Zampini ierr = PetscObjectQuery((PetscObject)(C),"_MatIS_PtAP",(PetscObject*)&c);CHKERRQ(ierr); 4575d48cdbSStefano Zampini if (!c) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing PtAP information"); 4675d48cdbSStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&ptap);CHKERRQ(ierr); 4775d48cdbSStefano Zampini ris[0] = ptap->ris0; 4875d48cdbSStefano Zampini ris[1] = ptap->ris1; 4975d48cdbSStefano Zampini cis[0] = ptap->cis0; 5075d48cdbSStefano Zampini cis[1] = ptap->cis1; 5175d48cdbSStefano Zampini n = ptap->ris1 ? 2 : 1; 5275d48cdbSStefano Zampini reuse = ptap->lP ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX; 5375d48cdbSStefano Zampini ierr = MatCreateSubMatrices(P,n,ris,cis,reuse,&ptap->lP);CHKERRQ(ierr); 5475d48cdbSStefano Zampini 5575d48cdbSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 5675d48cdbSStefano Zampini ierr = MatISGetLocalMat(C,&lC);CHKERRQ(ierr); 5775d48cdbSStefano Zampini if (ptap->ris1) { /* unsymmetric A mapping */ 5875d48cdbSStefano Zampini Mat lPt; 5975d48cdbSStefano Zampini 6075d48cdbSStefano Zampini ierr = MatTranspose(ptap->lP[1],MAT_INITIAL_MATRIX,&lPt);CHKERRQ(ierr); 6175d48cdbSStefano Zampini ierr = MatMatMatMult(lPt,lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6275d48cdbSStefano Zampini if (matis->storel2l) { 6375d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",(PetscObject)lPt);CHKERRQ(ierr); 6475d48cdbSStefano Zampini } 6575d48cdbSStefano Zampini ierr = MatDestroy(&lPt);CHKERRQ(ierr); 6675d48cdbSStefano Zampini } else { 6775d48cdbSStefano Zampini ierr = MatPtAP(lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6875d48cdbSStefano Zampini if (matis->storel2l) { 6975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(C),"_MatIS_PtAP_l2l",(PetscObject)ptap->lP[0]);CHKERRQ(ierr); 7075d48cdbSStefano Zampini } 7175d48cdbSStefano Zampini } 7275d48cdbSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7375d48cdbSStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 7475d48cdbSStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 7575d48cdbSStefano Zampini } 7675d48cdbSStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7775d48cdbSStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7875d48cdbSStefano Zampini PetscFunctionReturn(0); 7975d48cdbSStefano Zampini } 8075d48cdbSStefano Zampini 8175d48cdbSStefano Zampini static PetscErrorCode MatGetNonzeroColumnsLocal_Private(Mat PT,IS *cis) 8275d48cdbSStefano Zampini { 8375d48cdbSStefano Zampini Mat Po,Pd; 8475d48cdbSStefano Zampini IS zd,zo; 8575d48cdbSStefano Zampini const PetscInt *garray; 8675d48cdbSStefano Zampini PetscInt *aux,i,bs; 8775d48cdbSStefano Zampini PetscInt dc,stc,oc,ctd,cto; 8875d48cdbSStefano Zampini PetscBool ismpiaij,ismpibaij,isseqaij,isseqbaij; 8975d48cdbSStefano Zampini MPI_Comm comm; 9075d48cdbSStefano Zampini PetscErrorCode ierr; 9175d48cdbSStefano Zampini 9275d48cdbSStefano Zampini PetscFunctionBegin; 9375d48cdbSStefano Zampini PetscValidHeaderSpecific(PT,MAT_CLASSID,1); 9475d48cdbSStefano Zampini PetscValidPointer(cis,2); 9575d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)PT,&comm);CHKERRQ(ierr); 9675d48cdbSStefano Zampini bs = 1; 9775d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 9875d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 9904637862SRichard Tran Mills ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 10075d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 10175d48cdbSStefano Zampini if (isseqaij || isseqbaij) { 10275d48cdbSStefano Zampini Pd = PT; 10375d48cdbSStefano Zampini Po = NULL; 10475d48cdbSStefano Zampini garray = NULL; 10575d48cdbSStefano Zampini } else if (ismpiaij) { 10675d48cdbSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10775d48cdbSStefano Zampini } else if (ismpibaij) { 10875d48cdbSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10975d48cdbSStefano Zampini ierr = MatGetBlockSize(PT,&bs);CHKERRQ(ierr); 11075d48cdbSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(PT))->type_name); 11175d48cdbSStefano Zampini 11275d48cdbSStefano Zampini /* identify any null columns in Pd or Po */ 11322f7620eSStefano Zampini /* We use a tolerance comparison since it may happen that, with geometric multigrid, 11422f7620eSStefano Zampini some of the columns are not really zero, but very close to */ 11575d48cdbSStefano Zampini zo = zd = NULL; 11675d48cdbSStefano Zampini if (Po) { 11722f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Po,PETSC_TRUE,PETSC_SMALL,&zo);CHKERRQ(ierr); 11875d48cdbSStefano Zampini } 11922f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Pd,PETSC_TRUE,PETSC_SMALL,&zd);CHKERRQ(ierr); 12075d48cdbSStefano Zampini 12175d48cdbSStefano Zampini ierr = MatGetLocalSize(PT,NULL,&dc);CHKERRQ(ierr); 12275d48cdbSStefano Zampini ierr = MatGetOwnershipRangeColumn(PT,&stc,NULL);CHKERRQ(ierr); 12375d48cdbSStefano Zampini if (Po) { ierr = MatGetLocalSize(Po,NULL,&oc);CHKERRQ(ierr); } 12475d48cdbSStefano Zampini else oc = 0; 12575d48cdbSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 12675d48cdbSStefano Zampini if (zd) { 12775d48cdbSStefano Zampini const PetscInt *idxs; 12875d48cdbSStefano Zampini PetscInt nz; 12975d48cdbSStefano Zampini 13075d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 13175d48cdbSStefano Zampini ierr = ISSetBlockSize(zd,bs);CHKERRQ(ierr); 13275d48cdbSStefano Zampini ierr = ISGetLocalSize(zd,&nz);CHKERRQ(ierr); 13375d48cdbSStefano Zampini ierr = ISGetIndices(zd,&idxs);CHKERRQ(ierr); 13475d48cdbSStefano Zampini ctd = nz/bs; 13575d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = (idxs[bs*i]+stc)/bs; 13675d48cdbSStefano Zampini ierr = ISRestoreIndices(zd,&idxs);CHKERRQ(ierr); 13775d48cdbSStefano Zampini } else { 13875d48cdbSStefano Zampini ctd = dc/bs; 13975d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = i+stc/bs; 14075d48cdbSStefano Zampini } 14175d48cdbSStefano Zampini if (zo) { 14275d48cdbSStefano Zampini const PetscInt *idxs; 14375d48cdbSStefano Zampini PetscInt nz; 14475d48cdbSStefano Zampini 14575d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 14675d48cdbSStefano Zampini ierr = ISSetBlockSize(zo,bs);CHKERRQ(ierr); 14775d48cdbSStefano Zampini ierr = ISGetLocalSize(zo,&nz);CHKERRQ(ierr); 14875d48cdbSStefano Zampini ierr = ISGetIndices(zo,&idxs);CHKERRQ(ierr); 14975d48cdbSStefano Zampini cto = nz/bs; 15075d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[idxs[bs*i]/bs]; 15175d48cdbSStefano Zampini ierr = ISRestoreIndices(zo,&idxs);CHKERRQ(ierr); 15275d48cdbSStefano Zampini } else { 15375d48cdbSStefano Zampini cto = oc/bs; 15475d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[i]; 15575d48cdbSStefano Zampini } 15675d48cdbSStefano Zampini ierr = ISCreateBlock(comm,bs,ctd+cto,aux,PETSC_OWN_POINTER,cis);CHKERRQ(ierr); 15775d48cdbSStefano Zampini ierr = ISDestroy(&zd);CHKERRQ(ierr); 15875d48cdbSStefano Zampini ierr = ISDestroy(&zo);CHKERRQ(ierr); 15975d48cdbSStefano Zampini PetscFunctionReturn(0); 16075d48cdbSStefano Zampini } 16175d48cdbSStefano Zampini 16275d48cdbSStefano Zampini static PetscErrorCode MatPtAPSymbolic_IS_XAIJ(Mat A,Mat P,PetscReal fill,Mat *C) 16375d48cdbSStefano Zampini { 16475d48cdbSStefano Zampini Mat PT; 16575d48cdbSStefano Zampini MatISPtAP ptap; 16675d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 16775d48cdbSStefano Zampini PetscContainer c; 16875d48cdbSStefano Zampini const PetscInt *garray; 16975d48cdbSStefano Zampini PetscInt ibs,N,dc; 17075d48cdbSStefano Zampini MPI_Comm comm; 17175d48cdbSStefano Zampini PetscErrorCode ierr; 17275d48cdbSStefano Zampini 17375d48cdbSStefano Zampini PetscFunctionBegin; 17475d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 17575d48cdbSStefano Zampini ierr = MatCreate(comm,C);CHKERRQ(ierr); 17675d48cdbSStefano Zampini ierr = MatSetType(*C,MATIS);CHKERRQ(ierr); 17775d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 17875d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 17975d48cdbSStefano Zampini ierr = MatSetSizes(*C,dc,dc,N,N);CHKERRQ(ierr); 18075d48cdbSStefano Zampini /* Not sure about this 18175d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18275d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18375d48cdbSStefano Zampini */ 18475d48cdbSStefano Zampini 18575d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 18675d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 18775d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 18875d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 18975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(*C),"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19075d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19175d48cdbSStefano Zampini ptap->fill = fill; 19275d48cdbSStefano Zampini 19375d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 19475d48cdbSStefano Zampini 19575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 19775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 19875d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 19975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20075d48cdbSStefano Zampini 20175d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 20575d48cdbSStefano Zampini 20675d48cdbSStefano Zampini Crl2g = NULL; 20775d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 20875d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 20975d48cdbSStefano Zampini PetscInt N1,ibs1; 21075d48cdbSStefano Zampini 21175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21475d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 21575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21675d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 21775d48cdbSStefano Zampini const PetscInt *i1,*i2; 21875d48cdbSStefano Zampini 21975d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 22175d48cdbSStefano Zampini ierr = PetscMemcmp(i1,i2,N*sizeof(*i1),&lsame);CHKERRQ(ierr); 22275d48cdbSStefano Zampini } 22375d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 22475d48cdbSStefano Zampini if (same) { 22575d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 22675d48cdbSStefano Zampini } else { 22775d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 22875d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 22975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23075d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23175d48cdbSStefano Zampini } 23275d48cdbSStefano Zampini } 23375d48cdbSStefano Zampini /* Not sure about this 23475d48cdbSStefano Zampini if (!Crl2g) { 23575d48cdbSStefano Zampini ierr = MatGetBlockSize(*C,&ibs);CHKERRQ(ierr); 23675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini */ 23975d48cdbSStefano Zampini ierr = MatSetLocalToGlobalMapping(*C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24275d48cdbSStefano Zampini 24375d48cdbSStefano Zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 24475d48cdbSStefano Zampini PetscFunctionReturn(0); 24575d48cdbSStefano Zampini } 24675d48cdbSStefano Zampini 24775d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 24875d48cdbSStefano Zampini { 24975d48cdbSStefano Zampini PetscErrorCode ierr; 25075d48cdbSStefano Zampini 25175d48cdbSStefano Zampini PetscFunctionBegin; 25275d48cdbSStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 25375d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25475d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 25575d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25675d48cdbSStefano Zampini } 25775d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 25875d48cdbSStefano Zampini ierr = ((*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 25975d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26075d48cdbSStefano Zampini PetscFunctionReturn(0); 26175d48cdbSStefano Zampini } 26275d48cdbSStefano Zampini 2635b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2645b003df0Sstefano_zampini { 2655b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2665b003df0Sstefano_zampini PetscInt i; 2675b003df0Sstefano_zampini PetscErrorCode ierr; 2685b003df0Sstefano_zampini 269ab4d48faSStefano Zampini PetscFunctionBegin; 2705b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2715b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2725b003df0Sstefano_zampini } 2735b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2745b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2755b003df0Sstefano_zampini } 2765b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 2775b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 2785b003df0Sstefano_zampini PetscFunctionReturn(0); 2795b003df0Sstefano_zampini } 280a72627d2SStefano Zampini 281c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2826989cf23SStefano Zampini { 283c9225affSStefano Zampini Mat B,lB; 284c9225affSStefano Zampini PetscErrorCode ierr; 285c9225affSStefano Zampini 286c9225affSStefano Zampini PetscFunctionBegin; 287c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 288c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 289c9225affSStefano Zampini PetscInt bs; 290c9225affSStefano Zampini IS is; 291c9225affSStefano Zampini 292c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 293c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 294c9225affSStefano Zampini if (bs > 1) { 295c9225affSStefano Zampini IS is2; 296c9225affSStefano Zampini PetscInt i,*aux; 297c9225affSStefano Zampini 298c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 299c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 300c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 301c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 302c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 303c9225affSStefano Zampini is = is2; 304c9225affSStefano Zampini } 305c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 306c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 307c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 308c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 309c9225affSStefano Zampini if (bs > 1) { 310c9225affSStefano Zampini IS is2; 311c9225affSStefano Zampini PetscInt i,*aux; 312c9225affSStefano Zampini 313c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 314c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 315c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 316c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 317c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 318c9225affSStefano Zampini is = is2; 319c9225affSStefano Zampini } 320c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 321c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 322c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 323c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 324c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 325c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 326c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 327c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 328c9225affSStefano Zampini } else { 329c9225affSStefano Zampini B = *newmat; 330c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 331c9225affSStefano Zampini lB = A; 332c9225affSStefano Zampini } 333c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 334c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 335c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 336c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 337c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 338c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 339c9225affSStefano Zampini } 340c9225affSStefano Zampini PetscFunctionReturn(0); 341c9225affSStefano Zampini } 342c9225affSStefano Zampini 343c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 344c9225affSStefano Zampini { 345c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 346c9225affSStefano Zampini PetscScalar *aa; 347c9225affSStefano Zampini const PetscInt *ii,*jj; 348c9225affSStefano Zampini PetscInt i,n,m; 349*fabe8965SStefano Zampini PetscInt *ecount,**eneighs; 350c9225affSStefano Zampini PetscBool flg; 351c9225affSStefano Zampini PetscErrorCode ierr; 352c9225affSStefano Zampini 353c9225affSStefano Zampini PetscFunctionBegin; 354c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 355c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 356*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 357c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 358c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 359c9225affSStefano Zampini for (i=0;i<n;i++) { 360*fabe8965SStefano Zampini if (ecount[i] > 1) { 361c9225affSStefano Zampini PetscInt j; 362c9225affSStefano Zampini 363c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 364c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 365*fabe8965SStefano Zampini PetscReal scal = 0.0; 366c9225affSStefano Zampini 367c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 368c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 369c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 370c9225affSStefano Zampini } 371c9225affSStefano Zampini } 372*fabe8965SStefano Zampini if (scal) aa[j] /= scal; 373c9225affSStefano Zampini } 374c9225affSStefano Zampini } 375c9225affSStefano Zampini } 376*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 377c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 378c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 379c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 380c9225affSStefano Zampini PetscFunctionReturn(0); 381c9225affSStefano Zampini } 382c9225affSStefano Zampini 383*fabe8965SStefano Zampini typedef enum {MAT_IS_DISASSEMBLE_L2G_NATURAL,MAT_IS_DISASSEMBLE_L2G_MAT, MAT_IS_DISASSEMBLE_L2G_ND} MatISDisassemblel2gType; 384*fabe8965SStefano Zampini 385c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 386c9225affSStefano Zampini { 387*fabe8965SStefano Zampini Mat Ad,Ao; 388*fabe8965SStefano Zampini IS is,ndmap,ndsub; 389c9225affSStefano Zampini MPI_Comm comm; 390*fabe8965SStefano Zampini const PetscInt *garray,*ndmapi; 391*fabe8965SStefano Zampini PetscInt bs,i,cnt,nl,*ncount,*ndmapc; 392*fabe8965SStefano Zampini PetscBool ismpiaij,ismpibaij; 393*fabe8965SStefano Zampini const char *const MatISDisassemblel2gTypes[] = {"NATURAL","MAT","ND","MatISDisassemblel2gType","MAT_IS_DISASSEMBLE_L2G_",0}; 394*fabe8965SStefano Zampini MatISDisassemblel2gType mode = MAT_IS_DISASSEMBLE_L2G_NATURAL; 395*fabe8965SStefano Zampini MatPartitioning part; 396*fabe8965SStefano Zampini PetscSF sf; 397c9225affSStefano Zampini PetscErrorCode ierr; 398c9225affSStefano Zampini 399c9225affSStefano Zampini PetscFunctionBegin; 400*fabe8965SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MatIS l2g disassembling options","Mat");CHKERRQ(ierr); 401*fabe8965SStefano Zampini ierr = PetscOptionsEnum("-mat_is_disassemble_l2g_type","Type of local-to-global mapping to be used for disassembling","MatISDisassemblel2gType",MatISDisassemblel2gTypes,(PetscEnum)mode,(PetscEnum*)&mode,NULL);CHKERRQ(ierr); 402*fabe8965SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 403*fabe8965SStefano Zampini if (mode == MAT_IS_DISASSEMBLE_L2G_MAT) { 404c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 405c9225affSStefano Zampini PetscFunctionReturn(0); 406c9225affSStefano Zampini } 407c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 408c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 409c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 410c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 411*fabe8965SStefano Zampini switch (mode) { 412*fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_ND: 413*fabe8965SStefano Zampini ierr = MatPartitioningCreate(comm,&part);CHKERRQ(ierr); 414*fabe8965SStefano Zampini ierr = MatPartitioningSetAdjacency(part,A);CHKERRQ(ierr); 415*fabe8965SStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)part,((PetscObject)A)->prefix);CHKERRQ(ierr); 416*fabe8965SStefano Zampini ierr = MatPartitioningSetFromOptions(part);CHKERRQ(ierr); 417*fabe8965SStefano Zampini ierr = MatPartitioningApplyND(part,&ndmap);CHKERRQ(ierr); 418*fabe8965SStefano Zampini ierr = MatPartitioningDestroy(&part);CHKERRQ(ierr); 419*fabe8965SStefano Zampini ierr = ISBuildTwoSided(ndmap,NULL,&ndsub);CHKERRQ(ierr); 420*fabe8965SStefano Zampini ierr = MatMPIAIJSetUseScalableIncreaseOverlap(A,PETSC_TRUE);CHKERRQ(ierr); 421*fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,1,&ndsub,1);CHKERRQ(ierr); 422*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ndsub,l2g);CHKERRQ(ierr); 423*fabe8965SStefano Zampini 424*fabe8965SStefano Zampini /* it may happen that a separator node is not properly shared */ 425*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(*l2g,&nl,&ncount,NULL);CHKERRQ(ierr); 426*fabe8965SStefano Zampini ierr = PetscSFCreate(comm,&sf);CHKERRQ(ierr); 427*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(*l2g,&garray);CHKERRQ(ierr); 428*fabe8965SStefano Zampini ierr = PetscSFSetGraphLayout(sf,A->rmap,nl,NULL,PETSC_OWN_POINTER,garray);CHKERRQ(ierr); 429*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(*l2g,&garray);CHKERRQ(ierr); 430*fabe8965SStefano Zampini ierr = PetscCalloc1(A->rmap->n,&ndmapc);CHKERRQ(ierr); 431*fabe8965SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 432*fabe8965SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 433*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(*l2g,NULL,&ncount,NULL);CHKERRQ(ierr); 434*fabe8965SStefano Zampini ierr = ISGetIndices(ndmap,&ndmapi);CHKERRQ(ierr); 435*fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 436*fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) 437*fabe8965SStefano Zampini cnt++; 438*fabe8965SStefano Zampini 439*fabe8965SStefano Zampini ierr = MPIU_Allreduce(&cnt,&i,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 440*fabe8965SStefano Zampini if (i) { /* we detected isolated separator nodes */ 441*fabe8965SStefano Zampini Mat A2,A3; 442*fabe8965SStefano Zampini IS *workis,is2; 443*fabe8965SStefano Zampini PetscScalar *vals; 444*fabe8965SStefano Zampini PetscInt gcnt = i,*dnz,*onz,j,*lndmapi; 445*fabe8965SStefano Zampini ISLocalToGlobalMapping ll2g; 446*fabe8965SStefano Zampini PetscBool flg; 447*fabe8965SStefano Zampini const PetscInt *ii,*jj; 448*fabe8965SStefano Zampini 449*fabe8965SStefano Zampini /* communicate global id of separators */ 450*fabe8965SStefano Zampini ierr = MatPreallocateInitialize(comm,A->rmap->n,A->cmap->n,dnz,onz);CHKERRQ(ierr); 451*fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 452*fabe8965SStefano Zampini dnz[i] = ndmapi[i] < 0 ? i + A->rmap->rstart : -1; 453*fabe8965SStefano Zampini 454*fabe8965SStefano Zampini ierr = PetscMalloc1(nl,&lndmapi);CHKERRQ(ierr); 455*fabe8965SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 456*fabe8965SStefano Zampini 457*fabe8965SStefano Zampini /* compute adjacency of isolated separators node */ 458*fabe8965SStefano Zampini ierr = PetscMalloc1(gcnt,&workis);CHKERRQ(ierr); 459*fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) { 460*fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 461*fabe8965SStefano Zampini ierr = ISCreateStride(comm,1,i+A->rmap->rstart,1,&workis[cnt++]);CHKERRQ(ierr); 462*fabe8965SStefano Zampini } 463*fabe8965SStefano Zampini } 464*fabe8965SStefano Zampini for (i = cnt; i < gcnt; i++) { 465*fabe8965SStefano Zampini ierr = ISCreateStride(comm,0,0,1,&workis[i]);CHKERRQ(ierr); 466*fabe8965SStefano Zampini } 467*fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 468*fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"ISOLATED");CHKERRQ(ierr); 469*fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 470*fabe8965SStefano Zampini } 471*fabe8965SStefano Zampini 472*fabe8965SStefano Zampini /* no communications since all the ISes correspond to locally owned rows */ 473*fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,gcnt,workis,1);CHKERRQ(ierr); 474*fabe8965SStefano Zampini 475*fabe8965SStefano Zampini /* end communicate global id of separators */ 476*fabe8965SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 477*fabe8965SStefano Zampini 478*fabe8965SStefano Zampini /* communicate new layers : create a matrix and transpose it */ 479*fabe8965SStefano Zampini ierr = PetscMemzero(dnz,A->rmap->n*sizeof(*dnz));CHKERRQ(ierr); 480*fabe8965SStefano Zampini ierr = PetscMemzero(onz,A->rmap->n*sizeof(*onz));CHKERRQ(ierr); 481*fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) { 482*fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 483*fabe8965SStefano Zampini const PetscInt* idxs; 484*fabe8965SStefano Zampini PetscInt s; 485*fabe8965SStefano Zampini 486*fabe8965SStefano Zampini ierr = ISGetLocalSize(workis[j],&s);CHKERRQ(ierr); 487*fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 488*fabe8965SStefano Zampini ierr = MatPreallocateSet(i+A->rmap->rstart,s,idxs,dnz,onz);CHKERRQ(ierr); 489*fabe8965SStefano Zampini j++; 490*fabe8965SStefano Zampini } 491*fabe8965SStefano Zampini } 492*fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 493*fabe8965SStefano Zampini 494*fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 495*fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"EXTENDED");CHKERRQ(ierr); 496*fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 497*fabe8965SStefano Zampini } 498*fabe8965SStefano Zampini 499*fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) j = PetscMax(j,dnz[i]+onz[i]); 500*fabe8965SStefano Zampini ierr = PetscMalloc1(j,&vals);CHKERRQ(ierr); 501*fabe8965SStefano Zampini for (i = 0; i < j; i++) vals[i] = 1.0; 502*fabe8965SStefano Zampini 503*fabe8965SStefano Zampini ierr = MatCreate(comm,&A2);CHKERRQ(ierr); 504*fabe8965SStefano Zampini ierr = MatSetType(A2,MATMPIAIJ);CHKERRQ(ierr); 505*fabe8965SStefano Zampini ierr = MatSetSizes(A2,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 506*fabe8965SStefano Zampini ierr = MatMPIAIJSetPreallocation(A2,0,dnz,0,onz);CHKERRQ(ierr); 507*fabe8965SStefano Zampini ierr = MatSetOption(A2,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 508*fabe8965SStefano Zampini for (i = 0, j = 0; i < A2->rmap->n; i++) { 509*fabe8965SStefano Zampini PetscInt row = i+A2->rmap->rstart,s = dnz[i] + onz[i]; 510*fabe8965SStefano Zampini const PetscInt* idxs; 511*fabe8965SStefano Zampini 512*fabe8965SStefano Zampini if (s) { 513*fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 514*fabe8965SStefano Zampini ierr = MatSetValues(A2,1,&row,s,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 515*fabe8965SStefano Zampini ierr = ISRestoreIndices(workis[j],&idxs);CHKERRQ(ierr); 516*fabe8965SStefano Zampini j++; 517*fabe8965SStefano Zampini } 518*fabe8965SStefano Zampini } 519*fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 520*fabe8965SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 521*fabe8965SStefano Zampini ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 522*fabe8965SStefano Zampini ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 523*fabe8965SStefano Zampini ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 524*fabe8965SStefano Zampini 525*fabe8965SStefano Zampini /* extract submatrix corresponding to the coupling "owned separators" x "isolated separators" */ 526*fabe8965SStefano Zampini for (i = 0, j = 0; i < nl; i++) 527*fabe8965SStefano Zampini if (lndmapi[i] >= 0) lndmapi[j++] = lndmapi[i]; 528*fabe8965SStefano Zampini ierr = ISCreateGeneral(comm,j,lndmapi,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 529*fabe8965SStefano Zampini ierr = MatMPIAIJGetLocalMatCondensed(A2,MAT_INITIAL_MATRIX,&is,NULL,&A3);CHKERRQ(ierr); 530*fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 531*fabe8965SStefano Zampini ierr = MatDestroy(&A2);CHKERRQ(ierr); 532*fabe8965SStefano Zampini 533*fabe8965SStefano Zampini /* extend local to global map to include connected isolated separators */ 534*fabe8965SStefano Zampini ierr = PetscObjectQuery((PetscObject)A3,"_petsc_GetLocalMatCondensed_iscol",(PetscObject*)&is);CHKERRQ(ierr); 535*fabe8965SStefano Zampini if (!is) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing column map"); 536*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&ll2g);CHKERRQ(ierr); 537*fabe8965SStefano Zampini ierr = MatGetRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 538*fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 539*fabe8965SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,ii[i],jj,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 540*fabe8965SStefano Zampini ierr = MatRestoreRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 541*fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 542*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ll2g,is,&is2);CHKERRQ(ierr); 543*fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 544*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ll2g);CHKERRQ(ierr); 545*fabe8965SStefano Zampini 546*fabe8965SStefano Zampini /* add new nodes to the local-to-global map */ 547*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(l2g);CHKERRQ(ierr); 548*fabe8965SStefano Zampini ierr = ISExpand(ndsub,is2,&is);CHKERRQ(ierr); 549*fabe8965SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 550*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 551*fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 552*fabe8965SStefano Zampini 553*fabe8965SStefano Zampini ierr = MatDestroy(&A3);CHKERRQ(ierr); 554*fabe8965SStefano Zampini ierr = PetscFree(lndmapi);CHKERRQ(ierr); 555*fabe8965SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 556*fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 557*fabe8965SStefano Zampini ierr = ISDestroy(&workis[i]);CHKERRQ(ierr); 558*fabe8965SStefano Zampini } 559*fabe8965SStefano Zampini ierr = PetscFree(workis);CHKERRQ(ierr); 560*fabe8965SStefano Zampini } 561*fabe8965SStefano Zampini ierr = ISRestoreIndices(ndmap,&ndmapi);CHKERRQ(ierr); 562*fabe8965SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 563*fabe8965SStefano Zampini ierr = PetscFree(ndmapc);CHKERRQ(ierr); 564*fabe8965SStefano Zampini ierr = ISDestroy(&ndmap);CHKERRQ(ierr); 565*fabe8965SStefano Zampini ierr = ISDestroy(&ndsub);CHKERRQ(ierr); 566*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(*l2g,bs);CHKERRQ(ierr); 567*fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingViewFromOptions(*l2g,NULL,"-matis_nd_l2g_view");CHKERRQ(ierr); 568*fabe8965SStefano Zampini break; 569*fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_NATURAL: 570*fabe8965SStefano Zampini if (ismpiaij) { 571*fabe8965SStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 572*fabe8965SStefano Zampini } else if (ismpibaij) { 573*fabe8965SStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 574c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 575c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 576c9225affSStefano Zampini if (A->rmap->n) { 577*fabe8965SStefano Zampini PetscInt dc,oc,stc,*aux; 578c9225affSStefano Zampini 579c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 580c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 581c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 582c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 583c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 584c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 585c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 586c9225affSStefano Zampini } else { 587c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 588c9225affSStefano Zampini } 589c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 590c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 591*fabe8965SStefano Zampini break; 592*fabe8965SStefano Zampini default: 593*fabe8965SStefano Zampini SETERRQ1(comm,PETSC_ERR_ARG_WRONG,"Unsupported l2g disassembling type %D",mode); 594c9225affSStefano Zampini } 595c9225affSStefano Zampini PetscFunctionReturn(0); 596c9225affSStefano Zampini } 597c9225affSStefano Zampini 598c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 599c9225affSStefano Zampini { 600c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 6016989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 6026989cf23SStefano Zampini IS is; 6036989cf23SStefano Zampini MPI_Comm comm; 6046989cf23SStefano Zampini void *ptrs[2]; 6056989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 606c9225affSStefano Zampini const PetscInt *garray; 6076989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 608c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 609c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 6106989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 611c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 612c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 613c9225affSStefano Zampini PetscMPIInt size; 6146989cf23SStefano Zampini PetscErrorCode ierr; 6156989cf23SStefano Zampini 616ab4d48faSStefano Zampini PetscFunctionBegin; 6176989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 618c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 619c9225affSStefano Zampini if (size == 1) { 620c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 621c9225affSStefano Zampini PetscFunctionReturn(0); 622c9225affSStefano Zampini } 623c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 624c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 625c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 626c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 627c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 628c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 629c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 630c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 631c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 632c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 633c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 634c9225affSStefano Zampini } 635c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 636c9225affSStefano Zampini Mat *newlA, lA; 637c9225affSStefano Zampini IS rows, cols; 638c9225affSStefano Zampini const PetscInt *ridx, *cidx; 639c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 640c9225affSStefano Zampini 641c9225affSStefano Zampini if (!B) B = *newmat; 642c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 643c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 644c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 645c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 646c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 647c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 648c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 649c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 650c9225affSStefano Zampini if (rl2g != cl2g) { 651c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 652c9225affSStefano Zampini } else { 653c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 654c9225affSStefano Zampini cols = rows; 655c9225affSStefano Zampini } 656c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 657c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 658c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 659c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 660c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 661c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 662c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 663c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 664c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 665c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 666c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 667c9225affSStefano Zampini } 668c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 669c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 670c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 671c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 672c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 673c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 674c9225affSStefano Zampini else *newmat = B; 675c9225affSStefano Zampini PetscFunctionReturn(0); 676c9225affSStefano Zampini } 677c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 678c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 679c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 680c9225affSStefano Zampini if (ismpiaij) { 681c9225affSStefano Zampini bs = 1; 682c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 683c9225affSStefano Zampini } else if (ismpibaij) { 684c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 685c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 686c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 687c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 688c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 689c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 690c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 691c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 6926989cf23SStefano Zampini 6936989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 6946989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 6956989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 6966989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 697c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 698c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 699c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 700c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 701c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 702c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 703c9225affSStefano Zampini /* store original pointers to be restored later */ 704c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 7056989cf23SStefano Zampini 7066989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 707c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 708c9225affSStefano Zampini if (bs > 1) { 709c9225affSStefano Zampini IS is2; 710c9225affSStefano Zampini 711c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 712c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 713c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 714c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 715c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 716c9225affSStefano Zampini is = is2; 717c9225affSStefano Zampini } 7186989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 7196989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 720e363d98aSStefano Zampini if (dr) { 721c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 722c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 723c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 724c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 725e363d98aSStefano Zampini lc = dc+oc; 726e363d98aSStefano Zampini } else { 727c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 728e363d98aSStefano Zampini lc = 0; 729e363d98aSStefano Zampini } 7306989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 7316989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 7326989cf23SStefano Zampini 7336989cf23SStefano Zampini /* create MATIS object */ 734c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 735c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 736c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 737c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 738c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 7396989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7406989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7416989cf23SStefano Zampini 7426989cf23SStefano Zampini /* merge local matrices */ 7436989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 7446989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 7456989cf23SStefano Zampini ii = aux; 7466989cf23SStefano Zampini jj = aux+dr+1; 7476989cf23SStefano Zampini aa = data; 7486989cf23SStefano Zampini *ii = *(di++) + *(oi++); 7496989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 7506989cf23SStefano Zampini { 7516989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 7526989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 7536989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 7546989cf23SStefano Zampini } 7556989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 756c9225affSStefano Zampini 757c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 758c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 759c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 760c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 761c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 762c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 763c9225affSStefano Zampini 7646989cf23SStefano Zampini ii = aux; 7656989cf23SStefano Zampini jj = aux+dr+1; 7666989cf23SStefano Zampini aa = data; 767e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 7686989cf23SStefano Zampini 7696989cf23SStefano Zampini /* create containers to destroy the data */ 7706989cf23SStefano Zampini ptrs[0] = aux; 7716989cf23SStefano Zampini ptrs[1] = data; 7726989cf23SStefano Zampini for (i=0; i<2; i++) { 7736989cf23SStefano Zampini PetscContainer c; 7746989cf23SStefano Zampini 7756989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 7766989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 777b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 7786989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 7796989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 7806989cf23SStefano Zampini } 781c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 782c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 783c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 784c9225affSStefano Zampini } 7856989cf23SStefano Zampini 7866989cf23SStefano Zampini /* finalize matrix */ 787c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 7886989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 789c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 790c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 791c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 792c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 793c9225affSStefano Zampini } else *newmat = B; 7946989cf23SStefano Zampini PetscFunctionReturn(0); 7956989cf23SStefano Zampini } 7966989cf23SStefano Zampini 797cf0a3239SStefano Zampini /*@ 7983d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 799cf0a3239SStefano Zampini 800cf0a3239SStefano Zampini Collective on MPI_Comm 801cf0a3239SStefano Zampini 802cf0a3239SStefano Zampini Input Parameters: 803cf0a3239SStefano Zampini + A - the matrix 804cf0a3239SStefano Zampini 805cf0a3239SStefano Zampini Level: advanced 806cf0a3239SStefano Zampini 80795452b02SPatrick Sanan Notes: 80895452b02SPatrick Sanan This function does not need to be called by the user. 809cf0a3239SStefano Zampini 810cf0a3239SStefano Zampini .keywords: matrix 811cf0a3239SStefano Zampini 812cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 813cf0a3239SStefano Zampini @*/ 814cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 815cf0a3239SStefano Zampini { 8167fa8f2d3SStefano Zampini PetscErrorCode ierr; 8177fa8f2d3SStefano Zampini 8187fa8f2d3SStefano Zampini PetscFunctionBegin; 819cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 820cf0a3239SStefano Zampini PetscValidType(A,1); 821cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 8227fa8f2d3SStefano Zampini PetscFunctionReturn(0); 8237fa8f2d3SStefano Zampini } 8247fa8f2d3SStefano Zampini 8255e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 8265e3038f0Sstefano_zampini { 8275e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 8285e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 8295e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 8305e3038f0Sstefano_zampini MPI_Comm comm; 8315b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 8325b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 8339e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 8345e3038f0Sstefano_zampini PetscErrorCode ierr; 8355e3038f0Sstefano_zampini 836ab4d48faSStefano Zampini PetscFunctionBegin; 8375e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 8385e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 8395e3038f0Sstefano_zampini rnest = NULL; 8405e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 8415e3038f0Sstefano_zampini PetscBool ismatis,isnest; 8425e3038f0Sstefano_zampini 8435e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 8445e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 8455e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 8465e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 8475e3038f0Sstefano_zampini if (isnest) { 8485e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 8495e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 8505e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 8515e3038f0Sstefano_zampini } 8525e3038f0Sstefano_zampini } 8535e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 8545b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 8559e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 8565e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 8579e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 8585e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 8595e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8605e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8615e3038f0Sstefano_zampini PetscBool ismatis; 8629e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 8635e3038f0Sstefano_zampini 8645e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 8655e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8665e3038f0Sstefano_zampini 8675e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 8689e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 8699e7b2b25Sstefano_zampini if (istrans[ij]) { 8709e7b2b25Sstefano_zampini Mat T,lT; 8719e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8729e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 8739e7b2b25Sstefano_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); 8749e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 8759e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 8769e7b2b25Sstefano_zampini } else { 8775e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 8785e3038f0Sstefano_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); 8799e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 8809e7b2b25Sstefano_zampini } 8815e3038f0Sstefano_zampini 8825e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 8835e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 8849e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 8855e3038f0Sstefano_zampini if (!l1 || !l2) continue; 8865e3038f0Sstefano_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); 8875e3038f0Sstefano_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); 8885e3038f0Sstefano_zampini lr[i] = l1; 8895e3038f0Sstefano_zampini lc[j] = l2; 8905e3038f0Sstefano_zampini 8915e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 8925e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 8935e3038f0Sstefano_zampini } 8945e3038f0Sstefano_zampini } 8955e3038f0Sstefano_zampini 8965e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 8975e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 8985e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8995e3038f0Sstefano_zampini rl2g = NULL; 9005e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 9015e3038f0Sstefano_zampini PetscInt n1,n2; 9025e3038f0Sstefano_zampini 9035e3038f0Sstefano_zampini if (!nest[i][j]) continue; 9049e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9059e7b2b25Sstefano_zampini Mat T; 9069e7b2b25Sstefano_zampini 9079e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 9089e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 9099e7b2b25Sstefano_zampini } else { 9105e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 9119e7b2b25Sstefano_zampini } 9125e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9135e3038f0Sstefano_zampini if (!n1) continue; 9145e3038f0Sstefano_zampini if (!rl2g) { 9155e3038f0Sstefano_zampini rl2g = cl2g; 9165e3038f0Sstefano_zampini } else { 9175e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9185e3038f0Sstefano_zampini PetscBool same; 9195e3038f0Sstefano_zampini 9205e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9215e3038f0Sstefano_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); 9225e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9235e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 9245e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 9255e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9265e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9275e3038f0Sstefano_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); 9285e3038f0Sstefano_zampini } 9295e3038f0Sstefano_zampini } 9305e3038f0Sstefano_zampini } 9315e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 9325e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 9335e3038f0Sstefano_zampini rl2g = NULL; 9345e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 9355e3038f0Sstefano_zampini PetscInt n1,n2; 9365e3038f0Sstefano_zampini 9375e3038f0Sstefano_zampini if (!nest[j][i]) continue; 9389e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 9399e7b2b25Sstefano_zampini Mat T; 9409e7b2b25Sstefano_zampini 9419e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 9429e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 9439e7b2b25Sstefano_zampini } else { 9445e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 9459e7b2b25Sstefano_zampini } 9465e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9475e3038f0Sstefano_zampini if (!n1) continue; 9485e3038f0Sstefano_zampini if (!rl2g) { 9495e3038f0Sstefano_zampini rl2g = cl2g; 9505e3038f0Sstefano_zampini } else { 9515e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9525e3038f0Sstefano_zampini PetscBool same; 9535e3038f0Sstefano_zampini 9545e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9555e3038f0Sstefano_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); 9565e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9575e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 9585e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 9595e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9605e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9615e3038f0Sstefano_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); 9625e3038f0Sstefano_zampini } 9635e3038f0Sstefano_zampini } 9645e3038f0Sstefano_zampini } 9655e3038f0Sstefano_zampini #endif 9665e3038f0Sstefano_zampini 9675e3038f0Sstefano_zampini B = NULL; 9685e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 9695b003df0Sstefano_zampini PetscInt stl; 9705b003df0Sstefano_zampini 9715e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 9725e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 9735e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9745b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9755e3038f0Sstefano_zampini Mat usedmat; 9765e3038f0Sstefano_zampini Mat_IS *matis; 9775e3038f0Sstefano_zampini const PetscInt *idxs; 9785e3038f0Sstefano_zampini 9795e3038f0Sstefano_zampini /* local IS for local NEST */ 9805b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9815e3038f0Sstefano_zampini 9825e3038f0Sstefano_zampini /* l2gmap */ 9835e3038f0Sstefano_zampini j = 0; 9845e3038f0Sstefano_zampini usedmat = nest[i][j]; 9859e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 9869e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 9879e7b2b25Sstefano_zampini 9889e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9899e7b2b25Sstefano_zampini Mat T; 9909e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 9919e7b2b25Sstefano_zampini usedmat = T; 9929e7b2b25Sstefano_zampini } 99382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 9945e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 9955e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 9969e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9979e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9989e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9999e7b2b25Sstefano_zampini } else { 10005e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10015e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10029e7b2b25Sstefano_zampini } 10035e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 10045e3038f0Sstefano_zampini stl += lr[i]; 10055e3038f0Sstefano_zampini } 10065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 10075e3038f0Sstefano_zampini 10085e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 10095e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 10105e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 10115b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10125e3038f0Sstefano_zampini Mat usedmat; 10135e3038f0Sstefano_zampini Mat_IS *matis; 10145e3038f0Sstefano_zampini const PetscInt *idxs; 10155e3038f0Sstefano_zampini 10165e3038f0Sstefano_zampini /* local IS for local NEST */ 10175b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10185e3038f0Sstefano_zampini 10195e3038f0Sstefano_zampini /* l2gmap */ 10205e3038f0Sstefano_zampini j = 0; 10215e3038f0Sstefano_zampini usedmat = nest[j][i]; 10229e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 10239e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 10249e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10259e7b2b25Sstefano_zampini Mat T; 10269e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 10279e7b2b25Sstefano_zampini usedmat = T; 10289e7b2b25Sstefano_zampini } 102982d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 10305e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10315e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 10329e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10339e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10349e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10359e7b2b25Sstefano_zampini } else { 10365e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10375e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10389e7b2b25Sstefano_zampini } 10395e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 10405e3038f0Sstefano_zampini stl += lc[i]; 10415e3038f0Sstefano_zampini } 10425e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 10435e3038f0Sstefano_zampini 10445e3038f0Sstefano_zampini /* Create MATIS */ 10455e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 10465e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 10475e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 10485e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 10495e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 10505e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 10515e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 10525e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 10535e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 10549e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 10559e7b2b25Sstefano_zampini if (istrans[i]) { 10569e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10579e7b2b25Sstefano_zampini } 10589e7b2b25Sstefano_zampini } 10595e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 10605e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10615e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10625e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10635e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 10645e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 10655e3038f0Sstefano_zampini } else { 10665e3038f0Sstefano_zampini *newmat = B; 10675e3038f0Sstefano_zampini } 10685e3038f0Sstefano_zampini } else { 10695e3038f0Sstefano_zampini if (lreuse) { 10705e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10715e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10725e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 10735e3038f0Sstefano_zampini if (snest[i*nc+j]) { 10745e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 10759e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10769e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 10779e7b2b25Sstefano_zampini } 10785e3038f0Sstefano_zampini } 10795e3038f0Sstefano_zampini } 10805e3038f0Sstefano_zampini } 10815e3038f0Sstefano_zampini } else { 10825b003df0Sstefano_zampini PetscInt stl; 10835b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 10845b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 10855b003df0Sstefano_zampini stl += lr[i]; 10865e3038f0Sstefano_zampini } 10875b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10885b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10895b003df0Sstefano_zampini stl += lc[i]; 10905e3038f0Sstefano_zampini } 10915e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 1092ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 10939e7b2b25Sstefano_zampini if (istrans[i]) { 10949e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10959e7b2b25Sstefano_zampini } 1096ab4d48faSStefano Zampini } 10975e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 10985e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10995e3038f0Sstefano_zampini } 11005e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11015e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11025e3038f0Sstefano_zampini } 11035e3038f0Sstefano_zampini 11045b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 11055b003df0Sstefano_zampini convert = PETSC_FALSE; 11065b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 11075b003df0Sstefano_zampini if (convert) { 11085b003df0Sstefano_zampini Mat M; 11095b003df0Sstefano_zampini MatISLocalFields lf; 11105b003df0Sstefano_zampini PetscContainer c; 11115b003df0Sstefano_zampini 11125b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 11135b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 11145b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 11155b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 11165b003df0Sstefano_zampini 11175b003df0Sstefano_zampini /* attach local fields to the matrix */ 11185b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 11195b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 11205b003df0Sstefano_zampini for (i=0;i<nr;i++) { 11215b003df0Sstefano_zampini PetscInt n,st; 11225b003df0Sstefano_zampini 11235b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 11245b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 11255b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 11265b003df0Sstefano_zampini } 11275b003df0Sstefano_zampini for (i=0;i<nc;i++) { 11285b003df0Sstefano_zampini PetscInt n,st; 11295b003df0Sstefano_zampini 11305b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 11315b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 11325b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 11335b003df0Sstefano_zampini } 11345b003df0Sstefano_zampini lf->nr = nr; 11355b003df0Sstefano_zampini lf->nc = nc; 11365b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 11375b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 11385b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 11395b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 11405b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 11415b003df0Sstefano_zampini } 11425b003df0Sstefano_zampini 11435e3038f0Sstefano_zampini /* Free workspace */ 11445e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 11455e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 11465e3038f0Sstefano_zampini } 11475e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 11485e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 11495e3038f0Sstefano_zampini } 11509e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 11515b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 11525e3038f0Sstefano_zampini PetscFunctionReturn(0); 11535e3038f0Sstefano_zampini } 11545e3038f0Sstefano_zampini 1155ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1156ad219c80Sstefano_zampini { 1157ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1158ad219c80Sstefano_zampini Vec ll,rr; 1159ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1160ad219c80Sstefano_zampini PetscScalar *x,*y; 1161ad219c80Sstefano_zampini PetscErrorCode ierr; 1162ad219c80Sstefano_zampini 1163ad219c80Sstefano_zampini PetscFunctionBegin; 1164ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 1165ad219c80Sstefano_zampini if (l) { 1166ad219c80Sstefano_zampini ll = matis->y; 1167ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1168ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1169ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1170ad219c80Sstefano_zampini } else { 1171ad219c80Sstefano_zampini ll = NULL; 1172ad219c80Sstefano_zampini } 1173ad219c80Sstefano_zampini if (r) { 1174ad219c80Sstefano_zampini rr = matis->x; 1175ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1176ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1177ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1178ad219c80Sstefano_zampini } else { 1179ad219c80Sstefano_zampini rr = NULL; 1180ad219c80Sstefano_zampini } 1181ad219c80Sstefano_zampini if (ll) { 1182ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1183ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1184ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1185ad219c80Sstefano_zampini } 1186ad219c80Sstefano_zampini if (rr) { 1187ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1188ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1189ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1190ad219c80Sstefano_zampini } 1191ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1192ad219c80Sstefano_zampini PetscFunctionReturn(0); 1193ad219c80Sstefano_zampini } 1194ad219c80Sstefano_zampini 11957fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 11967fa8f2d3SStefano Zampini { 11977fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 11987fa8f2d3SStefano Zampini MatInfo info; 11997fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 12007fa8f2d3SStefano Zampini PetscInt bs; 12017fa8f2d3SStefano Zampini PetscErrorCode ierr; 12027fa8f2d3SStefano Zampini 12037fa8f2d3SStefano Zampini PetscFunctionBegin; 12047fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 12057fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 12067fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 12077fa8f2d3SStefano Zampini isend[0] = info.nz_used; 12087fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 12097fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 12107fa8f2d3SStefano Zampini isend[3] = info.memory; 12117fa8f2d3SStefano Zampini isend[4] = info.mallocs; 12127fa8f2d3SStefano Zampini } else { 12137fa8f2d3SStefano Zampini isend[0] = 0.; 12147fa8f2d3SStefano Zampini isend[1] = 0.; 12157fa8f2d3SStefano Zampini isend[2] = 0.; 12167fa8f2d3SStefano Zampini isend[3] = 0.; 12177fa8f2d3SStefano Zampini isend[4] = 0.; 12187fa8f2d3SStefano Zampini } 12197fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 12207fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 12217fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 12227fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 12237fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 12247fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 12257fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 12267fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 12277fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 12287fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12297fa8f2d3SStefano Zampini 12307fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12317fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12327fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12337fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12347fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12357fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 12367fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 12377fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12387fa8f2d3SStefano Zampini 12397fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12407fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12417fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12427fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12437fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12447fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 1245d7f69cd0SStefano Zampini } 1246d7f69cd0SStefano Zampini ginfo->block_size = bs; 1247d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 1248d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 1249d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 12505e3038f0Sstefano_zampini PetscFunctionReturn(0); 12515e3038f0Sstefano_zampini } 12525e3038f0Sstefano_zampini 1253d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1254d7f69cd0SStefano Zampini { 1255d7f69cd0SStefano Zampini Mat C,lC,lA; 1256d7f69cd0SStefano Zampini PetscErrorCode ierr; 1257d7f69cd0SStefano Zampini 1258d7f69cd0SStefano Zampini PetscFunctionBegin; 1259cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1260cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1261d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1262d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1263d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1264d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1265d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1266d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1267cf37664fSBarry Smith } else { 1268cf37664fSBarry Smith C = *B; 1269d7f69cd0SStefano Zampini } 1270d7f69cd0SStefano Zampini 1271d7f69cd0SStefano Zampini /* perform local transposition */ 1272d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1273d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1274d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1275d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1276d7f69cd0SStefano Zampini 1277cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1278d7f69cd0SStefano Zampini *B = C; 1279d7f69cd0SStefano Zampini } else { 1280d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1281d7f69cd0SStefano Zampini } 12827aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12837aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1284d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1285d7f69cd0SStefano Zampini } 1286d7f69cd0SStefano Zampini 12873fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 12883fd1c9e7SStefano Zampini { 12893fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 12903fd1c9e7SStefano Zampini PetscErrorCode ierr; 12913fd1c9e7SStefano Zampini 12923fd1c9e7SStefano Zampini PetscFunctionBegin; 12934b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 12943fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12953fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12963fd1c9e7SStefano Zampini } 12973fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 12983fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 12993fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13003fd1c9e7SStefano Zampini } 13013fd1c9e7SStefano Zampini 13023fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 13033fd1c9e7SStefano Zampini { 13044b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 13053fd1c9e7SStefano Zampini PetscErrorCode ierr; 13063fd1c9e7SStefano Zampini 13073fd1c9e7SStefano Zampini PetscFunctionBegin; 13084b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 13093fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 13103fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13113fd1c9e7SStefano Zampini } 13123fd1c9e7SStefano Zampini 1313f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1314f26d0771SStefano Zampini { 1315f26d0771SStefano Zampini PetscErrorCode ierr; 1316f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1317f26d0771SStefano Zampini 1318f26d0771SStefano Zampini PetscFunctionBegin; 1319f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1320f26d0771SStefano 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); 1321f26d0771SStefano Zampini #endif 1322f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1323f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1324b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1325f26d0771SStefano Zampini PetscFunctionReturn(0); 1326f26d0771SStefano Zampini } 1327f26d0771SStefano Zampini 1328f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1329f26d0771SStefano Zampini { 1330f26d0771SStefano Zampini PetscErrorCode ierr; 1331f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1332f26d0771SStefano Zampini 1333f26d0771SStefano Zampini PetscFunctionBegin; 1334f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1335f26d0771SStefano 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); 1336f26d0771SStefano Zampini #endif 1337f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1338f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1339b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1340f26d0771SStefano Zampini PetscFunctionReturn(0); 1341f26d0771SStefano Zampini } 1342f26d0771SStefano Zampini 1343f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 1344a8116848SStefano Zampini { 1345a8116848SStefano Zampini PetscInt *owners = map->range; 1346a8116848SStefano Zampini PetscInt n = map->n; 1347a8116848SStefano Zampini PetscSF sf; 1348a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 1349a8116848SStefano Zampini PetscSFNode *ridxs; 1350a8116848SStefano Zampini PetscMPIInt rank; 1351a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 1352a8116848SStefano Zampini PetscErrorCode ierr; 1353a8116848SStefano Zampini 1354a8116848SStefano Zampini PetscFunctionBegin; 1355fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 1356a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 1357a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 1358a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 1359a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 1360a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 1361a8116848SStefano Zampini for (r = 0; r < N; ++r) { 1362a8116848SStefano Zampini const PetscInt idx = idxs[r]; 1363a8116848SStefano 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); 1364a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 1365a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 1366a8116848SStefano Zampini } 1367a8116848SStefano Zampini ridxs[r].rank = p; 1368a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 1369a8116848SStefano Zampini } 1370a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 1371a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 1372a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1373a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1374f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 1375a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 1376f0ae7da4SStefano Zampini 1377f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1378a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 1379a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 1380a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1381a8116848SStefano Zampini start -= cum; 1382a8116848SStefano Zampini cum = 0; 1383a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 1384a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1385a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1386a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 1387a8116848SStefano Zampini } 1388a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1389a8116848SStefano Zampini /* Compress and put in indices */ 1390a8116848SStefano Zampini for (r = 0; r < n; ++r) 1391a8116848SStefano Zampini if (lidxs[r] >= 0) { 1392a8116848SStefano Zampini if (work) work[len] = work[r]; 1393a8116848SStefano Zampini lidxs[len++] = r; 1394a8116848SStefano Zampini } 1395a8116848SStefano Zampini if (on) *on = len; 1396a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 1397a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 1398a8116848SStefano Zampini PetscFunctionReturn(0); 1399a8116848SStefano Zampini } 1400a8116848SStefano Zampini 14017dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1402a8116848SStefano Zampini { 1403a8116848SStefano Zampini Mat locmat,newlocmat; 1404a8116848SStefano Zampini Mat_IS *newmatis; 1405a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1406a8116848SStefano Zampini Vec rtest,ltest; 1407a8116848SStefano Zampini const PetscScalar *array; 1408a8116848SStefano Zampini #endif 1409a8116848SStefano Zampini const PetscInt *idxs; 1410a8116848SStefano Zampini PetscInt i,m,n; 1411a8116848SStefano Zampini PetscErrorCode ierr; 1412a8116848SStefano Zampini 1413a8116848SStefano Zampini PetscFunctionBegin; 1414a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1415a8116848SStefano Zampini PetscBool ismatis; 1416a8116848SStefano Zampini 1417a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1418a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1419a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1420a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1421a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1422a8116848SStefano Zampini } 1423a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1424a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1425a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1426a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1427a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1428a8116848SStefano Zampini for (i=0;i<n;i++) { 1429a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1430a8116848SStefano Zampini } 1431a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1432a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1433a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1434a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1435a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1436fd479f66SMatthew 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])); 1437a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1438a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1439a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1440a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1441a8116848SStefano Zampini for (i=0;i<n;i++) { 1442a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1443a8116848SStefano Zampini } 1444a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1445a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1446a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1447a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1448a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1449fd479f66SMatthew 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])); 1450a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1451a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1452a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1453a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1454a8116848SStefano Zampini #endif 1455a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1456a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1457a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1458a8116848SStefano Zampini IS is; 1459a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1460306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 146194342113SStefano Zampini PetscBool cong; 1462a8116848SStefano Zampini MPI_Comm comm; 1463a8116848SStefano Zampini 1464a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1465306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1466306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1467306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1468306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1469306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1470a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1471a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1472a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1473a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1474a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1475306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1476a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1477a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1478f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1479a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 14803d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 14813d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1482a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1483a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1484a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1485a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1486a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 14873d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1488a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1489a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14903d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1491a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1492a8116848SStefano Zampini lidxs[newloc] = i; 1493a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1494a8116848SStefano Zampini } 1495a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1496a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1497306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1498a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1499a8116848SStefano Zampini /* local is to extract local submatrix */ 1500a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1501a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 150294342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 150394342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1504a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1505a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1506a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1507a8116848SStefano Zampini } else { 1508a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1509a8116848SStefano Zampini 1510a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1511a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1512f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1513a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 15143d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1515a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1516a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1517a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1518a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1519a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 15203d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1521a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1522a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 15233d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1524a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1525a8116848SStefano Zampini lidxs[newloc] = i; 1526a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1527a8116848SStefano Zampini } 1528a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1529a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1530306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1531a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1532a8116848SStefano Zampini /* local is to extract local submatrix */ 1533a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1534a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1535a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1536a8116848SStefano Zampini } 1537a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1538a8116848SStefano Zampini } else { 1539a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1540a8116848SStefano Zampini } 1541a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1542a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 15437dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1544a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1545a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1546a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1547a8116848SStefano Zampini } 1548a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1549a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1550a8116848SStefano Zampini PetscFunctionReturn(0); 1551a8116848SStefano Zampini } 1552a8116848SStefano Zampini 1553a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 15542b404112SStefano Zampini { 15552b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 15562b404112SStefano Zampini PetscBool ismatis; 15572b404112SStefano Zampini PetscErrorCode ierr; 15582b404112SStefano Zampini 15592b404112SStefano Zampini PetscFunctionBegin; 15602b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 15612b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 15622b404112SStefano Zampini b = (Mat_IS*)B->data; 15632b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1564cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 15652b404112SStefano Zampini PetscFunctionReturn(0); 15662b404112SStefano Zampini } 15672b404112SStefano Zampini 1568a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 15696bd84002SStefano Zampini { 1570527b2640SStefano Zampini Vec v; 1571527b2640SStefano Zampini const PetscScalar *array; 1572527b2640SStefano Zampini PetscInt i,n; 15736bd84002SStefano Zampini PetscErrorCode ierr; 15746bd84002SStefano Zampini 15756bd84002SStefano Zampini PetscFunctionBegin; 1576527b2640SStefano Zampini *missing = PETSC_FALSE; 1577527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1578527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1579527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1580527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1581527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1582527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1583527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1584527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1585527b2640SStefano Zampini if (d) { 1586527b2640SStefano Zampini *d = -1; 1587527b2640SStefano Zampini if (*missing) { 1588527b2640SStefano Zampini PetscInt rstart; 1589527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1590527b2640SStefano Zampini *d = i+rstart; 1591527b2640SStefano Zampini } 1592527b2640SStefano Zampini } 15936bd84002SStefano Zampini PetscFunctionReturn(0); 15946bd84002SStefano Zampini } 15956bd84002SStefano Zampini 1596cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 159728f4e0baSStefano Zampini { 159828f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 159928f4e0baSStefano Zampini const PetscInt *gidxs; 16004f2d7cafSStefano Zampini PetscInt nleaves; 160128f4e0baSStefano Zampini PetscErrorCode ierr; 160228f4e0baSStefano Zampini 160328f4e0baSStefano Zampini PetscFunctionBegin; 16044f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 160575d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 160675d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 160728f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 16083bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 16094f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 16104f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 16113bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 16124f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1613a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 16143d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1615a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1616a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 16173d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1618a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 16193d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1620a8116848SStefano Zampini } else { 1621a8116848SStefano Zampini matis->csf = matis->sf; 1622a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1623a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1624a8116848SStefano Zampini } 162528f4e0baSStefano Zampini PetscFunctionReturn(0); 162628f4e0baSStefano Zampini } 16272e1947a5SStefano Zampini 1628eb82efa4SStefano Zampini /*@ 162975d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 163075d48cdbSStefano Zampini 163175d48cdbSStefano Zampini Collective on MPI_Comm 163275d48cdbSStefano Zampini 163375d48cdbSStefano Zampini Input Parameters: 163475d48cdbSStefano Zampini + A - the matrix 163575d48cdbSStefano Zampini - store - the boolean flag 163675d48cdbSStefano Zampini 163775d48cdbSStefano Zampini Level: advanced 163875d48cdbSStefano Zampini 163975d48cdbSStefano Zampini Notes: 164075d48cdbSStefano Zampini 164175d48cdbSStefano Zampini .keywords: matrix 164275d48cdbSStefano Zampini 164375d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 164475d48cdbSStefano Zampini @*/ 164575d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 164675d48cdbSStefano Zampini { 164775d48cdbSStefano Zampini PetscErrorCode ierr; 164875d48cdbSStefano Zampini 164975d48cdbSStefano Zampini PetscFunctionBegin; 165075d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 165175d48cdbSStefano Zampini PetscValidType(A,1); 165275d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 165375d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 165475d48cdbSStefano Zampini PetscFunctionReturn(0); 165575d48cdbSStefano Zampini } 165675d48cdbSStefano Zampini 165775d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 165875d48cdbSStefano Zampini { 165975d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 166075d48cdbSStefano Zampini PetscErrorCode ierr; 166175d48cdbSStefano Zampini 166275d48cdbSStefano Zampini PetscFunctionBegin; 166375d48cdbSStefano Zampini matis->storel2l = store; 166475d48cdbSStefano Zampini if (!store) { 166575d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 166675d48cdbSStefano Zampini } 166775d48cdbSStefano Zampini PetscFunctionReturn(0); 166875d48cdbSStefano Zampini } 166975d48cdbSStefano Zampini 167075d48cdbSStefano Zampini /*@ 1671f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1672f03112d0SStefano Zampini 1673f03112d0SStefano Zampini Collective on MPI_Comm 1674f03112d0SStefano Zampini 1675f03112d0SStefano Zampini Input Parameters: 1676f03112d0SStefano Zampini + A - the matrix 1677f03112d0SStefano Zampini - fix - the boolean flag 1678f03112d0SStefano Zampini 1679f03112d0SStefano Zampini Level: advanced 1680f03112d0SStefano Zampini 1681f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1682f03112d0SStefano Zampini 1683f03112d0SStefano Zampini .keywords: matrix 1684f03112d0SStefano Zampini 1685f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1686f03112d0SStefano Zampini @*/ 1687f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1688f03112d0SStefano Zampini { 1689f03112d0SStefano Zampini PetscErrorCode ierr; 1690f03112d0SStefano Zampini 1691f03112d0SStefano Zampini PetscFunctionBegin; 1692f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1693f03112d0SStefano Zampini PetscValidType(A,1); 1694f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1695f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1696f03112d0SStefano Zampini PetscFunctionReturn(0); 1697f03112d0SStefano Zampini } 1698f03112d0SStefano Zampini 1699f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1700f03112d0SStefano Zampini { 1701f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1702f03112d0SStefano Zampini 1703f03112d0SStefano Zampini PetscFunctionBegin; 1704f03112d0SStefano Zampini matis->locempty = fix; 1705f03112d0SStefano Zampini PetscFunctionReturn(0); 1706f03112d0SStefano Zampini } 1707f03112d0SStefano Zampini 1708f03112d0SStefano Zampini /*@ 1709a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1710a88811baSStefano Zampini 1711a88811baSStefano Zampini Collective on MPI_Comm 1712a88811baSStefano Zampini 1713a88811baSStefano Zampini Input Parameters: 1714a88811baSStefano Zampini + B - the matrix 1715a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1716a88811baSStefano Zampini (same value is used for all local rows) 1717a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1718a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1719a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1720a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1721a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1722a88811baSStefano Zampini the diagonal entry even if it is zero. 1723a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1724a88811baSStefano Zampini submatrix (same value is used for all local rows). 1725a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1726a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1727a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1728a88811baSStefano Zampini structure. The size of this array is equal to the number 1729a88811baSStefano Zampini of local rows, i.e 'm'. 1730a88811baSStefano Zampini 1731a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1732a88811baSStefano Zampini 1733a88811baSStefano Zampini Level: intermediate 1734a88811baSStefano Zampini 173595452b02SPatrick Sanan Notes: 173695452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1737a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1738a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1739a88811baSStefano Zampini 1740a88811baSStefano Zampini .keywords: matrix 1741a88811baSStefano Zampini 17423c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1743a88811baSStefano Zampini @*/ 17442e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 17452e1947a5SStefano Zampini { 17462e1947a5SStefano Zampini PetscErrorCode ierr; 17472e1947a5SStefano Zampini 17482e1947a5SStefano Zampini PetscFunctionBegin; 17492e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 17502e1947a5SStefano Zampini PetscValidType(B,1); 17512e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 17522e1947a5SStefano Zampini PetscFunctionReturn(0); 17532e1947a5SStefano Zampini } 17542e1947a5SStefano Zampini 1755844bd0d7SStefano Zampini /* this is used by DMDA */ 1756844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 17572e1947a5SStefano Zampini { 17582e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 175928f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 17602e1947a5SStefano Zampini PetscErrorCode ierr; 17612e1947a5SStefano Zampini 17622e1947a5SStefano Zampini PetscFunctionBegin; 17636c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1764cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 17654f2d7cafSStefano Zampini 17664f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 17674f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 17684f2d7cafSStefano Zampini 17694f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 17704f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 17714f2d7cafSStefano Zampini 177228f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 177328f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 177428f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 177528f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17764f2d7cafSStefano Zampini 17774f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 177828f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 17790f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 17800f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 17810f2f62c7SStefano Zampini #endif 17824f2d7cafSStefano Zampini 17834f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 178428f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17854f2d7cafSStefano Zampini 17864f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 178728f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17880f2f62c7SStefano Zampini 17890f2f62c7SStefano Zampini /* for other matrix types */ 17900f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 17912e1947a5SStefano Zampini PetscFunctionReturn(0); 17922e1947a5SStefano Zampini } 1793b4319ba4SBarry Smith 17943927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 17953927de2eSStefano Zampini { 17963927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 17973927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1798ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 17993927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 18003927de2eSStefano Zampini PetscInt lrows,lcols; 18013927de2eSStefano Zampini PetscInt local_rows,local_cols; 1802f03112d0SStefano Zampini PetscMPIInt size; 18033927de2eSStefano Zampini PetscBool isdense,issbaij; 18043927de2eSStefano Zampini PetscErrorCode ierr; 18053927de2eSStefano Zampini 18063927de2eSStefano Zampini PetscFunctionBegin; 1807f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 18083927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 18093927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 18103927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 18113927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 18123927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1813ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1814ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 18157230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1816ecf5a873SStefano Zampini } else { 1817ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1818ecf5a873SStefano Zampini } 1819ecf5a873SStefano Zampini 18203927de2eSStefano Zampini if (issbaij) { 18213927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 18223927de2eSStefano Zampini } 18233927de2eSStefano Zampini /* 1824ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 18253927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 18263927de2eSStefano Zampini */ 1827cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 18283927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 18293927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 18303927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 18313927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 18323927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1833f03112d0SStefano Zampini for (i=0;i<size;i++) { 18343927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 18353927de2eSStefano Zampini row_ownership[j] = i; 18363927de2eSStefano Zampini } 18373927de2eSStefano Zampini } 18387230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 18393927de2eSStefano Zampini 18403927de2eSStefano Zampini /* 18413927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 18423927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 18433927de2eSStefano Zampini */ 18443927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 18453927de2eSStefano Zampini /* preallocation as a MATAIJ */ 18463927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 18473927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 184812dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 184912dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1850ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 18513927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 18523927de2eSStefano Zampini my_dnz[i] += 1; 18533927de2eSStefano Zampini } else { /* offdiag block */ 18543927de2eSStefano Zampini my_onz[i] += 1; 18553927de2eSStefano Zampini } 18563927de2eSStefano Zampini } 18573927de2eSStefano Zampini } 1858bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1859bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1860bb1015c3SStefano Zampini PetscBool done; 1861bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1862938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1863bb1015c3SStefano Zampini jptr = jj; 1864bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1865bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1866bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1867bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1868bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1869bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1870bb1015c3SStefano Zampini my_dnz[i] += 1; 1871bb1015c3SStefano Zampini } else { /* offdiag block */ 1872bb1015c3SStefano Zampini my_onz[i] += 1; 1873bb1015c3SStefano Zampini } 1874bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1875bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1876bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1877bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1878bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1879bb1015c3SStefano Zampini } else { 1880bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1881bb1015c3SStefano Zampini } 1882bb1015c3SStefano Zampini } 1883bb1015c3SStefano Zampini } 1884bb1015c3SStefano Zampini } 1885bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1886938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1887bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 18883927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 18893927de2eSStefano Zampini const PetscInt *cols; 1890ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 18913927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18923927de2eSStefano Zampini for (j=0;j<ncols;j++) { 18933927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1894ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 18953927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 18963927de2eSStefano Zampini my_dnz[i] += 1; 18973927de2eSStefano Zampini } else { /* offdiag block */ 18983927de2eSStefano Zampini my_onz[i] += 1; 18993927de2eSStefano Zampini } 19003927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1901d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 19023927de2eSStefano Zampini owner = row_ownership[index_col]; 19033927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1904d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 19053927de2eSStefano Zampini } else { 1906d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 19073927de2eSStefano Zampini } 19083927de2eSStefano Zampini } 19093927de2eSStefano Zampini } 19103927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 19113927de2eSStefano Zampini } 19123927de2eSStefano Zampini } 1913ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 19147230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1915ecf5a873SStefano Zampini } 19164f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 19173927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1918ecf5a873SStefano Zampini 1919ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 19203927de2eSStefano Zampini if (maxreduce) { 19213927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 19223927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1923bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 19243927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 19253927de2eSStefano Zampini } else { 19263927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 19273927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1928bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 19293927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 19303927de2eSStefano Zampini } 19313927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 19323927de2eSStefano Zampini 193353b44cf5SStefano Zampini 193453b44cf5SStefano Zampini 19353927de2eSStefano Zampini /* Resize preallocation if overestimated */ 19363927de2eSStefano Zampini for (i=0;i<lrows;i++) { 19373927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 19383927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 19393927de2eSStefano Zampini } 19401670daf9Sstefano_zampini 19411670daf9Sstefano_zampini /* Set preallocation */ 1942268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 19433927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 194453b44cf5SStefano Zampini for (i=0;i<lrows;i+=bs) { 194553b44cf5SStefano Zampini PetscInt b, d = dnz[i],o = onz[i]; 194653b44cf5SStefano Zampini 194753b44cf5SStefano Zampini for (b=1;b<bs;b++) { 194853b44cf5SStefano Zampini d = PetscMax(d,dnz[i+b]); 194953b44cf5SStefano Zampini o = PetscMax(o,onz[i+b]); 195053b44cf5SStefano Zampini } 195153b44cf5SStefano Zampini dnz[i/bs] = PetscMin(d/bs + d%bs,lcols/bs); 195253b44cf5SStefano Zampini onz[i/bs] = PetscMin(o/bs + o%bs,(cols-lcols)/bs); 19533927de2eSStefano Zampini } 1954268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 19553927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 19563927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 19573927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 19583927de2eSStefano Zampini if (issbaij) { 19593927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 19603927de2eSStefano Zampini } 19619be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19623927de2eSStefano Zampini PetscFunctionReturn(0); 19633927de2eSStefano Zampini } 19643927de2eSStefano Zampini 1965487b449aSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_IS_XAIJ(Mat mat, MatType mtype, MatReuse reuse, Mat *M) 1966b7ce53b6SStefano Zampini { 1967b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1968487b449aSStefano Zampini Mat local_mat,MT; 1969b7ce53b6SStefano Zampini /* info on mat */ 197053b44cf5SStefano Zampini PetscInt rbs,cbs,rows,cols,lrows,lcols; 1971b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1972b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1973b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1974b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1975b9ed4604SStefano Zampini #endif 1976f03112d0SStefano Zampini PetscMPIInt size; 1977b7ce53b6SStefano Zampini /* values insertion */ 1978b7ce53b6SStefano Zampini PetscScalar *array; 1979b7ce53b6SStefano Zampini /* work */ 1980b7ce53b6SStefano Zampini PetscErrorCode ierr; 1981b7ce53b6SStefano Zampini 1982b7ce53b6SStefano Zampini PetscFunctionBegin; 1983b7ce53b6SStefano Zampini /* get info from mat */ 1984f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1985f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 19861670daf9Sstefano_zampini Mat B; 198753b44cf5SStefano Zampini IS irows = NULL,icols = NULL; 1988487b449aSStefano Zampini PetscInt rbs,cbs; 19891670daf9Sstefano_zampini 1990487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 1991487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 199253b44cf5SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { /* check if l2g maps are one-to-one */ 199353b44cf5SStefano Zampini IS rows,cols; 199453b44cf5SStefano Zampini const PetscInt *ridxs,*cidxs; 199553b44cf5SStefano Zampini PetscInt i,nw,*work; 199653b44cf5SStefano Zampini 199753b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 199853b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&nw);CHKERRQ(ierr); 199953b44cf5SStefano Zampini nw = nw/rbs; 200053b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 200153b44cf5SStefano Zampini for (i=0;i<nw;i++) work[ridxs[i]] += 1; 200253b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 200353b44cf5SStefano Zampini if (i == nw) { 200453b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,nw,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 2005acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 200653b44cf5SStefano Zampini ierr = ISInvertPermutation(rows,PETSC_DECIDE,&irows);CHKERRQ(ierr); 2007acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 200853b44cf5SStefano Zampini } 200953b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 201053b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 201153b44cf5SStefano Zampini if (irows && mat->rmap->mapping != mat->cmap->mapping) { 201253b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 201353b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->cmap->mapping,&nw);CHKERRQ(ierr); 201453b44cf5SStefano Zampini nw = nw/cbs; 201553b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 201653b44cf5SStefano Zampini for (i=0;i<nw;i++) work[cidxs[i]] += 1; 201753b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 201853b44cf5SStefano Zampini if (i == nw) { 201953b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,nw,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 202053b44cf5SStefano Zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 202153b44cf5SStefano Zampini ierr = ISInvertPermutation(cols,PETSC_DECIDE,&icols);CHKERRQ(ierr); 202253b44cf5SStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 202353b44cf5SStefano Zampini } 202453b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 202553b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 202653b44cf5SStefano Zampini } else if (irows) { 202753b44cf5SStefano Zampini ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); 202853b44cf5SStefano Zampini icols = irows; 202953b44cf5SStefano Zampini } 203053b44cf5SStefano Zampini } else { 203153b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject*)&irows);CHKERRQ(ierr); 203253b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject*)&icols);CHKERRQ(ierr); 203353b44cf5SStefano Zampini if (irows) { ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); } 203453b44cf5SStefano Zampini if (icols) { ierr = PetscObjectReference((PetscObject)icols);CHKERRQ(ierr); } 203553b44cf5SStefano Zampini } 203653b44cf5SStefano Zampini if (!irows || !icols) { 203753b44cf5SStefano Zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 203853b44cf5SStefano Zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 203953b44cf5SStefano Zampini goto general_assembly; 204053b44cf5SStefano Zampini } 2041487b449aSStefano Zampini ierr = MatConvert(matis->A,(rbs == cbs && rbs > 1) ? MATSEQBAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 2042487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 20437dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 204453b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject)irows);CHKERRQ(ierr); 204553b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject)icols);CHKERRQ(ierr); 2046487b449aSStefano Zampini } else { 2047487b449aSStefano Zampini Mat C; 2048487b449aSStefano Zampini 2049487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 2050487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 2051487b449aSStefano Zampini } 2052acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 2053acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 2054acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 20557c03b4e8SStefano Zampini PetscFunctionReturn(0); 20567c03b4e8SStefano Zampini } 205753b44cf5SStefano Zampini general_assembly: 2058b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 205953b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 206053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 20613cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 2062b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 2063b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 20644099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 2065b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 2066b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 2067b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 2068b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 2069b9ed4604SStefano Zampini lb[0] = isseqdense; 2070b9ed4604SStefano Zampini lb[1] = isseqaij; 2071b9ed4604SStefano Zampini lb[2] = isseqbaij; 2072b9ed4604SStefano Zampini lb[3] = isseqsbaij; 2073b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 2074b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 2075b9ed4604SStefano Zampini #endif 2076b7ce53b6SStefano Zampini 2077487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2078487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 2079487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 2080487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 208153b44cf5SStefano Zampini ierr = MatSetBlockSizes(MT,rbs,cbs);CHKERRQ(ierr); 2082487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 2083b7ce53b6SStefano Zampini } else { 208453b44cf5SStefano Zampini PetscInt mrbs,mcbs,mrows,mcols,mlrows,mlcols; 2085487b449aSStefano Zampini 2086b7ce53b6SStefano Zampini /* some checks */ 2087487b449aSStefano Zampini MT = *M; 208853b44cf5SStefano Zampini ierr = MatGetBlockSizes(MT,&mrbs,&mcbs);CHKERRQ(ierr); 2089487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 2090487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 20916c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 20926c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 20936c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 20946c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 209553b44cf5SStefano Zampini if (mrbs != rbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong row block size (%d != %d)",rbs,mrbs); 209653b44cf5SStefano Zampini if (mcbs != cbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong col block size (%d != %d)",cbs,mcbs); 2097487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 2098b7ce53b6SStefano Zampini } 2099d9a9e74cSStefano Zampini 2100b9ed4604SStefano Zampini if (isseqsbaij) { 2101d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 2102d9a9e74cSStefano Zampini } else { 2103d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 2104d9a9e74cSStefano Zampini local_mat = matis->A; 2105d9a9e74cSStefano Zampini } 2106686e3a49SStefano Zampini 2107b7ce53b6SStefano Zampini /* Set values */ 2108487b449aSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2109b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 211065066ba5SStefano Zampini PetscInt i,*dummy; 2111ecf5a873SStefano Zampini 211265066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 211365066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 2114487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 2115d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 2116487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 2117d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 211865066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 2119686e3a49SStefano Zampini } else if (isseqaij) { 2120ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 2121686e3a49SStefano Zampini PetscBool done; 2122686e3a49SStefano Zampini 2123d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2124938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 2125d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 2126686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 2127487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 2128686e3a49SStefano Zampini } 2129d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2130938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 2131d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 2132686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 2133ecf5a873SStefano Zampini PetscInt i; 2134c0962df8SStefano Zampini 2135686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 2136686e3a49SStefano Zampini PetscInt j; 2137ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 2138686e3a49SStefano Zampini 2139ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 2140487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 2141ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 2142686e3a49SStefano Zampini } 2143b7ce53b6SStefano Zampini } 2144487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2145d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 2146487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2147b9ed4604SStefano Zampini if (isseqdense) { 2148487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 2149487b449aSStefano Zampini } 2150487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 2151487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 2152487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 2153487b449aSStefano Zampini *M = MT; 2154b7ce53b6SStefano Zampini } 2155b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2156b7ce53b6SStefano Zampini } 2157b7ce53b6SStefano Zampini 2158b7ce53b6SStefano Zampini /*@ 2159b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 2160b7ce53b6SStefano Zampini 2161b7ce53b6SStefano Zampini Input Parameter: 2162b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 2163b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 2164b7ce53b6SStefano Zampini 2165b7ce53b6SStefano Zampini Output Parameter: 2166b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 2167b7ce53b6SStefano Zampini 2168b7ce53b6SStefano Zampini Level: developer 2169b7ce53b6SStefano Zampini 217095452b02SPatrick Sanan Notes: 2171487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 2172b7ce53b6SStefano Zampini 2173487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2174b7ce53b6SStefano Zampini @*/ 2175b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2176b7ce53b6SStefano Zampini { 2177b7ce53b6SStefano Zampini PetscErrorCode ierr; 2178b7ce53b6SStefano Zampini 2179b7ce53b6SStefano Zampini PetscFunctionBegin; 2180b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2181b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2182b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2183487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2184b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2185b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 21866c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2187b7ce53b6SStefano Zampini } 2188487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2189b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2190b7ce53b6SStefano Zampini } 2191b7ce53b6SStefano Zampini 2192ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2193ad6194a2SStefano Zampini { 2194ad6194a2SStefano Zampini PetscErrorCode ierr; 2195ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2196c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2197ad6194a2SStefano Zampini Mat B,localmat; 2198ad6194a2SStefano Zampini 2199ad6194a2SStefano Zampini PetscFunctionBegin; 2200c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2201c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2202ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2203ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 2204c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),rbs == cbs ? rbs : 1,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 2205ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2206ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2207b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2208b0f2910eSStefano Zampini if (matis->sf) { 2209b0f2910eSStefano Zampini Mat_IS *bmatis = (Mat_IS*)(B->data); 2210b0f2910eSStefano Zampini 2211b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->sf);CHKERRQ(ierr); 2212b0f2910eSStefano Zampini bmatis->sf = matis->sf; 2213b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&bmatis->sf_rootdata,matis->sf->nleaves,&bmatis->sf_leafdata);CHKERRQ(ierr); 2214b0f2910eSStefano Zampini if (matis->sf != matis->csf) { 2215b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->csf);CHKERRQ(ierr); 2216b0f2910eSStefano Zampini bmatis->csf = matis->csf; 2217b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&bmatis->csf_rootdata,matis->csf->nleaves,&bmatis->csf_leafdata);CHKERRQ(ierr); 2218b0f2910eSStefano Zampini } else { 2219b0f2910eSStefano Zampini bmatis->csf = bmatis->sf; 2220b0f2910eSStefano Zampini bmatis->csf_leafdata = bmatis->sf_leafdata; 2221b0f2910eSStefano Zampini bmatis->csf_rootdata = bmatis->sf_rootdata; 2222b0f2910eSStefano Zampini } 2223b0f2910eSStefano Zampini } 2224ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2225ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2226ad6194a2SStefano Zampini *newmat = B; 2227ad6194a2SStefano Zampini PetscFunctionReturn(0); 2228ad6194a2SStefano Zampini } 2229ad6194a2SStefano Zampini 2230a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 223169796d55SStefano Zampini { 223269796d55SStefano Zampini PetscErrorCode ierr; 223369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 223469796d55SStefano Zampini PetscBool local_sym; 223569796d55SStefano Zampini 223669796d55SStefano Zampini PetscFunctionBegin; 223769796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2238b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 223969796d55SStefano Zampini PetscFunctionReturn(0); 224069796d55SStefano Zampini } 224169796d55SStefano Zampini 2242a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 224369796d55SStefano Zampini { 224469796d55SStefano Zampini PetscErrorCode ierr; 224569796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 224669796d55SStefano Zampini PetscBool local_sym; 224769796d55SStefano Zampini 224869796d55SStefano Zampini PetscFunctionBegin; 224969796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2250b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 225169796d55SStefano Zampini PetscFunctionReturn(0); 225269796d55SStefano Zampini } 225369796d55SStefano Zampini 225445471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 225545471136SStefano Zampini { 225645471136SStefano Zampini PetscErrorCode ierr; 225745471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 225845471136SStefano Zampini PetscBool local_sym; 225945471136SStefano Zampini 226045471136SStefano Zampini PetscFunctionBegin; 226145471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 226245471136SStefano Zampini *flg = PETSC_FALSE; 226345471136SStefano Zampini PetscFunctionReturn(0); 226445471136SStefano Zampini } 226545471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 226645471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 226745471136SStefano Zampini PetscFunctionReturn(0); 226845471136SStefano Zampini } 226945471136SStefano Zampini 2270a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2271b4319ba4SBarry Smith { 2272dfbe8321SBarry Smith PetscErrorCode ierr; 2273b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2274b4319ba4SBarry Smith 2275b4319ba4SBarry Smith PetscFunctionBegin; 22766bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2277e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2278e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 22796bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 22806bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 22813fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2282a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2283a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2284a8116848SStefano Zampini if (b->sf != b->csf) { 2285a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2286a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2287f03112d0SStefano Zampini } else b->csf = NULL; 228828f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 228928f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2290bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2291dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 2292bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2293b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2294b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 22952e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 2296cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 229775d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2298f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2299487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2300487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2301487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2302487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2303487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2304487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2305487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2306b4319ba4SBarry Smith PetscFunctionReturn(0); 2307b4319ba4SBarry Smith } 2308b4319ba4SBarry Smith 2309a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2310b4319ba4SBarry Smith { 2311dfbe8321SBarry Smith PetscErrorCode ierr; 2312b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2313b4319ba4SBarry Smith PetscScalar zero = 0.0; 2314b4319ba4SBarry Smith 2315b4319ba4SBarry Smith PetscFunctionBegin; 2316b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2317e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2318e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2319b4319ba4SBarry Smith 2320b4319ba4SBarry Smith /* multiply the local matrix */ 2321b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2322b4319ba4SBarry Smith 2323b4319ba4SBarry Smith /* scatter product back into global memory */ 23242dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2325e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2326e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2327b4319ba4SBarry Smith PetscFunctionReturn(0); 2328b4319ba4SBarry Smith } 2329b4319ba4SBarry Smith 2330a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23312e74eeadSLisandro Dalcin { 2332650997f4SStefano Zampini Vec temp_vec; 23332e74eeadSLisandro Dalcin PetscErrorCode ierr; 23342e74eeadSLisandro Dalcin 23352e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2336650997f4SStefano Zampini if (v3 != v2) { 2337650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2338650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2339650997f4SStefano Zampini } else { 2340650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2341650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2342650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2343650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2344650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2345650997f4SStefano Zampini } 23462e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23472e74eeadSLisandro Dalcin } 23482e74eeadSLisandro Dalcin 2349a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 23502e74eeadSLisandro Dalcin { 23512e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23522e74eeadSLisandro Dalcin PetscErrorCode ierr; 23532e74eeadSLisandro Dalcin 2354e176bc59SStefano Zampini PetscFunctionBegin; 23552e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2356e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2357e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23582e74eeadSLisandro Dalcin 23592e74eeadSLisandro Dalcin /* multiply the local matrix */ 2360e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 23612e74eeadSLisandro Dalcin 23622e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2363e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2364e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2365e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23662e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23672e74eeadSLisandro Dalcin } 23682e74eeadSLisandro Dalcin 2369a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23702e74eeadSLisandro Dalcin { 2371650997f4SStefano Zampini Vec temp_vec; 23722e74eeadSLisandro Dalcin PetscErrorCode ierr; 23732e74eeadSLisandro Dalcin 23742e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2375650997f4SStefano Zampini if (v3 != v2) { 2376650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2377650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2378650997f4SStefano Zampini } else { 2379650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2380650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2381650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2382650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2383650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2384650997f4SStefano Zampini } 23852e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23862e74eeadSLisandro Dalcin } 23872e74eeadSLisandro Dalcin 2388a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2389b4319ba4SBarry Smith { 2390b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2391dfbe8321SBarry Smith PetscErrorCode ierr; 2392b4319ba4SBarry Smith PetscViewer sviewer; 2393ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2394b4319ba4SBarry Smith 2395b4319ba4SBarry Smith PetscFunctionBegin; 2396ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2397ee2491ecSStefano Zampini if (isascii) { 2398ee2491ecSStefano Zampini PetscViewerFormat format; 2399ee2491ecSStefano Zampini 2400ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2401ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2402ee2491ecSStefano Zampini } 2403ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 24043f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2405b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 24063f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 24076e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2408b4319ba4SBarry Smith PetscFunctionReturn(0); 2409b4319ba4SBarry Smith } 2410b4319ba4SBarry Smith 2411a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2412b4319ba4SBarry Smith { 2413dfbe8321SBarry Smith PetscErrorCode ierr; 2414e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 2415b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2416e176bc59SStefano Zampini Vec cglobal,rglobal; 2417b4319ba4SBarry Smith 2418b4319ba4SBarry Smith PetscFunctionBegin; 2419784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 2420e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 24213bbff08aSStefano Zampini /* Destroy any previous data */ 242270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 242370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 24243fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2425e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2426e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 24271c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2428872cf891SStefano Zampini if (is->csf != is->sf) { 2429872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2430872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2431f03112d0SStefano Zampini } else is->csf = NULL; 243228f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 243328f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 24343bbff08aSStefano Zampini 24353bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2436fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2437fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2438e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2439e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2440e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2441e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 24426625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 24436625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 24446625354bSStefano Zampini PetscBool same,gsame; 24456625354bSStefano Zampini 24466625354bSStefano Zampini same = PETSC_FALSE; 24476625354bSStefano Zampini if (nr == nc && cbs == rbs) { 24486625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 24496625354bSStefano Zampini 24506625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24516625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 24526625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 24536625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24546625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 24556625354bSStefano Zampini } 24566625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 24576625354bSStefano Zampini if (gsame) cmapping = rmapping; 24586625354bSStefano Zampini } 245953b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 246053b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 24616625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 24626625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 24636625354bSStefano Zampini 24646625354bSStefano Zampini /* Create the local matrix A */ 2465f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 2466e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 2467e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2468e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 2469ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2470ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 2471b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 2472c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2473c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2474b4319ba4SBarry Smith 2475f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 247653b44cf5SStefano Zampini IS from; 247753b44cf5SStefano Zampini const PetscInt *garray; 247853b44cf5SStefano Zampini 2479b4319ba4SBarry Smith /* Create the local work vectors */ 24803bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2481b4319ba4SBarry Smith 2482e176bc59SStefano Zampini /* setup the global to local scatters */ 2483e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 248453b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&garray);CHKERRQ(ierr); 248553b44cf5SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 248653b44cf5SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 248753b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&garray);CHKERRQ(ierr); 2488e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 248953b44cf5SStefano Zampini if (rmapping != cmapping) { 249053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&garray);CHKERRQ(ierr); 249153b44cf5SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 249253b44cf5SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 249353b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&garray);CHKERRQ(ierr); 249453b44cf5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 2495e176bc59SStefano Zampini } else { 2496e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 2497e176bc59SStefano Zampini is->cctx = is->rctx; 2498e176bc59SStefano Zampini } 24993fd1c9e7SStefano Zampini 25003fd1c9e7SStefano Zampini /* interface counter vector (local) */ 25013fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 25023fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 25033fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25043fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25053fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 25063fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 25073fd1c9e7SStefano Zampini 25083fd1c9e7SStefano Zampini /* free workspace */ 2509e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2510e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 25116bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 2512f26d0771SStefano Zampini } 251348ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2514b4319ba4SBarry Smith PetscFunctionReturn(0); 2515b4319ba4SBarry Smith } 2516b4319ba4SBarry Smith 2517a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 25182e74eeadSLisandro Dalcin { 25192e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 25202e74eeadSLisandro Dalcin PetscErrorCode ierr; 252197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 252297563a80SStefano Zampini PetscInt i,zm,zn; 252397563a80SStefano Zampini #endif 2524f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 25252e74eeadSLisandro Dalcin 25262e74eeadSLisandro Dalcin PetscFunctionBegin; 25272e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2528f26d0771SStefano 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); 252997563a80SStefano Zampini /* count negative indices */ 253097563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 253197563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 25322e74eeadSLisandro Dalcin #endif 253397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 253497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 253597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 253697563a80SStefano Zampini /* count negative indices (should be the same as before) */ 253797563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 253897563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2539b4f971dfSStefano 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"); 2540b4f971dfSStefano 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"); 254197563a80SStefano Zampini #endif 25422e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 25432e74eeadSLisandro Dalcin PetscFunctionReturn(0); 25442e74eeadSLisandro Dalcin } 25452e74eeadSLisandro Dalcin 2546a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 254797563a80SStefano Zampini { 254897563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 254997563a80SStefano Zampini PetscErrorCode ierr; 255097563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 255197563a80SStefano Zampini PetscInt i,zm,zn; 255297563a80SStefano Zampini #endif 2553f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 255497563a80SStefano Zampini 255597563a80SStefano Zampini PetscFunctionBegin; 255697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2557f26d0771SStefano 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); 255897563a80SStefano Zampini /* count negative indices */ 255997563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 256097563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 256197563a80SStefano Zampini #endif 256297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 256397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 256497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 256597563a80SStefano Zampini /* count negative indices (should be the same as before) */ 256697563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 256797563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2568b4f971dfSStefano 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"); 2569b4f971dfSStefano 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"); 257097563a80SStefano Zampini #endif 2571d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 257297563a80SStefano Zampini PetscFunctionReturn(0); 257397563a80SStefano Zampini } 257497563a80SStefano Zampini 2575a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2576b4319ba4SBarry Smith { 2577dfbe8321SBarry Smith PetscErrorCode ierr; 2578b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2579b4319ba4SBarry Smith 2580b4319ba4SBarry Smith PetscFunctionBegin; 2581b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2582872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2583872cf891SStefano Zampini } else { 2584b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2585872cf891SStefano Zampini } 2586b4319ba4SBarry Smith PetscFunctionReturn(0); 2587b4319ba4SBarry Smith } 2588b4319ba4SBarry Smith 2589a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2590f0006bf2SLisandro Dalcin { 2591f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2592f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2593f0006bf2SLisandro Dalcin 2594f0006bf2SLisandro Dalcin PetscFunctionBegin; 2595b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2596b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2597b4f971dfSStefano Zampini PetscInt ibs,bs; 2598b4f971dfSStefano Zampini 2599b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2600b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2601b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2602b4f971dfSStefano Zampini #endif 2603b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2604b4f971dfSStefano Zampini } else { 2605f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2606b4f971dfSStefano Zampini } 2607f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2608f0006bf2SLisandro Dalcin } 2609f0006bf2SLisandro Dalcin 2610f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2611f0ae7da4SStefano Zampini { 2612f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2613f0ae7da4SStefano Zampini PetscErrorCode ierr; 2614f0ae7da4SStefano Zampini 2615f0ae7da4SStefano Zampini PetscFunctionBegin; 2616f0ae7da4SStefano Zampini if (!n) { 2617f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2618f0ae7da4SStefano Zampini } else { 2619f0ae7da4SStefano Zampini PetscInt i; 2620f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2621f0ae7da4SStefano Zampini 2622f0ae7da4SStefano Zampini if (columns) { 2623f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2624f0ae7da4SStefano Zampini } else { 2625f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2626f0ae7da4SStefano Zampini } 2627f0ae7da4SStefano Zampini if (diag != 0.) { 2628f0ae7da4SStefano Zampini const PetscScalar *array; 2629f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2630f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2631f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2632f0ae7da4SStefano Zampini } 2633f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2634f0ae7da4SStefano Zampini } 2635f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2636f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2637f0ae7da4SStefano Zampini } 2638f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2639f0ae7da4SStefano Zampini } 2640f0ae7da4SStefano Zampini 2641f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 26422e74eeadSLisandro Dalcin { 26436e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 26446e520ac8SStefano Zampini PetscInt nr,nl,len,i; 26456e520ac8SStefano Zampini PetscInt *lrows; 26462e74eeadSLisandro Dalcin PetscErrorCode ierr; 26472e74eeadSLisandro Dalcin 26482e74eeadSLisandro Dalcin PetscFunctionBegin; 2649f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2650f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2651f0ae7da4SStefano Zampini PetscBool cong; 265226b0207aSStefano Zampini 2653f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 265426b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2655268753edSStefano 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"); 2656268753edSStefano 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"); 2657268753edSStefano 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"); 2658f0ae7da4SStefano Zampini } 2659f0ae7da4SStefano Zampini #endif 26606e520ac8SStefano Zampini /* get locally owned rows */ 2661f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 26626e520ac8SStefano Zampini /* fix right hand side if needed */ 26636e520ac8SStefano Zampini if (x && b) { 26646e520ac8SStefano Zampini const PetscScalar *xx; 26656e520ac8SStefano Zampini PetscScalar *bb; 26666e520ac8SStefano Zampini 26676e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 26686e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 26696e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 26706e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 26716e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 26722e74eeadSLisandro Dalcin } 26736e520ac8SStefano Zampini /* get rows associated to the local matrices */ 26743d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 26756e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 26766e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 26776e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 26786e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 26796e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26806e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26816e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26826e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 26836e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2684f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 26856e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26862e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26872e74eeadSLisandro Dalcin } 26882e74eeadSLisandro Dalcin 2689f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2690b4319ba4SBarry Smith { 2691dfbe8321SBarry Smith PetscErrorCode ierr; 2692b4319ba4SBarry Smith 2693b4319ba4SBarry Smith PetscFunctionBegin; 2694f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2695f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2696f0ae7da4SStefano Zampini } 26972205254eSKarl Rupp 2698f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2699f0ae7da4SStefano Zampini { 2700f0ae7da4SStefano Zampini PetscErrorCode ierr; 2701f0ae7da4SStefano Zampini 2702f0ae7da4SStefano Zampini PetscFunctionBegin; 2703f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2704b4319ba4SBarry Smith PetscFunctionReturn(0); 2705b4319ba4SBarry Smith } 2706b4319ba4SBarry Smith 2707a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2708b4319ba4SBarry Smith { 2709b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2710dfbe8321SBarry Smith PetscErrorCode ierr; 2711b4319ba4SBarry Smith 2712b4319ba4SBarry Smith PetscFunctionBegin; 2713b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2714b4319ba4SBarry Smith PetscFunctionReturn(0); 2715b4319ba4SBarry Smith } 2716b4319ba4SBarry Smith 2717a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2718b4319ba4SBarry Smith { 2719b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2720dfbe8321SBarry Smith PetscErrorCode ierr; 2721b4319ba4SBarry Smith 2722b4319ba4SBarry Smith PetscFunctionBegin; 2723b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2724872cf891SStefano Zampini /* fix for local empty rows/cols */ 2725872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2726872cf891SStefano Zampini Mat newlA; 2727f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2728f03112d0SStefano Zampini IS nzr,nzc; 2729f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2730f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2731872cf891SStefano Zampini 2732f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2733f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2734f03112d0SStefano Zampini if (!nzr) { 2735f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2736872cf891SStefano Zampini } 2737f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2738f03112d0SStefano Zampini if (!nzc) { 2739f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2740872cf891SStefano Zampini } 2741f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2742f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2743f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2744f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2745f03112d0SStefano Zampini IS is1,is2; 2746f03112d0SStefano Zampini 2747f03112d0SStefano Zampini /* need new global l2g map */ 2748f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2749f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2750f03112d0SStefano Zampini 2751872cf891SStefano Zampini /* extract valid submatrix */ 2752f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2753f03112d0SStefano Zampini 2754f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2755f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2756f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2757f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2758872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2759f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2760f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2761f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 2762f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2763f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2764f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2765f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2766f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2767f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2768f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 2769f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 2770f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2771f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2772f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2773f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2774f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2775f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2776f03112d0SStefano Zampini newlA = is->A; 2777f03112d0SStefano Zampini } 2778f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2779f03112d0SStefano Zampini if (newl2g) { 2780f03112d0SStefano Zampini IS gnzr,gnzc; 2781f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2782f03112d0SStefano Zampini 2783f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2784f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2785f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2786f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2787f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2788f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2789f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2790f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2791f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2792f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2793f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2794f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2795f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2796f03112d0SStefano Zampini } 2797872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2798872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2799f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2800f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2801872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2802f03112d0SStefano Zampini } 2803b4319ba4SBarry Smith PetscFunctionReturn(0); 2804b4319ba4SBarry Smith } 2805b4319ba4SBarry Smith 2806a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2807b4319ba4SBarry Smith { 2808b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2809b4319ba4SBarry Smith 2810b4319ba4SBarry Smith PetscFunctionBegin; 2811b4319ba4SBarry Smith *local = is->A; 2812b4319ba4SBarry Smith PetscFunctionReturn(0); 2813b4319ba4SBarry Smith } 2814b4319ba4SBarry Smith 28153b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 28163b3b1effSJed Brown { 28173b3b1effSJed Brown PetscFunctionBegin; 28183b3b1effSJed Brown *local = NULL; 28193b3b1effSJed Brown PetscFunctionReturn(0); 28203b3b1effSJed Brown } 28213b3b1effSJed Brown 2822b4319ba4SBarry Smith /*@ 2823b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2824b4319ba4SBarry Smith 2825b4319ba4SBarry Smith Input Parameter: 2826b4319ba4SBarry Smith . mat - the matrix 2827b4319ba4SBarry Smith 2828b4319ba4SBarry Smith Output Parameter: 2829eb82efa4SStefano Zampini . local - the local matrix 2830b4319ba4SBarry Smith 2831b4319ba4SBarry Smith Level: advanced 2832b4319ba4SBarry Smith 2833b4319ba4SBarry Smith Notes: 2834b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2835b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2836b4319ba4SBarry Smith of the MatSetValues() operation. 2837b4319ba4SBarry Smith 28383b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 283996a6f129SJed Brown 2840b4319ba4SBarry Smith .seealso: MATIS 2841b4319ba4SBarry Smith @*/ 28427087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2843b4319ba4SBarry Smith { 28444ac538c5SBarry Smith PetscErrorCode ierr; 2845b4319ba4SBarry Smith 2846b4319ba4SBarry Smith PetscFunctionBegin; 28470700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2848b4319ba4SBarry Smith PetscValidPointer(local,2); 28494ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2850b4319ba4SBarry Smith PetscFunctionReturn(0); 2851b4319ba4SBarry Smith } 2852b4319ba4SBarry Smith 28533b3b1effSJed Brown /*@ 28543b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 28553b3b1effSJed Brown 28563b3b1effSJed Brown Input Parameter: 28573b3b1effSJed Brown . mat - the matrix 28583b3b1effSJed Brown 28593b3b1effSJed Brown Output Parameter: 28603b3b1effSJed Brown . local - the local matrix 28613b3b1effSJed Brown 28623b3b1effSJed Brown Level: advanced 28633b3b1effSJed Brown 28643b3b1effSJed Brown .seealso: MATIS 28653b3b1effSJed Brown @*/ 28663b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 28673b3b1effSJed Brown { 28683b3b1effSJed Brown PetscErrorCode ierr; 28693b3b1effSJed Brown 28703b3b1effSJed Brown PetscFunctionBegin; 28713b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 28723b3b1effSJed Brown PetscValidPointer(local,2); 28733b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 28743b3b1effSJed Brown PetscFunctionReturn(0); 28753b3b1effSJed Brown } 28763b3b1effSJed Brown 2877a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 28783b03a366Sstefano_zampini { 28793b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 28803b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 28813b03a366Sstefano_zampini PetscErrorCode ierr; 28823b03a366Sstefano_zampini 28833b03a366Sstefano_zampini PetscFunctionBegin; 28844e4c7dbeSStefano Zampini if (is->A) { 28853b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 28863b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2887f0ae7da4SStefano 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); 28884e4c7dbeSStefano Zampini } 28893b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 28903b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 28913b03a366Sstefano_zampini is->A = local; 28923b03a366Sstefano_zampini PetscFunctionReturn(0); 28933b03a366Sstefano_zampini } 28943b03a366Sstefano_zampini 28953b03a366Sstefano_zampini /*@ 2896eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 28973b03a366Sstefano_zampini 28983b03a366Sstefano_zampini Input Parameter: 28993b03a366Sstefano_zampini . mat - the matrix 2900eb82efa4SStefano Zampini . local - the local matrix 29013b03a366Sstefano_zampini 29023b03a366Sstefano_zampini Output Parameter: 29033b03a366Sstefano_zampini 29043b03a366Sstefano_zampini Level: advanced 29053b03a366Sstefano_zampini 29063b03a366Sstefano_zampini Notes: 29073b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 29083b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 29093b03a366Sstefano_zampini 29103b03a366Sstefano_zampini .seealso: MATIS 29113b03a366Sstefano_zampini @*/ 29123b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 29133b03a366Sstefano_zampini { 29143b03a366Sstefano_zampini PetscErrorCode ierr; 29153b03a366Sstefano_zampini 29163b03a366Sstefano_zampini PetscFunctionBegin; 29173b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2918b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 29193b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 29203b03a366Sstefano_zampini PetscFunctionReturn(0); 29213b03a366Sstefano_zampini } 29223b03a366Sstefano_zampini 2923a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 29246726f965SBarry Smith { 29256726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 29266726f965SBarry Smith PetscErrorCode ierr; 29276726f965SBarry Smith 29286726f965SBarry Smith PetscFunctionBegin; 29296726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 29306726f965SBarry Smith PetscFunctionReturn(0); 29316726f965SBarry Smith } 29326726f965SBarry Smith 2933a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 29342e74eeadSLisandro Dalcin { 29352e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 29362e74eeadSLisandro Dalcin PetscErrorCode ierr; 29372e74eeadSLisandro Dalcin 29382e74eeadSLisandro Dalcin PetscFunctionBegin; 29392e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 29402e74eeadSLisandro Dalcin PetscFunctionReturn(0); 29412e74eeadSLisandro Dalcin } 29422e74eeadSLisandro Dalcin 2943a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 29442e74eeadSLisandro Dalcin { 29452e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 29462e74eeadSLisandro Dalcin PetscErrorCode ierr; 29472e74eeadSLisandro Dalcin 29482e74eeadSLisandro Dalcin PetscFunctionBegin; 29492e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2950e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 29512e74eeadSLisandro Dalcin 29522e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 29532e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2954e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2955e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 29562e74eeadSLisandro Dalcin PetscFunctionReturn(0); 29572e74eeadSLisandro Dalcin } 29582e74eeadSLisandro Dalcin 2959a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 29606726f965SBarry Smith { 29616726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 29626726f965SBarry Smith PetscErrorCode ierr; 29636726f965SBarry Smith 29646726f965SBarry Smith PetscFunctionBegin; 29654e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 29666726f965SBarry Smith PetscFunctionReturn(0); 29676726f965SBarry Smith } 29686726f965SBarry Smith 2969f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2970f26d0771SStefano Zampini { 2971f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2972f26d0771SStefano Zampini Mat_IS *x; 2973f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2974f26d0771SStefano Zampini PetscBool ismatis; 2975f26d0771SStefano Zampini #endif 2976f26d0771SStefano Zampini PetscErrorCode ierr; 2977f26d0771SStefano Zampini 2978f26d0771SStefano Zampini PetscFunctionBegin; 2979f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2980f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2981f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2982f26d0771SStefano Zampini #endif 2983f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2984f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2985f26d0771SStefano Zampini PetscFunctionReturn(0); 2986f26d0771SStefano Zampini } 2987f26d0771SStefano Zampini 2988f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2989f26d0771SStefano Zampini { 2990f26d0771SStefano Zampini Mat lA; 2991f26d0771SStefano Zampini Mat_IS *matis; 2992f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2993f26d0771SStefano Zampini IS is; 2994f26d0771SStefano Zampini const PetscInt *rg,*rl; 2995f26d0771SStefano Zampini PetscInt nrg; 2996f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2997f26d0771SStefano Zampini PetscErrorCode ierr; 2998f26d0771SStefano Zampini 2999f26d0771SStefano Zampini PetscFunctionBegin; 3000f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3001f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3002f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3003f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 3004f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3005f0ae7da4SStefano 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); 3006f26d0771SStefano Zampini #endif 3007f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3008f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3009f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3010f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3011f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 3012f26d0771SStefano Zampini #else 3013f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3014f26d0771SStefano Zampini #endif 3015f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3016f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3017f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3018f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3019f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3020f26d0771SStefano Zampini /* compute new l2g map for columns */ 3021f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 3022f26d0771SStefano Zampini const PetscInt *cg,*cl; 3023f26d0771SStefano Zampini PetscInt ncg; 3024f26d0771SStefano Zampini PetscInt ncl; 3025f26d0771SStefano Zampini 3026f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3027f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3028f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3029f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 3030f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3031f0ae7da4SStefano 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); 3032f26d0771SStefano Zampini #endif 3033f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3034f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3035f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3036f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3037f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 3038f26d0771SStefano Zampini #else 3039f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3040f26d0771SStefano Zampini #endif 3041f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3042f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3043f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3044f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3045f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3046f26d0771SStefano Zampini } else { 3047f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3048f26d0771SStefano Zampini cl2g = rl2g; 3049f26d0771SStefano Zampini } 3050f26d0771SStefano Zampini /* create the MATIS submatrix */ 3051f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3052f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3053f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3054f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3055b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3056f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3057f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3058f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3059f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3060f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3061f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3062f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3063f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3064f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3065f26d0771SStefano Zampini /* remove unsupported ops */ 3066f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3067f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3068f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3069f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3070f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3071f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3072f26d0771SStefano Zampini PetscFunctionReturn(0); 3073f26d0771SStefano Zampini } 3074f26d0771SStefano Zampini 3075872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3076872cf891SStefano Zampini { 3077872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 3078872cf891SStefano Zampini PetscErrorCode ierr; 3079872cf891SStefano Zampini 3080872cf891SStefano Zampini PetscFunctionBegin; 3081872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3082872cf891SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)A); 3083f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 308475d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 3085872cf891SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 3086872cf891SStefano Zampini PetscFunctionReturn(0); 3087872cf891SStefano Zampini } 3088872cf891SStefano Zampini 3089284134d9SBarry Smith /*@ 30903c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3091284134d9SBarry Smith process but not across processes. 3092284134d9SBarry Smith 3093284134d9SBarry Smith Input Parameters: 3094284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3095e176bc59SStefano Zampini . bs - block size of the matrix 3096df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3097e176bc59SStefano Zampini . rmap - local to global map for rows 3098e176bc59SStefano Zampini - cmap - local to global map for cols 3099284134d9SBarry Smith 3100284134d9SBarry Smith Output Parameter: 3101284134d9SBarry Smith . A - the resulting matrix 3102284134d9SBarry Smith 31038e6c10adSSatish Balay Level: advanced 31048e6c10adSSatish Balay 310595452b02SPatrick Sanan Notes: 310695452b02SPatrick Sanan See MATIS for more details. 31076fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 31086fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 31093c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 3110284134d9SBarry Smith 3111284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3112284134d9SBarry Smith @*/ 3113e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3114284134d9SBarry Smith { 3115284134d9SBarry Smith PetscErrorCode ierr; 3116284134d9SBarry Smith 3117284134d9SBarry Smith PetscFunctionBegin; 31186fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 3119284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3120284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 31216fdf41d1SStefano Zampini if (bs > 0) { 3122284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 31236fdf41d1SStefano Zampini } 3124284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3125e176bc59SStefano Zampini if (rmap && cmap) { 3126e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3127e176bc59SStefano Zampini } else if (!rmap) { 3128e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 3129e176bc59SStefano Zampini } else { 3130e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 3131e176bc59SStefano Zampini } 3132284134d9SBarry Smith PetscFunctionReturn(0); 3133284134d9SBarry Smith } 3134284134d9SBarry Smith 3135b4319ba4SBarry Smith /*MC 3136f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3137b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 3138b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 3139b4319ba4SBarry Smith product is handled "implicitly". 3140b4319ba4SBarry Smith 3141b4319ba4SBarry Smith Operations Provided: 31426726f965SBarry Smith + MatMult() 31432e74eeadSLisandro Dalcin . MatMultAdd() 31442e74eeadSLisandro Dalcin . MatMultTranspose() 31452e74eeadSLisandro Dalcin . MatMultTransposeAdd() 31466726f965SBarry Smith . MatZeroEntries() 31476726f965SBarry Smith . MatSetOption() 31482e74eeadSLisandro Dalcin . MatZeroRows() 31492e74eeadSLisandro Dalcin . MatSetValues() 315097563a80SStefano Zampini . MatSetValuesBlocked() 31516726f965SBarry Smith . MatSetValuesLocal() 315297563a80SStefano Zampini . MatSetValuesBlockedLocal() 31532e74eeadSLisandro Dalcin . MatScale() 31542e74eeadSLisandro Dalcin . MatGetDiagonal() 31552b404112SStefano Zampini . MatMissingDiagonal() 31562b404112SStefano Zampini . MatDuplicate() 31572b404112SStefano Zampini . MatCopy() 3158f26d0771SStefano Zampini . MatAXPY() 31597dae84e0SHong Zhang . MatCreateSubMatrix() 3160f26d0771SStefano Zampini . MatGetLocalSubMatrix() 3161d7f69cd0SStefano Zampini . MatTranspose() 316275d48cdbSStefano Zampini . MatPtAP() (with P of AIJ type) 31636726f965SBarry Smith - MatSetLocalToGlobalMapping() 3164b4319ba4SBarry Smith 3165b4319ba4SBarry Smith Options Database Keys: 316675d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 316775d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 316875d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3169b4319ba4SBarry Smith 317095452b02SPatrick Sanan Notes: 317195452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3172b4319ba4SBarry Smith 3173b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3174b4319ba4SBarry Smith 3175b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3176eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3177b4319ba4SBarry Smith 3178b4319ba4SBarry Smith Level: advanced 3179b4319ba4SBarry Smith 3180f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3181b4319ba4SBarry Smith 3182b4319ba4SBarry Smith M*/ 3183b4319ba4SBarry Smith 31848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3185b4319ba4SBarry Smith { 3186dfbe8321SBarry Smith PetscErrorCode ierr; 3187b4319ba4SBarry Smith Mat_IS *b; 3188b4319ba4SBarry Smith 3189b4319ba4SBarry Smith PetscFunctionBegin; 3190b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 3191b4319ba4SBarry Smith A->data = (void*)b; 3192b4319ba4SBarry Smith 3193e176bc59SStefano Zampini /* matrix ops */ 3194e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3195b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 31962e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 31972e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 31982e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3199b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3200b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 32012e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 320298921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3203b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3204f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 32052e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3206f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3207b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3208b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3209b4319ba4SBarry Smith A->ops->view = MatView_IS; 32106726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 32112e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 32122e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 32136726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 321469796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 321569796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 321645471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3217ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 32186bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 32192b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3220659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 32217dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3222f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 32233fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 32243fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3225d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 32267fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3227ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3228872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3229b4319ba4SBarry Smith 3230b7ce53b6SStefano Zampini /* special MATIS functions */ 3231bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 32323b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3233bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3234487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 32352e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 3236cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 323775d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3238f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3239487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3240487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3241487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3242487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3243487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3244487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3245487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 324617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3247b4319ba4SBarry Smith PetscFunctionReturn(0); 3248b4319ba4SBarry Smith } 3249