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> 12a72d46e8SStefano Zampini #include <petsc/private/vecimpl.h> 13*e432b41dSStefano Zampini #include <petsc/private/hashseti.h> 1428f4e0baSStefano Zampini 15f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 16b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 17b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 188546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat); 19f26d0771SStefano Zampini 2075d48cdbSStefano Zampini static PetscErrorCode MatISContainerDestroyPtAP_Private(void *ptr) 2175d48cdbSStefano Zampini { 2275d48cdbSStefano Zampini MatISPtAP ptap = (MatISPtAP)ptr; 2375d48cdbSStefano Zampini PetscErrorCode ierr; 2475d48cdbSStefano Zampini 2575d48cdbSStefano Zampini PetscFunctionBegin; 2675d48cdbSStefano Zampini ierr = MatDestroySubMatrices(ptap->ris1 ? 2 : 1,&ptap->lP);CHKERRQ(ierr); 2775d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis0);CHKERRQ(ierr); 2875d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis1);CHKERRQ(ierr); 2975d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris0);CHKERRQ(ierr); 3075d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 3175d48cdbSStefano Zampini ierr = PetscFree(ptap);CHKERRQ(ierr); 3275d48cdbSStefano Zampini PetscFunctionReturn(0); 3375d48cdbSStefano Zampini } 3475d48cdbSStefano Zampini 3575d48cdbSStefano Zampini static PetscErrorCode MatPtAPNumeric_IS_XAIJ(Mat A, Mat P, Mat C) 3675d48cdbSStefano Zampini { 3775d48cdbSStefano Zampini MatISPtAP ptap; 3875d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3975d48cdbSStefano Zampini Mat lA,lC; 4075d48cdbSStefano Zampini MatReuse reuse; 4175d48cdbSStefano Zampini IS ris[2],cis[2]; 4275d48cdbSStefano Zampini PetscContainer c; 4375d48cdbSStefano Zampini PetscInt n; 4475d48cdbSStefano Zampini PetscErrorCode ierr; 4575d48cdbSStefano Zampini 4675d48cdbSStefano Zampini PetscFunctionBegin; 476afe12f5SStefano Zampini ierr = PetscObjectQuery((PetscObject)C,"_MatIS_PtAP",(PetscObject*)&c);CHKERRQ(ierr); 482c71b3e2SJacob Faibussowitsch PetscCheckFalse(!c,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing PtAP information"); 4975d48cdbSStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&ptap);CHKERRQ(ierr); 5075d48cdbSStefano Zampini ris[0] = ptap->ris0; 5175d48cdbSStefano Zampini ris[1] = ptap->ris1; 5275d48cdbSStefano Zampini cis[0] = ptap->cis0; 5375d48cdbSStefano Zampini cis[1] = ptap->cis1; 5475d48cdbSStefano Zampini n = ptap->ris1 ? 2 : 1; 5575d48cdbSStefano Zampini reuse = ptap->lP ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX; 5675d48cdbSStefano Zampini ierr = MatCreateSubMatrices(P,n,ris,cis,reuse,&ptap->lP);CHKERRQ(ierr); 5775d48cdbSStefano Zampini 5875d48cdbSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 5975d48cdbSStefano Zampini ierr = MatISGetLocalMat(C,&lC);CHKERRQ(ierr); 6075d48cdbSStefano Zampini if (ptap->ris1) { /* unsymmetric A mapping */ 6175d48cdbSStefano Zampini Mat lPt; 6275d48cdbSStefano Zampini 6375d48cdbSStefano Zampini ierr = MatTranspose(ptap->lP[1],MAT_INITIAL_MATRIX,&lPt);CHKERRQ(ierr); 6475d48cdbSStefano Zampini ierr = MatMatMatMult(lPt,lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6575d48cdbSStefano Zampini if (matis->storel2l) { 6675d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",(PetscObject)lPt);CHKERRQ(ierr); 6775d48cdbSStefano Zampini } 6875d48cdbSStefano Zampini ierr = MatDestroy(&lPt);CHKERRQ(ierr); 6975d48cdbSStefano Zampini } else { 7075d48cdbSStefano Zampini ierr = MatPtAP(lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 7175d48cdbSStefano Zampini if (matis->storel2l) { 724222ddf1SHong Zhang ierr = PetscObjectCompose((PetscObject)C,"_MatIS_PtAP_l2l",(PetscObject)ptap->lP[0]);CHKERRQ(ierr); 7375d48cdbSStefano Zampini } 7475d48cdbSStefano Zampini } 7575d48cdbSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7675d48cdbSStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 7775d48cdbSStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 7875d48cdbSStefano Zampini } 7975d48cdbSStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8075d48cdbSStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8175d48cdbSStefano Zampini PetscFunctionReturn(0); 8275d48cdbSStefano Zampini } 8375d48cdbSStefano Zampini 8475d48cdbSStefano Zampini static PetscErrorCode MatGetNonzeroColumnsLocal_Private(Mat PT,IS *cis) 8575d48cdbSStefano Zampini { 8675d48cdbSStefano Zampini Mat Po,Pd; 8775d48cdbSStefano Zampini IS zd,zo; 8875d48cdbSStefano Zampini const PetscInt *garray; 8975d48cdbSStefano Zampini PetscInt *aux,i,bs; 9075d48cdbSStefano Zampini PetscInt dc,stc,oc,ctd,cto; 9175d48cdbSStefano Zampini PetscBool ismpiaij,ismpibaij,isseqaij,isseqbaij; 9275d48cdbSStefano Zampini MPI_Comm comm; 9375d48cdbSStefano Zampini PetscErrorCode ierr; 9475d48cdbSStefano Zampini 9575d48cdbSStefano Zampini PetscFunctionBegin; 9675d48cdbSStefano Zampini PetscValidHeaderSpecific(PT,MAT_CLASSID,1); 9775d48cdbSStefano Zampini PetscValidPointer(cis,2); 9875d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)PT,&comm);CHKERRQ(ierr); 9975d48cdbSStefano Zampini bs = 1; 100b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 101b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 10204637862SRichard Tran Mills ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 10375d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 10475d48cdbSStefano Zampini if (isseqaij || isseqbaij) { 10575d48cdbSStefano Zampini Pd = PT; 10675d48cdbSStefano Zampini Po = NULL; 10775d48cdbSStefano Zampini garray = NULL; 10875d48cdbSStefano Zampini } else if (ismpiaij) { 10975d48cdbSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 11075d48cdbSStefano Zampini } else if (ismpibaij) { 11175d48cdbSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 11275d48cdbSStefano Zampini ierr = MatGetBlockSize(PT,&bs);CHKERRQ(ierr); 11398921bdaSJacob Faibussowitsch } else SETERRQ(comm,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(PT))->type_name); 11475d48cdbSStefano Zampini 11575d48cdbSStefano Zampini /* identify any null columns in Pd or Po */ 11622f7620eSStefano Zampini /* We use a tolerance comparison since it may happen that, with geometric multigrid, 11722f7620eSStefano Zampini some of the columns are not really zero, but very close to */ 11875d48cdbSStefano Zampini zo = zd = NULL; 11975d48cdbSStefano Zampini if (Po) { 12022f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Po,PETSC_TRUE,PETSC_SMALL,&zo);CHKERRQ(ierr); 12175d48cdbSStefano Zampini } 12222f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Pd,PETSC_TRUE,PETSC_SMALL,&zd);CHKERRQ(ierr); 12375d48cdbSStefano Zampini 12475d48cdbSStefano Zampini ierr = MatGetLocalSize(PT,NULL,&dc);CHKERRQ(ierr); 12575d48cdbSStefano Zampini ierr = MatGetOwnershipRangeColumn(PT,&stc,NULL);CHKERRQ(ierr); 12675d48cdbSStefano Zampini if (Po) { ierr = MatGetLocalSize(Po,NULL,&oc);CHKERRQ(ierr); } 12775d48cdbSStefano Zampini else oc = 0; 12875d48cdbSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 12975d48cdbSStefano Zampini if (zd) { 13075d48cdbSStefano Zampini const PetscInt *idxs; 13175d48cdbSStefano Zampini PetscInt nz; 13275d48cdbSStefano Zampini 13375d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 13475d48cdbSStefano Zampini ierr = ISSetBlockSize(zd,bs);CHKERRQ(ierr); 13575d48cdbSStefano Zampini ierr = ISGetLocalSize(zd,&nz);CHKERRQ(ierr); 13675d48cdbSStefano Zampini ierr = ISGetIndices(zd,&idxs);CHKERRQ(ierr); 13775d48cdbSStefano Zampini ctd = nz/bs; 13875d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = (idxs[bs*i]+stc)/bs; 13975d48cdbSStefano Zampini ierr = ISRestoreIndices(zd,&idxs);CHKERRQ(ierr); 14075d48cdbSStefano Zampini } else { 14175d48cdbSStefano Zampini ctd = dc/bs; 14275d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = i+stc/bs; 14375d48cdbSStefano Zampini } 14475d48cdbSStefano Zampini if (zo) { 14575d48cdbSStefano Zampini const PetscInt *idxs; 14675d48cdbSStefano Zampini PetscInt nz; 14775d48cdbSStefano Zampini 14875d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 14975d48cdbSStefano Zampini ierr = ISSetBlockSize(zo,bs);CHKERRQ(ierr); 15075d48cdbSStefano Zampini ierr = ISGetLocalSize(zo,&nz);CHKERRQ(ierr); 15175d48cdbSStefano Zampini ierr = ISGetIndices(zo,&idxs);CHKERRQ(ierr); 15275d48cdbSStefano Zampini cto = nz/bs; 15375d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[idxs[bs*i]/bs]; 15475d48cdbSStefano Zampini ierr = ISRestoreIndices(zo,&idxs);CHKERRQ(ierr); 15575d48cdbSStefano Zampini } else { 15675d48cdbSStefano Zampini cto = oc/bs; 15775d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[i]; 15875d48cdbSStefano Zampini } 15975d48cdbSStefano Zampini ierr = ISCreateBlock(comm,bs,ctd+cto,aux,PETSC_OWN_POINTER,cis);CHKERRQ(ierr); 16075d48cdbSStefano Zampini ierr = ISDestroy(&zd);CHKERRQ(ierr); 16175d48cdbSStefano Zampini ierr = ISDestroy(&zo);CHKERRQ(ierr); 16275d48cdbSStefano Zampini PetscFunctionReturn(0); 16375d48cdbSStefano Zampini } 16475d48cdbSStefano Zampini 1654222ddf1SHong Zhang static PetscErrorCode MatPtAPSymbolic_IS_XAIJ(Mat A,Mat P,PetscReal fill,Mat C) 16675d48cdbSStefano Zampini { 1678546b261SStefano Zampini Mat PT,lA; 16875d48cdbSStefano Zampini MatISPtAP ptap; 16975d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 17075d48cdbSStefano Zampini PetscContainer c; 1718546b261SStefano Zampini MatType lmtype; 17275d48cdbSStefano Zampini const PetscInt *garray; 17375d48cdbSStefano Zampini PetscInt ibs,N,dc; 17475d48cdbSStefano Zampini MPI_Comm comm; 17575d48cdbSStefano Zampini PetscErrorCode ierr; 17675d48cdbSStefano Zampini 17775d48cdbSStefano Zampini PetscFunctionBegin; 17875d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 1794222ddf1SHong Zhang ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1808546b261SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1818546b261SStefano Zampini ierr = MatGetType(lA,&lmtype);CHKERRQ(ierr); 1824222ddf1SHong Zhang ierr = MatISSetLocalMatType(C,lmtype);CHKERRQ(ierr); 18375d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 18475d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 1854222ddf1SHong Zhang ierr = MatSetSizes(C,dc,dc,N,N);CHKERRQ(ierr); 18675d48cdbSStefano Zampini /* Not sure about this 18775d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18875d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18975d48cdbSStefano Zampini */ 19075d48cdbSStefano Zampini 19175d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 19275d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 19375d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 19475d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 1954222ddf1SHong Zhang ierr = PetscObjectCompose((PetscObject)C,"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19775d48cdbSStefano Zampini ptap->fill = fill; 19875d48cdbSStefano Zampini 199*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 20075d48cdbSStefano Zampini 20175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 20575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20675d48cdbSStefano Zampini 20775d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20875d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 21075d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 21175d48cdbSStefano Zampini 21275d48cdbSStefano Zampini Crl2g = NULL; 21375d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 21475d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 21575d48cdbSStefano Zampini PetscInt N1,ibs1; 21675d48cdbSStefano Zampini 21775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 22175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22275d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 22375d48cdbSStefano Zampini const PetscInt *i1,*i2; 22475d48cdbSStefano Zampini 22575d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22675d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 227580bdb30SBarry Smith ierr = PetscArraycmp(i1,i2,N,&lsame);CHKERRQ(ierr); 22875d48cdbSStefano Zampini } 229820f2d46SBarry Smith ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRMPI(ierr); 23075d48cdbSStefano Zampini if (same) { 23175d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 23275d48cdbSStefano Zampini } else { 23375d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 23475d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 23575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23675d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini } 23975d48cdbSStefano Zampini /* Not sure about this 24075d48cdbSStefano Zampini if (!Crl2g) { 2414222ddf1SHong Zhang ierr = MatGetBlockSize(C,&ibs);CHKERRQ(ierr); 24275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 24375d48cdbSStefano Zampini } 24475d48cdbSStefano Zampini */ 2454222ddf1SHong Zhang ierr = MatSetLocalToGlobalMapping(C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24875d48cdbSStefano Zampini 2494222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 25075d48cdbSStefano Zampini PetscFunctionReturn(0); 25175d48cdbSStefano Zampini } 25275d48cdbSStefano Zampini 2534222ddf1SHong Zhang /* ----------------------------------------- */ 2544222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_IS_XAIJ(Mat C) 25575d48cdbSStefano Zampini { 25675d48cdbSStefano Zampini PetscErrorCode ierr; 2574222ddf1SHong Zhang Mat_Product *product = C->product; 2584222ddf1SHong Zhang Mat A=product->A,P=product->B; 2594222ddf1SHong Zhang PetscReal fill=product->fill; 26075d48cdbSStefano Zampini 26175d48cdbSStefano Zampini PetscFunctionBegin; 26275d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 2634222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 26475d48cdbSStefano Zampini PetscFunctionReturn(0); 26575d48cdbSStefano Zampini } 26675d48cdbSStefano Zampini 2674222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_IS_XAIJ_PtAP(Mat C) 2684222ddf1SHong Zhang { 2694222ddf1SHong Zhang PetscFunctionBegin; 2704222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_IS_XAIJ; 2714222ddf1SHong Zhang PetscFunctionReturn(0); 2724222ddf1SHong Zhang } 2734222ddf1SHong Zhang 2744222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat C) 2754222ddf1SHong Zhang { 2764222ddf1SHong Zhang PetscErrorCode ierr; 2774222ddf1SHong Zhang Mat_Product *product = C->product; 2784222ddf1SHong Zhang 2794222ddf1SHong Zhang PetscFunctionBegin; 2804222ddf1SHong Zhang if (product->type == MATPRODUCT_PtAP) { 2814222ddf1SHong Zhang ierr = MatProductSetFromOptions_IS_XAIJ_PtAP(C);CHKERRQ(ierr); 2826718818eSStefano Zampini } 2834222ddf1SHong Zhang PetscFunctionReturn(0); 2844222ddf1SHong Zhang } 2854222ddf1SHong Zhang 2864222ddf1SHong Zhang /* ----------------------------------------- */ 2875b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2885b003df0Sstefano_zampini { 2895b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2905b003df0Sstefano_zampini PetscInt i; 2915b003df0Sstefano_zampini PetscErrorCode ierr; 2925b003df0Sstefano_zampini 293ab4d48faSStefano Zampini PetscFunctionBegin; 2945b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2955b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2965b003df0Sstefano_zampini } 2975b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2985b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2995b003df0Sstefano_zampini } 3005b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 3015b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 3025b003df0Sstefano_zampini PetscFunctionReturn(0); 3035b003df0Sstefano_zampini } 304a72627d2SStefano Zampini 305c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 3066989cf23SStefano Zampini { 307c9225affSStefano Zampini Mat B,lB; 308c9225affSStefano Zampini PetscErrorCode ierr; 309c9225affSStefano Zampini 310c9225affSStefano Zampini PetscFunctionBegin; 311c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 312c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 313c9225affSStefano Zampini PetscInt bs; 314c9225affSStefano Zampini IS is; 315c9225affSStefano Zampini 316c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 317c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 318c9225affSStefano Zampini if (bs > 1) { 319c9225affSStefano Zampini IS is2; 320c9225affSStefano Zampini PetscInt i,*aux; 321c9225affSStefano Zampini 322c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 323c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 324c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 325c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 326c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 327c9225affSStefano Zampini is = is2; 328c9225affSStefano Zampini } 329c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 330c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 331c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 332c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 333c9225affSStefano Zampini if (bs > 1) { 334c9225affSStefano Zampini IS is2; 335c9225affSStefano Zampini PetscInt i,*aux; 336c9225affSStefano Zampini 337c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 338c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 339c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 340c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 341c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 342c9225affSStefano Zampini is = is2; 343c9225affSStefano Zampini } 344c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 345c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 346c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 347c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 348c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 349c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 350c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 351c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 352c9225affSStefano Zampini } else { 353c9225affSStefano Zampini B = *newmat; 354c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 355c9225affSStefano Zampini lB = A; 356c9225affSStefano Zampini } 357c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 358c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 359c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 360c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 361c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 362c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 363c9225affSStefano Zampini } 364c9225affSStefano Zampini PetscFunctionReturn(0); 365c9225affSStefano Zampini } 366c9225affSStefano Zampini 367c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 368c9225affSStefano Zampini { 369c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 370c9225affSStefano Zampini PetscScalar *aa; 371c9225affSStefano Zampini const PetscInt *ii,*jj; 372c9225affSStefano Zampini PetscInt i,n,m; 373fabe8965SStefano Zampini PetscInt *ecount,**eneighs; 374c9225affSStefano Zampini PetscBool flg; 375c9225affSStefano Zampini PetscErrorCode ierr; 376c9225affSStefano Zampini 377c9225affSStefano Zampini PetscFunctionBegin; 378c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 3792c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 380*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(matis->rmapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 3812c71b3e2SJacob Faibussowitsch PetscCheckFalse(m != n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %" PetscInt_FMT " != %" PetscInt_FMT,m,n); 382c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 383c9225affSStefano Zampini for (i=0;i<n;i++) { 384fabe8965SStefano Zampini if (ecount[i] > 1) { 385c9225affSStefano Zampini PetscInt j; 386c9225affSStefano Zampini 387c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 388c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 389fabe8965SStefano Zampini PetscReal scal = 0.0; 390c9225affSStefano Zampini 391c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 392c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 393c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 394c9225affSStefano Zampini } 395c9225affSStefano Zampini } 396fabe8965SStefano Zampini if (scal) aa[j] /= scal; 397c9225affSStefano Zampini } 398c9225affSStefano Zampini } 399c9225affSStefano Zampini } 400*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(matis->rmapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 401c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 402c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 4032c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 404c9225affSStefano Zampini PetscFunctionReturn(0); 405c9225affSStefano Zampini } 406c9225affSStefano Zampini 407fabe8965SStefano Zampini typedef enum {MAT_IS_DISASSEMBLE_L2G_NATURAL,MAT_IS_DISASSEMBLE_L2G_MAT, MAT_IS_DISASSEMBLE_L2G_ND} MatISDisassemblel2gType; 408fabe8965SStefano Zampini 409c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 410c9225affSStefano Zampini { 411fabe8965SStefano Zampini Mat Ad,Ao; 412fabe8965SStefano Zampini IS is,ndmap,ndsub; 413c9225affSStefano Zampini MPI_Comm comm; 414fabe8965SStefano Zampini const PetscInt *garray,*ndmapi; 415fabe8965SStefano Zampini PetscInt bs,i,cnt,nl,*ncount,*ndmapc; 416fabe8965SStefano Zampini PetscBool ismpiaij,ismpibaij; 417f4259b30SLisandro Dalcin const char *const MatISDisassemblel2gTypes[] = {"NATURAL","MAT","ND","MatISDisassemblel2gType","MAT_IS_DISASSEMBLE_L2G_",NULL}; 418fabe8965SStefano Zampini MatISDisassemblel2gType mode = MAT_IS_DISASSEMBLE_L2G_NATURAL; 419fabe8965SStefano Zampini MatPartitioning part; 420fabe8965SStefano Zampini PetscSF sf; 421c9225affSStefano Zampini PetscErrorCode ierr; 422c9225affSStefano Zampini 423c9225affSStefano Zampini PetscFunctionBegin; 424fabe8965SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MatIS l2g disassembling options","Mat");CHKERRQ(ierr); 425fabe8965SStefano Zampini ierr = PetscOptionsEnum("-mat_is_disassemble_l2g_type","Type of local-to-global mapping to be used for disassembling","MatISDisassemblel2gType",MatISDisassemblel2gTypes,(PetscEnum)mode,(PetscEnum*)&mode,NULL);CHKERRQ(ierr); 426fabe8965SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 427fabe8965SStefano Zampini if (mode == MAT_IS_DISASSEMBLE_L2G_MAT) { 428c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 429c9225affSStefano Zampini PetscFunctionReturn(0); 430c9225affSStefano Zampini } 431c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 432b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 433b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 434c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 435fabe8965SStefano Zampini switch (mode) { 436fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_ND: 437fabe8965SStefano Zampini ierr = MatPartitioningCreate(comm,&part);CHKERRQ(ierr); 438fabe8965SStefano Zampini ierr = MatPartitioningSetAdjacency(part,A);CHKERRQ(ierr); 439fabe8965SStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)part,((PetscObject)A)->prefix);CHKERRQ(ierr); 440fabe8965SStefano Zampini ierr = MatPartitioningSetFromOptions(part);CHKERRQ(ierr); 441fabe8965SStefano Zampini ierr = MatPartitioningApplyND(part,&ndmap);CHKERRQ(ierr); 442fabe8965SStefano Zampini ierr = MatPartitioningDestroy(&part);CHKERRQ(ierr); 443fabe8965SStefano Zampini ierr = ISBuildTwoSided(ndmap,NULL,&ndsub);CHKERRQ(ierr); 444fabe8965SStefano Zampini ierr = MatMPIAIJSetUseScalableIncreaseOverlap(A,PETSC_TRUE);CHKERRQ(ierr); 445fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,1,&ndsub,1);CHKERRQ(ierr); 446fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ndsub,l2g);CHKERRQ(ierr); 447fabe8965SStefano Zampini 448fabe8965SStefano Zampini /* it may happen that a separator node is not properly shared */ 449fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(*l2g,&nl,&ncount,NULL);CHKERRQ(ierr); 450fabe8965SStefano Zampini ierr = PetscSFCreate(comm,&sf);CHKERRQ(ierr); 451fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(*l2g,&garray);CHKERRQ(ierr); 452fabe8965SStefano Zampini ierr = PetscSFSetGraphLayout(sf,A->rmap,nl,NULL,PETSC_OWN_POINTER,garray);CHKERRQ(ierr); 453fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(*l2g,&garray);CHKERRQ(ierr); 454fabe8965SStefano Zampini ierr = PetscCalloc1(A->rmap->n,&ndmapc);CHKERRQ(ierr); 45583df288dSJunchao Zhang ierr = PetscSFReduceBegin(sf,MPIU_INT,ncount,ndmapc,MPI_REPLACE);CHKERRQ(ierr); 45683df288dSJunchao Zhang ierr = PetscSFReduceEnd(sf,MPIU_INT,ncount,ndmapc,MPI_REPLACE);CHKERRQ(ierr); 457fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(*l2g,NULL,&ncount,NULL);CHKERRQ(ierr); 458fabe8965SStefano Zampini ierr = ISGetIndices(ndmap,&ndmapi);CHKERRQ(ierr); 459fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 460fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) 461fabe8965SStefano Zampini cnt++; 462fabe8965SStefano Zampini 463820f2d46SBarry Smith ierr = MPIU_Allreduce(&cnt,&i,1,MPIU_INT,MPI_MAX,comm);CHKERRMPI(ierr); 464fabe8965SStefano Zampini if (i) { /* we detected isolated separator nodes */ 465fabe8965SStefano Zampini Mat A2,A3; 466fabe8965SStefano Zampini IS *workis,is2; 467fabe8965SStefano Zampini PetscScalar *vals; 468fabe8965SStefano Zampini PetscInt gcnt = i,*dnz,*onz,j,*lndmapi; 469fabe8965SStefano Zampini ISLocalToGlobalMapping ll2g; 470fabe8965SStefano Zampini PetscBool flg; 471fabe8965SStefano Zampini const PetscInt *ii,*jj; 472fabe8965SStefano Zampini 473fabe8965SStefano Zampini /* communicate global id of separators */ 474fabe8965SStefano Zampini ierr = MatPreallocateInitialize(comm,A->rmap->n,A->cmap->n,dnz,onz);CHKERRQ(ierr); 475fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 476fabe8965SStefano Zampini dnz[i] = ndmapi[i] < 0 ? i + A->rmap->rstart : -1; 477fabe8965SStefano Zampini 478fabe8965SStefano Zampini ierr = PetscMalloc1(nl,&lndmapi);CHKERRQ(ierr); 479ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf,MPIU_INT,dnz,lndmapi,MPI_REPLACE);CHKERRQ(ierr); 480fabe8965SStefano Zampini 481fabe8965SStefano Zampini /* compute adjacency of isolated separators node */ 482fabe8965SStefano Zampini ierr = PetscMalloc1(gcnt,&workis);CHKERRQ(ierr); 483fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) { 484fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 485fabe8965SStefano Zampini ierr = ISCreateStride(comm,1,i+A->rmap->rstart,1,&workis[cnt++]);CHKERRQ(ierr); 486fabe8965SStefano Zampini } 487fabe8965SStefano Zampini } 488fabe8965SStefano Zampini for (i = cnt; i < gcnt; i++) { 489fabe8965SStefano Zampini ierr = ISCreateStride(comm,0,0,1,&workis[i]);CHKERRQ(ierr); 490fabe8965SStefano Zampini } 491fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 492fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"ISOLATED");CHKERRQ(ierr); 493fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 494fabe8965SStefano Zampini } 495fabe8965SStefano Zampini 496fabe8965SStefano Zampini /* no communications since all the ISes correspond to locally owned rows */ 497fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,gcnt,workis,1);CHKERRQ(ierr); 498fabe8965SStefano Zampini 499fabe8965SStefano Zampini /* end communicate global id of separators */ 500ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf,MPIU_INT,dnz,lndmapi,MPI_REPLACE);CHKERRQ(ierr); 501fabe8965SStefano Zampini 502fabe8965SStefano Zampini /* communicate new layers : create a matrix and transpose it */ 503580bdb30SBarry Smith ierr = PetscArrayzero(dnz,A->rmap->n);CHKERRQ(ierr); 504580bdb30SBarry Smith ierr = PetscArrayzero(onz,A->rmap->n);CHKERRQ(ierr); 505fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) { 506fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 507fabe8965SStefano Zampini const PetscInt* idxs; 508fabe8965SStefano Zampini PetscInt s; 509fabe8965SStefano Zampini 510fabe8965SStefano Zampini ierr = ISGetLocalSize(workis[j],&s);CHKERRQ(ierr); 511fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 512fabe8965SStefano Zampini ierr = MatPreallocateSet(i+A->rmap->rstart,s,idxs,dnz,onz);CHKERRQ(ierr); 513fabe8965SStefano Zampini j++; 514fabe8965SStefano Zampini } 515fabe8965SStefano Zampini } 5162c71b3e2SJacob Faibussowitsch PetscCheckFalse(j != cnt,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %" PetscInt_FMT " != %" PetscInt_FMT,j,cnt); 517fabe8965SStefano Zampini 518fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 519fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"EXTENDED");CHKERRQ(ierr); 520fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 521fabe8965SStefano Zampini } 522fabe8965SStefano Zampini 523fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) j = PetscMax(j,dnz[i]+onz[i]); 524fabe8965SStefano Zampini ierr = PetscMalloc1(j,&vals);CHKERRQ(ierr); 525fabe8965SStefano Zampini for (i = 0; i < j; i++) vals[i] = 1.0; 526fabe8965SStefano Zampini 527fabe8965SStefano Zampini ierr = MatCreate(comm,&A2);CHKERRQ(ierr); 528fabe8965SStefano Zampini ierr = MatSetType(A2,MATMPIAIJ);CHKERRQ(ierr); 529fabe8965SStefano Zampini ierr = MatSetSizes(A2,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 530fabe8965SStefano Zampini ierr = MatMPIAIJSetPreallocation(A2,0,dnz,0,onz);CHKERRQ(ierr); 531fabe8965SStefano Zampini ierr = MatSetOption(A2,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 532fabe8965SStefano Zampini for (i = 0, j = 0; i < A2->rmap->n; i++) { 533fabe8965SStefano Zampini PetscInt row = i+A2->rmap->rstart,s = dnz[i] + onz[i]; 534fabe8965SStefano Zampini const PetscInt* idxs; 535fabe8965SStefano Zampini 536fabe8965SStefano Zampini if (s) { 537fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 538fabe8965SStefano Zampini ierr = MatSetValues(A2,1,&row,s,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 539fabe8965SStefano Zampini ierr = ISRestoreIndices(workis[j],&idxs);CHKERRQ(ierr); 540fabe8965SStefano Zampini j++; 541fabe8965SStefano Zampini } 542fabe8965SStefano Zampini } 5432c71b3e2SJacob Faibussowitsch PetscCheckFalse(j != cnt,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %" PetscInt_FMT " != %" PetscInt_FMT,j,cnt); 544fabe8965SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 545fabe8965SStefano Zampini ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 546fabe8965SStefano Zampini ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 547fabe8965SStefano Zampini ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 548fabe8965SStefano Zampini 549fabe8965SStefano Zampini /* extract submatrix corresponding to the coupling "owned separators" x "isolated separators" */ 550fabe8965SStefano Zampini for (i = 0, j = 0; i < nl; i++) 551fabe8965SStefano Zampini if (lndmapi[i] >= 0) lndmapi[j++] = lndmapi[i]; 552fabe8965SStefano Zampini ierr = ISCreateGeneral(comm,j,lndmapi,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 553fabe8965SStefano Zampini ierr = MatMPIAIJGetLocalMatCondensed(A2,MAT_INITIAL_MATRIX,&is,NULL,&A3);CHKERRQ(ierr); 554fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 555fabe8965SStefano Zampini ierr = MatDestroy(&A2);CHKERRQ(ierr); 556fabe8965SStefano Zampini 557fabe8965SStefano Zampini /* extend local to global map to include connected isolated separators */ 558fabe8965SStefano Zampini ierr = PetscObjectQuery((PetscObject)A3,"_petsc_GetLocalMatCondensed_iscol",(PetscObject*)&is);CHKERRQ(ierr); 5592c71b3e2SJacob Faibussowitsch PetscCheckFalse(!is,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing column map"); 560fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&ll2g);CHKERRQ(ierr); 561fabe8965SStefano Zampini ierr = MatGetRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 5622c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 563fabe8965SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,ii[i],jj,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 564fabe8965SStefano Zampini ierr = MatRestoreRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 5652c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 566fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ll2g,is,&is2);CHKERRQ(ierr); 567fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 568fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ll2g);CHKERRQ(ierr); 569fabe8965SStefano Zampini 570fabe8965SStefano Zampini /* add new nodes to the local-to-global map */ 571fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(l2g);CHKERRQ(ierr); 572fabe8965SStefano Zampini ierr = ISExpand(ndsub,is2,&is);CHKERRQ(ierr); 573fabe8965SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 574fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 575fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 576fabe8965SStefano Zampini 577fabe8965SStefano Zampini ierr = MatDestroy(&A3);CHKERRQ(ierr); 578fabe8965SStefano Zampini ierr = PetscFree(lndmapi);CHKERRQ(ierr); 579fabe8965SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 580fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 581fabe8965SStefano Zampini ierr = ISDestroy(&workis[i]);CHKERRQ(ierr); 582fabe8965SStefano Zampini } 583fabe8965SStefano Zampini ierr = PetscFree(workis);CHKERRQ(ierr); 584fabe8965SStefano Zampini } 585fabe8965SStefano Zampini ierr = ISRestoreIndices(ndmap,&ndmapi);CHKERRQ(ierr); 586fabe8965SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 587fabe8965SStefano Zampini ierr = PetscFree(ndmapc);CHKERRQ(ierr); 588fabe8965SStefano Zampini ierr = ISDestroy(&ndmap);CHKERRQ(ierr); 589fabe8965SStefano Zampini ierr = ISDestroy(&ndsub);CHKERRQ(ierr); 590fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(*l2g,bs);CHKERRQ(ierr); 591fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingViewFromOptions(*l2g,NULL,"-matis_nd_l2g_view");CHKERRQ(ierr); 592fabe8965SStefano Zampini break; 593fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_NATURAL: 594fabe8965SStefano Zampini if (ismpiaij) { 595fabe8965SStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 596fabe8965SStefano Zampini } else if (ismpibaij) { 597fabe8965SStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 59898921bdaSJacob Faibussowitsch } else SETERRQ(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 5992c71b3e2SJacob Faibussowitsch PetscCheckFalse(!garray,comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 600c9225affSStefano Zampini if (A->rmap->n) { 601fabe8965SStefano Zampini PetscInt dc,oc,stc,*aux; 602c9225affSStefano Zampini 603c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 604c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 605c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 606c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 607c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 608c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 609c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 610c9225affSStefano Zampini } else { 611c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 612c9225affSStefano Zampini } 613c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 614c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 615fabe8965SStefano Zampini break; 616fabe8965SStefano Zampini default: 61798921bdaSJacob Faibussowitsch SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Unsupported l2g disassembling type %d",mode); 618c9225affSStefano Zampini } 619c9225affSStefano Zampini PetscFunctionReturn(0); 620c9225affSStefano Zampini } 621c9225affSStefano Zampini 622c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 623c9225affSStefano Zampini { 624c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 6256989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 6266989cf23SStefano Zampini IS is; 6276989cf23SStefano Zampini MPI_Comm comm; 6286989cf23SStefano Zampini void *ptrs[2]; 6296989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 630c9225affSStefano Zampini const PetscInt *garray; 6316989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 632c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 633c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 6346989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 635c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 636c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 637c9225affSStefano Zampini PetscMPIInt size; 6386989cf23SStefano Zampini PetscErrorCode ierr; 6396989cf23SStefano Zampini 640ab4d48faSStefano Zampini PetscFunctionBegin; 6416989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 642ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 643c9225affSStefano Zampini if (size == 1) { 644c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 645c9225affSStefano Zampini PetscFunctionReturn(0); 646c9225affSStefano Zampini } 647c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 648c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 649c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 650c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 651c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 652c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 653c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 654c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 655c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 656c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 657c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 658c9225affSStefano Zampini } 659c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 660c9225affSStefano Zampini Mat *newlA, lA; 661c9225affSStefano Zampini IS rows, cols; 662c9225affSStefano Zampini const PetscInt *ridx, *cidx; 663c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 664c9225affSStefano Zampini 665c9225affSStefano Zampini if (!B) B = *newmat; 666*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 667c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 668c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 669c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 670c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 671c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 672c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 673c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 674c9225affSStefano Zampini if (rl2g != cl2g) { 675c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 676c9225affSStefano Zampini } else { 677c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 678c9225affSStefano Zampini cols = rows; 679c9225affSStefano Zampini } 680c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 681c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 682c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 683c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 684c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 685c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 686c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 687c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 688c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 689c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 690c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 691c9225affSStefano Zampini } 692c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 693c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 694c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 695c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 696c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 697c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 698c9225affSStefano Zampini else *newmat = B; 699c9225affSStefano Zampini PetscFunctionReturn(0); 700c9225affSStefano Zampini } 701c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 702b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 703b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 704c9225affSStefano Zampini if (ismpiaij) { 705c9225affSStefano Zampini bs = 1; 706c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 707c9225affSStefano Zampini } else if (ismpibaij) { 708c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 709c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 710c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 711c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 71298921bdaSJacob Faibussowitsch } else SETERRQ(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 713c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 714c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 7152c71b3e2SJacob Faibussowitsch PetscCheckFalse(!garray,comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 7166989cf23SStefano Zampini 7176989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 7186989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 7196989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 7206989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 721c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 722c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 7232c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 724c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 7252c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 726c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 727c9225affSStefano Zampini /* store original pointers to be restored later */ 728c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 7296989cf23SStefano Zampini 7306989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 731c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 732c9225affSStefano Zampini if (bs > 1) { 733c9225affSStefano Zampini IS is2; 734c9225affSStefano Zampini 735c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 736c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 737c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 738c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 739c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 740c9225affSStefano Zampini is = is2; 741c9225affSStefano Zampini } 7426989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 7436989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 744e363d98aSStefano Zampini if (dr) { 745c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 746c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 747c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 748c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 749e363d98aSStefano Zampini lc = dc+oc; 750e363d98aSStefano Zampini } else { 751c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 752e363d98aSStefano Zampini lc = 0; 753e363d98aSStefano Zampini } 7546989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 7556989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 7566989cf23SStefano Zampini 7576989cf23SStefano Zampini /* create MATIS object */ 758c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 759c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 760c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 761c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 762c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 7636989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7646989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7656989cf23SStefano Zampini 7666989cf23SStefano Zampini /* merge local matrices */ 7676989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 7686989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 7696989cf23SStefano Zampini ii = aux; 7706989cf23SStefano Zampini jj = aux+dr+1; 7716989cf23SStefano Zampini aa = data; 7726989cf23SStefano Zampini *ii = *(di++) + *(oi++); 7736989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 7746989cf23SStefano Zampini { 7756989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 7766989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 7776989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 7786989cf23SStefano Zampini } 7796989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 780c9225affSStefano Zampini 781c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 7822c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 783c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 7842c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 785c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 786c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 787c9225affSStefano Zampini 7886989cf23SStefano Zampini ii = aux; 7896989cf23SStefano Zampini jj = aux+dr+1; 7906989cf23SStefano Zampini aa = data; 791e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 7926989cf23SStefano Zampini 7936989cf23SStefano Zampini /* create containers to destroy the data */ 7946989cf23SStefano Zampini ptrs[0] = aux; 7956989cf23SStefano Zampini ptrs[1] = data; 7966989cf23SStefano Zampini for (i=0; i<2; i++) { 7976989cf23SStefano Zampini PetscContainer c; 7986989cf23SStefano Zampini 7996989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 8006989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 801b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 8026989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 8036989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 8046989cf23SStefano Zampini } 805c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 806c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 807c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 808c9225affSStefano Zampini } 8096989cf23SStefano Zampini 8106989cf23SStefano Zampini /* finalize matrix */ 811c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 8126989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 813c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 814c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 815c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 816c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 817c9225affSStefano Zampini } else *newmat = B; 8186989cf23SStefano Zampini PetscFunctionReturn(0); 8196989cf23SStefano Zampini } 8206989cf23SStefano Zampini 8215e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 8225e3038f0Sstefano_zampini { 8235e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 8245e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 8255e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 8265e3038f0Sstefano_zampini MPI_Comm comm; 8275b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 8285b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 8299e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 8305e3038f0Sstefano_zampini PetscErrorCode ierr; 8315e3038f0Sstefano_zampini 832ab4d48faSStefano Zampini PetscFunctionBegin; 8335e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 8345e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 8355e3038f0Sstefano_zampini rnest = NULL; 8365e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 8375e3038f0Sstefano_zampini PetscBool ismatis,isnest; 8385e3038f0Sstefano_zampini 8395e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 8402c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name); 8415e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 8425e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 8435e3038f0Sstefano_zampini if (isnest) { 8445e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 8455e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 8465e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 8475e3038f0Sstefano_zampini } 8485e3038f0Sstefano_zampini } 8495e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 8505b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 851071fcb05SBarry Smith ierr = PetscCalloc6(nr,&isrow,nc,&iscol,nr,&islrow,nc,&islcol,nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 8525e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 8535e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8545e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8555e3038f0Sstefano_zampini PetscBool ismatis; 8569e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 8575e3038f0Sstefano_zampini 8585e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 8595e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8605e3038f0Sstefano_zampini 8615e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 8629e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 8639e7b2b25Sstefano_zampini if (istrans[ij]) { 8649e7b2b25Sstefano_zampini Mat T,lT; 8659e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8669e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 8672c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") (transposed) is not of type MATIS",i,j); 8689e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 8699e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 8709e7b2b25Sstefano_zampini } else { 8715e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 8722c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") is not of type MATIS",i,j); 8739e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 8749e7b2b25Sstefano_zampini } 8755e3038f0Sstefano_zampini 8765e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 8775e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 8789e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 8795e3038f0Sstefano_zampini if (!l1 || !l2) continue; 8802c71b3e2SJacob Faibussowitsch PetscCheckFalse(lr[i] && l1 != lr[i],PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid local size %" PetscInt_FMT " != %" PetscInt_FMT,i,j,lr[i],l1); 8812c71b3e2SJacob Faibussowitsch PetscCheckFalse(lc[j] && l2 != lc[j],PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid local size %" PetscInt_FMT " != %" PetscInt_FMT,i,j,lc[j],l2); 8825e3038f0Sstefano_zampini lr[i] = l1; 8835e3038f0Sstefano_zampini lc[j] = l2; 8845e3038f0Sstefano_zampini 8855e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 8865e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 8875e3038f0Sstefano_zampini } 8885e3038f0Sstefano_zampini } 8895e3038f0Sstefano_zampini 89076bd3646SJed Brown if (PetscDefined (USE_DEBUG)) { 8915e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 8925e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8935e3038f0Sstefano_zampini rl2g = NULL; 8945e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8955e3038f0Sstefano_zampini PetscInt n1,n2; 8965e3038f0Sstefano_zampini 8975e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8989e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8999e7b2b25Sstefano_zampini Mat T; 9009e7b2b25Sstefano_zampini 9019e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 902*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 9039e7b2b25Sstefano_zampini } else { 904*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 9059e7b2b25Sstefano_zampini } 9065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9075e3038f0Sstefano_zampini if (!n1) continue; 9085e3038f0Sstefano_zampini if (!rl2g) { 9095e3038f0Sstefano_zampini rl2g = cl2g; 9105e3038f0Sstefano_zampini } else { 9115e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9125e3038f0Sstefano_zampini PetscBool same; 9135e3038f0Sstefano_zampini 9145e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9152c71b3e2SJacob Faibussowitsch PetscCheckFalse(n1 != n2,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid row l2gmap size %" PetscInt_FMT " != %" PetscInt_FMT,i,j,n1,n2); 9165e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9175e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 918580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9195e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9205e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9212c71b3e2SJacob Faibussowitsch PetscCheckFalse(!same,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid row l2gmap",i,j); 9225e3038f0Sstefano_zampini } 9235e3038f0Sstefano_zampini } 9245e3038f0Sstefano_zampini } 9255e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 9265e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 9275e3038f0Sstefano_zampini rl2g = NULL; 9285e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 9295e3038f0Sstefano_zampini PetscInt n1,n2; 9305e3038f0Sstefano_zampini 9315e3038f0Sstefano_zampini if (!nest[j][i]) continue; 9329e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 9339e7b2b25Sstefano_zampini Mat T; 9349e7b2b25Sstefano_zampini 9359e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 936*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 9379e7b2b25Sstefano_zampini } else { 938*e432b41dSStefano Zampini ierr = MatISGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 9399e7b2b25Sstefano_zampini } 9405e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9415e3038f0Sstefano_zampini if (!n1) continue; 9425e3038f0Sstefano_zampini if (!rl2g) { 9435e3038f0Sstefano_zampini rl2g = cl2g; 9445e3038f0Sstefano_zampini } else { 9455e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9465e3038f0Sstefano_zampini PetscBool same; 9475e3038f0Sstefano_zampini 9485e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9492c71b3e2SJacob Faibussowitsch PetscCheckFalse(n1 != n2,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid column l2gmap size %" PetscInt_FMT " != %" PetscInt_FMT,j,i,n1,n2); 9505e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9515e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 952580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9535e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9545e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9552c71b3e2SJacob Faibussowitsch PetscCheckFalse(!same,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%" PetscInt_FMT ",%" PetscInt_FMT ") has invalid column l2gmap",j,i); 9565e3038f0Sstefano_zampini } 9575e3038f0Sstefano_zampini } 9585e3038f0Sstefano_zampini } 95976bd3646SJed Brown } 9605e3038f0Sstefano_zampini 9615e3038f0Sstefano_zampini B = NULL; 9625e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 9635b003df0Sstefano_zampini PetscInt stl; 9645b003df0Sstefano_zampini 9655e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 9665e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 9675e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9685b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9695e3038f0Sstefano_zampini Mat usedmat; 9705e3038f0Sstefano_zampini Mat_IS *matis; 9715e3038f0Sstefano_zampini const PetscInt *idxs; 9725e3038f0Sstefano_zampini 9735e3038f0Sstefano_zampini /* local IS for local NEST */ 9745b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9755e3038f0Sstefano_zampini 9765e3038f0Sstefano_zampini /* l2gmap */ 9775e3038f0Sstefano_zampini j = 0; 9785e3038f0Sstefano_zampini usedmat = nest[i][j]; 9799e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 9802c71b3e2SJacob Faibussowitsch PetscCheckFalse(!usedmat,comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 9819e7b2b25Sstefano_zampini 9829e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9839e7b2b25Sstefano_zampini Mat T; 9849e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 9859e7b2b25Sstefano_zampini usedmat = T; 9869e7b2b25Sstefano_zampini } 9875e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 9885e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 9899e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 990ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 991ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 9929e7b2b25Sstefano_zampini } else { 993ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 994ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 9959e7b2b25Sstefano_zampini } 9965e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 9975e3038f0Sstefano_zampini stl += lr[i]; 9985e3038f0Sstefano_zampini } 9995e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 10005e3038f0Sstefano_zampini 10015e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 10025e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 10035e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 10045b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10055e3038f0Sstefano_zampini Mat usedmat; 10065e3038f0Sstefano_zampini Mat_IS *matis; 10075e3038f0Sstefano_zampini const PetscInt *idxs; 10085e3038f0Sstefano_zampini 10095e3038f0Sstefano_zampini /* local IS for local NEST */ 10105b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10115e3038f0Sstefano_zampini 10125e3038f0Sstefano_zampini /* l2gmap */ 10135e3038f0Sstefano_zampini j = 0; 10145e3038f0Sstefano_zampini usedmat = nest[j][i]; 10159e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 10162c71b3e2SJacob Faibussowitsch PetscCheckFalse(!usedmat,comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 10179e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10189e7b2b25Sstefano_zampini Mat T; 10199e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 10209e7b2b25Sstefano_zampini usedmat = T; 10219e7b2b25Sstefano_zampini } 10225e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10235e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 10249e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 1025ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 1026ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 10279e7b2b25Sstefano_zampini } else { 1028ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 1029ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl,MPI_REPLACE);CHKERRQ(ierr); 10309e7b2b25Sstefano_zampini } 10315e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 10325e3038f0Sstefano_zampini stl += lc[i]; 10335e3038f0Sstefano_zampini } 10345e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 10355e3038f0Sstefano_zampini 10365e3038f0Sstefano_zampini /* Create MATIS */ 10375e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 10385e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 10395e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 10405e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 10415e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 10428546b261SStefano Zampini ierr = MatISSetLocalMatType(B,MATNEST);CHKERRQ(ierr); 10438546b261SStefano Zampini { /* hack : avoid setup of scatters */ 10448546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10458546b261SStefano Zampini matis->islocalref = PETSC_TRUE; 10468546b261SStefano Zampini } 10475e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 10485e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 10495e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 10505e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 10518546b261SStefano Zampini ierr = MatNestSetVecType(lA,VECNEST);CHKERRQ(ierr); 10529e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 10539e7b2b25Sstefano_zampini if (istrans[i]) { 10549e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10559e7b2b25Sstefano_zampini } 10569e7b2b25Sstefano_zampini } 10575e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 10585e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10598546b261SStefano Zampini { /* hack : setup of scatters done here */ 10608546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10618546b261SStefano Zampini 10628546b261SStefano Zampini matis->islocalref = PETSC_FALSE; 10638546b261SStefano Zampini ierr = MatISSetUpScatters_Private(B);CHKERRQ(ierr); 10648546b261SStefano Zampini } 10655e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10665e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10675e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 10685e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 10695e3038f0Sstefano_zampini } else { 10705e3038f0Sstefano_zampini *newmat = B; 10715e3038f0Sstefano_zampini } 10725e3038f0Sstefano_zampini } else { 10735e3038f0Sstefano_zampini if (lreuse) { 10745e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10755e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10765e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 10775e3038f0Sstefano_zampini if (snest[i*nc+j]) { 10785e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 10799e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10809e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 10819e7b2b25Sstefano_zampini } 10825e3038f0Sstefano_zampini } 10835e3038f0Sstefano_zampini } 10845e3038f0Sstefano_zampini } 10855e3038f0Sstefano_zampini } else { 10865b003df0Sstefano_zampini PetscInt stl; 10875b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 10885b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 10895b003df0Sstefano_zampini stl += lr[i]; 10905e3038f0Sstefano_zampini } 10915b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10925b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10935b003df0Sstefano_zampini stl += lc[i]; 10945e3038f0Sstefano_zampini } 10955e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 1096ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 10979e7b2b25Sstefano_zampini if (istrans[i]) { 10989e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10999e7b2b25Sstefano_zampini } 1100ab4d48faSStefano Zampini } 11015e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 11025e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 11035e3038f0Sstefano_zampini } 11045e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11055e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11065e3038f0Sstefano_zampini } 11075e3038f0Sstefano_zampini 11085b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 11095b003df0Sstefano_zampini convert = PETSC_FALSE; 11105b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 11115b003df0Sstefano_zampini if (convert) { 11125b003df0Sstefano_zampini Mat M; 11135b003df0Sstefano_zampini MatISLocalFields lf; 11145b003df0Sstefano_zampini PetscContainer c; 11155b003df0Sstefano_zampini 11165b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 11175b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 11185b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 11195b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 11205b003df0Sstefano_zampini 11215b003df0Sstefano_zampini /* attach local fields to the matrix */ 11225b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 1123071fcb05SBarry Smith ierr = PetscMalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 11245b003df0Sstefano_zampini for (i=0;i<nr;i++) { 11255b003df0Sstefano_zampini PetscInt n,st; 11265b003df0Sstefano_zampini 11275b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 11285b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 11295b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 11305b003df0Sstefano_zampini } 11315b003df0Sstefano_zampini for (i=0;i<nc;i++) { 11325b003df0Sstefano_zampini PetscInt n,st; 11335b003df0Sstefano_zampini 11345b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 11355b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 11365b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 11375b003df0Sstefano_zampini } 11385b003df0Sstefano_zampini lf->nr = nr; 11395b003df0Sstefano_zampini lf->nc = nc; 11405b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 11415b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 11425b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 11435b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 11445b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 11455b003df0Sstefano_zampini } 11465b003df0Sstefano_zampini 11475e3038f0Sstefano_zampini /* Free workspace */ 11485e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 11495e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 11505e3038f0Sstefano_zampini } 11515e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 11525e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 11535e3038f0Sstefano_zampini } 11549e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 11555b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 11565e3038f0Sstefano_zampini PetscFunctionReturn(0); 11575e3038f0Sstefano_zampini } 11585e3038f0Sstefano_zampini 1159ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1160ad219c80Sstefano_zampini { 1161ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1162ad219c80Sstefano_zampini Vec ll,rr; 1163ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1164ad219c80Sstefano_zampini PetscScalar *x,*y; 1165ad219c80Sstefano_zampini PetscErrorCode ierr; 1166ad219c80Sstefano_zampini 1167ad219c80Sstefano_zampini PetscFunctionBegin; 1168ad219c80Sstefano_zampini if (l) { 1169ad219c80Sstefano_zampini ll = matis->y; 1170ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1171ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1172ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y,MPI_REPLACE);CHKERRQ(ierr); 1173ad219c80Sstefano_zampini } else { 1174ad219c80Sstefano_zampini ll = NULL; 1175ad219c80Sstefano_zampini } 1176ad219c80Sstefano_zampini if (r) { 1177ad219c80Sstefano_zampini rr = matis->x; 1178ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1179ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1180ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x,MPI_REPLACE);CHKERRQ(ierr); 1181ad219c80Sstefano_zampini } else { 1182ad219c80Sstefano_zampini rr = NULL; 1183ad219c80Sstefano_zampini } 1184ad219c80Sstefano_zampini if (ll) { 1185ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y,MPI_REPLACE);CHKERRQ(ierr); 1186ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1187ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1188ad219c80Sstefano_zampini } 1189ad219c80Sstefano_zampini if (rr) { 1190ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x,MPI_REPLACE);CHKERRQ(ierr); 1191ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1192ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1193ad219c80Sstefano_zampini } 1194ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1195ad219c80Sstefano_zampini PetscFunctionReturn(0); 1196ad219c80Sstefano_zampini } 1197ad219c80Sstefano_zampini 11987fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 11997fa8f2d3SStefano Zampini { 12007fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 12017fa8f2d3SStefano Zampini MatInfo info; 12023966268fSBarry Smith PetscLogDouble isend[6],irecv[6]; 12037fa8f2d3SStefano Zampini PetscInt bs; 12047fa8f2d3SStefano Zampini PetscErrorCode ierr; 12057fa8f2d3SStefano Zampini 12067fa8f2d3SStefano Zampini PetscFunctionBegin; 12077fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1208a2ccb5f9Sstefano_zampini if (matis->A->ops->getinfo) { 12097fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 12107fa8f2d3SStefano Zampini isend[0] = info.nz_used; 12117fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 12127fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 12137fa8f2d3SStefano Zampini isend[3] = info.memory; 12147fa8f2d3SStefano Zampini isend[4] = info.mallocs; 1215a2ccb5f9Sstefano_zampini } else { 1216a2ccb5f9Sstefano_zampini isend[0] = 0.; 1217a2ccb5f9Sstefano_zampini isend[1] = 0.; 1218a2ccb5f9Sstefano_zampini isend[2] = 0.; 1219a2ccb5f9Sstefano_zampini isend[3] = 0.; 1220a2ccb5f9Sstefano_zampini isend[4] = 0.; 1221a2ccb5f9Sstefano_zampini } 1222314ce898Sstefano_zampini isend[5] = matis->A->num_ass; 12237fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 12247fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 12257fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 12267fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 12277fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 12287fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 1229314ce898Sstefano_zampini ginfo->assemblies = isend[5]; 12307fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 1231820f2d46SBarry Smith ierr = MPIU_Allreduce(isend,irecv,6,MPIU_PETSCLOGDOUBLE,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 12327fa8f2d3SStefano Zampini 12337fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12347fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12357fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12367fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12377fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 1238314ce898Sstefano_zampini ginfo->assemblies = irecv[5]; 12397fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 1240820f2d46SBarry Smith ierr = MPIU_Allreduce(isend,irecv,5,MPIU_PETSCLOGDOUBLE,MPI_SUM,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 12417fa8f2d3SStefano Zampini 12427fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12437fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12447fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12457fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12467fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12477fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 12487fa8f2d3SStefano Zampini } 12497fa8f2d3SStefano Zampini ginfo->block_size = bs; 12507fa8f2d3SStefano Zampini ginfo->fill_ratio_given = 0; 12517fa8f2d3SStefano Zampini ginfo->fill_ratio_needed = 0; 12527fa8f2d3SStefano Zampini ginfo->factor_mallocs = 0; 12535e3038f0Sstefano_zampini PetscFunctionReturn(0); 12545e3038f0Sstefano_zampini } 12555e3038f0Sstefano_zampini 12568b9382cfSStefano Zampini static PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1257d7f69cd0SStefano Zampini { 1258d7f69cd0SStefano Zampini Mat C,lC,lA; 1259d7f69cd0SStefano Zampini PetscErrorCode ierr; 1260d7f69cd0SStefano Zampini 1261d7f69cd0SStefano Zampini PetscFunctionBegin; 1262cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1263cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1264d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1265d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1266d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1267d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1268d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1269d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1270*e432b41dSStefano Zampini } else C = *B; 1271d7f69cd0SStefano Zampini 1272d7f69cd0SStefano Zampini /* perform local transposition */ 1273d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1274d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1275*e432b41dSStefano Zampini ierr = MatSetLocalToGlobalMapping(lC,lA->cmap->mapping,lA->rmap->mapping);CHKERRQ(ierr); 1276d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1277d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1278d7f69cd0SStefano Zampini 1279cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1280d7f69cd0SStefano Zampini *B = C; 1281d7f69cd0SStefano Zampini } else { 1282d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1283d7f69cd0SStefano Zampini } 12847aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12857aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1286d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1287d7f69cd0SStefano Zampini } 1288d7f69cd0SStefano Zampini 12898b9382cfSStefano Zampini static PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 12903fd1c9e7SStefano Zampini { 12913fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 12923fd1c9e7SStefano Zampini PetscErrorCode ierr; 12933fd1c9e7SStefano Zampini 12943fd1c9e7SStefano Zampini PetscFunctionBegin; 12954b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 12963fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12973fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12983fd1c9e7SStefano Zampini } 12993fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 13003fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 13013fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13023fd1c9e7SStefano Zampini } 13033fd1c9e7SStefano Zampini 13048b9382cfSStefano Zampini static PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 13053fd1c9e7SStefano Zampini { 13064b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 13073fd1c9e7SStefano Zampini PetscErrorCode ierr; 13083fd1c9e7SStefano Zampini 13093fd1c9e7SStefano Zampini PetscFunctionBegin; 13104b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 13113fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 13123fd1c9e7SStefano Zampini PetscFunctionReturn(0); 13133fd1c9e7SStefano Zampini } 13143fd1c9e7SStefano Zampini 1315f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1316f26d0771SStefano Zampini { 1317f26d0771SStefano Zampini PetscErrorCode ierr; 1318f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1319f26d0771SStefano Zampini 1320f26d0771SStefano Zampini PetscFunctionBegin; 13212c71b3e2SJacob Faibussowitsch PetscCheckFalse(m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION,PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %d: they are %" PetscInt_FMT " %" PetscInt_FMT,MATIS_MAX_ENTRIES_INSERTION,m,n); 1322f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1323f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1324b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1325f26d0771SStefano Zampini PetscFunctionReturn(0); 1326f26d0771SStefano Zampini } 1327f26d0771SStefano Zampini 1328f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1329f26d0771SStefano Zampini { 1330f26d0771SStefano Zampini PetscErrorCode ierr; 1331f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1332f26d0771SStefano Zampini 1333f26d0771SStefano Zampini PetscFunctionBegin; 13342c71b3e2SJacob Faibussowitsch PetscCheckFalse(m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION,PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %d: they are %" PetscInt_FMT " %" PetscInt_FMT,MATIS_MAX_ENTRIES_INSERTION,m,n); 1335f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1336f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1337b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1338f26d0771SStefano Zampini PetscFunctionReturn(0); 1339f26d0771SStefano Zampini } 1340f26d0771SStefano Zampini 13417dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1342a8116848SStefano Zampini { 1343a8116848SStefano Zampini Mat locmat,newlocmat; 1344a8116848SStefano Zampini Mat_IS *newmatis; 1345a8116848SStefano Zampini const PetscInt *idxs; 1346a8116848SStefano Zampini PetscInt i,m,n; 1347a8116848SStefano Zampini PetscErrorCode ierr; 1348a8116848SStefano Zampini 1349a8116848SStefano Zampini PetscFunctionBegin; 1350a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1351a8116848SStefano Zampini PetscBool ismatis; 1352a8116848SStefano Zampini 1353a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 13542c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1355a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 13562c71b3e2SJacob Faibussowitsch PetscCheckFalse(!newmatis->getsub_ris,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 13572c71b3e2SJacob Faibussowitsch PetscCheckFalse(!newmatis->getsub_cis,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1358a8116848SStefano Zampini } 1359a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 136076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 136176bd3646SJed Brown Vec rtest,ltest; 136276bd3646SJed Brown const PetscScalar *array; 136376bd3646SJed Brown 1364a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1365a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1366a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1367a8116848SStefano Zampini for (i=0;i<n;i++) { 1368a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1369a8116848SStefano Zampini } 1370a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1371a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1372a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1373a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1374a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 13752c71b3e2SJacob Faibussowitsch for (i=0;i<n;i++) PetscCheckFalse(array[i] != 0. && array[i] != 1.,PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %" PetscInt_FMT " counted %" PetscInt_FMT " times! Irow may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1376a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1377a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1378a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1379a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1380a8116848SStefano Zampini for (i=0;i<n;i++) { 1381a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1382a8116848SStefano Zampini } 1383a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1384a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1385a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1386a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1387a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 13882c71b3e2SJacob Faibussowitsch for (i=0;i<n;i++) PetscCheckFalse(array[i] != 0. && array[i] != 1.,PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %" PetscInt_FMT " counted %" PetscInt_FMT " times! Icol may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1389a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1390a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1391a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1392a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 139376bd3646SJed Brown } 1394a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1395a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1396a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1397a8116848SStefano Zampini IS is; 1398a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1399306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 140094342113SStefano Zampini PetscBool cong; 1401a8116848SStefano Zampini MPI_Comm comm; 1402a8116848SStefano Zampini 1403a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1404306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1405306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1406306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1407306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1408306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1409a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1410a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1411a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1412a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1413a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1414306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1415a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1416a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1417a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1418a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1419580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,matis->sf->nroots);CHKERRQ(ierr); 1420a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1421a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1422a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1423ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 1424ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 14253d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1426a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1427a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14283d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1429a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1430a8116848SStefano Zampini lidxs[newloc] = i; 1431a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1432a8116848SStefano Zampini } 1433a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1434a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1435306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1436a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1437a8116848SStefano Zampini /* local is to extract local submatrix */ 1438a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1439a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 144094342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 144194342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1442a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1443a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1444a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1445a8116848SStefano Zampini } else { 1446a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1447a8116848SStefano Zampini 1448a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1449a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1450a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1451a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1452580bdb30SBarry Smith ierr = PetscArrayzero(matis->csf_rootdata,matis->csf->nroots);CHKERRQ(ierr); 1453a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1454a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1455a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1456ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 1457ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 14583d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1459a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1460a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14613d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1462a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1463a8116848SStefano Zampini lidxs[newloc] = i; 1464a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1465a8116848SStefano Zampini } 1466a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1467a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1468306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1469a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1470a8116848SStefano Zampini /* local is to extract local submatrix */ 1471a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1472a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1473a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1474a8116848SStefano Zampini } 1475a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1476a8116848SStefano Zampini } else { 1477a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1478a8116848SStefano Zampini } 1479a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1480a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 14817dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1482a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1483a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1484a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1485a8116848SStefano Zampini } 1486a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1487a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1488a8116848SStefano Zampini PetscFunctionReturn(0); 1489a8116848SStefano Zampini } 1490a8116848SStefano Zampini 1491a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 14922b404112SStefano Zampini { 14932b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 14942b404112SStefano Zampini PetscBool ismatis; 14952b404112SStefano Zampini PetscErrorCode ierr; 14962b404112SStefano Zampini 14972b404112SStefano Zampini PetscFunctionBegin; 14982b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 14992c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 15002b404112SStefano Zampini b = (Mat_IS*)B->data; 15012b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1502cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 15032b404112SStefano Zampini PetscFunctionReturn(0); 15042b404112SStefano Zampini } 15052b404112SStefano Zampini 1506a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 15076bd84002SStefano Zampini { 1508527b2640SStefano Zampini Vec v; 1509527b2640SStefano Zampini const PetscScalar *array; 1510527b2640SStefano Zampini PetscInt i,n; 15116bd84002SStefano Zampini PetscErrorCode ierr; 15126bd84002SStefano Zampini 15136bd84002SStefano Zampini PetscFunctionBegin; 1514527b2640SStefano Zampini *missing = PETSC_FALSE; 1515527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1516527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1517527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1518527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1519527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1520527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1521527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1522527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1523527b2640SStefano Zampini if (d) { 1524527b2640SStefano Zampini *d = -1; 1525527b2640SStefano Zampini if (*missing) { 1526527b2640SStefano Zampini PetscInt rstart; 1527527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1528527b2640SStefano Zampini *d = i+rstart; 1529527b2640SStefano Zampini } 1530527b2640SStefano Zampini } 15316bd84002SStefano Zampini PetscFunctionReturn(0); 15326bd84002SStefano Zampini } 15336bd84002SStefano Zampini 1534cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 153528f4e0baSStefano Zampini { 153628f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 153728f4e0baSStefano Zampini const PetscInt *gidxs; 15384f2d7cafSStefano Zampini PetscInt nleaves; 153928f4e0baSStefano Zampini PetscErrorCode ierr; 154028f4e0baSStefano Zampini 154128f4e0baSStefano Zampini PetscFunctionBegin; 15424f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 154328f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 1544*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->rmapping,&gidxs);CHKERRQ(ierr); 1545*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->rmapping,&nleaves);CHKERRQ(ierr); 15464f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1547*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->rmapping,&gidxs);CHKERRQ(ierr); 15484f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1549*e432b41dSStefano Zampini if (matis->rmapping != matis->cmapping) { /* setup SF for columns */ 1550*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->cmapping,&nleaves);CHKERRQ(ierr); 1551a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1552*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->cmapping,&gidxs);CHKERRQ(ierr); 15533d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1554*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->cmapping,&gidxs);CHKERRQ(ierr); 15553d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1556a8116848SStefano Zampini } else { 1557a8116848SStefano Zampini matis->csf = matis->sf; 1558a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1559a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1560a8116848SStefano Zampini } 156128f4e0baSStefano Zampini PetscFunctionReturn(0); 156228f4e0baSStefano Zampini } 15632e1947a5SStefano Zampini 1564eb82efa4SStefano Zampini /*@ 156575d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 156675d48cdbSStefano Zampini 1567d083f849SBarry Smith Collective 156875d48cdbSStefano Zampini 156975d48cdbSStefano Zampini Input Parameters: 157075d48cdbSStefano Zampini + A - the matrix 157175d48cdbSStefano Zampini - store - the boolean flag 157275d48cdbSStefano Zampini 157375d48cdbSStefano Zampini Level: advanced 157475d48cdbSStefano Zampini 157575d48cdbSStefano Zampini Notes: 157675d48cdbSStefano Zampini 157775d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 157875d48cdbSStefano Zampini @*/ 157975d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 158075d48cdbSStefano Zampini { 158175d48cdbSStefano Zampini PetscErrorCode ierr; 158275d48cdbSStefano Zampini 158375d48cdbSStefano Zampini PetscFunctionBegin; 158475d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 158575d48cdbSStefano Zampini PetscValidType(A,1); 158675d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 158775d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 158875d48cdbSStefano Zampini PetscFunctionReturn(0); 158975d48cdbSStefano Zampini } 159075d48cdbSStefano Zampini 159175d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 159275d48cdbSStefano Zampini { 159375d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 159475d48cdbSStefano Zampini PetscErrorCode ierr; 159575d48cdbSStefano Zampini 159675d48cdbSStefano Zampini PetscFunctionBegin; 159775d48cdbSStefano Zampini matis->storel2l = store; 159875d48cdbSStefano Zampini if (!store) { 159975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 160075d48cdbSStefano Zampini } 160175d48cdbSStefano Zampini PetscFunctionReturn(0); 160275d48cdbSStefano Zampini } 160375d48cdbSStefano Zampini 160475d48cdbSStefano Zampini /*@ 1605f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1606f03112d0SStefano Zampini 1607d083f849SBarry Smith Collective 1608f03112d0SStefano Zampini 1609f03112d0SStefano Zampini Input Parameters: 1610f03112d0SStefano Zampini + A - the matrix 1611f03112d0SStefano Zampini - fix - the boolean flag 1612f03112d0SStefano Zampini 1613f03112d0SStefano Zampini Level: advanced 1614f03112d0SStefano Zampini 1615f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1616f03112d0SStefano Zampini 1617f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1618f03112d0SStefano Zampini @*/ 1619f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1620f03112d0SStefano Zampini { 1621f03112d0SStefano Zampini PetscErrorCode ierr; 1622f03112d0SStefano Zampini 1623f03112d0SStefano Zampini PetscFunctionBegin; 1624f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1625f03112d0SStefano Zampini PetscValidType(A,1); 1626f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1627f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1628f03112d0SStefano Zampini PetscFunctionReturn(0); 1629f03112d0SStefano Zampini } 1630f03112d0SStefano Zampini 1631f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1632f03112d0SStefano Zampini { 1633f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1634f03112d0SStefano Zampini 1635f03112d0SStefano Zampini PetscFunctionBegin; 1636f03112d0SStefano Zampini matis->locempty = fix; 1637f03112d0SStefano Zampini PetscFunctionReturn(0); 1638f03112d0SStefano Zampini } 1639f03112d0SStefano Zampini 1640f03112d0SStefano Zampini /*@ 1641a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1642a88811baSStefano Zampini 1643d083f849SBarry Smith Collective 1644a88811baSStefano Zampini 1645a88811baSStefano Zampini Input Parameters: 1646a88811baSStefano Zampini + B - the matrix 1647a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1648a88811baSStefano Zampini (same value is used for all local rows) 1649a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1650a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1651a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1652a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1653a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1654a88811baSStefano Zampini the diagonal entry even if it is zero. 1655a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1656a88811baSStefano Zampini submatrix (same value is used for all local rows). 1657a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1658a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1659a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1660a88811baSStefano Zampini structure. The size of this array is equal to the number 1661a88811baSStefano Zampini of local rows, i.e 'm'. 1662a88811baSStefano Zampini 1663a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1664a88811baSStefano Zampini 1665a88811baSStefano Zampini Level: intermediate 1666a88811baSStefano Zampini 166795452b02SPatrick Sanan Notes: 166895452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1669a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1670a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1671a88811baSStefano Zampini 16723c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1673a88811baSStefano Zampini @*/ 16742e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16752e1947a5SStefano Zampini { 16762e1947a5SStefano Zampini PetscErrorCode ierr; 16772e1947a5SStefano Zampini 16782e1947a5SStefano Zampini PetscFunctionBegin; 16792e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 16802e1947a5SStefano Zampini PetscValidType(B,1); 16812e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 16822e1947a5SStefano Zampini PetscFunctionReturn(0); 16832e1947a5SStefano Zampini } 16842e1947a5SStefano Zampini 1685844bd0d7SStefano Zampini /* this is used by DMDA */ 1686844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16872e1947a5SStefano Zampini { 16882e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 168928f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 16902e1947a5SStefano Zampini PetscErrorCode ierr; 16912e1947a5SStefano Zampini 16922e1947a5SStefano Zampini PetscFunctionBegin; 1693fc989267SStefano Zampini ierr = MatSetUp(B);CHKERRQ(ierr); 16944f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 16954f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 16964f2d7cafSStefano Zampini 16974f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 16984f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 16994f2d7cafSStefano Zampini 1700ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 170128f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 170228f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 1703ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 17044f2d7cafSStefano Zampini 17054f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 170628f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 17070f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 17080f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 17090f2f62c7SStefano Zampini #endif 17104f2d7cafSStefano Zampini 1711fc989267SStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) { 1712fc989267SStefano Zampini PetscInt b; 1713fc989267SStefano Zampini 1714fc989267SStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 1715fc989267SStefano Zampini for (b=1;b<bs;b++) { 1716fc989267SStefano Zampini matis->sf_leafdata[i] = PetscMax(matis->sf_leafdata[i],matis->sf_leafdata[i*bs+b]/bs); 1717fc989267SStefano Zampini } 1718fc989267SStefano Zampini } 171928f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17204f2d7cafSStefano Zampini 172100a59248SStefano Zampini nlocalcols /= bs; 172200a59248SStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols - i); 172328f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17240f2f62c7SStefano Zampini 17250f2f62c7SStefano Zampini /* for other matrix types */ 17260f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 17272e1947a5SStefano Zampini PetscFunctionReturn(0); 17282e1947a5SStefano Zampini } 1729b4319ba4SBarry Smith 17303927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 17313927de2eSStefano Zampini { 17323927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 17333927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1734ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 17353927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 17363927de2eSStefano Zampini PetscInt lrows,lcols; 17373927de2eSStefano Zampini PetscInt local_rows,local_cols; 1738f03112d0SStefano Zampini PetscMPIInt size; 17393927de2eSStefano Zampini PetscBool isdense,issbaij; 17403927de2eSStefano Zampini PetscErrorCode ierr; 17413927de2eSStefano Zampini 17423927de2eSStefano Zampini PetscFunctionBegin; 1743ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRMPI(ierr); 17443927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 17453927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 17463927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1747b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1748b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1749*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->rmapping,&global_indices_r);CHKERRQ(ierr); 1750*e432b41dSStefano Zampini if (matis->rmapping != matis->cmapping) { 1751*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->cmapping,&global_indices_c);CHKERRQ(ierr); 17520dfc91b7SStefano Zampini } else global_indices_c = global_indices_r; 1753ecf5a873SStefano Zampini 17543927de2eSStefano Zampini if (issbaij) { 17553927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 17563927de2eSStefano Zampini } 17573927de2eSStefano Zampini /* 1758ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 17593927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 17603927de2eSStefano Zampini */ 17613927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 17623927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 17633927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 17643927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 17653927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1766f03112d0SStefano Zampini for (i=0;i<size;i++) { 17673927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 17683927de2eSStefano Zampini row_ownership[j] = i; 17693927de2eSStefano Zampini } 17703927de2eSStefano Zampini } 17717230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 17723927de2eSStefano Zampini 17733927de2eSStefano Zampini /* 17743927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 17753927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 17763927de2eSStefano Zampini */ 17773927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 17783927de2eSStefano Zampini /* preallocation as a MATAIJ */ 17793927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 17803927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 178112dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 178212dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1783ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 17843927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1]) { /* diag block */ 17853927de2eSStefano Zampini my_dnz[i] += 1; 17863927de2eSStefano Zampini } else { /* offdiag block */ 17873927de2eSStefano Zampini my_onz[i] += 1; 17883927de2eSStefano Zampini } 17893927de2eSStefano Zampini } 17903927de2eSStefano Zampini } 1791bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1792bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1793bb1015c3SStefano Zampini PetscBool done; 1794bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 17952c71b3e2SJacob Faibussowitsch PetscCheckFalse(!done,PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1796bb1015c3SStefano Zampini jptr = jj; 1797bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1798bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1799bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1800bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1801bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1802bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1]) { /* diag block */ 1803bb1015c3SStefano Zampini my_dnz[i] += 1; 1804bb1015c3SStefano Zampini } else { /* offdiag block */ 1805bb1015c3SStefano Zampini my_onz[i] += 1; 1806bb1015c3SStefano Zampini } 1807bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1808bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1809bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1810bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1]) { 1811bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1812bb1015c3SStefano Zampini } else { 1813bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1814bb1015c3SStefano Zampini } 1815bb1015c3SStefano Zampini } 1816bb1015c3SStefano Zampini } 1817bb1015c3SStefano Zampini } 1818bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 18192c71b3e2SJacob Faibussowitsch PetscCheckFalse(!done,PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1820bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 18213927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 18223927de2eSStefano Zampini const PetscInt *cols; 1823ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 18243927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18253927de2eSStefano Zampini for (j=0;j<ncols;j++) { 18263927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1827ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 18283927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1]) { /* diag block */ 18293927de2eSStefano Zampini my_dnz[i] += 1; 18303927de2eSStefano Zampini } else { /* offdiag block */ 18313927de2eSStefano Zampini my_onz[i] += 1; 18323927de2eSStefano Zampini } 18333927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1834d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 18353927de2eSStefano Zampini owner = row_ownership[index_col]; 18363927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1]) { 1837d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 18383927de2eSStefano Zampini } else { 1839d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 18403927de2eSStefano Zampini } 18413927de2eSStefano Zampini } 18423927de2eSStefano Zampini } 18433927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18443927de2eSStefano Zampini } 18453927de2eSStefano Zampini } 1846ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 1847*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->cmapping,&global_indices_c);CHKERRQ(ierr); 1848ecf5a873SStefano Zampini } 1849*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->rmapping,&global_indices_r);CHKERRQ(ierr); 18503927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1851ecf5a873SStefano Zampini 1852ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 18533927de2eSStefano Zampini if (maxreduce) { 18543927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18553927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1856bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18573927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 18583927de2eSStefano Zampini } else { 18593927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18603927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1861bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18623927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 18633927de2eSStefano Zampini } 18643927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 18653927de2eSStefano Zampini 18663927de2eSStefano Zampini /* Resize preallocation if overestimated */ 18673927de2eSStefano Zampini for (i=0;i<lrows;i++) { 18683927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 18693927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 18703927de2eSStefano Zampini } 18711670daf9Sstefano_zampini 18721670daf9Sstefano_zampini /* Set preallocation */ 18730dfc91b7SStefano Zampini ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr); 1874268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 18753927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 187653b44cf5SStefano Zampini for (i=0;i<lrows;i+=bs) { 187753b44cf5SStefano Zampini PetscInt b, d = dnz[i],o = onz[i]; 187853b44cf5SStefano Zampini 187953b44cf5SStefano Zampini for (b=1;b<bs;b++) { 188053b44cf5SStefano Zampini d = PetscMax(d,dnz[i+b]); 188153b44cf5SStefano Zampini o = PetscMax(o,onz[i+b]); 188253b44cf5SStefano Zampini } 188353b44cf5SStefano Zampini dnz[i/bs] = PetscMin(d/bs + d%bs,lcols/bs); 188453b44cf5SStefano Zampini onz[i/bs] = PetscMin(o/bs + o%bs,(cols-lcols)/bs); 18853927de2eSStefano Zampini } 1886268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 18873927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18883927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18893927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 18903927de2eSStefano Zampini if (issbaij) { 18913927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 18923927de2eSStefano Zampini } 18939be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 18943927de2eSStefano Zampini PetscFunctionReturn(0); 18953927de2eSStefano Zampini } 18963927de2eSStefano Zampini 1897487b449aSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_IS_XAIJ(Mat mat, MatType mtype, MatReuse reuse, Mat *M) 1898b7ce53b6SStefano Zampini { 1899b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1900487b449aSStefano Zampini Mat local_mat,MT; 190153b44cf5SStefano Zampini PetscInt rbs,cbs,rows,cols,lrows,lcols; 1902b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1903b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1904f03112d0SStefano Zampini PetscMPIInt size; 19051683a169SBarry Smith const PetscScalar *array; 1906b7ce53b6SStefano Zampini PetscErrorCode ierr; 1907b7ce53b6SStefano Zampini 1908b7ce53b6SStefano Zampini PetscFunctionBegin; 1909ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 1910f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 19111670daf9Sstefano_zampini Mat B; 191253b44cf5SStefano Zampini IS irows = NULL,icols = NULL; 1913487b449aSStefano Zampini PetscInt rbs,cbs; 19141670daf9Sstefano_zampini 1915*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(matis->rmapping,&rbs);CHKERRQ(ierr); 1916*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(matis->cmapping,&cbs);CHKERRQ(ierr); 191753b44cf5SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { /* check if l2g maps are one-to-one */ 191853b44cf5SStefano Zampini IS rows,cols; 191953b44cf5SStefano Zampini const PetscInt *ridxs,*cidxs; 192053b44cf5SStefano Zampini PetscInt i,nw,*work; 192153b44cf5SStefano Zampini 1922*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(matis->rmapping,&ridxs);CHKERRQ(ierr); 1923*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->rmapping,&nw);CHKERRQ(ierr); 192453b44cf5SStefano Zampini nw = nw/rbs; 192553b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 192653b44cf5SStefano Zampini for (i=0;i<nw;i++) work[ridxs[i]] += 1; 192753b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 192853b44cf5SStefano Zampini if (i == nw) { 192953b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,nw,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 1930acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 193153b44cf5SStefano Zampini ierr = ISInvertPermutation(rows,PETSC_DECIDE,&irows);CHKERRQ(ierr); 1932acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 193353b44cf5SStefano Zampini } 1934*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(matis->rmapping,&ridxs);CHKERRQ(ierr); 193553b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1936*e432b41dSStefano Zampini if (irows && matis->rmapping != matis->cmapping) { 1937*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(matis->cmapping,&cidxs);CHKERRQ(ierr); 1938*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->cmapping,&nw);CHKERRQ(ierr); 193953b44cf5SStefano Zampini nw = nw/cbs; 194053b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 194153b44cf5SStefano Zampini for (i=0;i<nw;i++) work[cidxs[i]] += 1; 194253b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 194353b44cf5SStefano Zampini if (i == nw) { 194453b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,nw,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 194553b44cf5SStefano Zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 194653b44cf5SStefano Zampini ierr = ISInvertPermutation(cols,PETSC_DECIDE,&icols);CHKERRQ(ierr); 194753b44cf5SStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 194853b44cf5SStefano Zampini } 1949*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(matis->cmapping,&cidxs);CHKERRQ(ierr); 195053b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 195153b44cf5SStefano Zampini } else if (irows) { 195253b44cf5SStefano Zampini ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); 195353b44cf5SStefano Zampini icols = irows; 195453b44cf5SStefano Zampini } 195553b44cf5SStefano Zampini } else { 195653b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject*)&irows);CHKERRQ(ierr); 195753b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject*)&icols);CHKERRQ(ierr); 195853b44cf5SStefano Zampini if (irows) { ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); } 195953b44cf5SStefano Zampini if (icols) { ierr = PetscObjectReference((PetscObject)icols);CHKERRQ(ierr); } 196053b44cf5SStefano Zampini } 196153b44cf5SStefano Zampini if (!irows || !icols) { 196253b44cf5SStefano Zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 196353b44cf5SStefano Zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 196453b44cf5SStefano Zampini goto general_assembly; 196553b44cf5SStefano Zampini } 1966d8e18881SStefano Zampini ierr = MatConvert(matis->A,mtype,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1967487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 19687dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 196953b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject)irows);CHKERRQ(ierr); 197053b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject)icols);CHKERRQ(ierr); 1971487b449aSStefano Zampini } else { 1972487b449aSStefano Zampini Mat C; 1973487b449aSStefano Zampini 1974487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 1975487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 1976487b449aSStefano Zampini } 1977acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1978acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1979acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 19807c03b4e8SStefano Zampini PetscFunctionReturn(0); 19817c03b4e8SStefano Zampini } 198253b44cf5SStefano Zampini general_assembly: 1983b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1984*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(matis->rmapping,&rbs);CHKERRQ(ierr); 1985*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(matis->cmapping,&cbs);CHKERRQ(ierr); 19863cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1987b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1988b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 19894099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1990b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1991b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 19922c71b3e2SJacob Faibussowitsch PetscCheckFalse(!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 199376bd3646SJed Brown if (PetscDefined (USE_DEBUG)) { 199476bd3646SJed Brown PetscBool lb[4],bb[4]; 199576bd3646SJed Brown 1996b9ed4604SStefano Zampini lb[0] = isseqdense; 1997b9ed4604SStefano Zampini lb[1] = isseqaij; 1998b9ed4604SStefano Zampini lb[2] = isseqbaij; 1999b9ed4604SStefano Zampini lb[3] = isseqsbaij; 2000820f2d46SBarry Smith ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr); 20012c71b3e2SJacob Faibussowitsch PetscCheckFalse(!bb[0] && !bb[1] && !bb[2] && !bb[3],PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 200276bd3646SJed Brown } 2003b7ce53b6SStefano Zampini 2004487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2005487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 2006487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 2007487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 200853b44cf5SStefano Zampini ierr = MatSetBlockSizes(MT,rbs,cbs);CHKERRQ(ierr); 2009487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 2010b7ce53b6SStefano Zampini } else { 201153b44cf5SStefano Zampini PetscInt mrbs,mcbs,mrows,mcols,mlrows,mlcols; 2012487b449aSStefano Zampini 2013b7ce53b6SStefano Zampini /* some checks */ 2014487b449aSStefano Zampini MT = *M; 201553b44cf5SStefano Zampini ierr = MatGetBlockSizes(MT,&mrbs,&mcbs);CHKERRQ(ierr); 2016487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 2017487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 20182c71b3e2SJacob Faibussowitsch PetscCheckFalse(mrows != rows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%" PetscInt_FMT " != %" PetscInt_FMT ")",rows,mrows); 20192c71b3e2SJacob Faibussowitsch PetscCheckFalse(mcols != cols,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%" PetscInt_FMT " != %" PetscInt_FMT ")",cols,mcols); 20202c71b3e2SJacob Faibussowitsch PetscCheckFalse(mlrows != lrows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%" PetscInt_FMT " != %" PetscInt_FMT ")",lrows,mlrows); 20212c71b3e2SJacob Faibussowitsch PetscCheckFalse(mlcols != lcols,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%" PetscInt_FMT " != %" PetscInt_FMT ")",lcols,mlcols); 20222c71b3e2SJacob Faibussowitsch PetscCheckFalse(mrbs != rbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong row block size (%" PetscInt_FMT " != %" PetscInt_FMT ")",rbs,mrbs); 20232c71b3e2SJacob Faibussowitsch PetscCheckFalse(mcbs != cbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong col block size (%" PetscInt_FMT " != %" PetscInt_FMT ")",cbs,mcbs); 2024487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 2025b7ce53b6SStefano Zampini } 2026d9a9e74cSStefano Zampini 20278546b261SStefano Zampini if (isseqsbaij || isseqbaij) { 20288546b261SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 20298546b261SStefano Zampini isseqaij = PETSC_TRUE; 2030d9a9e74cSStefano Zampini } else { 2031d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 2032d9a9e74cSStefano Zampini local_mat = matis->A; 2033d9a9e74cSStefano Zampini } 2034686e3a49SStefano Zampini 2035b7ce53b6SStefano Zampini /* Set values */ 2036*e432b41dSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,matis->rmapping,matis->cmapping);CHKERRQ(ierr); 2037b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 203865066ba5SStefano Zampini PetscInt i,*dummy; 2039ecf5a873SStefano Zampini 204065066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 204165066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 2042487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 20431683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&array);CHKERRQ(ierr); 2044487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 20451683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&array);CHKERRQ(ierr); 204665066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 2047686e3a49SStefano Zampini } else if (isseqaij) { 20486afe12f5SStefano Zampini const PetscInt *blocks; 20496afe12f5SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy, nb; 2050686e3a49SStefano Zampini PetscBool done; 20511683a169SBarry Smith PetscScalar *sarray; 2052686e3a49SStefano Zampini 2053d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 20542c71b3e2SJacob Faibussowitsch PetscCheckFalse(!done,PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 20551683a169SBarry Smith ierr = MatSeqAIJGetArray(local_mat,&sarray);CHKERRQ(ierr); 20566afe12f5SStefano Zampini ierr = MatGetVariableBlockSizes(local_mat,&nb,&blocks);CHKERRQ(ierr); 20576afe12f5SStefano Zampini if (nb) { /* speed up assembly for special blocked matrices (used by BDDC) */ 20586afe12f5SStefano Zampini PetscInt sum; 20596afe12f5SStefano Zampini 20606afe12f5SStefano Zampini for (i=0,sum=0;i<nb;i++) sum += blocks[i]; 20616afe12f5SStefano Zampini if (sum == nvtxs) { 20626afe12f5SStefano Zampini PetscInt r; 20636afe12f5SStefano Zampini 20646afe12f5SStefano Zampini for (i=0,r=0;i<nb;i++) { 20656bdcaf15SBarry Smith PetscAssert(blocks[i] == xadj[r+1] - xadj[r],PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid block sizes prescribed for block %" PetscInt_FMT ": expected %" PetscInt_FMT ", got %" PetscInt_FMT,i,blocks[i],xadj[r+1] - xadj[r]); 20661683a169SBarry Smith ierr = MatSetValuesLocal(MT,blocks[i],adjncy+xadj[r],blocks[i],adjncy+xadj[r],sarray+xadj[r],ADD_VALUES);CHKERRQ(ierr); 20676afe12f5SStefano Zampini r += blocks[i]; 20686afe12f5SStefano Zampini } 20696afe12f5SStefano Zampini } else { 2070686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 20711683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 2072686e3a49SStefano Zampini } 20736afe12f5SStefano Zampini } 20746afe12f5SStefano Zampini } else { 20756afe12f5SStefano Zampini for (i=0;i<nvtxs;i++) { 20761683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 20776afe12f5SStefano Zampini } 20786afe12f5SStefano Zampini } 2079d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 20802c71b3e2SJacob Faibussowitsch PetscCheckFalse(!done,PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 20811683a169SBarry Smith ierr = MatSeqAIJRestoreArray(local_mat,&sarray);CHKERRQ(ierr); 2082686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 2083ecf5a873SStefano Zampini PetscInt i; 2084c0962df8SStefano Zampini 2085686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 2086686e3a49SStefano Zampini PetscInt j; 2087ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 2088686e3a49SStefano Zampini 20891683a169SBarry Smith ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2090487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 20911683a169SBarry Smith ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2092686e3a49SStefano Zampini } 2093b7ce53b6SStefano Zampini } 2094487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2095d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 2096487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2097b9ed4604SStefano Zampini if (isseqdense) { 2098487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 2099487b449aSStefano Zampini } 2100487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 2101487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 2102487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 2103487b449aSStefano Zampini *M = MT; 2104b7ce53b6SStefano Zampini } 2105b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2106b7ce53b6SStefano Zampini } 2107b7ce53b6SStefano Zampini 2108b7ce53b6SStefano Zampini /*@ 2109b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 2110b7ce53b6SStefano Zampini 2111d8d19677SJose E. Roman Input Parameters: 2112a2b725a8SWilliam Gropp + mat - the matrix (should be of type MATIS) 2113a2b725a8SWilliam Gropp - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 2114b7ce53b6SStefano Zampini 2115b7ce53b6SStefano Zampini Output Parameter: 2116b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 2117b7ce53b6SStefano Zampini 2118b7ce53b6SStefano Zampini Level: developer 2119b7ce53b6SStefano Zampini 212095452b02SPatrick Sanan Notes: 2121487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 2122b7ce53b6SStefano Zampini 2123487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2124b7ce53b6SStefano Zampini @*/ 2125b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2126b7ce53b6SStefano Zampini { 2127b7ce53b6SStefano Zampini PetscErrorCode ierr; 2128b7ce53b6SStefano Zampini 2129b7ce53b6SStefano Zampini PetscFunctionBegin; 2130b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2131b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2132b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2133487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2134b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2135b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 21362c71b3e2SJacob Faibussowitsch PetscCheckFalse(mat == *newmat,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2137b7ce53b6SStefano Zampini } 2138487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2139b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2140b7ce53b6SStefano Zampini } 2141b7ce53b6SStefano Zampini 21428b9382cfSStefano Zampini static PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2143ad6194a2SStefano Zampini { 2144ad6194a2SStefano Zampini PetscErrorCode ierr; 2145ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2146c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2147ad6194a2SStefano Zampini Mat B,localmat; 2148ad6194a2SStefano Zampini 2149ad6194a2SStefano Zampini PetscFunctionBegin; 2150c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2151c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2152ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2153ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 21548546b261SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 21558546b261SStefano Zampini ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 21568546b261SStefano Zampini ierr = MatSetBlockSize(B,rbs == cbs ? rbs : 1);CHKERRQ(ierr); 21578546b261SStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 21588546b261SStefano Zampini ierr = MatISSetLocalMatType(B,matis->lmattype);CHKERRQ(ierr); 21598546b261SStefano Zampini ierr = MatSetLocalToGlobalMapping(B,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2160ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2161*e432b41dSStefano Zampini ierr = MatSetLocalToGlobalMapping(localmat,matis->A->rmap->mapping,matis->A->cmap->mapping);CHKERRQ(ierr); 2162ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2163b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2164ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2165ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2166ad6194a2SStefano Zampini *newmat = B; 2167ad6194a2SStefano Zampini PetscFunctionReturn(0); 2168ad6194a2SStefano Zampini } 2169ad6194a2SStefano Zampini 2170a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 217169796d55SStefano Zampini { 217269796d55SStefano Zampini PetscErrorCode ierr; 217369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 217469796d55SStefano Zampini PetscBool local_sym; 217569796d55SStefano Zampini 217669796d55SStefano Zampini PetscFunctionBegin; 217769796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2178820f2d46SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 217969796d55SStefano Zampini PetscFunctionReturn(0); 218069796d55SStefano Zampini } 218169796d55SStefano Zampini 2182a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 218369796d55SStefano Zampini { 218469796d55SStefano Zampini PetscErrorCode ierr; 218569796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 218669796d55SStefano Zampini PetscBool local_sym; 218769796d55SStefano Zampini 218869796d55SStefano Zampini PetscFunctionBegin; 2189*e432b41dSStefano Zampini if (matis->rmapping != matis->cmapping) { 2190*e432b41dSStefano Zampini *flg = PETSC_FALSE; 2191*e432b41dSStefano Zampini PetscFunctionReturn(0); 2192*e432b41dSStefano Zampini } 219369796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2194820f2d46SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 219569796d55SStefano Zampini PetscFunctionReturn(0); 219669796d55SStefano Zampini } 219769796d55SStefano Zampini 219845471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 219945471136SStefano Zampini { 220045471136SStefano Zampini PetscErrorCode ierr; 220145471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 220245471136SStefano Zampini PetscBool local_sym; 220345471136SStefano Zampini 220445471136SStefano Zampini PetscFunctionBegin; 2205*e432b41dSStefano Zampini if (matis->rmapping != matis->cmapping) { 220645471136SStefano Zampini *flg = PETSC_FALSE; 220745471136SStefano Zampini PetscFunctionReturn(0); 220845471136SStefano Zampini } 220945471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 2210820f2d46SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 221145471136SStefano Zampini PetscFunctionReturn(0); 221245471136SStefano Zampini } 221345471136SStefano Zampini 2214a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2215b4319ba4SBarry Smith { 2216dfbe8321SBarry Smith PetscErrorCode ierr; 2217b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2218b4319ba4SBarry Smith 2219b4319ba4SBarry Smith PetscFunctionBegin; 2220b89f26deSStefano Zampini ierr = PetscFree(b->bdiag);CHKERRQ(ierr); 22218546b261SStefano Zampini ierr = PetscFree(b->lmattype);CHKERRQ(ierr); 22226bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2223e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2224e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 22256bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 22266bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 22273fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2228a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2229a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2230a8116848SStefano Zampini if (b->sf != b->csf) { 2231a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2232a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2233f03112d0SStefano Zampini } else b->csf = NULL; 223428f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 223528f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2236*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&b->rmapping);CHKERRQ(ierr); 2237*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&b->cmapping);CHKERRQ(ierr); 2238bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2239f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 22408546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",NULL);CHKERRQ(ierr); 2241bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2242b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2243b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 22442e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 224575d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2246f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2247*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalToGlobalMapping_C",NULL);CHKERRQ(ierr); 2248487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2249487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2250487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2251487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2252487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2253487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2254487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2255*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetPreallocationCOOLocal_C",NULL);CHKERRQ(ierr); 2256*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetPreallocationCOO_C",NULL);CHKERRQ(ierr); 2257*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetValuesCOO_C",NULL);CHKERRQ(ierr); 2258b4319ba4SBarry Smith PetscFunctionReturn(0); 2259b4319ba4SBarry Smith } 2260b4319ba4SBarry Smith 2261a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2262b4319ba4SBarry Smith { 2263dfbe8321SBarry Smith PetscErrorCode ierr; 2264b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2265b4319ba4SBarry Smith PetscScalar zero = 0.0; 2266b4319ba4SBarry Smith 2267b4319ba4SBarry Smith PetscFunctionBegin; 2268b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2269e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2270e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2271b4319ba4SBarry Smith 2272b4319ba4SBarry Smith /* multiply the local matrix */ 2273b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2274b4319ba4SBarry Smith 2275b4319ba4SBarry Smith /* scatter product back into global memory */ 22762dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2277e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2278e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2279b4319ba4SBarry Smith PetscFunctionReturn(0); 2280b4319ba4SBarry Smith } 2281b4319ba4SBarry Smith 2282a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 22832e74eeadSLisandro Dalcin { 2284650997f4SStefano Zampini Vec temp_vec; 22852e74eeadSLisandro Dalcin PetscErrorCode ierr; 22862e74eeadSLisandro Dalcin 22872e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2288650997f4SStefano Zampini if (v3 != v2) { 2289650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2290650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2291650997f4SStefano Zampini } else { 2292650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2293650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2294650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2295650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2296650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2297650997f4SStefano Zampini } 22982e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22992e74eeadSLisandro Dalcin } 23002e74eeadSLisandro Dalcin 2301a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 23022e74eeadSLisandro Dalcin { 23032e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 23042e74eeadSLisandro Dalcin PetscErrorCode ierr; 23052e74eeadSLisandro Dalcin 2306e176bc59SStefano Zampini PetscFunctionBegin; 23072e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2308e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2309e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23102e74eeadSLisandro Dalcin 23112e74eeadSLisandro Dalcin /* multiply the local matrix */ 2312e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 23132e74eeadSLisandro Dalcin 23142e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2315e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2316e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2317e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23182e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23192e74eeadSLisandro Dalcin } 23202e74eeadSLisandro Dalcin 2321a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23222e74eeadSLisandro Dalcin { 2323650997f4SStefano Zampini Vec temp_vec; 23242e74eeadSLisandro Dalcin PetscErrorCode ierr; 23252e74eeadSLisandro Dalcin 23262e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2327650997f4SStefano Zampini if (v3 != v2) { 2328650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2329650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2330650997f4SStefano Zampini } else { 2331650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2332650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2333650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2334650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2335650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2336650997f4SStefano Zampini } 23372e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23382e74eeadSLisandro Dalcin } 23392e74eeadSLisandro Dalcin 2340a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2341b4319ba4SBarry Smith { 2342b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2343dfbe8321SBarry Smith PetscErrorCode ierr; 2344b4319ba4SBarry Smith PetscViewer sviewer; 2345ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2346b4319ba4SBarry Smith 2347b4319ba4SBarry Smith PetscFunctionBegin; 2348ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2349ee2491ecSStefano Zampini if (isascii) { 2350ee2491ecSStefano Zampini PetscViewerFormat format; 2351ee2491ecSStefano Zampini 2352ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2353ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2354ee2491ecSStefano Zampini } 2355ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 23563f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2357b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 23583f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 23596e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2360b4319ba4SBarry Smith PetscFunctionReturn(0); 2361b4319ba4SBarry Smith } 2362b4319ba4SBarry Smith 2363b89f26deSStefano Zampini static PetscErrorCode MatInvertBlockDiagonal_IS(Mat mat,const PetscScalar **values) 2364b89f26deSStefano Zampini { 2365b89f26deSStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 2366b89f26deSStefano Zampini MPI_Datatype nodeType; 2367b89f26deSStefano Zampini const PetscScalar *lv; 2368b89f26deSStefano Zampini PetscInt bs; 2369b89f26deSStefano Zampini PetscErrorCode ierr; 2370b89f26deSStefano Zampini 2371b89f26deSStefano Zampini PetscFunctionBegin; 2372b89f26deSStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2373b89f26deSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 2374b89f26deSStefano Zampini ierr = MatInvertBlockDiagonal(is->A,&lv);CHKERRQ(ierr); 2375b89f26deSStefano Zampini if (!is->bdiag) { 2376b89f26deSStefano Zampini ierr = PetscMalloc1(bs*mat->rmap->n,&is->bdiag);CHKERRQ(ierr); 2377b89f26deSStefano Zampini } 2378ffc4695bSBarry Smith ierr = MPI_Type_contiguous(bs,MPIU_SCALAR,&nodeType);CHKERRMPI(ierr); 2379ffc4695bSBarry Smith ierr = MPI_Type_commit(&nodeType);CHKERRMPI(ierr); 238083df288dSJunchao Zhang ierr = PetscSFReduceBegin(is->sf,nodeType,lv,is->bdiag,MPI_REPLACE);CHKERRQ(ierr); 238183df288dSJunchao Zhang ierr = PetscSFReduceEnd(is->sf,nodeType,lv,is->bdiag,MPI_REPLACE);CHKERRQ(ierr); 2382ffc4695bSBarry Smith ierr = MPI_Type_free(&nodeType);CHKERRMPI(ierr); 2383b89f26deSStefano Zampini if (values) *values = is->bdiag; 2384b89f26deSStefano Zampini PetscFunctionReturn(0); 2385b89f26deSStefano Zampini } 2386b89f26deSStefano Zampini 23878546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat A) 2388b4319ba4SBarry Smith { 2389e176bc59SStefano Zampini Vec cglobal,rglobal; 23908546b261SStefano Zampini IS from; 23918546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2392b89f26deSStefano Zampini PetscScalar sum; 23938546b261SStefano Zampini const PetscInt *garray; 23948546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 2395*e432b41dSStefano Zampini VecType rtype; 23968546b261SStefano Zampini PetscErrorCode ierr; 2397b4319ba4SBarry Smith 2398b4319ba4SBarry Smith PetscFunctionBegin; 2399*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->rmapping,&nr);CHKERRQ(ierr); 2400*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->rmapping,&rbs);CHKERRQ(ierr); 2401*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->cmapping,&nc);CHKERRQ(ierr); 2402*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->cmapping,&cbs);CHKERRQ(ierr); 240370cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 240470cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 24053fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2406e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2407e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 24088546b261SStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2409b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_TRUE);CHKERRQ(ierr); 2410*e432b41dSStefano Zampini ierr = VecGetRootType_Private(is->y,&rtype);CHKERRQ(ierr); 24118546b261SStefano Zampini ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 2412*e432b41dSStefano Zampini ierr = PetscStrallocpy(rtype,&A->defaultvectype);CHKERRQ(ierr); 24138546b261SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 2414b470e4b4SRichard Tran Mills ierr = VecBindToCPU(rglobal,PETSC_TRUE);CHKERRQ(ierr); 2415*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(is->rmapping,&garray);CHKERRQ(ierr); 24168546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 24179448b7f1SJunchao Zhang ierr = VecScatterCreate(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 2418*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(is->rmapping,&garray);CHKERRQ(ierr); 24198546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 2420*e432b41dSStefano Zampini if (is->rmapping != is->cmapping) { 2421*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(is->cmapping,&garray);CHKERRQ(ierr); 24228546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 24239448b7f1SJunchao Zhang ierr = VecScatterCreate(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 2424*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(is->cmapping,&garray);CHKERRQ(ierr); 24258546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24268546b261SStefano Zampini } else { 24278546b261SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 24288546b261SStefano Zampini is->cctx = is->rctx; 24298546b261SStefano Zampini } 2430b89f26deSStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 2431b89f26deSStefano Zampini 24328546b261SStefano Zampini /* interface counter vector (local) */ 24338546b261SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 2434b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_TRUE);CHKERRQ(ierr); 24358546b261SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 24368546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24378546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24388546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24398546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2440b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_FALSE);CHKERRQ(ierr); 2441b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_FALSE);CHKERRQ(ierr); 2442b89f26deSStefano Zampini 2443b89f26deSStefano Zampini /* special functions for block-diagonal matrices */ 2444b89f26deSStefano Zampini ierr = VecSum(rglobal,&sum);CHKERRQ(ierr); 2445b89f26deSStefano Zampini A->ops->invertblockdiagonal = NULL; 2446*e432b41dSStefano Zampini if ((PetscInt)(PetscRealPart(sum)) == A->rmap->N && A->rmap->N == A->cmap->N && is->rmapping == is->cmapping) A->ops->invertblockdiagonal = MatInvertBlockDiagonal_IS; 24478546b261SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2448b0cc1f67SStefano Zampini 2449b0cc1f67SStefano Zampini /* setup SF for general purpose shared indices based communications */ 2450b0cc1f67SStefano Zampini ierr = MatISSetUpSF_IS(A);CHKERRQ(ierr); 24518546b261SStefano Zampini PetscFunctionReturn(0); 24528546b261SStefano Zampini } 24538546b261SStefano Zampini 2454*e432b41dSStefano Zampini static PetscErrorCode MatISFilterL2GMap(Mat A, ISLocalToGlobalMapping map, ISLocalToGlobalMapping *nmap, ISLocalToGlobalMapping *lmap) 2455*e432b41dSStefano Zampini { 2456*e432b41dSStefano Zampini IS is; 2457*e432b41dSStefano Zampini ISLocalToGlobalMappingType l2gtype; 2458*e432b41dSStefano Zampini const PetscInt *idxs; 2459*e432b41dSStefano Zampini PetscHSetI ht; 2460*e432b41dSStefano Zampini PetscInt *nidxs; 2461*e432b41dSStefano Zampini PetscInt i,n,bs,c; 2462*e432b41dSStefano Zampini PetscBool flg[] = {PETSC_FALSE,PETSC_FALSE}; 2463*e432b41dSStefano Zampini PetscErrorCode ierr; 2464*e432b41dSStefano Zampini 2465*e432b41dSStefano Zampini PetscFunctionBegin; 2466*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(map,&n);CHKERRQ(ierr); 2467*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(map,&bs);CHKERRQ(ierr); 2468*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(map,&idxs);CHKERRQ(ierr); 2469*e432b41dSStefano Zampini ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 2470*e432b41dSStefano Zampini ierr = PetscMalloc1(n/bs,&nidxs);CHKERRQ(ierr); 2471*e432b41dSStefano Zampini for (i=0,c=0;i<n/bs;i++) { 2472*e432b41dSStefano Zampini PetscBool missing; 2473*e432b41dSStefano Zampini if (idxs[i] < 0) { flg[0] = PETSC_TRUE; continue; } 2474*e432b41dSStefano Zampini ierr = PetscHSetIQueryAdd(ht,idxs[i],&missing);CHKERRQ(ierr); 2475*e432b41dSStefano Zampini if (!missing) flg[1] = PETSC_TRUE; 2476*e432b41dSStefano Zampini else nidxs[c++] = idxs[i]; 2477*e432b41dSStefano Zampini } 2478*e432b41dSStefano Zampini ierr = PetscHSetIDestroy(&ht);CHKERRQ(ierr); 2479*e432b41dSStefano Zampini ierr = MPIU_Allreduce(MPI_IN_PLACE,flg,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 2480*e432b41dSStefano Zampini if (!flg[0] && !flg[1]) { /* Entries are all non negative and unique */ 2481*e432b41dSStefano Zampini *nmap = NULL; 2482*e432b41dSStefano Zampini *lmap = NULL; 2483*e432b41dSStefano Zampini ierr = PetscFree(nidxs);CHKERRQ(ierr); 2484*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(map,&idxs);CHKERRQ(ierr); 2485*e432b41dSStefano Zampini PetscFunctionReturn(0); 2486*e432b41dSStefano Zampini } 2487*e432b41dSStefano Zampini 2488*e432b41dSStefano Zampini /* New l2g map without negative or repeated indices */ 2489*e432b41dSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,c,nidxs,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 2490*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,nmap);CHKERRQ(ierr); 2491*e432b41dSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2492*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetType(map,&l2gtype);CHKERRQ(ierr); 2493*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingSetType(*nmap,l2gtype);CHKERRQ(ierr); 2494*e432b41dSStefano Zampini 2495*e432b41dSStefano Zampini /* New local l2g map for repeated indices */ 2496*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(*nmap,IS_GTOLM_MASK,n/bs,idxs,NULL,nidxs);CHKERRQ(ierr); 2497*e432b41dSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,bs,n/bs,nidxs,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 2498*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,lmap);CHKERRQ(ierr); 2499*e432b41dSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2500*e432b41dSStefano Zampini 2501*e432b41dSStefano Zampini ierr = PetscFree(nidxs);CHKERRQ(ierr); 2502*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(map,&idxs);CHKERRQ(ierr); 2503*e432b41dSStefano Zampini PetscFunctionReturn(0); 2504*e432b41dSStefano Zampini } 2505*e432b41dSStefano Zampini 25068546b261SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 25078546b261SStefano Zampini { 25088546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2509*e432b41dSStefano Zampini ISLocalToGlobalMapping localrmapping = NULL, localcmapping = NULL; 2510*e432b41dSStefano Zampini PetscBool cong, freem[] = { PETSC_FALSE, PETSC_FALSE }; 2511*e432b41dSStefano Zampini PetscInt nr,rbs,nc,cbs; 2512*e432b41dSStefano Zampini PetscErrorCode ierr; 25138546b261SStefano Zampini 25148546b261SStefano Zampini PetscFunctionBegin; 2515fc989267SStefano Zampini if (rmapping) PetscCheckSameComm(A,1,rmapping,2); 2516fc989267SStefano Zampini if (cmapping) PetscCheckSameComm(A,1,cmapping,3); 2517*e432b41dSStefano Zampini 2518*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&is->rmapping);CHKERRQ(ierr); 2519*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&is->cmapping);CHKERRQ(ierr); 2520fc989267SStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2521fc989267SStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2522fc989267SStefano Zampini ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); 2523*e432b41dSStefano Zampini 2524fc989267SStefano Zampini /* If NULL, local space matches global space */ 2525fc989267SStefano Zampini if (!rmapping) { 2526fc989267SStefano Zampini IS is; 2527fc989267SStefano Zampini 2528fc989267SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->N,0,1,&is);CHKERRQ(ierr); 2529fc989267SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rmapping);CHKERRQ(ierr); 2530fc989267SStefano Zampini if (A->rmap->bs > 0) { ierr = ISLocalToGlobalMappingSetBlockSize(rmapping,A->rmap->bs);CHKERRQ(ierr); } 2531fc989267SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2532*e432b41dSStefano Zampini freem[0] = PETSC_TRUE; 2533*e432b41dSStefano Zampini if (!cmapping && cong && A->rmap->bs == A->cmap->bs) cmapping = rmapping; 2534*e432b41dSStefano Zampini } else if (!is->islocalref) { /* check if the l2g map has negative or repeated entries */ 2535*e432b41dSStefano Zampini ierr = MatISFilterL2GMap(A,rmapping,&is->rmapping,&localrmapping);CHKERRQ(ierr); 2536*e432b41dSStefano Zampini if (rmapping == cmapping) { 2537*e432b41dSStefano Zampini ierr = PetscObjectReference((PetscObject)is->rmapping);CHKERRQ(ierr); 2538*e432b41dSStefano Zampini is->cmapping = is->rmapping; 2539*e432b41dSStefano Zampini ierr = PetscObjectReference((PetscObject)localrmapping);CHKERRQ(ierr); 2540*e432b41dSStefano Zampini localcmapping = localrmapping; 2541fc989267SStefano Zampini } 2542fc989267SStefano Zampini } 2543fc989267SStefano Zampini if (!cmapping) { 2544fc989267SStefano Zampini IS is; 2545fc989267SStefano Zampini 2546fc989267SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->N,0,1,&is);CHKERRQ(ierr); 2547fc989267SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cmapping);CHKERRQ(ierr); 2548fc989267SStefano Zampini if (A->cmap->bs > 0) { ierr = ISLocalToGlobalMappingSetBlockSize(cmapping,A->cmap->bs);CHKERRQ(ierr); } 2549fc989267SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2550*e432b41dSStefano Zampini freem[1] = PETSC_TRUE; 2551*e432b41dSStefano Zampini } else if (cmapping != rmapping && !is->islocalref) { /* check if the l2g map has negative or repeated entries */ 2552*e432b41dSStefano Zampini ierr = MatISFilterL2GMap(A,cmapping,&is->cmapping,&localcmapping);CHKERRQ(ierr); 2553*e432b41dSStefano Zampini } 2554*e432b41dSStefano Zampini if (!is->rmapping) { 2555*e432b41dSStefano Zampini ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 2556*e432b41dSStefano Zampini is->rmapping = rmapping; 2557*e432b41dSStefano Zampini } 2558*e432b41dSStefano Zampini if (!is->cmapping) { 2559*e432b41dSStefano Zampini ierr = PetscObjectReference((PetscObject)cmapping);CHKERRQ(ierr); 2560*e432b41dSStefano Zampini is->cmapping = cmapping; 2561fc989267SStefano Zampini } 2562fc989267SStefano Zampini 2563fc989267SStefano Zampini /* Clean up */ 25641c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2565872cf891SStefano Zampini if (is->csf != is->sf) { 2566872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2567872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2568f03112d0SStefano Zampini } else is->csf = NULL; 256928f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 257028f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 2571b89f26deSStefano Zampini ierr = PetscFree(is->bdiag);CHKERRQ(ierr); 25723bbff08aSStefano Zampini 2573fc989267SStefano Zampini /* check if the two mappings are actually the same for square matrices since MATIS has some optimization for this case 2574fc989267SStefano Zampini (DOLFIN passes 2 different objects) */ 2575*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->rmapping,&nr);CHKERRQ(ierr); 2576*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->rmapping,&rbs);CHKERRQ(ierr); 2577*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->cmapping,&nc);CHKERRQ(ierr); 2578*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->cmapping,&cbs);CHKERRQ(ierr); 2579*e432b41dSStefano Zampini if (is->rmapping != is->cmapping && cong) { 2580*e432b41dSStefano Zampini PetscBool same = PETSC_FALSE; 25816625354bSStefano Zampini if (nr == nc && cbs == rbs) { 25826625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 25836625354bSStefano Zampini 2584*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(is->rmapping,&idxs1);CHKERRQ(ierr); 2585*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(is->cmapping,&idxs2);CHKERRQ(ierr); 2586580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,nr/rbs,&same);CHKERRQ(ierr); 2587*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(is->rmapping,&idxs1);CHKERRQ(ierr); 2588*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(is->cmapping,&idxs2);CHKERRQ(ierr); 25896625354bSStefano Zampini } 2590fc989267SStefano Zampini ierr = MPIU_Allreduce(MPI_IN_PLACE,&same,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 2591*e432b41dSStefano Zampini if (same) { 2592*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&is->cmapping);CHKERRQ(ierr); 2593*e432b41dSStefano Zampini ierr = PetscObjectReference((PetscObject)is->rmapping);CHKERRQ(ierr); 2594*e432b41dSStefano Zampini is->cmapping = is->rmapping; 2595*e432b41dSStefano Zampini } 25966625354bSStefano Zampini } 259753b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 259853b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 2599*e432b41dSStefano Zampini /* Pass the user defined maps to the layout */ 26006625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 2601*e432b41dSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 2602*e432b41dSStefano Zampini if (freem[0]) { ierr = ISLocalToGlobalMappingDestroy(&rmapping);CHKERRQ(ierr); } 2603*e432b41dSStefano Zampini if (freem[1]) { ierr = ISLocalToGlobalMappingDestroy(&cmapping);CHKERRQ(ierr); } 26046625354bSStefano Zampini 26056625354bSStefano Zampini /* Create the local matrix A */ 2606f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 26078546b261SStefano Zampini ierr = MatSetType(is->A,is->lmattype);CHKERRQ(ierr); 2608e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2609e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 26108546b261SStefano Zampini ierr = MatSetOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 26118546b261SStefano Zampini ierr = MatAppendOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2612c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2613c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2614*e432b41dSStefano Zampini ierr = MatSetLocalToGlobalMapping(is->A,localrmapping,localcmapping);CHKERRQ(ierr); 2615*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&localrmapping);CHKERRQ(ierr); 2616*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&localcmapping);CHKERRQ(ierr); 2617b4319ba4SBarry Smith 2618fc989267SStefano Zampini /* setup scatters and local vectors for MatMult */ 2619*e432b41dSStefano Zampini if (!is->islocalref) { ierr = MatISSetUpScatters_Private(A);CHKERRQ(ierr); } 2620fc989267SStefano Zampini A->preallocated = PETSC_TRUE; 2621fc989267SStefano Zampini PetscFunctionReturn(0); 2622fc989267SStefano Zampini } 2623fc989267SStefano Zampini 2624fc989267SStefano Zampini static PetscErrorCode MatSetUp_IS(Mat A) 2625fc989267SStefano Zampini { 2626fc989267SStefano Zampini ISLocalToGlobalMapping rmap, cmap; 2627fc989267SStefano Zampini PetscErrorCode ierr; 2628fc989267SStefano Zampini 2629fc989267SStefano Zampini PetscFunctionBegin; 2630fc989267SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rmap,&cmap);CHKERRQ(ierr); 2631fc989267SStefano Zampini if (!rmap && !cmap) { 2632fc989267SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,NULL,NULL);CHKERRQ(ierr); 2633fc989267SStefano Zampini } 2634b4319ba4SBarry Smith PetscFunctionReturn(0); 2635b4319ba4SBarry Smith } 2636b4319ba4SBarry Smith 2637a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 26382e74eeadSLisandro Dalcin { 26392e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 26402e74eeadSLisandro Dalcin PetscErrorCode ierr; 2641f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 26422e74eeadSLisandro Dalcin 26432e74eeadSLisandro Dalcin PetscFunctionBegin; 2644*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApply(is->rmapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 2645*e432b41dSStefano Zampini if (m != n || rows != cols || is->cmapping != is->rmapping) { 2646*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApply(is->cmapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 26472e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 2648*e432b41dSStefano Zampini } else { 2649*e432b41dSStefano Zampini ierr = MatSetValues(is->A,m,rows_l,m,rows_l,values,addv);CHKERRQ(ierr); 2650*e432b41dSStefano Zampini } 26512e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26522e74eeadSLisandro Dalcin } 26532e74eeadSLisandro Dalcin 2654a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 265597563a80SStefano Zampini { 265697563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 265797563a80SStefano Zampini PetscErrorCode ierr; 2658f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 265997563a80SStefano Zampini 266097563a80SStefano Zampini PetscFunctionBegin; 2661*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(is->rmapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 2662*e432b41dSStefano Zampini if (m != n || rows != cols || is->cmapping != is->rmapping) { 2663*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApply(is->cmapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 2664d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 2665*e432b41dSStefano Zampini } else { 2666*e432b41dSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,rows_l,values,addv);CHKERRQ(ierr); 2667*e432b41dSStefano Zampini } 266897563a80SStefano Zampini PetscFunctionReturn(0); 266997563a80SStefano Zampini } 267097563a80SStefano Zampini 2671a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2672b4319ba4SBarry Smith { 2673dfbe8321SBarry Smith PetscErrorCode ierr; 2674b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2675b4319ba4SBarry Smith 2676b4319ba4SBarry Smith PetscFunctionBegin; 2677*e432b41dSStefano Zampini if (is->A->rmap->mapping || is->A->cmap->mapping) { 2678872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2679872cf891SStefano Zampini } else { 2680b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2681872cf891SStefano Zampini } 2682b4319ba4SBarry Smith PetscFunctionReturn(0); 2683b4319ba4SBarry Smith } 2684b4319ba4SBarry Smith 2685a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2686f0006bf2SLisandro Dalcin { 2687f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2688f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2689f0006bf2SLisandro Dalcin 2690f0006bf2SLisandro Dalcin PetscFunctionBegin; 2691*e432b41dSStefano Zampini if (is->A->rmap->mapping || is->A->cmap->mapping) { 2692b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2693b4f971dfSStefano Zampini } else { 2694f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2695b4f971dfSStefano Zampini } 2696f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2697f0006bf2SLisandro Dalcin } 2698f0006bf2SLisandro Dalcin 2699f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2700f0ae7da4SStefano Zampini { 2701f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2702f0ae7da4SStefano Zampini PetscErrorCode ierr; 2703f0ae7da4SStefano Zampini 2704f0ae7da4SStefano Zampini PetscFunctionBegin; 2705f0ae7da4SStefano Zampini if (!n) { 2706f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2707f0ae7da4SStefano Zampini } else { 2708f0ae7da4SStefano Zampini PetscInt i; 2709f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2710f0ae7da4SStefano Zampini 2711f0ae7da4SStefano Zampini if (columns) { 2712f4259b30SLisandro Dalcin ierr = MatZeroRowsColumns(is->A,n,rows,diag,NULL,NULL);CHKERRQ(ierr); 2713f0ae7da4SStefano Zampini } else { 2714f4259b30SLisandro Dalcin ierr = MatZeroRows(is->A,n,rows,diag,NULL,NULL);CHKERRQ(ierr); 2715f0ae7da4SStefano Zampini } 2716f0ae7da4SStefano Zampini if (diag != 0.) { 2717f0ae7da4SStefano Zampini const PetscScalar *array; 2718f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2719f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2720f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2721f0ae7da4SStefano Zampini } 2722f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2723f0ae7da4SStefano Zampini } 2724f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2725f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2726f0ae7da4SStefano Zampini } 2727f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2728f0ae7da4SStefano Zampini } 2729f0ae7da4SStefano Zampini 2730f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 27312e74eeadSLisandro Dalcin { 27326e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 27336e520ac8SStefano Zampini PetscInt nr,nl,len,i; 27346e520ac8SStefano Zampini PetscInt *lrows; 27352e74eeadSLisandro Dalcin PetscErrorCode ierr; 27362e74eeadSLisandro Dalcin 27372e74eeadSLisandro Dalcin PetscFunctionBegin; 2738cf9c20a2SJed Brown if (PetscUnlikelyDebug(columns || diag != 0. || (x && b))) { 2739f0ae7da4SStefano Zampini PetscBool cong; 274026b0207aSStefano Zampini 2741f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 274226b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 27432c71b3e2SJacob Faibussowitsch PetscCheckFalse(!cong && columns,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"); 27442c71b3e2SJacob Faibussowitsch PetscCheckFalse(!cong && diag != 0.,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"); 27452c71b3e2SJacob Faibussowitsch PetscCheckFalse(!cong && x && b,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent, and the l2g maps be the same"); 2746f0ae7da4SStefano Zampini } 27476e520ac8SStefano Zampini /* get locally owned rows */ 2748a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 27496e520ac8SStefano Zampini /* fix right hand side if needed */ 27506e520ac8SStefano Zampini if (x && b) { 27516e520ac8SStefano Zampini const PetscScalar *xx; 27526e520ac8SStefano Zampini PetscScalar *bb; 27536e520ac8SStefano Zampini 27546e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 27556e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 27566e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 27576e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 27586e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 27592e74eeadSLisandro Dalcin } 27606e520ac8SStefano Zampini /* get rows associated to the local matrices */ 27616e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 2762580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,nl);CHKERRQ(ierr); 2763580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,A->rmap->n);CHKERRQ(ierr); 27646e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 27656e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 2766ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 2767ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata,MPI_REPLACE);CHKERRQ(ierr); 27686e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 27696e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2770f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 27716e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 27722e74eeadSLisandro Dalcin PetscFunctionReturn(0); 27732e74eeadSLisandro Dalcin } 27742e74eeadSLisandro Dalcin 2775f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2776b4319ba4SBarry Smith { 2777dfbe8321SBarry Smith PetscErrorCode ierr; 2778b4319ba4SBarry Smith 2779b4319ba4SBarry Smith PetscFunctionBegin; 2780f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2781f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2782f0ae7da4SStefano Zampini } 27832205254eSKarl Rupp 2784f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2785f0ae7da4SStefano Zampini { 2786f0ae7da4SStefano Zampini PetscErrorCode ierr; 2787f0ae7da4SStefano Zampini 2788f0ae7da4SStefano Zampini PetscFunctionBegin; 2789f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2790b4319ba4SBarry Smith PetscFunctionReturn(0); 2791b4319ba4SBarry Smith } 2792b4319ba4SBarry Smith 2793a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2794b4319ba4SBarry Smith { 2795b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2796dfbe8321SBarry Smith PetscErrorCode ierr; 2797b4319ba4SBarry Smith 2798b4319ba4SBarry Smith PetscFunctionBegin; 2799b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2800b4319ba4SBarry Smith PetscFunctionReturn(0); 2801b4319ba4SBarry Smith } 2802b4319ba4SBarry Smith 2803a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2804b4319ba4SBarry Smith { 2805b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2806dfbe8321SBarry Smith PetscErrorCode ierr; 2807b4319ba4SBarry Smith 2808b4319ba4SBarry Smith PetscFunctionBegin; 2809b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2810872cf891SStefano Zampini /* fix for local empty rows/cols */ 2811872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2812872cf891SStefano Zampini Mat newlA; 2813f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2814f03112d0SStefano Zampini IS nzr,nzc; 2815f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2816f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2817872cf891SStefano Zampini 2818f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2819f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2820f03112d0SStefano Zampini if (!nzr) { 2821f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2822872cf891SStefano Zampini } 2823f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2824f03112d0SStefano Zampini if (!nzc) { 2825f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2826872cf891SStefano Zampini } 2827f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2828f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2829*e432b41dSStefano Zampini if (nnzr != nr || nnzc != nc) { /* need new global l2g map */ 2830f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 283155b25c41SPierre Jolivet ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 2832f03112d0SStefano Zampini 2833872cf891SStefano Zampini /* extract valid submatrix */ 2834f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2835f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2836f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 283755b25c41SPierre Jolivet ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 2838f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2839f03112d0SStefano Zampini newlA = is->A; 2840f03112d0SStefano Zampini } 2841*e432b41dSStefano Zampini 2842f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2843f03112d0SStefano Zampini if (newl2g) { 2844*e432b41dSStefano Zampini IS zr,zc; 2845*e432b41dSStefano Zampini const PetscInt *ridxs,*cidxs,*zridxs,*zcidxs; 2846*e432b41dSStefano Zampini PetscInt *nidxs,i; 2847f03112d0SStefano Zampini 2848*e432b41dSStefano Zampini ierr = ISComplement(nzr,0,nr,&zr);CHKERRQ(ierr); 2849*e432b41dSStefano Zampini ierr = ISComplement(nzc,0,nc,&zc);CHKERRQ(ierr); 2850*e432b41dSStefano Zampini ierr = PetscMalloc1(PetscMax(nr,nc),&nidxs);CHKERRQ(ierr); 2851*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->rmapping,&ridxs);CHKERRQ(ierr); 2852*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->cmapping,&cidxs);CHKERRQ(ierr); 2853*e432b41dSStefano Zampini ierr = ISGetIndices(zr,&zridxs);CHKERRQ(ierr); 2854*e432b41dSStefano Zampini ierr = ISGetIndices(zc,&zcidxs);CHKERRQ(ierr); 2855*e432b41dSStefano Zampini ierr = ISGetLocalSize(zr,&nnzr);CHKERRQ(ierr); 2856*e432b41dSStefano Zampini ierr = ISGetLocalSize(zc,&nnzc);CHKERRQ(ierr); 2857*e432b41dSStefano Zampini 2858*e432b41dSStefano Zampini ierr = PetscArraycpy(nidxs,ridxs,nr);CHKERRQ(ierr); 2859*e432b41dSStefano Zampini for (i = 0; i < nnzr; i++) nidxs[zridxs[i]] = -1; 2860*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nr,nidxs,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2861*e432b41dSStefano Zampini ierr = PetscArraycpy(nidxs,cidxs,nc);CHKERRQ(ierr); 2862*e432b41dSStefano Zampini for (i = 0; i < nnzc; i++) nidxs[zcidxs[i]] = -1; 2863*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nc,nidxs,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2864*e432b41dSStefano Zampini 2865*e432b41dSStefano Zampini ierr = ISRestoreIndices(zr,&zridxs);CHKERRQ(ierr); 2866*e432b41dSStefano Zampini ierr = ISRestoreIndices(zc,&zcidxs);CHKERRQ(ierr); 2867*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->rmapping,&ridxs);CHKERRQ(ierr); 2868*e432b41dSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->cmapping,&cidxs);CHKERRQ(ierr); 2869*e432b41dSStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2870*e432b41dSStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2871*e432b41dSStefano Zampini ierr = ISDestroy(&zr);CHKERRQ(ierr); 2872*e432b41dSStefano Zampini ierr = ISDestroy(&zc);CHKERRQ(ierr); 2873*e432b41dSStefano Zampini ierr = PetscFree(nidxs);CHKERRQ(ierr); 2874f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2875f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2876f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2877f03112d0SStefano Zampini } 2878872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2879872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2880f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2881f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2882872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2883f03112d0SStefano Zampini } 2884b4319ba4SBarry Smith PetscFunctionReturn(0); 2885b4319ba4SBarry Smith } 2886b4319ba4SBarry Smith 2887a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2888b4319ba4SBarry Smith { 2889b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2890b4319ba4SBarry Smith 2891b4319ba4SBarry Smith PetscFunctionBegin; 2892b4319ba4SBarry Smith *local = is->A; 2893b4319ba4SBarry Smith PetscFunctionReturn(0); 2894b4319ba4SBarry Smith } 2895b4319ba4SBarry Smith 28963b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 28973b3b1effSJed Brown { 28983b3b1effSJed Brown PetscFunctionBegin; 28993b3b1effSJed Brown *local = NULL; 29003b3b1effSJed Brown PetscFunctionReturn(0); 29013b3b1effSJed Brown } 29023b3b1effSJed Brown 2903b4319ba4SBarry Smith /*@ 2904b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2905b4319ba4SBarry Smith 2906b4319ba4SBarry Smith Input Parameter: 2907b4319ba4SBarry Smith . mat - the matrix 2908b4319ba4SBarry Smith 2909b4319ba4SBarry Smith Output Parameter: 2910eb82efa4SStefano Zampini . local - the local matrix 2911b4319ba4SBarry Smith 2912b4319ba4SBarry Smith Level: advanced 2913b4319ba4SBarry Smith 2914b4319ba4SBarry Smith Notes: 2915b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2916b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2917b4319ba4SBarry Smith of the MatSetValues() operation. 2918b4319ba4SBarry Smith 29193b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 292096a6f129SJed Brown 2921b4319ba4SBarry Smith .seealso: MATIS 2922b4319ba4SBarry Smith @*/ 29237087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2924b4319ba4SBarry Smith { 29254ac538c5SBarry Smith PetscErrorCode ierr; 2926b4319ba4SBarry Smith 2927b4319ba4SBarry Smith PetscFunctionBegin; 29280700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2929b4319ba4SBarry Smith PetscValidPointer(local,2); 29304ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2931b4319ba4SBarry Smith PetscFunctionReturn(0); 2932b4319ba4SBarry Smith } 2933b4319ba4SBarry Smith 29343b3b1effSJed Brown /*@ 29353b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 29363b3b1effSJed Brown 29373b3b1effSJed Brown Input Parameter: 29383b3b1effSJed Brown . mat - the matrix 29393b3b1effSJed Brown 29403b3b1effSJed Brown Output Parameter: 29413b3b1effSJed Brown . local - the local matrix 29423b3b1effSJed Brown 29433b3b1effSJed Brown Level: advanced 29443b3b1effSJed Brown 29453b3b1effSJed Brown .seealso: MATIS 29463b3b1effSJed Brown @*/ 29473b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 29483b3b1effSJed Brown { 29493b3b1effSJed Brown PetscErrorCode ierr; 29503b3b1effSJed Brown 29513b3b1effSJed Brown PetscFunctionBegin; 29523b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29533b3b1effSJed Brown PetscValidPointer(local,2); 29543b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 29553b3b1effSJed Brown PetscFunctionReturn(0); 29563b3b1effSJed Brown } 29573b3b1effSJed Brown 29588546b261SStefano Zampini static PetscErrorCode MatISSetLocalMatType_IS(Mat mat,MatType mtype) 29598546b261SStefano Zampini { 29608546b261SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 29618546b261SStefano Zampini PetscErrorCode ierr; 29628546b261SStefano Zampini 29638546b261SStefano Zampini PetscFunctionBegin; 29648546b261SStefano Zampini if (is->A) { 29658546b261SStefano Zampini ierr = MatSetType(is->A,mtype);CHKERRQ(ierr); 29668546b261SStefano Zampini } 29678546b261SStefano Zampini ierr = PetscFree(is->lmattype);CHKERRQ(ierr); 29688546b261SStefano Zampini ierr = PetscStrallocpy(mtype,&is->lmattype);CHKERRQ(ierr); 29698546b261SStefano Zampini PetscFunctionReturn(0); 29708546b261SStefano Zampini } 29718546b261SStefano Zampini 29728546b261SStefano Zampini /*@ 29738546b261SStefano Zampini MatISSetLocalMatType - Specifies the type of local matrix 29748546b261SStefano Zampini 2975d8d19677SJose E. Roman Input Parameters: 2976a2b725a8SWilliam Gropp + mat - the matrix 2977a2b725a8SWilliam Gropp - mtype - the local matrix type 29788546b261SStefano Zampini 29798546b261SStefano Zampini Output Parameter: 29808546b261SStefano Zampini 29818546b261SStefano Zampini Level: advanced 29828546b261SStefano Zampini 29838546b261SStefano Zampini .seealso: MATIS, MatSetType(), MatType 29848546b261SStefano Zampini @*/ 29858546b261SStefano Zampini PetscErrorCode MatISSetLocalMatType(Mat mat,MatType mtype) 29868546b261SStefano Zampini { 29878546b261SStefano Zampini PetscErrorCode ierr; 29888546b261SStefano Zampini 29898546b261SStefano Zampini PetscFunctionBegin; 29908546b261SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29918546b261SStefano Zampini ierr = PetscUseMethod(mat,"MatISSetLocalMatType_C",(Mat,MatType),(mat,mtype));CHKERRQ(ierr); 29928546b261SStefano Zampini PetscFunctionReturn(0); 29938546b261SStefano Zampini } 29948546b261SStefano Zampini 2995a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 29963b03a366Sstefano_zampini { 29973b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 29983b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 29993b03a366Sstefano_zampini PetscErrorCode ierr; 30008546b261SStefano Zampini MatType mtype,otype; 30018546b261SStefano Zampini PetscBool sametype = PETSC_TRUE; 30023b03a366Sstefano_zampini 30033b03a366Sstefano_zampini PetscFunctionBegin; 3004*e432b41dSStefano Zampini if (is->A && !is->islocalref) { 30053b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 30063b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 30072c71b3e2SJacob Faibussowitsch PetscCheckFalse(orows != nrows || ocols != ncols,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local MATIS matrix should be of size %" PetscInt_FMT "x%" PetscInt_FMT " (you passed a %" PetscInt_FMT "x%" PetscInt_FMT " matrix)",orows,ocols,nrows,ncols); 30088546b261SStefano Zampini ierr = MatGetType(local,&mtype);CHKERRQ(ierr); 30098546b261SStefano Zampini ierr = MatGetType(is->A,&otype);CHKERRQ(ierr); 30108546b261SStefano Zampini ierr = PetscStrcmp(mtype,otype,&sametype);CHKERRQ(ierr); 30114e4c7dbeSStefano Zampini } 30123b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 30133b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 30143b03a366Sstefano_zampini is->A = local; 30158546b261SStefano Zampini ierr = MatGetType(is->A,&mtype);CHKERRQ(ierr); 30168546b261SStefano Zampini ierr = MatISSetLocalMatType(mat,mtype);CHKERRQ(ierr); 30178546b261SStefano Zampini if (!sametype && !is->islocalref) { 30188546b261SStefano Zampini ierr = MatISSetUpScatters_Private(mat);CHKERRQ(ierr); 30198546b261SStefano Zampini } 30203b03a366Sstefano_zampini PetscFunctionReturn(0); 30213b03a366Sstefano_zampini } 30223b03a366Sstefano_zampini 30233b03a366Sstefano_zampini /*@ 3024eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 30253b03a366Sstefano_zampini 30268546b261SStefano Zampini Collective on Mat 30278546b261SStefano Zampini 3028d8d19677SJose E. Roman Input Parameters: 3029a2b725a8SWilliam Gropp + mat - the matrix 3030a2b725a8SWilliam Gropp - local - the local matrix 30313b03a366Sstefano_zampini 30323b03a366Sstefano_zampini Output Parameter: 30333b03a366Sstefano_zampini 30343b03a366Sstefano_zampini Level: advanced 30353b03a366Sstefano_zampini 30363b03a366Sstefano_zampini Notes: 30373b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 30383b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 30393b03a366Sstefano_zampini 30403b03a366Sstefano_zampini .seealso: MATIS 30413b03a366Sstefano_zampini @*/ 30423b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 30433b03a366Sstefano_zampini { 30443b03a366Sstefano_zampini PetscErrorCode ierr; 30453b03a366Sstefano_zampini 30463b03a366Sstefano_zampini PetscFunctionBegin; 30473b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3048b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 30493b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 30503b03a366Sstefano_zampini PetscFunctionReturn(0); 30513b03a366Sstefano_zampini } 30523b03a366Sstefano_zampini 3053a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 30546726f965SBarry Smith { 30556726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30566726f965SBarry Smith PetscErrorCode ierr; 30576726f965SBarry Smith 30586726f965SBarry Smith PetscFunctionBegin; 30596726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 30606726f965SBarry Smith PetscFunctionReturn(0); 30616726f965SBarry Smith } 30626726f965SBarry Smith 3063a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 30642e74eeadSLisandro Dalcin { 30652e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30662e74eeadSLisandro Dalcin PetscErrorCode ierr; 30672e74eeadSLisandro Dalcin 30682e74eeadSLisandro Dalcin PetscFunctionBegin; 30692e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 30702e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30712e74eeadSLisandro Dalcin } 30722e74eeadSLisandro Dalcin 3073a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 30742e74eeadSLisandro Dalcin { 30752e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30762e74eeadSLisandro Dalcin PetscErrorCode ierr; 30772e74eeadSLisandro Dalcin 30782e74eeadSLisandro Dalcin PetscFunctionBegin; 30792e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 3080e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 30812e74eeadSLisandro Dalcin 30822e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 30832e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 3084e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3085e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 30862e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30872e74eeadSLisandro Dalcin } 30882e74eeadSLisandro Dalcin 3089a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 30906726f965SBarry Smith { 30916726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30926726f965SBarry Smith PetscErrorCode ierr; 30936726f965SBarry Smith 30946726f965SBarry Smith PetscFunctionBegin; 30954e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 30966726f965SBarry Smith PetscFunctionReturn(0); 30976726f965SBarry Smith } 30986726f965SBarry Smith 3099f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 3100f26d0771SStefano Zampini { 3101f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 3102f26d0771SStefano Zampini Mat_IS *x; 3103f26d0771SStefano Zampini PetscErrorCode ierr; 3104f26d0771SStefano Zampini 3105f26d0771SStefano Zampini PetscFunctionBegin; 310676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 310776bd3646SJed Brown PetscBool ismatis; 3108f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 31092c71b3e2SJacob Faibussowitsch PetscCheckFalse(!ismatis,PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 311076bd3646SJed Brown } 3111f26d0771SStefano Zampini x = (Mat_IS*)X->data; 3112f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 3113f26d0771SStefano Zampini PetscFunctionReturn(0); 3114f26d0771SStefano Zampini } 3115f26d0771SStefano Zampini 3116f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 3117f26d0771SStefano Zampini { 3118f26d0771SStefano Zampini Mat lA; 3119*e432b41dSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 3120f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 3121f26d0771SStefano Zampini IS is; 3122f26d0771SStefano Zampini const PetscInt *rg,*rl; 3123f26d0771SStefano Zampini PetscInt nrg; 3124f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 3125f26d0771SStefano Zampini PetscErrorCode ierr; 3126f26d0771SStefano Zampini 3127f26d0771SStefano Zampini PetscFunctionBegin; 3128f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3129f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3130f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3131f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 313276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 31332c71b3e2SJacob Faibussowitsch for (i=0; i<nrl; i++) PetscCheckFalse(rl[i]>=nrg,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row index %" PetscInt_FMT " -> %" PetscInt_FMT " greater then maximum possible %" PetscInt_FMT,i,rl[i],nrg); 313476bd3646SJed Brown } 3135f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3136f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3137f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3138f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3139f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3140f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3141f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3142f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3143f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3144f26d0771SStefano Zampini /* compute new l2g map for columns */ 3145*e432b41dSStefano Zampini if (col != row || matis->rmapping != matis->cmapping || matis->A->rmap->mapping != matis->A->cmap->mapping) { 3146f26d0771SStefano Zampini const PetscInt *cg,*cl; 3147f26d0771SStefano Zampini PetscInt ncg; 3148f26d0771SStefano Zampini PetscInt ncl; 3149f26d0771SStefano Zampini 3150f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3151f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3152f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3153f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 315476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 31552c71b3e2SJacob Faibussowitsch for (i=0; i<ncl; i++) PetscCheckFalse(cl[i]>=ncg,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local column index %" PetscInt_FMT " -> %" PetscInt_FMT " greater then maximum possible %" PetscInt_FMT,i,cl[i],ncg); 315676bd3646SJed Brown } 3157f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3158f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3159f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3160f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3161f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3162f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3163f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3164f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3165f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3166f26d0771SStefano Zampini } else { 3167f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3168f26d0771SStefano Zampini cl2g = rl2g; 3169f26d0771SStefano Zampini } 3170f26d0771SStefano Zampini /* create the MATIS submatrix */ 3171f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3172f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3173f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3174f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3175b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3176f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3177f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3178f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3179f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3180f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3181f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3182f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3183f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3184f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3185*e432b41dSStefano Zampini 3186f26d0771SStefano Zampini /* remove unsupported ops */ 3187f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3188f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3189f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3190f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3191f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3192f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3193f26d0771SStefano Zampini PetscFunctionReturn(0); 3194f26d0771SStefano Zampini } 3195f26d0771SStefano Zampini 3196872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3197872cf891SStefano Zampini { 3198872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 31998546b261SStefano Zampini char type[256]; 32008546b261SStefano Zampini PetscBool flg; 3201872cf891SStefano Zampini PetscErrorCode ierr; 3202872cf891SStefano Zampini 3203872cf891SStefano Zampini PetscFunctionBegin; 3204872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3205f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 320675d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 32078546b261SStefano Zampini ierr = PetscOptionsFList("-matis_localmat_type","Matrix type","MatISSetLocalMatType",MatList,a->lmattype,type,256,&flg);CHKERRQ(ierr); 32088546b261SStefano Zampini if (flg) { 32098546b261SStefano Zampini ierr = MatISSetLocalMatType(A,type);CHKERRQ(ierr); 32108546b261SStefano Zampini } 32118546b261SStefano Zampini if (a->A) { 32128546b261SStefano Zampini ierr = MatSetFromOptions(a->A);CHKERRQ(ierr); 32138546b261SStefano Zampini } 32140af67c1bSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 3215872cf891SStefano Zampini PetscFunctionReturn(0); 3216872cf891SStefano Zampini } 3217872cf891SStefano Zampini 3218284134d9SBarry Smith /*@ 32193c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3220284134d9SBarry Smith process but not across processes. 3221284134d9SBarry Smith 3222284134d9SBarry Smith Input Parameters: 3223284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3224e176bc59SStefano Zampini . bs - block size of the matrix 3225df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3226e176bc59SStefano Zampini . rmap - local to global map for rows 3227e176bc59SStefano Zampini - cmap - local to global map for cols 3228284134d9SBarry Smith 3229284134d9SBarry Smith Output Parameter: 3230284134d9SBarry Smith . A - the resulting matrix 3231284134d9SBarry Smith 32328e6c10adSSatish Balay Level: advanced 32338e6c10adSSatish Balay 323495452b02SPatrick Sanan Notes: 323595452b02SPatrick Sanan See MATIS for more details. 3236fc989267SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the distributed vectors 32376fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 3238fc989267SStefano Zampini If rmap (cmap) is NULL, then the local row (column) spaces matches the global space. 3239284134d9SBarry Smith 3240284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3241284134d9SBarry Smith @*/ 3242e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3243284134d9SBarry Smith { 3244284134d9SBarry Smith PetscErrorCode ierr; 3245284134d9SBarry Smith 3246284134d9SBarry Smith PetscFunctionBegin; 3247284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3248284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 32496fdf41d1SStefano Zampini if (bs > 0) { 3250284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 32516fdf41d1SStefano Zampini } 3252284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3253e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3254284134d9SBarry Smith PetscFunctionReturn(0); 3255284134d9SBarry Smith } 3256284134d9SBarry Smith 32578b9382cfSStefano Zampini static PetscErrorCode MatHasOperation_IS(Mat A, MatOperation op, PetscBool *has) 32588b9382cfSStefano Zampini { 32598b9382cfSStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 32608b9382cfSStefano Zampini PetscErrorCode ierr; 32618b9382cfSStefano Zampini 32628b9382cfSStefano Zampini PetscFunctionBegin; 32638b9382cfSStefano Zampini *has = PETSC_FALSE; 32648b9382cfSStefano Zampini if (!((void**)A->ops)[op]) PetscFunctionReturn(0); 32658b9382cfSStefano Zampini ierr = MatHasOperation(a->A,op,has);CHKERRQ(ierr); 32668b9382cfSStefano Zampini PetscFunctionReturn(0); 32678b9382cfSStefano Zampini } 32688b9382cfSStefano Zampini 3269*e432b41dSStefano Zampini static PetscErrorCode MatSetValuesCOO_IS(Mat A,const PetscScalar v[],InsertMode imode) 3270*e432b41dSStefano Zampini { 3271*e432b41dSStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 3272*e432b41dSStefano Zampini PetscErrorCode ierr; 3273*e432b41dSStefano Zampini 3274*e432b41dSStefano Zampini PetscFunctionBegin; 3275*e432b41dSStefano Zampini ierr = MatSetValuesCOO(a->A,v,imode);CHKERRQ(ierr); 3276*e432b41dSStefano Zampini ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3277*e432b41dSStefano Zampini ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3278*e432b41dSStefano Zampini PetscFunctionReturn(0); 3279*e432b41dSStefano Zampini } 3280*e432b41dSStefano Zampini 3281*e432b41dSStefano Zampini static PetscErrorCode MatSetPreallocationCOOLocal_IS(Mat A,PetscCount ncoo,PetscInt coo_i[],PetscInt coo_j[]) 3282*e432b41dSStefano Zampini { 3283*e432b41dSStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 3284*e432b41dSStefano Zampini PetscErrorCode ierr; 3285*e432b41dSStefano Zampini 3286*e432b41dSStefano Zampini PetscFunctionBegin; 3287*e432b41dSStefano Zampini PetscCheck(a->A,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Need to provide l2g map first via MatSetLocalToGlobalMapping"); 3288*e432b41dSStefano Zampini if (a->A->rmap->mapping || a->A->cmap->mapping) { 3289*e432b41dSStefano Zampini ierr = MatSetPreallocationCOOLocal(a->A,ncoo,coo_i,coo_j);CHKERRQ(ierr); 3290*e432b41dSStefano Zampini } else { 3291*e432b41dSStefano Zampini ierr = MatSetPreallocationCOO(a->A,ncoo,coo_i,coo_j);CHKERRQ(ierr); 3292*e432b41dSStefano Zampini } 3293*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetValuesCOO_C",MatSetValuesCOO_IS);CHKERRQ(ierr); 3294*e432b41dSStefano Zampini A->preallocated = PETSC_TRUE; 3295*e432b41dSStefano Zampini PetscFunctionReturn(0); 3296*e432b41dSStefano Zampini } 3297*e432b41dSStefano Zampini 3298*e432b41dSStefano Zampini static PetscErrorCode MatSetPreallocationCOO_IS(Mat A,PetscCount ncoo,const PetscInt coo_i[],const PetscInt coo_j[]) 3299*e432b41dSStefano Zampini { 3300*e432b41dSStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 3301*e432b41dSStefano Zampini PetscInt *coo_il, *coo_jl, incoo; 3302*e432b41dSStefano Zampini PetscErrorCode ierr; 3303*e432b41dSStefano Zampini 3304*e432b41dSStefano Zampini PetscFunctionBegin; 3305*e432b41dSStefano Zampini PetscCheck(a->A,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Need to provide l2g map first via MatSetLocalToGlobalMapping"); 3306*e432b41dSStefano Zampini PetscCheck(ncoo <= PETSC_MAX_INT,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support",ncoo); 3307*e432b41dSStefano Zampini ierr = PetscMalloc2(ncoo,&coo_il,ncoo,&coo_jl);CHKERRQ(ierr); 3308*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApply(a->rmapping,IS_GTOLM_MASK,ncoo,coo_i,&incoo,coo_il);CHKERRQ(ierr); 3309*e432b41dSStefano Zampini ierr = ISGlobalToLocalMappingApply(a->cmapping,IS_GTOLM_MASK,ncoo,coo_j,&incoo,coo_jl);CHKERRQ(ierr); 3310*e432b41dSStefano Zampini ierr = MatSetPreallocationCOO(a->A,ncoo,coo_il,coo_jl);CHKERRQ(ierr); 3311*e432b41dSStefano Zampini ierr = PetscFree2(coo_il,coo_jl);CHKERRQ(ierr); 3312*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetValuesCOO_C",MatSetValuesCOO_IS);CHKERRQ(ierr); 3313*e432b41dSStefano Zampini A->preallocated = PETSC_TRUE; 3314*e432b41dSStefano Zampini PetscFunctionReturn(0); 3315*e432b41dSStefano Zampini } 3316*e432b41dSStefano Zampini 3317*e432b41dSStefano Zampini /*@ 3318*e432b41dSStefano Zampini MatISGetLocalToGlobalMapping - Gets the local-to-global numbering of the MATIS object 3319*e432b41dSStefano Zampini 3320*e432b41dSStefano Zampini Not Collective 3321*e432b41dSStefano Zampini 3322*e432b41dSStefano Zampini Input Parameter: 3323*e432b41dSStefano Zampini . A - the matrix 3324*e432b41dSStefano Zampini 3325*e432b41dSStefano Zampini Output Parameters: 3326*e432b41dSStefano Zampini + rmapping - row mapping 3327*e432b41dSStefano Zampini - cmapping - column mapping 3328*e432b41dSStefano Zampini 3329*e432b41dSStefano Zampini Notes: The returned map can be different from the one used to construct the MATIS object, since it will not contain negative or repeated indices. 3330*e432b41dSStefano Zampini 3331*e432b41dSStefano Zampini Level: advanced 3332*e432b41dSStefano Zampini 3333*e432b41dSStefano Zampini .seealso: MatSetLocalToGlobalMapping() 3334*e432b41dSStefano Zampini @*/ 3335*e432b41dSStefano Zampini PetscErrorCode MatISGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 3336*e432b41dSStefano Zampini { 3337*e432b41dSStefano Zampini PetscErrorCode ierr; 3338*e432b41dSStefano Zampini 3339*e432b41dSStefano Zampini PetscFunctionBegin; 3340*e432b41dSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3341*e432b41dSStefano Zampini PetscValidType(A,1); 3342*e432b41dSStefano Zampini if (rmapping) PetscValidPointer(rmapping,2); 3343*e432b41dSStefano Zampini if (cmapping) PetscValidPointer(cmapping,3); 3344*e432b41dSStefano Zampini ierr = PetscUseMethod(A,"MatISGetLocalToGlobalMapping_C",(Mat,ISLocalToGlobalMapping*,ISLocalToGlobalMapping*),(A,rmapping,cmapping));CHKERRQ(ierr); 3345*e432b41dSStefano Zampini PetscFunctionReturn(0); 3346*e432b41dSStefano Zampini } 3347*e432b41dSStefano Zampini 3348*e432b41dSStefano Zampini static PetscErrorCode MatISGetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping *r, ISLocalToGlobalMapping *c) 3349*e432b41dSStefano Zampini { 3350*e432b41dSStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 3351*e432b41dSStefano Zampini 3352*e432b41dSStefano Zampini PetscFunctionBegin; 3353*e432b41dSStefano Zampini if (r) *r = a->rmapping; 3354*e432b41dSStefano Zampini if (c) *c = a->cmapping; 3355*e432b41dSStefano Zampini PetscFunctionReturn(0); 3356*e432b41dSStefano Zampini } 3357*e432b41dSStefano Zampini 3358b4319ba4SBarry Smith /*MC 3359f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3360b89f26deSStefano Zampini This stores the matrices in globally unassembled form. Each processor assembles only its local Neumann problem and the parallel matrix vector 3361b4319ba4SBarry Smith product is handled "implicitly". 3362b4319ba4SBarry Smith 3363b4319ba4SBarry Smith Options Database Keys: 336475d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 336575d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 336675d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3367b4319ba4SBarry Smith 336895452b02SPatrick Sanan Notes: 336995452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3370b4319ba4SBarry Smith 3371b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3372b4319ba4SBarry Smith 3373b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3374eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3375b4319ba4SBarry Smith 3376b4319ba4SBarry Smith Level: advanced 3377b4319ba4SBarry Smith 3378f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3379b4319ba4SBarry Smith 3380b4319ba4SBarry Smith M*/ 33818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3382b4319ba4SBarry Smith { 3383dfbe8321SBarry Smith PetscErrorCode ierr; 3384*e432b41dSStefano Zampini Mat_IS *a; 3385b4319ba4SBarry Smith 3386b4319ba4SBarry Smith PetscFunctionBegin; 3387*e432b41dSStefano Zampini ierr = PetscNewLog(A,&a);CHKERRQ(ierr); 3388*e432b41dSStefano Zampini ierr = PetscStrallocpy(MATAIJ,&a->lmattype);CHKERRQ(ierr); 3389*e432b41dSStefano Zampini A->data = (void*)a; 3390b4319ba4SBarry Smith 3391e176bc59SStefano Zampini /* matrix ops */ 3392e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3393b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 33942e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 33952e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 33962e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3397b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3398b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 33992e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 340098921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3401b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3402f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 34032e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3404f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3405b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3406b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3407b4319ba4SBarry Smith A->ops->view = MatView_IS; 34086726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 34092e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 34102e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 34116726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 341269796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 341369796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 341445471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3415ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 34166bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 34172b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3418659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 34197dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3420f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 34213fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 34223fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3423d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 34247fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3425ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3426872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3427fc989267SStefano Zampini A->ops->setup = MatSetUp_IS; 34288b9382cfSStefano Zampini A->ops->hasoperation = MatHasOperation_IS; 3429b4319ba4SBarry Smith 3430b7ce53b6SStefano Zampini /* special MATIS functions */ 34318546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",MatISSetLocalMatType_IS);CHKERRQ(ierr); 3432bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 34333b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3434bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3435487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 34362e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 343775d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3438f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3439*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalToGlobalMapping_C",MatISGetLocalToGlobalMapping_IS);CHKERRQ(ierr); 3440487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3441487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3442487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3443487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3444487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3445487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3446487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3447*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetPreallocationCOOLocal_C",MatSetPreallocationCOOLocal_IS);CHKERRQ(ierr); 3448*e432b41dSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetPreallocationCOO_C",MatSetPreallocationCOO_IS);CHKERRQ(ierr); 344917667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3450b4319ba4SBarry Smith PetscFunctionReturn(0); 3451b4319ba4SBarry Smith } 3452