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 const PetscScalar *sc; 347c9225affSStefano Zampini PetscScalar *aa; 348c9225affSStefano Zampini const PetscInt *ii,*jj; 349c9225affSStefano Zampini PetscInt i,n,m; 350c9225affSStefano Zampini PetscInt *ecount,**eneighs,n_neigh,*neigh,*n_shared,**shared; 351c9225affSStefano Zampini PetscBool flg; 352c9225affSStefano Zampini PetscErrorCode ierr; 353c9225affSStefano Zampini 354c9225affSStefano Zampini PetscFunctionBegin; 355c9225affSStefano Zampini ierr = VecGetLocalSize(matis->counter,&n);CHKERRQ(ierr); 356c9225affSStefano Zampini ierr = PetscCalloc1(n,&ecount);CHKERRQ(ierr); 357c9225affSStefano Zampini ierr = PetscMalloc1(n,&eneighs);CHKERRQ(ierr); 358c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(A->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 359c9225affSStefano Zampini for (i=1,m=0;i<n_neigh;i++) { 360c9225affSStefano Zampini PetscInt j; 361c9225affSStefano Zampini 362c9225affSStefano Zampini m += n_shared[i]; 363c9225affSStefano Zampini for (j=0;j<n_shared[i];j++) ecount[shared[i][j]]++; 364c9225affSStefano Zampini } 365c9225affSStefano Zampini if (n) { ierr = PetscMalloc1(m,&eneighs[0]);CHKERRQ(ierr); } 366c9225affSStefano Zampini for (i=1;i<n;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 367c9225affSStefano Zampini ierr = PetscMemzero(ecount,n*sizeof(PetscInt));CHKERRQ(ierr); 368c9225affSStefano Zampini for (i=1;i<n_neigh;i++) { 369c9225affSStefano Zampini PetscInt j; 370c9225affSStefano Zampini 371c9225affSStefano Zampini for (j=0;j<n_shared[i];j++) { 372c9225affSStefano Zampini PetscInt k = shared[i][j]; 373c9225affSStefano Zampini 374c9225affSStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 375c9225affSStefano Zampini ecount[k]++; 376c9225affSStefano Zampini } 377c9225affSStefano Zampini } 378c9225affSStefano Zampini for (i=0;i<n;i++) { ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); } 379c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(A->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 380c9225affSStefano Zampini ierr = VecGetArrayRead(matis->counter,&sc);CHKERRQ(ierr); 381c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 382c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 383c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 384c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 385c9225affSStefano Zampini for (i=0;i<n;i++) { 386c9225affSStefano Zampini if (PetscUnlikely(ecount[i])) { 387c9225affSStefano Zampini PetscInt j; 388c9225affSStefano Zampini 389c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 390c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 391c9225affSStefano Zampini PetscScalar scal = 1.0; 392c9225affSStefano Zampini 393c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 394c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 395c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 396c9225affSStefano Zampini } 397c9225affSStefano Zampini } 398c9225affSStefano Zampini aa[j] /= scal; 399c9225affSStefano Zampini } 400c9225affSStefano Zampini } 401c9225affSStefano Zampini } 402c9225affSStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 403c9225affSStefano Zampini if (n) { 404c9225affSStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 405c9225affSStefano Zampini } 406c9225affSStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 407c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 408c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 409c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 410c9225affSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&sc);CHKERRQ(ierr); 411c9225affSStefano Zampini PetscFunctionReturn(0); 412c9225affSStefano Zampini } 413c9225affSStefano Zampini 414c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 415c9225affSStefano Zampini { 416c9225affSStefano Zampini Mat /*Ad,*/Ao; 417c9225affSStefano Zampini IS is; 418c9225affSStefano Zampini MPI_Comm comm; 419c9225affSStefano Zampini const PetscInt *garray; 420c9225affSStefano Zampini PetscInt bs, mode = 0; 421c9225affSStefano Zampini PetscBool ismpiaij,ismpibaij,useAl2g = PETSC_FALSE; 422c9225affSStefano Zampini PetscErrorCode ierr; 423c9225affSStefano Zampini 424c9225affSStefano Zampini PetscFunctionBegin; 425c9225affSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-mat_aij_is_usel2g",&useAl2g,NULL);CHKERRQ(ierr); 426c9225affSStefano Zampini if (useAl2g) { 427c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 428c9225affSStefano Zampini PetscFunctionReturn(0); 429c9225affSStefano Zampini } 430c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 431c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 432c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 433c9225affSStefano Zampini if (ismpiaij) { 434c9225affSStefano Zampini bs = 1; 435c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,NULL,&Ao,&garray);CHKERRQ(ierr); 436c9225affSStefano Zampini } else if (ismpibaij) { 437c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 438c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,NULL,&Ao,&garray);CHKERRQ(ierr); 439c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 440c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 441c9225affSStefano Zampini switch(mode) { 442c9225affSStefano Zampini default: 443c9225affSStefano Zampini if (A->rmap->n) { 444c9225affSStefano Zampini PetscInt i,dc,oc,stc,*aux; 445c9225affSStefano Zampini 446c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 447c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 448c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 449c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 450c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 451c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 452c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 453c9225affSStefano Zampini } else { 454c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 455c9225affSStefano Zampini } 456c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 457c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 458c9225affSStefano Zampini } 459c9225affSStefano Zampini PetscFunctionReturn(0); 460c9225affSStefano Zampini } 461c9225affSStefano Zampini 462c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 463c9225affSStefano Zampini { 464c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 4656989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 4666989cf23SStefano Zampini IS is; 4676989cf23SStefano Zampini MPI_Comm comm; 4686989cf23SStefano Zampini void *ptrs[2]; 4696989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 470c9225affSStefano Zampini const PetscInt *garray; 4716989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 472c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 473c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 4746989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 475c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 476c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 477c9225affSStefano Zampini PetscMPIInt size; 4786989cf23SStefano Zampini PetscErrorCode ierr; 4796989cf23SStefano Zampini 480ab4d48faSStefano Zampini PetscFunctionBegin; 4816989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 482c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 483c9225affSStefano Zampini if (size == 1) { 484c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 485c9225affSStefano Zampini PetscFunctionReturn(0); 486c9225affSStefano Zampini } 487c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 488c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 489c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 490c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 491c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 492c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 493c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 494c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 495c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 496c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 497c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 498c9225affSStefano Zampini } 499c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 500c9225affSStefano Zampini Mat *newlA, lA; 501c9225affSStefano Zampini IS rows, cols; 502c9225affSStefano Zampini const PetscInt *ridx, *cidx; 503c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 504c9225affSStefano Zampini 505c9225affSStefano Zampini if (!B) B = *newmat; 506c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 507c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 508c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 509c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 510c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 511c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 512c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 513c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 514c9225affSStefano Zampini if (rl2g != cl2g) { 515c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 516c9225affSStefano Zampini } else { 517c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 518c9225affSStefano Zampini cols = rows; 519c9225affSStefano Zampini } 520c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 521c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 522c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 523c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 524c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 525c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 526c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 527c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 528c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 529c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 530c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 531c9225affSStefano Zampini } 532c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 533c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 534c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 535c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 536c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 537c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 538c9225affSStefano Zampini else *newmat = B; 539c9225affSStefano Zampini PetscFunctionReturn(0); 540c9225affSStefano Zampini } 541c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 542c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 543c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 544c9225affSStefano Zampini if (ismpiaij) { 545c9225affSStefano Zampini bs = 1; 546c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 547c9225affSStefano Zampini } else if (ismpibaij) { 548c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 549c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 550c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 551c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 552c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 553c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 554c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 555c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 5566989cf23SStefano Zampini 5576989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 5586989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 5596989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 5606989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 561c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 562c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 563c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 564c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 565c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 566c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 567c9225affSStefano Zampini /* store original pointers to be restored later */ 568c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 5696989cf23SStefano Zampini 5706989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 571c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 572c9225affSStefano Zampini if (bs > 1) { 573c9225affSStefano Zampini IS is2; 574c9225affSStefano Zampini 575c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 576c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 577c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 578c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 579c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 580c9225affSStefano Zampini is = is2; 581c9225affSStefano Zampini } 5826989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 5836989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 584e363d98aSStefano Zampini if (dr) { 585c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 586c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 587c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 588c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 589e363d98aSStefano Zampini lc = dc+oc; 590e363d98aSStefano Zampini } else { 591c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 592e363d98aSStefano Zampini lc = 0; 593e363d98aSStefano Zampini } 5946989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 5956989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 5966989cf23SStefano Zampini 5976989cf23SStefano Zampini /* create MATIS object */ 598c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 599c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 600c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 601c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 602c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 6036989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6046989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6056989cf23SStefano Zampini 6066989cf23SStefano Zampini /* merge local matrices */ 6076989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 6086989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 6096989cf23SStefano Zampini ii = aux; 6106989cf23SStefano Zampini jj = aux+dr+1; 6116989cf23SStefano Zampini aa = data; 6126989cf23SStefano Zampini *ii = *(di++) + *(oi++); 6136989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 6146989cf23SStefano Zampini { 6156989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 6166989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 6176989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 6186989cf23SStefano Zampini } 6196989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 620c9225affSStefano Zampini 621c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 622c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 623c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 624c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 625c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 626c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 627c9225affSStefano Zampini 6286989cf23SStefano Zampini ii = aux; 6296989cf23SStefano Zampini jj = aux+dr+1; 6306989cf23SStefano Zampini aa = data; 631e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 6326989cf23SStefano Zampini 6336989cf23SStefano Zampini /* create containers to destroy the data */ 6346989cf23SStefano Zampini ptrs[0] = aux; 6356989cf23SStefano Zampini ptrs[1] = data; 6366989cf23SStefano Zampini for (i=0; i<2; i++) { 6376989cf23SStefano Zampini PetscContainer c; 6386989cf23SStefano Zampini 6396989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 6406989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 641b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 6426989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 6436989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 6446989cf23SStefano Zampini } 645c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 646c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 647c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 648c9225affSStefano Zampini } 6496989cf23SStefano Zampini 6506989cf23SStefano Zampini /* finalize matrix */ 651c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 6526989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 653c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 654c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 655c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 656c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 657c9225affSStefano Zampini } else *newmat = B; 6586989cf23SStefano Zampini PetscFunctionReturn(0); 6596989cf23SStefano Zampini } 6606989cf23SStefano Zampini 661cf0a3239SStefano Zampini /*@ 6623d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 663cf0a3239SStefano Zampini 664cf0a3239SStefano Zampini Collective on MPI_Comm 665cf0a3239SStefano Zampini 666cf0a3239SStefano Zampini Input Parameters: 667cf0a3239SStefano Zampini + A - the matrix 668cf0a3239SStefano Zampini 669cf0a3239SStefano Zampini Level: advanced 670cf0a3239SStefano Zampini 67195452b02SPatrick Sanan Notes: 67295452b02SPatrick Sanan This function does not need to be called by the user. 673cf0a3239SStefano Zampini 674cf0a3239SStefano Zampini .keywords: matrix 675cf0a3239SStefano Zampini 676cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 677cf0a3239SStefano Zampini @*/ 678cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 679cf0a3239SStefano Zampini { 6807fa8f2d3SStefano Zampini PetscErrorCode ierr; 6817fa8f2d3SStefano Zampini 6827fa8f2d3SStefano Zampini PetscFunctionBegin; 683cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 684cf0a3239SStefano Zampini PetscValidType(A,1); 685cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 6867fa8f2d3SStefano Zampini PetscFunctionReturn(0); 6877fa8f2d3SStefano Zampini } 6887fa8f2d3SStefano Zampini 6895e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 6905e3038f0Sstefano_zampini { 6915e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 6925e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 6935e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 6945e3038f0Sstefano_zampini MPI_Comm comm; 6955b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 6965b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 6979e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 6985e3038f0Sstefano_zampini PetscErrorCode ierr; 6995e3038f0Sstefano_zampini 700ab4d48faSStefano Zampini PetscFunctionBegin; 7015e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 7025e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 7035e3038f0Sstefano_zampini rnest = NULL; 7045e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 7055e3038f0Sstefano_zampini PetscBool ismatis,isnest; 7065e3038f0Sstefano_zampini 7075e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 7085e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 7095e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 7105e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 7115e3038f0Sstefano_zampini if (isnest) { 7125e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 7135e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 7145e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 7155e3038f0Sstefano_zampini } 7165e3038f0Sstefano_zampini } 7175e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 7185b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 7199e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 7205e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 7219e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 7225e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 7235e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 7245e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 7255e3038f0Sstefano_zampini PetscBool ismatis; 7269e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 7275e3038f0Sstefano_zampini 7285e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 7295e3038f0Sstefano_zampini if (!nest[i][j]) continue; 7305e3038f0Sstefano_zampini 7315e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 7329e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 7339e7b2b25Sstefano_zampini if (istrans[ij]) { 7349e7b2b25Sstefano_zampini Mat T,lT; 7359e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 7369e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 7379e7b2b25Sstefano_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); 7389e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 7399e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 7409e7b2b25Sstefano_zampini } else { 7415e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 7425e3038f0Sstefano_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); 7439e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 7449e7b2b25Sstefano_zampini } 7455e3038f0Sstefano_zampini 7465e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 7475e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 7489e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 7495e3038f0Sstefano_zampini if (!l1 || !l2) continue; 7505e3038f0Sstefano_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); 7515e3038f0Sstefano_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); 7525e3038f0Sstefano_zampini lr[i] = l1; 7535e3038f0Sstefano_zampini lc[j] = l2; 7545e3038f0Sstefano_zampini 7555e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 7565e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 7575e3038f0Sstefano_zampini } 7585e3038f0Sstefano_zampini } 7595e3038f0Sstefano_zampini 7605e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 7615e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 7625e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 7635e3038f0Sstefano_zampini rl2g = NULL; 7645e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 7655e3038f0Sstefano_zampini PetscInt n1,n2; 7665e3038f0Sstefano_zampini 7675e3038f0Sstefano_zampini if (!nest[i][j]) continue; 7689e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 7699e7b2b25Sstefano_zampini Mat T; 7709e7b2b25Sstefano_zampini 7719e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 7729e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 7739e7b2b25Sstefano_zampini } else { 7745e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 7759e7b2b25Sstefano_zampini } 7765e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 7775e3038f0Sstefano_zampini if (!n1) continue; 7785e3038f0Sstefano_zampini if (!rl2g) { 7795e3038f0Sstefano_zampini rl2g = cl2g; 7805e3038f0Sstefano_zampini } else { 7815e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 7825e3038f0Sstefano_zampini PetscBool same; 7835e3038f0Sstefano_zampini 7845e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 7855e3038f0Sstefano_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); 7865e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 7875e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 7885e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 7895e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 7905e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 7915e3038f0Sstefano_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); 7925e3038f0Sstefano_zampini } 7935e3038f0Sstefano_zampini } 7945e3038f0Sstefano_zampini } 7955e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 7965e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 7975e3038f0Sstefano_zampini rl2g = NULL; 7985e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 7995e3038f0Sstefano_zampini PetscInt n1,n2; 8005e3038f0Sstefano_zampini 8015e3038f0Sstefano_zampini if (!nest[j][i]) continue; 8029e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8039e7b2b25Sstefano_zampini Mat T; 8049e7b2b25Sstefano_zampini 8059e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 8069e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 8079e7b2b25Sstefano_zampini } else { 8085e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 8099e7b2b25Sstefano_zampini } 8105e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 8115e3038f0Sstefano_zampini if (!n1) continue; 8125e3038f0Sstefano_zampini if (!rl2g) { 8135e3038f0Sstefano_zampini rl2g = cl2g; 8145e3038f0Sstefano_zampini } else { 8155e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 8165e3038f0Sstefano_zampini PetscBool same; 8175e3038f0Sstefano_zampini 8185e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 8195e3038f0Sstefano_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); 8205e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 8215e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 8225e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 8235e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 8245e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 8255e3038f0Sstefano_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); 8265e3038f0Sstefano_zampini } 8275e3038f0Sstefano_zampini } 8285e3038f0Sstefano_zampini } 8295e3038f0Sstefano_zampini #endif 8305e3038f0Sstefano_zampini 8315e3038f0Sstefano_zampini B = NULL; 8325e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 8335b003df0Sstefano_zampini PetscInt stl; 8345b003df0Sstefano_zampini 8355e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 8365e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 8375e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 8385b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 8395e3038f0Sstefano_zampini Mat usedmat; 8405e3038f0Sstefano_zampini Mat_IS *matis; 8415e3038f0Sstefano_zampini const PetscInt *idxs; 8425e3038f0Sstefano_zampini 8435e3038f0Sstefano_zampini /* local IS for local NEST */ 8445b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 8455e3038f0Sstefano_zampini 8465e3038f0Sstefano_zampini /* l2gmap */ 8475e3038f0Sstefano_zampini j = 0; 8485e3038f0Sstefano_zampini usedmat = nest[i][j]; 8499e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 8509e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 8519e7b2b25Sstefano_zampini 8529e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8539e7b2b25Sstefano_zampini Mat T; 8549e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 8559e7b2b25Sstefano_zampini usedmat = T; 8569e7b2b25Sstefano_zampini } 85782d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 8585e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 8595e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 8609e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8619e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8629e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8639e7b2b25Sstefano_zampini } else { 8645e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8655e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8669e7b2b25Sstefano_zampini } 8675e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 8685e3038f0Sstefano_zampini stl += lr[i]; 8695e3038f0Sstefano_zampini } 8705e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 8715e3038f0Sstefano_zampini 8725e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 8735e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 8745e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 8755b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 8765e3038f0Sstefano_zampini Mat usedmat; 8775e3038f0Sstefano_zampini Mat_IS *matis; 8785e3038f0Sstefano_zampini const PetscInt *idxs; 8795e3038f0Sstefano_zampini 8805e3038f0Sstefano_zampini /* local IS for local NEST */ 8815b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 8825e3038f0Sstefano_zampini 8835e3038f0Sstefano_zampini /* l2gmap */ 8845e3038f0Sstefano_zampini j = 0; 8855e3038f0Sstefano_zampini usedmat = nest[j][i]; 8869e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 8879e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 8889e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8899e7b2b25Sstefano_zampini Mat T; 8909e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 8919e7b2b25Sstefano_zampini usedmat = T; 8929e7b2b25Sstefano_zampini } 89382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 8945e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 8955e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 8969e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8979e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8989e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8999e7b2b25Sstefano_zampini } else { 9005e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9015e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9029e7b2b25Sstefano_zampini } 9035e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 9045e3038f0Sstefano_zampini stl += lc[i]; 9055e3038f0Sstefano_zampini } 9065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 9075e3038f0Sstefano_zampini 9085e3038f0Sstefano_zampini /* Create MATIS */ 9095e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 9105e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 9115e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 9125e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 9135e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 9145e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 9155e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 9165e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 9175e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 9189e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 9199e7b2b25Sstefano_zampini if (istrans[i]) { 9209e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 9219e7b2b25Sstefano_zampini } 9229e7b2b25Sstefano_zampini } 9235e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 9245e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 9255e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9265e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9275e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 9285e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 9295e3038f0Sstefano_zampini } else { 9305e3038f0Sstefano_zampini *newmat = B; 9315e3038f0Sstefano_zampini } 9325e3038f0Sstefano_zampini } else { 9335e3038f0Sstefano_zampini if (lreuse) { 9345e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 9355e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 9365e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 9375e3038f0Sstefano_zampini if (snest[i*nc+j]) { 9385e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 9399e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9409e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 9419e7b2b25Sstefano_zampini } 9425e3038f0Sstefano_zampini } 9435e3038f0Sstefano_zampini } 9445e3038f0Sstefano_zampini } 9455e3038f0Sstefano_zampini } else { 9465b003df0Sstefano_zampini PetscInt stl; 9475b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9485b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9495b003df0Sstefano_zampini stl += lr[i]; 9505e3038f0Sstefano_zampini } 9515b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 9525b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 9535b003df0Sstefano_zampini stl += lc[i]; 9545e3038f0Sstefano_zampini } 9555e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 956ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 9579e7b2b25Sstefano_zampini if (istrans[i]) { 9589e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 9599e7b2b25Sstefano_zampini } 960ab4d48faSStefano Zampini } 9615e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 9625e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 9635e3038f0Sstefano_zampini } 9645e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9655e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9665e3038f0Sstefano_zampini } 9675e3038f0Sstefano_zampini 9685b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 9695b003df0Sstefano_zampini convert = PETSC_FALSE; 9705b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 9715b003df0Sstefano_zampini if (convert) { 9725b003df0Sstefano_zampini Mat M; 9735b003df0Sstefano_zampini MatISLocalFields lf; 9745b003df0Sstefano_zampini PetscContainer c; 9755b003df0Sstefano_zampini 9765b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 9775b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 9785b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 9795b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 9805b003df0Sstefano_zampini 9815b003df0Sstefano_zampini /* attach local fields to the matrix */ 9825b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 9835b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 9845b003df0Sstefano_zampini for (i=0;i<nr;i++) { 9855b003df0Sstefano_zampini PetscInt n,st; 9865b003df0Sstefano_zampini 9875b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 9885b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 9895b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 9905b003df0Sstefano_zampini } 9915b003df0Sstefano_zampini for (i=0;i<nc;i++) { 9925b003df0Sstefano_zampini PetscInt n,st; 9935b003df0Sstefano_zampini 9945b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 9955b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 9965b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 9975b003df0Sstefano_zampini } 9985b003df0Sstefano_zampini lf->nr = nr; 9995b003df0Sstefano_zampini lf->nc = nc; 10005b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 10015b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 10025b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 10035b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 10045b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 10055b003df0Sstefano_zampini } 10065b003df0Sstefano_zampini 10075e3038f0Sstefano_zampini /* Free workspace */ 10085e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10095e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 10105e3038f0Sstefano_zampini } 10115e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 10125e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 10135e3038f0Sstefano_zampini } 10149e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 10155b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 10165e3038f0Sstefano_zampini PetscFunctionReturn(0); 10175e3038f0Sstefano_zampini } 10185e3038f0Sstefano_zampini 1019ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1020ad219c80Sstefano_zampini { 1021ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1022ad219c80Sstefano_zampini Vec ll,rr; 1023ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1024ad219c80Sstefano_zampini PetscScalar *x,*y; 1025ad219c80Sstefano_zampini PetscErrorCode ierr; 1026ad219c80Sstefano_zampini 1027ad219c80Sstefano_zampini PetscFunctionBegin; 1028ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 1029ad219c80Sstefano_zampini if (l) { 1030ad219c80Sstefano_zampini ll = matis->y; 1031ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1032ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1033ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1034ad219c80Sstefano_zampini } else { 1035ad219c80Sstefano_zampini ll = NULL; 1036ad219c80Sstefano_zampini } 1037ad219c80Sstefano_zampini if (r) { 1038ad219c80Sstefano_zampini rr = matis->x; 1039ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1040ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1041ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1042ad219c80Sstefano_zampini } else { 1043ad219c80Sstefano_zampini rr = NULL; 1044ad219c80Sstefano_zampini } 1045ad219c80Sstefano_zampini if (ll) { 1046ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1047ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1048ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1049ad219c80Sstefano_zampini } 1050ad219c80Sstefano_zampini if (rr) { 1051ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1052ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1053ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1054ad219c80Sstefano_zampini } 1055ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1056ad219c80Sstefano_zampini PetscFunctionReturn(0); 1057ad219c80Sstefano_zampini } 1058ad219c80Sstefano_zampini 10597fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 10607fa8f2d3SStefano Zampini { 10617fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 10627fa8f2d3SStefano Zampini MatInfo info; 10637fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 10647fa8f2d3SStefano Zampini PetscInt bs; 10657fa8f2d3SStefano Zampini PetscErrorCode ierr; 10667fa8f2d3SStefano Zampini 10677fa8f2d3SStefano Zampini PetscFunctionBegin; 10687fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10697fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 10707fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 10717fa8f2d3SStefano Zampini isend[0] = info.nz_used; 10727fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 10737fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 10747fa8f2d3SStefano Zampini isend[3] = info.memory; 10757fa8f2d3SStefano Zampini isend[4] = info.mallocs; 10767fa8f2d3SStefano Zampini } else { 10777fa8f2d3SStefano Zampini isend[0] = 0.; 10787fa8f2d3SStefano Zampini isend[1] = 0.; 10797fa8f2d3SStefano Zampini isend[2] = 0.; 10807fa8f2d3SStefano Zampini isend[3] = 0.; 10817fa8f2d3SStefano Zampini isend[4] = 0.; 10827fa8f2d3SStefano Zampini } 10837fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 10847fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 10857fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 10867fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 10877fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 10887fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 10897fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 10907fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 10917fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 10927fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 10937fa8f2d3SStefano Zampini 10947fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 10957fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 10967fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 10977fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 10987fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 10997fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 11007fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 11017fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 11027fa8f2d3SStefano Zampini 11037fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 11047fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 11057fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 11067fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 11077fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 11087fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 1109d7f69cd0SStefano Zampini } 1110d7f69cd0SStefano Zampini ginfo->block_size = bs; 1111d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 1112d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 1113d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 11145e3038f0Sstefano_zampini PetscFunctionReturn(0); 11155e3038f0Sstefano_zampini } 11165e3038f0Sstefano_zampini 1117d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1118d7f69cd0SStefano Zampini { 1119d7f69cd0SStefano Zampini Mat C,lC,lA; 1120d7f69cd0SStefano Zampini PetscErrorCode ierr; 1121d7f69cd0SStefano Zampini 1122d7f69cd0SStefano Zampini PetscFunctionBegin; 1123cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1124cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1125d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1126d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1127d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1128d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1129d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1130d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1131cf37664fSBarry Smith } else { 1132cf37664fSBarry Smith C = *B; 1133d7f69cd0SStefano Zampini } 1134d7f69cd0SStefano Zampini 1135d7f69cd0SStefano Zampini /* perform local transposition */ 1136d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1137d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1138d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1139d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1140d7f69cd0SStefano Zampini 1141cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1142d7f69cd0SStefano Zampini *B = C; 1143d7f69cd0SStefano Zampini } else { 1144d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1145d7f69cd0SStefano Zampini } 11467aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11477aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1148d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1149d7f69cd0SStefano Zampini } 1150d7f69cd0SStefano Zampini 11513fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 11523fd1c9e7SStefano Zampini { 11533fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 11543fd1c9e7SStefano Zampini PetscErrorCode ierr; 11553fd1c9e7SStefano Zampini 11563fd1c9e7SStefano Zampini PetscFunctionBegin; 11574b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 11583fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11593fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11603fd1c9e7SStefano Zampini } 11613fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 11623fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 11633fd1c9e7SStefano Zampini PetscFunctionReturn(0); 11643fd1c9e7SStefano Zampini } 11653fd1c9e7SStefano Zampini 11663fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 11673fd1c9e7SStefano Zampini { 11684b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 11693fd1c9e7SStefano Zampini PetscErrorCode ierr; 11703fd1c9e7SStefano Zampini 11713fd1c9e7SStefano Zampini PetscFunctionBegin; 11724b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 11733fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 11743fd1c9e7SStefano Zampini PetscFunctionReturn(0); 11753fd1c9e7SStefano Zampini } 11763fd1c9e7SStefano Zampini 1177f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1178f26d0771SStefano Zampini { 1179f26d0771SStefano Zampini PetscErrorCode ierr; 1180f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1181f26d0771SStefano Zampini 1182f26d0771SStefano Zampini PetscFunctionBegin; 1183f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1184f26d0771SStefano 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); 1185f26d0771SStefano Zampini #endif 1186f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1187f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1188b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1189f26d0771SStefano Zampini PetscFunctionReturn(0); 1190f26d0771SStefano Zampini } 1191f26d0771SStefano Zampini 1192f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1193f26d0771SStefano Zampini { 1194f26d0771SStefano Zampini PetscErrorCode ierr; 1195f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1196f26d0771SStefano Zampini 1197f26d0771SStefano Zampini PetscFunctionBegin; 1198f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1199f26d0771SStefano 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); 1200f26d0771SStefano Zampini #endif 1201f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1202f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1203b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1204f26d0771SStefano Zampini PetscFunctionReturn(0); 1205f26d0771SStefano Zampini } 1206f26d0771SStefano Zampini 1207f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 1208a8116848SStefano Zampini { 1209a8116848SStefano Zampini PetscInt *owners = map->range; 1210a8116848SStefano Zampini PetscInt n = map->n; 1211a8116848SStefano Zampini PetscSF sf; 1212a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 1213a8116848SStefano Zampini PetscSFNode *ridxs; 1214a8116848SStefano Zampini PetscMPIInt rank; 1215a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 1216a8116848SStefano Zampini PetscErrorCode ierr; 1217a8116848SStefano Zampini 1218a8116848SStefano Zampini PetscFunctionBegin; 1219fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 1220a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 1221a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 1222a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 1223a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 1224a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 1225a8116848SStefano Zampini for (r = 0; r < N; ++r) { 1226a8116848SStefano Zampini const PetscInt idx = idxs[r]; 1227a8116848SStefano 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); 1228a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 1229a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 1230a8116848SStefano Zampini } 1231a8116848SStefano Zampini ridxs[r].rank = p; 1232a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 1233a8116848SStefano Zampini } 1234a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 1235a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 1236a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1237a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1238f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 1239a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 1240f0ae7da4SStefano Zampini 1241f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1242a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 1243a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 1244a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1245a8116848SStefano Zampini start -= cum; 1246a8116848SStefano Zampini cum = 0; 1247a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 1248a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1249a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1250a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 1251a8116848SStefano Zampini } 1252a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1253a8116848SStefano Zampini /* Compress and put in indices */ 1254a8116848SStefano Zampini for (r = 0; r < n; ++r) 1255a8116848SStefano Zampini if (lidxs[r] >= 0) { 1256a8116848SStefano Zampini if (work) work[len] = work[r]; 1257a8116848SStefano Zampini lidxs[len++] = r; 1258a8116848SStefano Zampini } 1259a8116848SStefano Zampini if (on) *on = len; 1260a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 1261a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 1262a8116848SStefano Zampini PetscFunctionReturn(0); 1263a8116848SStefano Zampini } 1264a8116848SStefano Zampini 12657dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1266a8116848SStefano Zampini { 1267a8116848SStefano Zampini Mat locmat,newlocmat; 1268a8116848SStefano Zampini Mat_IS *newmatis; 1269a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1270a8116848SStefano Zampini Vec rtest,ltest; 1271a8116848SStefano Zampini const PetscScalar *array; 1272a8116848SStefano Zampini #endif 1273a8116848SStefano Zampini const PetscInt *idxs; 1274a8116848SStefano Zampini PetscInt i,m,n; 1275a8116848SStefano Zampini PetscErrorCode ierr; 1276a8116848SStefano Zampini 1277a8116848SStefano Zampini PetscFunctionBegin; 1278a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1279a8116848SStefano Zampini PetscBool ismatis; 1280a8116848SStefano Zampini 1281a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1282a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1283a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1284a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1285a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1286a8116848SStefano Zampini } 1287a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1288a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1289a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1290a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1291a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1292a8116848SStefano Zampini for (i=0;i<n;i++) { 1293a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1294a8116848SStefano Zampini } 1295a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1296a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1297a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1298a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1299a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1300fd479f66SMatthew 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])); 1301a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1302a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1303a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1304a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1305a8116848SStefano Zampini for (i=0;i<n;i++) { 1306a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1307a8116848SStefano Zampini } 1308a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1309a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1310a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1311a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1312a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1313fd479f66SMatthew 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])); 1314a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1315a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1316a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1317a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1318a8116848SStefano Zampini #endif 1319a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1320a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1321a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1322a8116848SStefano Zampini IS is; 1323a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1324306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 132594342113SStefano Zampini PetscBool cong; 1326a8116848SStefano Zampini MPI_Comm comm; 1327a8116848SStefano Zampini 1328a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1329306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1330306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1331306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1332306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1333306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1334a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1335a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1336a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1337a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1338a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1339306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1340a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1341a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1342f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1343a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 13443d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 13453d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1346a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1347a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1348a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1349a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1350a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13513d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1352a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1353a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 13543d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1355a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1356a8116848SStefano Zampini lidxs[newloc] = i; 1357a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1358a8116848SStefano Zampini } 1359a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1360a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1361306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1362a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1363a8116848SStefano Zampini /* local is to extract local submatrix */ 1364a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1365a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 136694342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 136794342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1368a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1369a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1370a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1371a8116848SStefano Zampini } else { 1372a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1373a8116848SStefano Zampini 1374a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1375a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1376f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1377a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 13783d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1379a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1380a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1381a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1382a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1383a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 13843d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1385a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1386a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 13873d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1388a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1389a8116848SStefano Zampini lidxs[newloc] = i; 1390a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1391a8116848SStefano Zampini } 1392a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1393a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1394306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1395a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1396a8116848SStefano Zampini /* local is to extract local submatrix */ 1397a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1398a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1399a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1400a8116848SStefano Zampini } 1401a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1402a8116848SStefano Zampini } else { 1403a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1404a8116848SStefano Zampini } 1405a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1406a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 14077dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1408a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1409a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1410a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1411a8116848SStefano Zampini } 1412a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1413a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1414a8116848SStefano Zampini PetscFunctionReturn(0); 1415a8116848SStefano Zampini } 1416a8116848SStefano Zampini 1417a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 14182b404112SStefano Zampini { 14192b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 14202b404112SStefano Zampini PetscBool ismatis; 14212b404112SStefano Zampini PetscErrorCode ierr; 14222b404112SStefano Zampini 14232b404112SStefano Zampini PetscFunctionBegin; 14242b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 14252b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 14262b404112SStefano Zampini b = (Mat_IS*)B->data; 14272b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1428cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 14292b404112SStefano Zampini PetscFunctionReturn(0); 14302b404112SStefano Zampini } 14312b404112SStefano Zampini 1432a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 14336bd84002SStefano Zampini { 1434527b2640SStefano Zampini Vec v; 1435527b2640SStefano Zampini const PetscScalar *array; 1436527b2640SStefano Zampini PetscInt i,n; 14376bd84002SStefano Zampini PetscErrorCode ierr; 14386bd84002SStefano Zampini 14396bd84002SStefano Zampini PetscFunctionBegin; 1440527b2640SStefano Zampini *missing = PETSC_FALSE; 1441527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1442527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1443527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1444527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1445527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1446527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1447527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1448527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1449527b2640SStefano Zampini if (d) { 1450527b2640SStefano Zampini *d = -1; 1451527b2640SStefano Zampini if (*missing) { 1452527b2640SStefano Zampini PetscInt rstart; 1453527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1454527b2640SStefano Zampini *d = i+rstart; 1455527b2640SStefano Zampini } 1456527b2640SStefano Zampini } 14576bd84002SStefano Zampini PetscFunctionReturn(0); 14586bd84002SStefano Zampini } 14596bd84002SStefano Zampini 1460cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 146128f4e0baSStefano Zampini { 146228f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 146328f4e0baSStefano Zampini const PetscInt *gidxs; 14644f2d7cafSStefano Zampini PetscInt nleaves; 146528f4e0baSStefano Zampini PetscErrorCode ierr; 146628f4e0baSStefano Zampini 146728f4e0baSStefano Zampini PetscFunctionBegin; 14684f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 146975d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 147075d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 147128f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 14723bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 14734f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 14744f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 14753bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 14764f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1477a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 14783d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1479a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1480a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 14813d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1482a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 14833d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1484a8116848SStefano Zampini } else { 1485a8116848SStefano Zampini matis->csf = matis->sf; 1486a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1487a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1488a8116848SStefano Zampini } 148928f4e0baSStefano Zampini PetscFunctionReturn(0); 149028f4e0baSStefano Zampini } 14912e1947a5SStefano Zampini 1492eb82efa4SStefano Zampini /*@ 149375d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 149475d48cdbSStefano Zampini 149575d48cdbSStefano Zampini Collective on MPI_Comm 149675d48cdbSStefano Zampini 149775d48cdbSStefano Zampini Input Parameters: 149875d48cdbSStefano Zampini + A - the matrix 149975d48cdbSStefano Zampini - store - the boolean flag 150075d48cdbSStefano Zampini 150175d48cdbSStefano Zampini Level: advanced 150275d48cdbSStefano Zampini 150375d48cdbSStefano Zampini Notes: 150475d48cdbSStefano Zampini 150575d48cdbSStefano Zampini .keywords: matrix 150675d48cdbSStefano Zampini 150775d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 150875d48cdbSStefano Zampini @*/ 150975d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 151075d48cdbSStefano Zampini { 151175d48cdbSStefano Zampini PetscErrorCode ierr; 151275d48cdbSStefano Zampini 151375d48cdbSStefano Zampini PetscFunctionBegin; 151475d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 151575d48cdbSStefano Zampini PetscValidType(A,1); 151675d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 151775d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 151875d48cdbSStefano Zampini PetscFunctionReturn(0); 151975d48cdbSStefano Zampini } 152075d48cdbSStefano Zampini 152175d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 152275d48cdbSStefano Zampini { 152375d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 152475d48cdbSStefano Zampini PetscErrorCode ierr; 152575d48cdbSStefano Zampini 152675d48cdbSStefano Zampini PetscFunctionBegin; 152775d48cdbSStefano Zampini matis->storel2l = store; 152875d48cdbSStefano Zampini if (!store) { 152975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 153075d48cdbSStefano Zampini } 153175d48cdbSStefano Zampini PetscFunctionReturn(0); 153275d48cdbSStefano Zampini } 153375d48cdbSStefano Zampini 153475d48cdbSStefano Zampini /*@ 1535*f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1536*f03112d0SStefano Zampini 1537*f03112d0SStefano Zampini Collective on MPI_Comm 1538*f03112d0SStefano Zampini 1539*f03112d0SStefano Zampini Input Parameters: 1540*f03112d0SStefano Zampini + A - the matrix 1541*f03112d0SStefano Zampini - fix - the boolean flag 1542*f03112d0SStefano Zampini 1543*f03112d0SStefano Zampini Level: advanced 1544*f03112d0SStefano Zampini 1545*f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1546*f03112d0SStefano Zampini 1547*f03112d0SStefano Zampini .keywords: matrix 1548*f03112d0SStefano Zampini 1549*f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1550*f03112d0SStefano Zampini @*/ 1551*f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1552*f03112d0SStefano Zampini { 1553*f03112d0SStefano Zampini PetscErrorCode ierr; 1554*f03112d0SStefano Zampini 1555*f03112d0SStefano Zampini PetscFunctionBegin; 1556*f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1557*f03112d0SStefano Zampini PetscValidType(A,1); 1558*f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1559*f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1560*f03112d0SStefano Zampini PetscFunctionReturn(0); 1561*f03112d0SStefano Zampini } 1562*f03112d0SStefano Zampini 1563*f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1564*f03112d0SStefano Zampini { 1565*f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1566*f03112d0SStefano Zampini 1567*f03112d0SStefano Zampini PetscFunctionBegin; 1568*f03112d0SStefano Zampini matis->locempty = fix; 1569*f03112d0SStefano Zampini PetscFunctionReturn(0); 1570*f03112d0SStefano Zampini } 1571*f03112d0SStefano Zampini 1572*f03112d0SStefano Zampini /*@ 1573a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1574a88811baSStefano Zampini 1575a88811baSStefano Zampini Collective on MPI_Comm 1576a88811baSStefano Zampini 1577a88811baSStefano Zampini Input Parameters: 1578a88811baSStefano Zampini + B - the matrix 1579a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1580a88811baSStefano Zampini (same value is used for all local rows) 1581a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1582a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1583a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1584a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1585a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1586a88811baSStefano Zampini the diagonal entry even if it is zero. 1587a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1588a88811baSStefano Zampini submatrix (same value is used for all local rows). 1589a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1590a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1591a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1592a88811baSStefano Zampini structure. The size of this array is equal to the number 1593a88811baSStefano Zampini of local rows, i.e 'm'. 1594a88811baSStefano Zampini 1595a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1596a88811baSStefano Zampini 1597a88811baSStefano Zampini Level: intermediate 1598a88811baSStefano Zampini 159995452b02SPatrick Sanan Notes: 160095452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1601a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1602a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1603a88811baSStefano Zampini 1604a88811baSStefano Zampini .keywords: matrix 1605a88811baSStefano Zampini 16063c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1607a88811baSStefano Zampini @*/ 16082e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16092e1947a5SStefano Zampini { 16102e1947a5SStefano Zampini PetscErrorCode ierr; 16112e1947a5SStefano Zampini 16122e1947a5SStefano Zampini PetscFunctionBegin; 16132e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 16142e1947a5SStefano Zampini PetscValidType(B,1); 16152e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 16162e1947a5SStefano Zampini PetscFunctionReturn(0); 16172e1947a5SStefano Zampini } 16182e1947a5SStefano Zampini 1619844bd0d7SStefano Zampini /* this is used by DMDA */ 1620844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16212e1947a5SStefano Zampini { 16222e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 162328f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 16242e1947a5SStefano Zampini PetscErrorCode ierr; 16252e1947a5SStefano Zampini 16262e1947a5SStefano Zampini PetscFunctionBegin; 16276c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1628cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 16294f2d7cafSStefano Zampini 16304f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 16314f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 16324f2d7cafSStefano Zampini 16334f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 16344f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 16354f2d7cafSStefano Zampini 163628f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 163728f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 163828f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 163928f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 16404f2d7cafSStefano Zampini 16414f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 164228f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 16430f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 16440f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 16450f2f62c7SStefano Zampini #endif 16464f2d7cafSStefano Zampini 16474f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 164828f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 16494f2d7cafSStefano Zampini 16504f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 165128f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 16520f2f62c7SStefano Zampini 16530f2f62c7SStefano Zampini /* for other matrix types */ 16540f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 16552e1947a5SStefano Zampini PetscFunctionReturn(0); 16562e1947a5SStefano Zampini } 1657b4319ba4SBarry Smith 16583927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 16593927de2eSStefano Zampini { 16603927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 16613927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1662ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 16633927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 16643927de2eSStefano Zampini PetscInt lrows,lcols; 16653927de2eSStefano Zampini PetscInt local_rows,local_cols; 1666*f03112d0SStefano Zampini PetscMPIInt size; 16673927de2eSStefano Zampini PetscBool isdense,issbaij; 16683927de2eSStefano Zampini PetscErrorCode ierr; 16693927de2eSStefano Zampini 16703927de2eSStefano Zampini PetscFunctionBegin; 1671*f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 16723927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 16733927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 16743927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 16753927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 16763927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1677ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1678ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 16797230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1680ecf5a873SStefano Zampini } else { 1681ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1682ecf5a873SStefano Zampini } 1683ecf5a873SStefano Zampini 16843927de2eSStefano Zampini if (issbaij) { 16853927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 16863927de2eSStefano Zampini } 16873927de2eSStefano Zampini /* 1688ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 16893927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 16903927de2eSStefano Zampini */ 1691cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 16923927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 16933927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 16943927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 16953927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 16963927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1697*f03112d0SStefano Zampini for (i=0;i<size;i++) { 16983927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 16993927de2eSStefano Zampini row_ownership[j] = i; 17003927de2eSStefano Zampini } 17013927de2eSStefano Zampini } 17027230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 17033927de2eSStefano Zampini 17043927de2eSStefano Zampini /* 17053927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 17063927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 17073927de2eSStefano Zampini */ 17083927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 17093927de2eSStefano Zampini /* preallocation as a MATAIJ */ 17103927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 17113927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 171212dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 171312dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1714ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 17153927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 17163927de2eSStefano Zampini my_dnz[i] += 1; 17173927de2eSStefano Zampini } else { /* offdiag block */ 17183927de2eSStefano Zampini my_onz[i] += 1; 17193927de2eSStefano Zampini } 17203927de2eSStefano Zampini } 17213927de2eSStefano Zampini } 1722bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1723bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1724bb1015c3SStefano Zampini PetscBool done; 1725bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1726938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1727bb1015c3SStefano Zampini jptr = jj; 1728bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1729bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1730bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1731bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1732bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1733bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1734bb1015c3SStefano Zampini my_dnz[i] += 1; 1735bb1015c3SStefano Zampini } else { /* offdiag block */ 1736bb1015c3SStefano Zampini my_onz[i] += 1; 1737bb1015c3SStefano Zampini } 1738bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1739bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1740bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1741bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1742bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1743bb1015c3SStefano Zampini } else { 1744bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1745bb1015c3SStefano Zampini } 1746bb1015c3SStefano Zampini } 1747bb1015c3SStefano Zampini } 1748bb1015c3SStefano Zampini } 1749bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1750938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1751bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 17523927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 17533927de2eSStefano Zampini const PetscInt *cols; 1754ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 17553927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 17563927de2eSStefano Zampini for (j=0;j<ncols;j++) { 17573927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1758ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 17593927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 17603927de2eSStefano Zampini my_dnz[i] += 1; 17613927de2eSStefano Zampini } else { /* offdiag block */ 17623927de2eSStefano Zampini my_onz[i] += 1; 17633927de2eSStefano Zampini } 17643927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1765d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 17663927de2eSStefano Zampini owner = row_ownership[index_col]; 17673927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1768d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 17693927de2eSStefano Zampini } else { 1770d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 17713927de2eSStefano Zampini } 17723927de2eSStefano Zampini } 17733927de2eSStefano Zampini } 17743927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 17753927de2eSStefano Zampini } 17763927de2eSStefano Zampini } 1777ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 17787230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1779ecf5a873SStefano Zampini } 17804f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 17813927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1782ecf5a873SStefano Zampini 1783ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 17843927de2eSStefano Zampini if (maxreduce) { 17853927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 17863927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1787bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 17883927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 17893927de2eSStefano Zampini } else { 17903927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 17913927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1792bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 17933927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 17943927de2eSStefano Zampini } 17953927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 17963927de2eSStefano Zampini 17973927de2eSStefano Zampini /* Resize preallocation if overestimated */ 17983927de2eSStefano Zampini for (i=0;i<lrows;i++) { 17993927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 18003927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 18013927de2eSStefano Zampini } 18021670daf9Sstefano_zampini 18031670daf9Sstefano_zampini /* Set preallocation */ 1804268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 18053927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 18063927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 18073927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 18083927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 18093927de2eSStefano Zampini } 1810268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 18113927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18123927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18133927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 18143927de2eSStefano Zampini if (issbaij) { 18153927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 18163927de2eSStefano Zampini } 18179be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 18183927de2eSStefano Zampini PetscFunctionReturn(0); 18193927de2eSStefano Zampini } 18203927de2eSStefano Zampini 1821487b449aSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_IS_XAIJ(Mat mat, MatType mtype, MatReuse reuse, Mat *M) 1822b7ce53b6SStefano Zampini { 1823b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1824487b449aSStefano Zampini Mat local_mat,MT; 1825b7ce53b6SStefano Zampini /* info on mat */ 18263cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1827b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1828b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1829b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1830b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1831b9ed4604SStefano Zampini #endif 1832*f03112d0SStefano Zampini PetscMPIInt size; 1833b7ce53b6SStefano Zampini /* values insertion */ 1834b7ce53b6SStefano Zampini PetscScalar *array; 1835b7ce53b6SStefano Zampini /* work */ 1836b7ce53b6SStefano Zampini PetscErrorCode ierr; 1837b7ce53b6SStefano Zampini 1838b7ce53b6SStefano Zampini PetscFunctionBegin; 1839b7ce53b6SStefano Zampini /* get info from mat */ 1840*f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1841*f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 18421670daf9Sstefano_zampini Mat B; 18431670daf9Sstefano_zampini IS rows,cols; 1844acdf38a7Sstefano_zampini IS irows,icols; 18451670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 1846487b449aSStefano Zampini PetscInt rbs,cbs; 18471670daf9Sstefano_zampini 1848487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 1849487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1850487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 1851487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 1852487b449aSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 1853487b449aSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 1854acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1855acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1856acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1857acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1858487b449aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 1859487b449aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1860acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1861acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 1862487b449aSStefano Zampini ierr = MatConvert(matis->A,(rbs == cbs && rbs > 1) ? MATSEQBAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1863487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 18647dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1865487b449aSStefano Zampini } else { 1866487b449aSStefano Zampini Mat C; 1867487b449aSStefano Zampini 1868487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 1869487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 1870487b449aSStefano Zampini } 1871acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1872acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1873acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 18747c03b4e8SStefano Zampini PetscFunctionReturn(0); 18757c03b4e8SStefano Zampini } 1876b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1877b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 18783cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1879b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1880b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 18814099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1882b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1883b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1884b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1885b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1886b9ed4604SStefano Zampini lb[0] = isseqdense; 1887b9ed4604SStefano Zampini lb[1] = isseqaij; 1888b9ed4604SStefano Zampini lb[2] = isseqbaij; 1889b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1890b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1891b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1892b9ed4604SStefano Zampini #endif 1893b7ce53b6SStefano Zampini 1894487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1895487b449aSStefano Zampini PetscBool isaij; 1896487b449aSStefano Zampini 1897487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 1898487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 1899487b449aSStefano Zampini ierr = PetscStrcmp(mtype,MATAIJ,&isaij);CHKERRQ(ierr); 1900487b449aSStefano Zampini if (isaij) { 1901b9ed4604SStefano Zampini if (!isseqsbaij) { 1902487b449aSStefano Zampini ierr = MatSetType(MT,MATAIJ);CHKERRQ(ierr); 1903b9ed4604SStefano Zampini } else { 1904487b449aSStefano Zampini ierr = MatSetType(MT,MATSBAIJ);CHKERRQ(ierr); 1905b9ed4604SStefano Zampini } 1906487b449aSStefano Zampini } else { 1907487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 1908487b449aSStefano Zampini } 1909487b449aSStefano Zampini ierr = MatSetBlockSize(MT,bs);CHKERRQ(ierr); 1910487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 1911b7ce53b6SStefano Zampini } else { 19123cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1913487b449aSStefano Zampini 1914b7ce53b6SStefano Zampini /* some checks */ 1915487b449aSStefano Zampini MT = *M; 1916487b449aSStefano Zampini ierr = MatGetBlockSize(MT,&mbs);CHKERRQ(ierr); 1917487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 1918487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 19196c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 19206c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 19216c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 19226c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 19236c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1924487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 1925b7ce53b6SStefano Zampini } 1926d9a9e74cSStefano Zampini 1927b9ed4604SStefano Zampini if (isseqsbaij) { 1928d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1929d9a9e74cSStefano Zampini } else { 1930d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1931d9a9e74cSStefano Zampini local_mat = matis->A; 1932d9a9e74cSStefano Zampini } 1933686e3a49SStefano Zampini 1934b7ce53b6SStefano Zampini /* Set values */ 1935487b449aSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1936b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 193765066ba5SStefano Zampini PetscInt i,*dummy; 1938ecf5a873SStefano Zampini 193965066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 194065066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 1941487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1942d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 1943487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 1944d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 194565066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 1946686e3a49SStefano Zampini } else if (isseqaij) { 1947ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1948686e3a49SStefano Zampini PetscBool done; 1949686e3a49SStefano Zampini 1950d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1951938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1952d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1953686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1954487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1955686e3a49SStefano Zampini } 1956d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1957938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1958d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1959686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1960ecf5a873SStefano Zampini PetscInt i; 1961c0962df8SStefano Zampini 1962686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1963686e3a49SStefano Zampini PetscInt j; 1964ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1965686e3a49SStefano Zampini 1966ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1967487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1968ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1969686e3a49SStefano Zampini } 1970b7ce53b6SStefano Zampini } 1971487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1972d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1973487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1974b9ed4604SStefano Zampini if (isseqdense) { 1975487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1976487b449aSStefano Zampini } 1977487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 1978487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 1979487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 1980487b449aSStefano Zampini *M = MT; 1981b7ce53b6SStefano Zampini } 1982b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1983b7ce53b6SStefano Zampini } 1984b7ce53b6SStefano Zampini 1985b7ce53b6SStefano Zampini /*@ 1986b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1987b7ce53b6SStefano Zampini 1988b7ce53b6SStefano Zampini Input Parameter: 1989b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1990b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1991b7ce53b6SStefano Zampini 1992b7ce53b6SStefano Zampini Output Parameter: 1993b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1994b7ce53b6SStefano Zampini 1995b7ce53b6SStefano Zampini Level: developer 1996b7ce53b6SStefano Zampini 199795452b02SPatrick Sanan Notes: 1998487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 1999b7ce53b6SStefano Zampini 2000487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2001b7ce53b6SStefano Zampini @*/ 2002b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2003b7ce53b6SStefano Zampini { 2004b7ce53b6SStefano Zampini PetscErrorCode ierr; 2005b7ce53b6SStefano Zampini 2006b7ce53b6SStefano Zampini PetscFunctionBegin; 2007b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2008b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2009b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2010487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2011b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2012b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 20136c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2014b7ce53b6SStefano Zampini } 2015487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2016b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2017b7ce53b6SStefano Zampini } 2018b7ce53b6SStefano Zampini 2019ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2020ad6194a2SStefano Zampini { 2021ad6194a2SStefano Zampini PetscErrorCode ierr; 2022ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2023c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2024ad6194a2SStefano Zampini Mat B,localmat; 2025ad6194a2SStefano Zampini 2026ad6194a2SStefano Zampini PetscFunctionBegin; 2027c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2028c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2029ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2030ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 2031c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),rbs == cbs ? rbs : 1,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 2032ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2033ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2034b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2035b0f2910eSStefano Zampini if (matis->sf) { 2036b0f2910eSStefano Zampini Mat_IS *bmatis = (Mat_IS*)(B->data); 2037b0f2910eSStefano Zampini 2038b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->sf);CHKERRQ(ierr); 2039b0f2910eSStefano Zampini bmatis->sf = matis->sf; 2040b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&bmatis->sf_rootdata,matis->sf->nleaves,&bmatis->sf_leafdata);CHKERRQ(ierr); 2041b0f2910eSStefano Zampini if (matis->sf != matis->csf) { 2042b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->csf);CHKERRQ(ierr); 2043b0f2910eSStefano Zampini bmatis->csf = matis->csf; 2044b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&bmatis->csf_rootdata,matis->csf->nleaves,&bmatis->csf_leafdata);CHKERRQ(ierr); 2045b0f2910eSStefano Zampini } else { 2046b0f2910eSStefano Zampini bmatis->csf = bmatis->sf; 2047b0f2910eSStefano Zampini bmatis->csf_leafdata = bmatis->sf_leafdata; 2048b0f2910eSStefano Zampini bmatis->csf_rootdata = bmatis->sf_rootdata; 2049b0f2910eSStefano Zampini } 2050b0f2910eSStefano Zampini } 2051ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2052ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2053ad6194a2SStefano Zampini *newmat = B; 2054ad6194a2SStefano Zampini PetscFunctionReturn(0); 2055ad6194a2SStefano Zampini } 2056ad6194a2SStefano Zampini 2057a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 205869796d55SStefano Zampini { 205969796d55SStefano Zampini PetscErrorCode ierr; 206069796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 206169796d55SStefano Zampini PetscBool local_sym; 206269796d55SStefano Zampini 206369796d55SStefano Zampini PetscFunctionBegin; 206469796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2065b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 206669796d55SStefano Zampini PetscFunctionReturn(0); 206769796d55SStefano Zampini } 206869796d55SStefano Zampini 2069a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 207069796d55SStefano Zampini { 207169796d55SStefano Zampini PetscErrorCode ierr; 207269796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 207369796d55SStefano Zampini PetscBool local_sym; 207469796d55SStefano Zampini 207569796d55SStefano Zampini PetscFunctionBegin; 207669796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2077b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 207869796d55SStefano Zampini PetscFunctionReturn(0); 207969796d55SStefano Zampini } 208069796d55SStefano Zampini 208145471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 208245471136SStefano Zampini { 208345471136SStefano Zampini PetscErrorCode ierr; 208445471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 208545471136SStefano Zampini PetscBool local_sym; 208645471136SStefano Zampini 208745471136SStefano Zampini PetscFunctionBegin; 208845471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 208945471136SStefano Zampini *flg = PETSC_FALSE; 209045471136SStefano Zampini PetscFunctionReturn(0); 209145471136SStefano Zampini } 209245471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 209345471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 209445471136SStefano Zampini PetscFunctionReturn(0); 209545471136SStefano Zampini } 209645471136SStefano Zampini 2097a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2098b4319ba4SBarry Smith { 2099dfbe8321SBarry Smith PetscErrorCode ierr; 2100b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2101b4319ba4SBarry Smith 2102b4319ba4SBarry Smith PetscFunctionBegin; 21036bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2104e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2105e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 21066bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 21076bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 21083fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2109a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2110a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2111a8116848SStefano Zampini if (b->sf != b->csf) { 2112a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2113a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2114*f03112d0SStefano Zampini } else b->csf = NULL; 211528f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 211628f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2117bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2118dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 2119bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2120b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2121b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 21222e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 2123cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 212475d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2125*f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2126487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2127487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2128487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2129487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2130487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2131487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2132487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2133b4319ba4SBarry Smith PetscFunctionReturn(0); 2134b4319ba4SBarry Smith } 2135b4319ba4SBarry Smith 2136a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2137b4319ba4SBarry Smith { 2138dfbe8321SBarry Smith PetscErrorCode ierr; 2139b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2140b4319ba4SBarry Smith PetscScalar zero = 0.0; 2141b4319ba4SBarry Smith 2142b4319ba4SBarry Smith PetscFunctionBegin; 2143b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2144e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2145e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2146b4319ba4SBarry Smith 2147b4319ba4SBarry Smith /* multiply the local matrix */ 2148b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2149b4319ba4SBarry Smith 2150b4319ba4SBarry Smith /* scatter product back into global memory */ 21512dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2152e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2153e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2154b4319ba4SBarry Smith PetscFunctionReturn(0); 2155b4319ba4SBarry Smith } 2156b4319ba4SBarry Smith 2157a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 21582e74eeadSLisandro Dalcin { 2159650997f4SStefano Zampini Vec temp_vec; 21602e74eeadSLisandro Dalcin PetscErrorCode ierr; 21612e74eeadSLisandro Dalcin 21622e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2163650997f4SStefano Zampini if (v3 != v2) { 2164650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2165650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2166650997f4SStefano Zampini } else { 2167650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2168650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2169650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2170650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2171650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2172650997f4SStefano Zampini } 21732e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21742e74eeadSLisandro Dalcin } 21752e74eeadSLisandro Dalcin 2176a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 21772e74eeadSLisandro Dalcin { 21782e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 21792e74eeadSLisandro Dalcin PetscErrorCode ierr; 21802e74eeadSLisandro Dalcin 2181e176bc59SStefano Zampini PetscFunctionBegin; 21822e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2183e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2184e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21852e74eeadSLisandro Dalcin 21862e74eeadSLisandro Dalcin /* multiply the local matrix */ 2187e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 21882e74eeadSLisandro Dalcin 21892e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2190e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2191e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2192e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21932e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21942e74eeadSLisandro Dalcin } 21952e74eeadSLisandro Dalcin 2196a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 21972e74eeadSLisandro Dalcin { 2198650997f4SStefano Zampini Vec temp_vec; 21992e74eeadSLisandro Dalcin PetscErrorCode ierr; 22002e74eeadSLisandro Dalcin 22012e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2202650997f4SStefano Zampini if (v3 != v2) { 2203650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2204650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2205650997f4SStefano Zampini } else { 2206650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2207650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2208650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2209650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2210650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2211650997f4SStefano Zampini } 22122e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22132e74eeadSLisandro Dalcin } 22142e74eeadSLisandro Dalcin 2215a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2216b4319ba4SBarry Smith { 2217b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2218dfbe8321SBarry Smith PetscErrorCode ierr; 2219b4319ba4SBarry Smith PetscViewer sviewer; 2220ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2221b4319ba4SBarry Smith 2222b4319ba4SBarry Smith PetscFunctionBegin; 2223ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2224ee2491ecSStefano Zampini if (isascii) { 2225ee2491ecSStefano Zampini PetscViewerFormat format; 2226ee2491ecSStefano Zampini 2227ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2228ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2229ee2491ecSStefano Zampini } 2230ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 22313f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2232b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 22333f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 22346e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2235b4319ba4SBarry Smith PetscFunctionReturn(0); 2236b4319ba4SBarry Smith } 2237b4319ba4SBarry Smith 2238a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2239b4319ba4SBarry Smith { 2240dfbe8321SBarry Smith PetscErrorCode ierr; 2241e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 2242b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2243b4319ba4SBarry Smith IS from,to; 2244e176bc59SStefano Zampini Vec cglobal,rglobal; 2245b4319ba4SBarry Smith 2246b4319ba4SBarry Smith PetscFunctionBegin; 2247784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 2248e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 22493bbff08aSStefano Zampini /* Destroy any previous data */ 225070cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 225170cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 22523fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2253e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2254e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 22551c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2256872cf891SStefano Zampini if (is->csf != is->sf) { 2257872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2258872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2259*f03112d0SStefano Zampini } else is->csf = NULL; 226028f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 226128f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 22623bbff08aSStefano Zampini 22633bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2264fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2265fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2266e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2267e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2268e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2269e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 22706625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 22716625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 22726625354bSStefano Zampini PetscBool same,gsame; 22736625354bSStefano Zampini 22746625354bSStefano Zampini same = PETSC_FALSE; 22756625354bSStefano Zampini if (nr == nc && cbs == rbs) { 22766625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 22776625354bSStefano Zampini 22786625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 22796625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 22806625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 22816625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 22826625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 22836625354bSStefano Zampini } 22846625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 22856625354bSStefano Zampini if (gsame) cmapping = rmapping; 22866625354bSStefano Zampini } 22876625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 22886625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 22896625354bSStefano Zampini 22906625354bSStefano Zampini /* Create the local matrix A */ 2291f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 2292e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 2293e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2294e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 2295ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2296ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 2297b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 2298c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2299c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2300b4319ba4SBarry Smith 2301f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 2302b4319ba4SBarry Smith /* Create the local work vectors */ 23033bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2304b4319ba4SBarry Smith 2305e176bc59SStefano Zampini /* setup the global to local scatters */ 2306e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 2307e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 2308784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 2309e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 2310e176bc59SStefano Zampini if (rmapping != cmapping) { 2311e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 2312e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 2313e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 2314e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 2315e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 2316e176bc59SStefano Zampini } else { 2317e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 2318e176bc59SStefano Zampini is->cctx = is->rctx; 2319e176bc59SStefano Zampini } 23203fd1c9e7SStefano Zampini 23213fd1c9e7SStefano Zampini /* interface counter vector (local) */ 23223fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 23233fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 23243fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23253fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23263fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23273fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23283fd1c9e7SStefano Zampini 23293fd1c9e7SStefano Zampini /* free workspace */ 2330e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2331e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 23326bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 23336bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 2334f26d0771SStefano Zampini } 233548ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2336b4319ba4SBarry Smith PetscFunctionReturn(0); 2337b4319ba4SBarry Smith } 2338b4319ba4SBarry Smith 2339a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 23402e74eeadSLisandro Dalcin { 23412e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 23422e74eeadSLisandro Dalcin PetscErrorCode ierr; 234397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 234497563a80SStefano Zampini PetscInt i,zm,zn; 234597563a80SStefano Zampini #endif 2346f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 23472e74eeadSLisandro Dalcin 23482e74eeadSLisandro Dalcin PetscFunctionBegin; 23492e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2350f26d0771SStefano 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); 235197563a80SStefano Zampini /* count negative indices */ 235297563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 235397563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 23542e74eeadSLisandro Dalcin #endif 235597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 235697563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 235797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 235897563a80SStefano Zampini /* count negative indices (should be the same as before) */ 235997563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 236097563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2361b4f971dfSStefano 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"); 2362b4f971dfSStefano 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"); 236397563a80SStefano Zampini #endif 23642e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 23652e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23662e74eeadSLisandro Dalcin } 23672e74eeadSLisandro Dalcin 2368a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 236997563a80SStefano Zampini { 237097563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 237197563a80SStefano Zampini PetscErrorCode ierr; 237297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 237397563a80SStefano Zampini PetscInt i,zm,zn; 237497563a80SStefano Zampini #endif 2375f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 237697563a80SStefano Zampini 237797563a80SStefano Zampini PetscFunctionBegin; 237897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2379f26d0771SStefano 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); 238097563a80SStefano Zampini /* count negative indices */ 238197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 238297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 238397563a80SStefano Zampini #endif 238497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 238597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 238697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 238797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 238897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 238997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2390b4f971dfSStefano 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"); 2391b4f971dfSStefano 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"); 239297563a80SStefano Zampini #endif 2393d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 239497563a80SStefano Zampini PetscFunctionReturn(0); 239597563a80SStefano Zampini } 239697563a80SStefano Zampini 2397a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2398b4319ba4SBarry Smith { 2399dfbe8321SBarry Smith PetscErrorCode ierr; 2400b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2401b4319ba4SBarry Smith 2402b4319ba4SBarry Smith PetscFunctionBegin; 2403b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2404872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2405872cf891SStefano Zampini } else { 2406b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2407872cf891SStefano Zampini } 2408b4319ba4SBarry Smith PetscFunctionReturn(0); 2409b4319ba4SBarry Smith } 2410b4319ba4SBarry Smith 2411a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2412f0006bf2SLisandro Dalcin { 2413f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2414f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2415f0006bf2SLisandro Dalcin 2416f0006bf2SLisandro Dalcin PetscFunctionBegin; 2417b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2418b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2419b4f971dfSStefano Zampini PetscInt ibs,bs; 2420b4f971dfSStefano Zampini 2421b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2422b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2423b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2424b4f971dfSStefano Zampini #endif 2425b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2426b4f971dfSStefano Zampini } else { 2427f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2428b4f971dfSStefano Zampini } 2429f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2430f0006bf2SLisandro Dalcin } 2431f0006bf2SLisandro Dalcin 2432f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2433f0ae7da4SStefano Zampini { 2434f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2435f0ae7da4SStefano Zampini PetscErrorCode ierr; 2436f0ae7da4SStefano Zampini 2437f0ae7da4SStefano Zampini PetscFunctionBegin; 2438f0ae7da4SStefano Zampini if (!n) { 2439f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2440f0ae7da4SStefano Zampini } else { 2441f0ae7da4SStefano Zampini PetscInt i; 2442f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2443f0ae7da4SStefano Zampini 2444f0ae7da4SStefano Zampini if (columns) { 2445f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2446f0ae7da4SStefano Zampini } else { 2447f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2448f0ae7da4SStefano Zampini } 2449f0ae7da4SStefano Zampini if (diag != 0.) { 2450f0ae7da4SStefano Zampini const PetscScalar *array; 2451f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2452f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2453f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2454f0ae7da4SStefano Zampini } 2455f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2456f0ae7da4SStefano Zampini } 2457f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2458f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2459f0ae7da4SStefano Zampini } 2460f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2461f0ae7da4SStefano Zampini } 2462f0ae7da4SStefano Zampini 2463f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 24642e74eeadSLisandro Dalcin { 24656e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 24666e520ac8SStefano Zampini PetscInt nr,nl,len,i; 24676e520ac8SStefano Zampini PetscInt *lrows; 24682e74eeadSLisandro Dalcin PetscErrorCode ierr; 24692e74eeadSLisandro Dalcin 24702e74eeadSLisandro Dalcin PetscFunctionBegin; 2471f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2472f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2473f0ae7da4SStefano Zampini PetscBool cong; 247426b0207aSStefano Zampini 2475f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 247626b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2477268753edSStefano 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"); 2478268753edSStefano 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"); 2479268753edSStefano 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"); 2480f0ae7da4SStefano Zampini } 2481f0ae7da4SStefano Zampini #endif 24826e520ac8SStefano Zampini /* get locally owned rows */ 2483f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 24846e520ac8SStefano Zampini /* fix right hand side if needed */ 24856e520ac8SStefano Zampini if (x && b) { 24866e520ac8SStefano Zampini const PetscScalar *xx; 24876e520ac8SStefano Zampini PetscScalar *bb; 24886e520ac8SStefano Zampini 24896e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 24906e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 24916e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 24926e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 24936e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 24942e74eeadSLisandro Dalcin } 24956e520ac8SStefano Zampini /* get rows associated to the local matrices */ 24963d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 24976e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 24986e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 24996e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 25006e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 25016e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 25026e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 25036e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 25046e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 25056e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2506f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 25076e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 25082e74eeadSLisandro Dalcin PetscFunctionReturn(0); 25092e74eeadSLisandro Dalcin } 25102e74eeadSLisandro Dalcin 2511f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2512b4319ba4SBarry Smith { 2513dfbe8321SBarry Smith PetscErrorCode ierr; 2514b4319ba4SBarry Smith 2515b4319ba4SBarry Smith PetscFunctionBegin; 2516f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2517f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2518f0ae7da4SStefano Zampini } 25192205254eSKarl Rupp 2520f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2521f0ae7da4SStefano Zampini { 2522f0ae7da4SStefano Zampini PetscErrorCode ierr; 2523f0ae7da4SStefano Zampini 2524f0ae7da4SStefano Zampini PetscFunctionBegin; 2525f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2526b4319ba4SBarry Smith PetscFunctionReturn(0); 2527b4319ba4SBarry Smith } 2528b4319ba4SBarry Smith 2529a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2530b4319ba4SBarry Smith { 2531b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2532dfbe8321SBarry Smith PetscErrorCode ierr; 2533b4319ba4SBarry Smith 2534b4319ba4SBarry Smith PetscFunctionBegin; 2535b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2536b4319ba4SBarry Smith PetscFunctionReturn(0); 2537b4319ba4SBarry Smith } 2538b4319ba4SBarry Smith 2539a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2540b4319ba4SBarry Smith { 2541b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2542dfbe8321SBarry Smith PetscErrorCode ierr; 2543b4319ba4SBarry Smith 2544b4319ba4SBarry Smith PetscFunctionBegin; 2545b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2546872cf891SStefano Zampini /* fix for local empty rows/cols */ 2547872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2548872cf891SStefano Zampini Mat newlA; 2549*f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2550*f03112d0SStefano Zampini IS nzr,nzc; 2551*f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2552*f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2553872cf891SStefano Zampini 2554*f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2555*f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2556*f03112d0SStefano Zampini if (!nzr) { 2557*f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2558872cf891SStefano Zampini } 2559*f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2560*f03112d0SStefano Zampini if (!nzc) { 2561*f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2562872cf891SStefano Zampini } 2563*f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2564*f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2565*f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2566*f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2567*f03112d0SStefano Zampini IS is1,is2; 2568*f03112d0SStefano Zampini 2569*f03112d0SStefano Zampini /* need new global l2g map */ 2570*f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2571*f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2572*f03112d0SStefano Zampini 2573872cf891SStefano Zampini /* extract valid submatrix */ 2574*f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2575*f03112d0SStefano Zampini 2576*f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2577*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2578*f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2579*f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2580872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2581*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2582*f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2583*f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 2584*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2585*f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2586*f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2587*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2588*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2589*f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2590*f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 2591*f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 2592*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2593*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2594*f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2595*f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2596*f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2597*f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2598*f03112d0SStefano Zampini newlA = is->A; 2599*f03112d0SStefano Zampini } 2600*f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2601*f03112d0SStefano Zampini if (newl2g) { 2602*f03112d0SStefano Zampini IS gnzr,gnzc; 2603*f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2604*f03112d0SStefano Zampini 2605*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2606*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2607*f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2608*f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2609*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2610*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2611*f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2612*f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2613*f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2614*f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2615*f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2616*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2617*f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2618*f03112d0SStefano Zampini } 2619872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2620872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2621*f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2622*f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2623872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2624*f03112d0SStefano Zampini } 2625b4319ba4SBarry Smith PetscFunctionReturn(0); 2626b4319ba4SBarry Smith } 2627b4319ba4SBarry Smith 2628a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2629b4319ba4SBarry Smith { 2630b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2631b4319ba4SBarry Smith 2632b4319ba4SBarry Smith PetscFunctionBegin; 2633b4319ba4SBarry Smith *local = is->A; 2634b4319ba4SBarry Smith PetscFunctionReturn(0); 2635b4319ba4SBarry Smith } 2636b4319ba4SBarry Smith 26373b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 26383b3b1effSJed Brown { 26393b3b1effSJed Brown PetscFunctionBegin; 26403b3b1effSJed Brown *local = NULL; 26413b3b1effSJed Brown PetscFunctionReturn(0); 26423b3b1effSJed Brown } 26433b3b1effSJed Brown 2644b4319ba4SBarry Smith /*@ 2645b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2646b4319ba4SBarry Smith 2647b4319ba4SBarry Smith Input Parameter: 2648b4319ba4SBarry Smith . mat - the matrix 2649b4319ba4SBarry Smith 2650b4319ba4SBarry Smith Output Parameter: 2651eb82efa4SStefano Zampini . local - the local matrix 2652b4319ba4SBarry Smith 2653b4319ba4SBarry Smith Level: advanced 2654b4319ba4SBarry Smith 2655b4319ba4SBarry Smith Notes: 2656b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2657b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2658b4319ba4SBarry Smith of the MatSetValues() operation. 2659b4319ba4SBarry Smith 26603b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 266196a6f129SJed Brown 2662b4319ba4SBarry Smith .seealso: MATIS 2663b4319ba4SBarry Smith @*/ 26647087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2665b4319ba4SBarry Smith { 26664ac538c5SBarry Smith PetscErrorCode ierr; 2667b4319ba4SBarry Smith 2668b4319ba4SBarry Smith PetscFunctionBegin; 26690700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2670b4319ba4SBarry Smith PetscValidPointer(local,2); 26714ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2672b4319ba4SBarry Smith PetscFunctionReturn(0); 2673b4319ba4SBarry Smith } 2674b4319ba4SBarry Smith 26753b3b1effSJed Brown /*@ 26763b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 26773b3b1effSJed Brown 26783b3b1effSJed Brown Input Parameter: 26793b3b1effSJed Brown . mat - the matrix 26803b3b1effSJed Brown 26813b3b1effSJed Brown Output Parameter: 26823b3b1effSJed Brown . local - the local matrix 26833b3b1effSJed Brown 26843b3b1effSJed Brown Level: advanced 26853b3b1effSJed Brown 26863b3b1effSJed Brown .seealso: MATIS 26873b3b1effSJed Brown @*/ 26883b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 26893b3b1effSJed Brown { 26903b3b1effSJed Brown PetscErrorCode ierr; 26913b3b1effSJed Brown 26923b3b1effSJed Brown PetscFunctionBegin; 26933b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 26943b3b1effSJed Brown PetscValidPointer(local,2); 26953b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 26963b3b1effSJed Brown PetscFunctionReturn(0); 26973b3b1effSJed Brown } 26983b3b1effSJed Brown 2699a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 27003b03a366Sstefano_zampini { 27013b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 27023b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 27033b03a366Sstefano_zampini PetscErrorCode ierr; 27043b03a366Sstefano_zampini 27053b03a366Sstefano_zampini PetscFunctionBegin; 27064e4c7dbeSStefano Zampini if (is->A) { 27073b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 27083b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2709f0ae7da4SStefano 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); 27104e4c7dbeSStefano Zampini } 27113b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 27123b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 27133b03a366Sstefano_zampini is->A = local; 27143b03a366Sstefano_zampini PetscFunctionReturn(0); 27153b03a366Sstefano_zampini } 27163b03a366Sstefano_zampini 27173b03a366Sstefano_zampini /*@ 2718eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 27193b03a366Sstefano_zampini 27203b03a366Sstefano_zampini Input Parameter: 27213b03a366Sstefano_zampini . mat - the matrix 2722eb82efa4SStefano Zampini . local - the local matrix 27233b03a366Sstefano_zampini 27243b03a366Sstefano_zampini Output Parameter: 27253b03a366Sstefano_zampini 27263b03a366Sstefano_zampini Level: advanced 27273b03a366Sstefano_zampini 27283b03a366Sstefano_zampini Notes: 27293b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 27303b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 27313b03a366Sstefano_zampini 27323b03a366Sstefano_zampini .seealso: MATIS 27333b03a366Sstefano_zampini @*/ 27343b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 27353b03a366Sstefano_zampini { 27363b03a366Sstefano_zampini PetscErrorCode ierr; 27373b03a366Sstefano_zampini 27383b03a366Sstefano_zampini PetscFunctionBegin; 27393b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2740b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 27413b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 27423b03a366Sstefano_zampini PetscFunctionReturn(0); 27433b03a366Sstefano_zampini } 27443b03a366Sstefano_zampini 2745a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 27466726f965SBarry Smith { 27476726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 27486726f965SBarry Smith PetscErrorCode ierr; 27496726f965SBarry Smith 27506726f965SBarry Smith PetscFunctionBegin; 27516726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 27526726f965SBarry Smith PetscFunctionReturn(0); 27536726f965SBarry Smith } 27546726f965SBarry Smith 2755a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 27562e74eeadSLisandro Dalcin { 27572e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 27582e74eeadSLisandro Dalcin PetscErrorCode ierr; 27592e74eeadSLisandro Dalcin 27602e74eeadSLisandro Dalcin PetscFunctionBegin; 27612e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 27622e74eeadSLisandro Dalcin PetscFunctionReturn(0); 27632e74eeadSLisandro Dalcin } 27642e74eeadSLisandro Dalcin 2765a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 27662e74eeadSLisandro Dalcin { 27672e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 27682e74eeadSLisandro Dalcin PetscErrorCode ierr; 27692e74eeadSLisandro Dalcin 27702e74eeadSLisandro Dalcin PetscFunctionBegin; 27712e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2772e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 27732e74eeadSLisandro Dalcin 27742e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 27752e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2776e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2777e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 27782e74eeadSLisandro Dalcin PetscFunctionReturn(0); 27792e74eeadSLisandro Dalcin } 27802e74eeadSLisandro Dalcin 2781a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 27826726f965SBarry Smith { 27836726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 27846726f965SBarry Smith PetscErrorCode ierr; 27856726f965SBarry Smith 27866726f965SBarry Smith PetscFunctionBegin; 27874e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 27886726f965SBarry Smith PetscFunctionReturn(0); 27896726f965SBarry Smith } 27906726f965SBarry Smith 2791f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2792f26d0771SStefano Zampini { 2793f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2794f26d0771SStefano Zampini Mat_IS *x; 2795f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2796f26d0771SStefano Zampini PetscBool ismatis; 2797f26d0771SStefano Zampini #endif 2798f26d0771SStefano Zampini PetscErrorCode ierr; 2799f26d0771SStefano Zampini 2800f26d0771SStefano Zampini PetscFunctionBegin; 2801f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2802f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2803f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2804f26d0771SStefano Zampini #endif 2805f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2806f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2807f26d0771SStefano Zampini PetscFunctionReturn(0); 2808f26d0771SStefano Zampini } 2809f26d0771SStefano Zampini 2810f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2811f26d0771SStefano Zampini { 2812f26d0771SStefano Zampini Mat lA; 2813f26d0771SStefano Zampini Mat_IS *matis; 2814f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2815f26d0771SStefano Zampini IS is; 2816f26d0771SStefano Zampini const PetscInt *rg,*rl; 2817f26d0771SStefano Zampini PetscInt nrg; 2818f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2819f26d0771SStefano Zampini PetscErrorCode ierr; 2820f26d0771SStefano Zampini 2821f26d0771SStefano Zampini PetscFunctionBegin; 2822f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2823f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2824f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2825f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2826f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2827f0ae7da4SStefano 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); 2828f26d0771SStefano Zampini #endif 2829f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2830f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2831f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2832f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2833f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2834f26d0771SStefano Zampini #else 2835f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2836f26d0771SStefano Zampini #endif 2837f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2838f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2839f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2840f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2841f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2842f26d0771SStefano Zampini /* compute new l2g map for columns */ 2843f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2844f26d0771SStefano Zampini const PetscInt *cg,*cl; 2845f26d0771SStefano Zampini PetscInt ncg; 2846f26d0771SStefano Zampini PetscInt ncl; 2847f26d0771SStefano Zampini 2848f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2849f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2850f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2851f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2852f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2853f0ae7da4SStefano 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); 2854f26d0771SStefano Zampini #endif 2855f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2856f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2857f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2858f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2859f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2860f26d0771SStefano Zampini #else 2861f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2862f26d0771SStefano Zampini #endif 2863f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2864f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2865f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2866f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2867f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2868f26d0771SStefano Zampini } else { 2869f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2870f26d0771SStefano Zampini cl2g = rl2g; 2871f26d0771SStefano Zampini } 2872f26d0771SStefano Zampini /* create the MATIS submatrix */ 2873f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2874f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2875f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2876f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2877b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2878f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2879f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2880f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2881f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2882f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2883f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2884f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2885f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2886f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2887f26d0771SStefano Zampini /* remove unsupported ops */ 2888f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2889f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2890f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2891f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2892f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2893f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2894f26d0771SStefano Zampini PetscFunctionReturn(0); 2895f26d0771SStefano Zampini } 2896f26d0771SStefano Zampini 2897872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 2898872cf891SStefano Zampini { 2899872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 2900872cf891SStefano Zampini PetscErrorCode ierr; 2901872cf891SStefano Zampini 2902872cf891SStefano Zampini PetscFunctionBegin; 2903872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 2904872cf891SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)A); 2905*f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 290675d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 2907872cf891SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 2908872cf891SStefano Zampini PetscFunctionReturn(0); 2909872cf891SStefano Zampini } 2910872cf891SStefano Zampini 2911284134d9SBarry Smith /*@ 29123c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2913284134d9SBarry Smith process but not across processes. 2914284134d9SBarry Smith 2915284134d9SBarry Smith Input Parameters: 2916284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2917e176bc59SStefano Zampini . bs - block size of the matrix 2918df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2919e176bc59SStefano Zampini . rmap - local to global map for rows 2920e176bc59SStefano Zampini - cmap - local to global map for cols 2921284134d9SBarry Smith 2922284134d9SBarry Smith Output Parameter: 2923284134d9SBarry Smith . A - the resulting matrix 2924284134d9SBarry Smith 29258e6c10adSSatish Balay Level: advanced 29268e6c10adSSatish Balay 292795452b02SPatrick Sanan Notes: 292895452b02SPatrick Sanan See MATIS for more details. 29296fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 29306fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 29313c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2932284134d9SBarry Smith 2933284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2934284134d9SBarry Smith @*/ 2935e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2936284134d9SBarry Smith { 2937284134d9SBarry Smith PetscErrorCode ierr; 2938284134d9SBarry Smith 2939284134d9SBarry Smith PetscFunctionBegin; 29406fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2941284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 2942284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 29436fdf41d1SStefano Zampini if (bs > 0) { 2944284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 29456fdf41d1SStefano Zampini } 2946284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2947e176bc59SStefano Zampini if (rmap && cmap) { 2948e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2949e176bc59SStefano Zampini } else if (!rmap) { 2950e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2951e176bc59SStefano Zampini } else { 2952e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2953e176bc59SStefano Zampini } 2954284134d9SBarry Smith PetscFunctionReturn(0); 2955284134d9SBarry Smith } 2956284134d9SBarry Smith 2957b4319ba4SBarry Smith /*MC 2958f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2959b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2960b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2961b4319ba4SBarry Smith product is handled "implicitly". 2962b4319ba4SBarry Smith 2963b4319ba4SBarry Smith Operations Provided: 29646726f965SBarry Smith + MatMult() 29652e74eeadSLisandro Dalcin . MatMultAdd() 29662e74eeadSLisandro Dalcin . MatMultTranspose() 29672e74eeadSLisandro Dalcin . MatMultTransposeAdd() 29686726f965SBarry Smith . MatZeroEntries() 29696726f965SBarry Smith . MatSetOption() 29702e74eeadSLisandro Dalcin . MatZeroRows() 29712e74eeadSLisandro Dalcin . MatSetValues() 297297563a80SStefano Zampini . MatSetValuesBlocked() 29736726f965SBarry Smith . MatSetValuesLocal() 297497563a80SStefano Zampini . MatSetValuesBlockedLocal() 29752e74eeadSLisandro Dalcin . MatScale() 29762e74eeadSLisandro Dalcin . MatGetDiagonal() 29772b404112SStefano Zampini . MatMissingDiagonal() 29782b404112SStefano Zampini . MatDuplicate() 29792b404112SStefano Zampini . MatCopy() 2980f26d0771SStefano Zampini . MatAXPY() 29817dae84e0SHong Zhang . MatCreateSubMatrix() 2982f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2983d7f69cd0SStefano Zampini . MatTranspose() 298475d48cdbSStefano Zampini . MatPtAP() (with P of AIJ type) 29856726f965SBarry Smith - MatSetLocalToGlobalMapping() 2986b4319ba4SBarry Smith 2987b4319ba4SBarry Smith Options Database Keys: 298875d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 298975d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 299075d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 2991b4319ba4SBarry Smith 299295452b02SPatrick Sanan Notes: 299395452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 2994b4319ba4SBarry Smith 2995b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2996b4319ba4SBarry Smith 2997b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2998eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2999b4319ba4SBarry Smith 3000b4319ba4SBarry Smith Level: advanced 3001b4319ba4SBarry Smith 3002f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3003b4319ba4SBarry Smith 3004b4319ba4SBarry Smith M*/ 3005b4319ba4SBarry Smith 30068cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3007b4319ba4SBarry Smith { 3008dfbe8321SBarry Smith PetscErrorCode ierr; 3009b4319ba4SBarry Smith Mat_IS *b; 3010b4319ba4SBarry Smith 3011b4319ba4SBarry Smith PetscFunctionBegin; 3012b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 3013b4319ba4SBarry Smith A->data = (void*)b; 3014b4319ba4SBarry Smith 3015e176bc59SStefano Zampini /* matrix ops */ 3016e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3017b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 30182e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 30192e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 30202e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3021b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3022b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 30232e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 302498921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3025b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3026f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 30272e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3028f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3029b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3030b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3031b4319ba4SBarry Smith A->ops->view = MatView_IS; 30326726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 30332e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 30342e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 30356726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 303669796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 303769796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 303845471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3039ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 30406bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 30412b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3042659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 30437dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3044f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 30453fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 30463fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3047d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 30487fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3049ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3050872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3051b4319ba4SBarry Smith 3052b7ce53b6SStefano Zampini /* special MATIS functions */ 3053bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 30543b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3056487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 30572e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 3058cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 305975d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3060*f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3061487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3062487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3063487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3064487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3065487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3066487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3067487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 306817667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3069b4319ba4SBarry Smith PetscFunctionReturn(0); 3070b4319ba4SBarry Smith } 3071