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> 1328f4e0baSStefano Zampini 14f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 15b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 16b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 178546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat); 18f26d0771SStefano Zampini 1975d48cdbSStefano Zampini static PetscErrorCode MatISContainerDestroyPtAP_Private(void *ptr) 2075d48cdbSStefano Zampini { 2175d48cdbSStefano Zampini MatISPtAP ptap = (MatISPtAP)ptr; 2275d48cdbSStefano Zampini PetscErrorCode ierr; 2375d48cdbSStefano Zampini 2475d48cdbSStefano Zampini PetscFunctionBegin; 2575d48cdbSStefano Zampini ierr = MatDestroySubMatrices(ptap->ris1 ? 2 : 1,&ptap->lP);CHKERRQ(ierr); 2675d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis0);CHKERRQ(ierr); 2775d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis1);CHKERRQ(ierr); 2875d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris0);CHKERRQ(ierr); 2975d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 3075d48cdbSStefano Zampini ierr = PetscFree(ptap);CHKERRQ(ierr); 3175d48cdbSStefano Zampini PetscFunctionReturn(0); 3275d48cdbSStefano Zampini } 3375d48cdbSStefano Zampini 3475d48cdbSStefano Zampini static PetscErrorCode MatPtAPNumeric_IS_XAIJ(Mat A, Mat P, Mat C) 3575d48cdbSStefano Zampini { 3675d48cdbSStefano Zampini MatISPtAP ptap; 3775d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3875d48cdbSStefano Zampini Mat lA,lC; 3975d48cdbSStefano Zampini MatReuse reuse; 4075d48cdbSStefano Zampini IS ris[2],cis[2]; 4175d48cdbSStefano Zampini PetscContainer c; 4275d48cdbSStefano Zampini PetscInt n; 4375d48cdbSStefano Zampini PetscErrorCode ierr; 4475d48cdbSStefano Zampini 4575d48cdbSStefano Zampini PetscFunctionBegin; 466afe12f5SStefano Zampini ierr = PetscObjectQuery((PetscObject)C,"_MatIS_PtAP",(PetscObject*)&c);CHKERRQ(ierr); 4775d48cdbSStefano Zampini if (!c) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing PtAP information"); 4875d48cdbSStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&ptap);CHKERRQ(ierr); 4975d48cdbSStefano Zampini ris[0] = ptap->ris0; 5075d48cdbSStefano Zampini ris[1] = ptap->ris1; 5175d48cdbSStefano Zampini cis[0] = ptap->cis0; 5275d48cdbSStefano Zampini cis[1] = ptap->cis1; 5375d48cdbSStefano Zampini n = ptap->ris1 ? 2 : 1; 5475d48cdbSStefano Zampini reuse = ptap->lP ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX; 5575d48cdbSStefano Zampini ierr = MatCreateSubMatrices(P,n,ris,cis,reuse,&ptap->lP);CHKERRQ(ierr); 5675d48cdbSStefano Zampini 5775d48cdbSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 5875d48cdbSStefano Zampini ierr = MatISGetLocalMat(C,&lC);CHKERRQ(ierr); 5975d48cdbSStefano Zampini if (ptap->ris1) { /* unsymmetric A mapping */ 6075d48cdbSStefano Zampini Mat lPt; 6175d48cdbSStefano Zampini 6275d48cdbSStefano Zampini ierr = MatTranspose(ptap->lP[1],MAT_INITIAL_MATRIX,&lPt);CHKERRQ(ierr); 6375d48cdbSStefano Zampini ierr = MatMatMatMult(lPt,lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6475d48cdbSStefano Zampini if (matis->storel2l) { 6575d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",(PetscObject)lPt);CHKERRQ(ierr); 6675d48cdbSStefano Zampini } 6775d48cdbSStefano Zampini ierr = MatDestroy(&lPt);CHKERRQ(ierr); 6875d48cdbSStefano Zampini } else { 6975d48cdbSStefano Zampini ierr = MatPtAP(lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 7075d48cdbSStefano Zampini if (matis->storel2l) { 714222ddf1SHong Zhang ierr = PetscObjectCompose((PetscObject)C,"_MatIS_PtAP_l2l",(PetscObject)ptap->lP[0]);CHKERRQ(ierr); 7275d48cdbSStefano Zampini } 7375d48cdbSStefano Zampini } 7475d48cdbSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7575d48cdbSStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 7675d48cdbSStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 7775d48cdbSStefano Zampini } 7875d48cdbSStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7975d48cdbSStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8075d48cdbSStefano Zampini PetscFunctionReturn(0); 8175d48cdbSStefano Zampini } 8275d48cdbSStefano Zampini 8375d48cdbSStefano Zampini static PetscErrorCode MatGetNonzeroColumnsLocal_Private(Mat PT,IS *cis) 8475d48cdbSStefano Zampini { 8575d48cdbSStefano Zampini Mat Po,Pd; 8675d48cdbSStefano Zampini IS zd,zo; 8775d48cdbSStefano Zampini const PetscInt *garray; 8875d48cdbSStefano Zampini PetscInt *aux,i,bs; 8975d48cdbSStefano Zampini PetscInt dc,stc,oc,ctd,cto; 9075d48cdbSStefano Zampini PetscBool ismpiaij,ismpibaij,isseqaij,isseqbaij; 9175d48cdbSStefano Zampini MPI_Comm comm; 9275d48cdbSStefano Zampini PetscErrorCode ierr; 9375d48cdbSStefano Zampini 9475d48cdbSStefano Zampini PetscFunctionBegin; 9575d48cdbSStefano Zampini PetscValidHeaderSpecific(PT,MAT_CLASSID,1); 9675d48cdbSStefano Zampini PetscValidPointer(cis,2); 9775d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)PT,&comm);CHKERRQ(ierr); 9875d48cdbSStefano Zampini bs = 1; 99b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 100b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 10104637862SRichard Tran Mills ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 10275d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 10375d48cdbSStefano Zampini if (isseqaij || isseqbaij) { 10475d48cdbSStefano Zampini Pd = PT; 10575d48cdbSStefano Zampini Po = NULL; 10675d48cdbSStefano Zampini garray = NULL; 10775d48cdbSStefano Zampini } else if (ismpiaij) { 10875d48cdbSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10975d48cdbSStefano Zampini } else if (ismpibaij) { 11075d48cdbSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 11175d48cdbSStefano Zampini ierr = MatGetBlockSize(PT,&bs);CHKERRQ(ierr); 11275d48cdbSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(PT))->type_name); 11375d48cdbSStefano Zampini 11475d48cdbSStefano Zampini /* identify any null columns in Pd or Po */ 11522f7620eSStefano Zampini /* We use a tolerance comparison since it may happen that, with geometric multigrid, 11622f7620eSStefano Zampini some of the columns are not really zero, but very close to */ 11775d48cdbSStefano Zampini zo = zd = NULL; 11875d48cdbSStefano Zampini if (Po) { 11922f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Po,PETSC_TRUE,PETSC_SMALL,&zo);CHKERRQ(ierr); 12075d48cdbSStefano Zampini } 12122f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Pd,PETSC_TRUE,PETSC_SMALL,&zd);CHKERRQ(ierr); 12275d48cdbSStefano Zampini 12375d48cdbSStefano Zampini ierr = MatGetLocalSize(PT,NULL,&dc);CHKERRQ(ierr); 12475d48cdbSStefano Zampini ierr = MatGetOwnershipRangeColumn(PT,&stc,NULL);CHKERRQ(ierr); 12575d48cdbSStefano Zampini if (Po) { ierr = MatGetLocalSize(Po,NULL,&oc);CHKERRQ(ierr); } 12675d48cdbSStefano Zampini else oc = 0; 12775d48cdbSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 12875d48cdbSStefano Zampini if (zd) { 12975d48cdbSStefano Zampini const PetscInt *idxs; 13075d48cdbSStefano Zampini PetscInt nz; 13175d48cdbSStefano Zampini 13275d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 13375d48cdbSStefano Zampini ierr = ISSetBlockSize(zd,bs);CHKERRQ(ierr); 13475d48cdbSStefano Zampini ierr = ISGetLocalSize(zd,&nz);CHKERRQ(ierr); 13575d48cdbSStefano Zampini ierr = ISGetIndices(zd,&idxs);CHKERRQ(ierr); 13675d48cdbSStefano Zampini ctd = nz/bs; 13775d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = (idxs[bs*i]+stc)/bs; 13875d48cdbSStefano Zampini ierr = ISRestoreIndices(zd,&idxs);CHKERRQ(ierr); 13975d48cdbSStefano Zampini } else { 14075d48cdbSStefano Zampini ctd = dc/bs; 14175d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = i+stc/bs; 14275d48cdbSStefano Zampini } 14375d48cdbSStefano Zampini if (zo) { 14475d48cdbSStefano Zampini const PetscInt *idxs; 14575d48cdbSStefano Zampini PetscInt nz; 14675d48cdbSStefano Zampini 14775d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 14875d48cdbSStefano Zampini ierr = ISSetBlockSize(zo,bs);CHKERRQ(ierr); 14975d48cdbSStefano Zampini ierr = ISGetLocalSize(zo,&nz);CHKERRQ(ierr); 15075d48cdbSStefano Zampini ierr = ISGetIndices(zo,&idxs);CHKERRQ(ierr); 15175d48cdbSStefano Zampini cto = nz/bs; 15275d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[idxs[bs*i]/bs]; 15375d48cdbSStefano Zampini ierr = ISRestoreIndices(zo,&idxs);CHKERRQ(ierr); 15475d48cdbSStefano Zampini } else { 15575d48cdbSStefano Zampini cto = oc/bs; 15675d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[i]; 15775d48cdbSStefano Zampini } 15875d48cdbSStefano Zampini ierr = ISCreateBlock(comm,bs,ctd+cto,aux,PETSC_OWN_POINTER,cis);CHKERRQ(ierr); 15975d48cdbSStefano Zampini ierr = ISDestroy(&zd);CHKERRQ(ierr); 16075d48cdbSStefano Zampini ierr = ISDestroy(&zo);CHKERRQ(ierr); 16175d48cdbSStefano Zampini PetscFunctionReturn(0); 16275d48cdbSStefano Zampini } 16375d48cdbSStefano Zampini 1644222ddf1SHong Zhang static PetscErrorCode MatPtAPSymbolic_IS_XAIJ(Mat A,Mat P,PetscReal fill,Mat C) 16575d48cdbSStefano Zampini { 1668546b261SStefano Zampini Mat PT,lA; 16775d48cdbSStefano Zampini MatISPtAP ptap; 16875d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 16975d48cdbSStefano Zampini PetscContainer c; 1708546b261SStefano Zampini MatType lmtype; 17175d48cdbSStefano Zampini const PetscInt *garray; 17275d48cdbSStefano Zampini PetscInt ibs,N,dc; 17375d48cdbSStefano Zampini MPI_Comm comm; 17475d48cdbSStefano Zampini PetscErrorCode ierr; 17575d48cdbSStefano Zampini 17675d48cdbSStefano Zampini PetscFunctionBegin; 17775d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 1784222ddf1SHong Zhang ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1798546b261SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1808546b261SStefano Zampini ierr = MatGetType(lA,&lmtype);CHKERRQ(ierr); 1814222ddf1SHong Zhang ierr = MatISSetLocalMatType(C,lmtype);CHKERRQ(ierr); 18275d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 18375d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 1844222ddf1SHong Zhang ierr = MatSetSizes(C,dc,dc,N,N);CHKERRQ(ierr); 18575d48cdbSStefano Zampini /* Not sure about this 18675d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18775d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18875d48cdbSStefano Zampini */ 18975d48cdbSStefano Zampini 19075d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 19175d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 19275d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 19375d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 1944222ddf1SHong Zhang ierr = PetscObjectCompose((PetscObject)C,"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19575d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ptap->fill = fill; 19775d48cdbSStefano Zampini 19875d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 19975d48cdbSStefano Zampini 20075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 20175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20575d48cdbSStefano Zampini 20675d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20775d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 20975d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 21075d48cdbSStefano Zampini 21175d48cdbSStefano Zampini Crl2g = NULL; 21275d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 21375d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 21475d48cdbSStefano Zampini PetscInt N1,ibs1; 21575d48cdbSStefano Zampini 21675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21975d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22175d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 22275d48cdbSStefano Zampini const PetscInt *i1,*i2; 22375d48cdbSStefano Zampini 22475d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22575d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 226580bdb30SBarry Smith ierr = PetscArraycmp(i1,i2,N,&lsame);CHKERRQ(ierr); 22775d48cdbSStefano Zampini } 22875d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 22975d48cdbSStefano Zampini if (same) { 23075d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 23175d48cdbSStefano Zampini } else { 23275d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 23375d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 23475d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23575d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23675d48cdbSStefano Zampini } 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini /* Not sure about this 23975d48cdbSStefano Zampini if (!Crl2g) { 2404222ddf1SHong Zhang ierr = MatGetBlockSize(C,&ibs);CHKERRQ(ierr); 24175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 24275d48cdbSStefano Zampini } 24375d48cdbSStefano Zampini */ 2444222ddf1SHong Zhang ierr = MatSetLocalToGlobalMapping(C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24775d48cdbSStefano Zampini 2484222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 24975d48cdbSStefano Zampini PetscFunctionReturn(0); 25075d48cdbSStefano Zampini } 25175d48cdbSStefano Zampini 2524222ddf1SHong Zhang /* ----------------------------------------- */ 2534222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_IS_XAIJ(Mat C) 25475d48cdbSStefano Zampini { 25575d48cdbSStefano Zampini PetscErrorCode ierr; 2564222ddf1SHong Zhang Mat_Product *product = C->product; 2574222ddf1SHong Zhang Mat A=product->A,P=product->B; 2584222ddf1SHong Zhang PetscReal fill=product->fill; 25975d48cdbSStefano Zampini 26075d48cdbSStefano Zampini PetscFunctionBegin; 26175d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 2624222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 26375d48cdbSStefano Zampini PetscFunctionReturn(0); 26475d48cdbSStefano Zampini } 26575d48cdbSStefano Zampini 2664222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_IS_XAIJ_PtAP(Mat C) 2674222ddf1SHong Zhang { 2684222ddf1SHong Zhang PetscFunctionBegin; 2694222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_IS_XAIJ; 2704222ddf1SHong Zhang PetscFunctionReturn(0); 2714222ddf1SHong Zhang } 2724222ddf1SHong Zhang 2734222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat C) 2744222ddf1SHong Zhang { 2754222ddf1SHong Zhang PetscErrorCode ierr; 2764222ddf1SHong Zhang Mat_Product *product = C->product; 2774222ddf1SHong Zhang 2784222ddf1SHong Zhang PetscFunctionBegin; 2794222ddf1SHong Zhang if (product->type == MATPRODUCT_PtAP) { 2804222ddf1SHong Zhang ierr = MatProductSetFromOptions_IS_XAIJ_PtAP(C);CHKERRQ(ierr); 281*544a5e07SHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatProduct type %s is not supported for IS and XAIJ matrices",MatProductTypes[product->type]); 2824222ddf1SHong Zhang PetscFunctionReturn(0); 2834222ddf1SHong Zhang } 2844222ddf1SHong Zhang 2854222ddf1SHong Zhang /* ----------------------------------------- */ 2865b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2875b003df0Sstefano_zampini { 2885b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2895b003df0Sstefano_zampini PetscInt i; 2905b003df0Sstefano_zampini PetscErrorCode ierr; 2915b003df0Sstefano_zampini 292ab4d48faSStefano Zampini PetscFunctionBegin; 2935b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2945b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2955b003df0Sstefano_zampini } 2965b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2975b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2985b003df0Sstefano_zampini } 2995b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 3005b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 3015b003df0Sstefano_zampini PetscFunctionReturn(0); 3025b003df0Sstefano_zampini } 303a72627d2SStefano Zampini 304c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 3056989cf23SStefano Zampini { 306c9225affSStefano Zampini Mat B,lB; 307c9225affSStefano Zampini PetscErrorCode ierr; 308c9225affSStefano Zampini 309c9225affSStefano Zampini PetscFunctionBegin; 310c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 311c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 312c9225affSStefano Zampini PetscInt bs; 313c9225affSStefano Zampini IS is; 314c9225affSStefano Zampini 315c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 316c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 317c9225affSStefano Zampini if (bs > 1) { 318c9225affSStefano Zampini IS is2; 319c9225affSStefano Zampini PetscInt i,*aux; 320c9225affSStefano Zampini 321c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 322c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 323c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 324c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 325c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 326c9225affSStefano Zampini is = is2; 327c9225affSStefano Zampini } 328c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 329c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 330c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 331c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 332c9225affSStefano Zampini if (bs > 1) { 333c9225affSStefano Zampini IS is2; 334c9225affSStefano Zampini PetscInt i,*aux; 335c9225affSStefano Zampini 336c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 337c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 338c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 339c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 340c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 341c9225affSStefano Zampini is = is2; 342c9225affSStefano Zampini } 343c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 344c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 345c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 346c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 347c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 348c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 349c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 350c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 351c9225affSStefano Zampini } else { 352c9225affSStefano Zampini B = *newmat; 353c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 354c9225affSStefano Zampini lB = A; 355c9225affSStefano Zampini } 356c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 357c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 358c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 359c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 360c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 361c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 362c9225affSStefano Zampini } 363c9225affSStefano Zampini PetscFunctionReturn(0); 364c9225affSStefano Zampini } 365c9225affSStefano Zampini 366c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 367c9225affSStefano Zampini { 368c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 369c9225affSStefano Zampini PetscScalar *aa; 370c9225affSStefano Zampini const PetscInt *ii,*jj; 371c9225affSStefano Zampini PetscInt i,n,m; 372fabe8965SStefano Zampini PetscInt *ecount,**eneighs; 373c9225affSStefano Zampini PetscBool flg; 374c9225affSStefano Zampini PetscErrorCode ierr; 375c9225affSStefano Zampini 376c9225affSStefano Zampini PetscFunctionBegin; 377c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 378c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 379fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 380c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 381c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 382c9225affSStefano Zampini for (i=0;i<n;i++) { 383fabe8965SStefano Zampini if (ecount[i] > 1) { 384c9225affSStefano Zampini PetscInt j; 385c9225affSStefano Zampini 386c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 387c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 388fabe8965SStefano Zampini PetscReal scal = 0.0; 389c9225affSStefano Zampini 390c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 391c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 392c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 393c9225affSStefano Zampini } 394c9225affSStefano Zampini } 395fabe8965SStefano Zampini if (scal) aa[j] /= scal; 396c9225affSStefano Zampini } 397c9225affSStefano Zampini } 398c9225affSStefano Zampini } 399fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 400c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 401c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 402c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 403c9225affSStefano Zampini PetscFunctionReturn(0); 404c9225affSStefano Zampini } 405c9225affSStefano Zampini 406fabe8965SStefano Zampini typedef enum {MAT_IS_DISASSEMBLE_L2G_NATURAL,MAT_IS_DISASSEMBLE_L2G_MAT, MAT_IS_DISASSEMBLE_L2G_ND} MatISDisassemblel2gType; 407fabe8965SStefano Zampini 408c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 409c9225affSStefano Zampini { 410fabe8965SStefano Zampini Mat Ad,Ao; 411fabe8965SStefano Zampini IS is,ndmap,ndsub; 412c9225affSStefano Zampini MPI_Comm comm; 413fabe8965SStefano Zampini const PetscInt *garray,*ndmapi; 414fabe8965SStefano Zampini PetscInt bs,i,cnt,nl,*ncount,*ndmapc; 415fabe8965SStefano Zampini PetscBool ismpiaij,ismpibaij; 416fabe8965SStefano Zampini const char *const MatISDisassemblel2gTypes[] = {"NATURAL","MAT","ND","MatISDisassemblel2gType","MAT_IS_DISASSEMBLE_L2G_",0}; 417fabe8965SStefano Zampini MatISDisassemblel2gType mode = MAT_IS_DISASSEMBLE_L2G_NATURAL; 418fabe8965SStefano Zampini MatPartitioning part; 419fabe8965SStefano Zampini PetscSF sf; 420c9225affSStefano Zampini PetscErrorCode ierr; 421c9225affSStefano Zampini 422c9225affSStefano Zampini PetscFunctionBegin; 423fabe8965SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MatIS l2g disassembling options","Mat");CHKERRQ(ierr); 424fabe8965SStefano 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); 425fabe8965SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 426fabe8965SStefano Zampini if (mode == MAT_IS_DISASSEMBLE_L2G_MAT) { 427c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 428c9225affSStefano Zampini PetscFunctionReturn(0); 429c9225affSStefano Zampini } 430c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 431b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 432b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 433c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 434fabe8965SStefano Zampini switch (mode) { 435fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_ND: 436fabe8965SStefano Zampini ierr = MatPartitioningCreate(comm,&part);CHKERRQ(ierr); 437fabe8965SStefano Zampini ierr = MatPartitioningSetAdjacency(part,A);CHKERRQ(ierr); 438fabe8965SStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)part,((PetscObject)A)->prefix);CHKERRQ(ierr); 439fabe8965SStefano Zampini ierr = MatPartitioningSetFromOptions(part);CHKERRQ(ierr); 440fabe8965SStefano Zampini ierr = MatPartitioningApplyND(part,&ndmap);CHKERRQ(ierr); 441fabe8965SStefano Zampini ierr = MatPartitioningDestroy(&part);CHKERRQ(ierr); 442fabe8965SStefano Zampini ierr = ISBuildTwoSided(ndmap,NULL,&ndsub);CHKERRQ(ierr); 443fabe8965SStefano Zampini ierr = MatMPIAIJSetUseScalableIncreaseOverlap(A,PETSC_TRUE);CHKERRQ(ierr); 444fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,1,&ndsub,1);CHKERRQ(ierr); 445fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ndsub,l2g);CHKERRQ(ierr); 446fabe8965SStefano Zampini 447fabe8965SStefano Zampini /* it may happen that a separator node is not properly shared */ 448fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(*l2g,&nl,&ncount,NULL);CHKERRQ(ierr); 449fabe8965SStefano Zampini ierr = PetscSFCreate(comm,&sf);CHKERRQ(ierr); 450fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(*l2g,&garray);CHKERRQ(ierr); 451fabe8965SStefano Zampini ierr = PetscSFSetGraphLayout(sf,A->rmap,nl,NULL,PETSC_OWN_POINTER,garray);CHKERRQ(ierr); 452fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(*l2g,&garray);CHKERRQ(ierr); 453fabe8965SStefano Zampini ierr = PetscCalloc1(A->rmap->n,&ndmapc);CHKERRQ(ierr); 454fabe8965SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 455fabe8965SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 456fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(*l2g,NULL,&ncount,NULL);CHKERRQ(ierr); 457fabe8965SStefano Zampini ierr = ISGetIndices(ndmap,&ndmapi);CHKERRQ(ierr); 458fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 459fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) 460fabe8965SStefano Zampini cnt++; 461fabe8965SStefano Zampini 462fabe8965SStefano Zampini ierr = MPIU_Allreduce(&cnt,&i,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 463fabe8965SStefano Zampini if (i) { /* we detected isolated separator nodes */ 464fabe8965SStefano Zampini Mat A2,A3; 465fabe8965SStefano Zampini IS *workis,is2; 466fabe8965SStefano Zampini PetscScalar *vals; 467fabe8965SStefano Zampini PetscInt gcnt = i,*dnz,*onz,j,*lndmapi; 468fabe8965SStefano Zampini ISLocalToGlobalMapping ll2g; 469fabe8965SStefano Zampini PetscBool flg; 470fabe8965SStefano Zampini const PetscInt *ii,*jj; 471fabe8965SStefano Zampini 472fabe8965SStefano Zampini /* communicate global id of separators */ 473fabe8965SStefano Zampini ierr = MatPreallocateInitialize(comm,A->rmap->n,A->cmap->n,dnz,onz);CHKERRQ(ierr); 474fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 475fabe8965SStefano Zampini dnz[i] = ndmapi[i] < 0 ? i + A->rmap->rstart : -1; 476fabe8965SStefano Zampini 477fabe8965SStefano Zampini ierr = PetscMalloc1(nl,&lndmapi);CHKERRQ(ierr); 478fabe8965SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 479fabe8965SStefano Zampini 480fabe8965SStefano Zampini /* compute adjacency of isolated separators node */ 481fabe8965SStefano Zampini ierr = PetscMalloc1(gcnt,&workis);CHKERRQ(ierr); 482fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) { 483fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 484fabe8965SStefano Zampini ierr = ISCreateStride(comm,1,i+A->rmap->rstart,1,&workis[cnt++]);CHKERRQ(ierr); 485fabe8965SStefano Zampini } 486fabe8965SStefano Zampini } 487fabe8965SStefano Zampini for (i = cnt; i < gcnt; i++) { 488fabe8965SStefano Zampini ierr = ISCreateStride(comm,0,0,1,&workis[i]);CHKERRQ(ierr); 489fabe8965SStefano Zampini } 490fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 491fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"ISOLATED");CHKERRQ(ierr); 492fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 493fabe8965SStefano Zampini } 494fabe8965SStefano Zampini 495fabe8965SStefano Zampini /* no communications since all the ISes correspond to locally owned rows */ 496fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,gcnt,workis,1);CHKERRQ(ierr); 497fabe8965SStefano Zampini 498fabe8965SStefano Zampini /* end communicate global id of separators */ 499fabe8965SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 500fabe8965SStefano Zampini 501fabe8965SStefano Zampini /* communicate new layers : create a matrix and transpose it */ 502580bdb30SBarry Smith ierr = PetscArrayzero(dnz,A->rmap->n);CHKERRQ(ierr); 503580bdb30SBarry Smith ierr = PetscArrayzero(onz,A->rmap->n);CHKERRQ(ierr); 504fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) { 505fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 506fabe8965SStefano Zampini const PetscInt* idxs; 507fabe8965SStefano Zampini PetscInt s; 508fabe8965SStefano Zampini 509fabe8965SStefano Zampini ierr = ISGetLocalSize(workis[j],&s);CHKERRQ(ierr); 510fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 511fabe8965SStefano Zampini ierr = MatPreallocateSet(i+A->rmap->rstart,s,idxs,dnz,onz);CHKERRQ(ierr); 512fabe8965SStefano Zampini j++; 513fabe8965SStefano Zampini } 514fabe8965SStefano Zampini } 515fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 516fabe8965SStefano Zampini 517fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 518fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"EXTENDED");CHKERRQ(ierr); 519fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 520fabe8965SStefano Zampini } 521fabe8965SStefano Zampini 522fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) j = PetscMax(j,dnz[i]+onz[i]); 523fabe8965SStefano Zampini ierr = PetscMalloc1(j,&vals);CHKERRQ(ierr); 524fabe8965SStefano Zampini for (i = 0; i < j; i++) vals[i] = 1.0; 525fabe8965SStefano Zampini 526fabe8965SStefano Zampini ierr = MatCreate(comm,&A2);CHKERRQ(ierr); 527fabe8965SStefano Zampini ierr = MatSetType(A2,MATMPIAIJ);CHKERRQ(ierr); 528fabe8965SStefano Zampini ierr = MatSetSizes(A2,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 529fabe8965SStefano Zampini ierr = MatMPIAIJSetPreallocation(A2,0,dnz,0,onz);CHKERRQ(ierr); 530fabe8965SStefano Zampini ierr = MatSetOption(A2,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 531fabe8965SStefano Zampini for (i = 0, j = 0; i < A2->rmap->n; i++) { 532fabe8965SStefano Zampini PetscInt row = i+A2->rmap->rstart,s = dnz[i] + onz[i]; 533fabe8965SStefano Zampini const PetscInt* idxs; 534fabe8965SStefano Zampini 535fabe8965SStefano Zampini if (s) { 536fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 537fabe8965SStefano Zampini ierr = MatSetValues(A2,1,&row,s,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 538fabe8965SStefano Zampini ierr = ISRestoreIndices(workis[j],&idxs);CHKERRQ(ierr); 539fabe8965SStefano Zampini j++; 540fabe8965SStefano Zampini } 541fabe8965SStefano Zampini } 542fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 543fabe8965SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 544fabe8965SStefano Zampini ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 545fabe8965SStefano Zampini ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 546fabe8965SStefano Zampini ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 547fabe8965SStefano Zampini 548fabe8965SStefano Zampini /* extract submatrix corresponding to the coupling "owned separators" x "isolated separators" */ 549fabe8965SStefano Zampini for (i = 0, j = 0; i < nl; i++) 550fabe8965SStefano Zampini if (lndmapi[i] >= 0) lndmapi[j++] = lndmapi[i]; 551fabe8965SStefano Zampini ierr = ISCreateGeneral(comm,j,lndmapi,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 552fabe8965SStefano Zampini ierr = MatMPIAIJGetLocalMatCondensed(A2,MAT_INITIAL_MATRIX,&is,NULL,&A3);CHKERRQ(ierr); 553fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 554fabe8965SStefano Zampini ierr = MatDestroy(&A2);CHKERRQ(ierr); 555fabe8965SStefano Zampini 556fabe8965SStefano Zampini /* extend local to global map to include connected isolated separators */ 557fabe8965SStefano Zampini ierr = PetscObjectQuery((PetscObject)A3,"_petsc_GetLocalMatCondensed_iscol",(PetscObject*)&is);CHKERRQ(ierr); 558fabe8965SStefano Zampini if (!is) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing column map"); 559fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&ll2g);CHKERRQ(ierr); 560fabe8965SStefano Zampini ierr = MatGetRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 561fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 562fabe8965SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,ii[i],jj,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 563fabe8965SStefano Zampini ierr = MatRestoreRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 564fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 565fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ll2g,is,&is2);CHKERRQ(ierr); 566fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 567fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ll2g);CHKERRQ(ierr); 568fabe8965SStefano Zampini 569fabe8965SStefano Zampini /* add new nodes to the local-to-global map */ 570fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(l2g);CHKERRQ(ierr); 571fabe8965SStefano Zampini ierr = ISExpand(ndsub,is2,&is);CHKERRQ(ierr); 572fabe8965SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 573fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 574fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 575fabe8965SStefano Zampini 576fabe8965SStefano Zampini ierr = MatDestroy(&A3);CHKERRQ(ierr); 577fabe8965SStefano Zampini ierr = PetscFree(lndmapi);CHKERRQ(ierr); 578fabe8965SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 579fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 580fabe8965SStefano Zampini ierr = ISDestroy(&workis[i]);CHKERRQ(ierr); 581fabe8965SStefano Zampini } 582fabe8965SStefano Zampini ierr = PetscFree(workis);CHKERRQ(ierr); 583fabe8965SStefano Zampini } 584fabe8965SStefano Zampini ierr = ISRestoreIndices(ndmap,&ndmapi);CHKERRQ(ierr); 585fabe8965SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 586fabe8965SStefano Zampini ierr = PetscFree(ndmapc);CHKERRQ(ierr); 587fabe8965SStefano Zampini ierr = ISDestroy(&ndmap);CHKERRQ(ierr); 588fabe8965SStefano Zampini ierr = ISDestroy(&ndsub);CHKERRQ(ierr); 589fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(*l2g,bs);CHKERRQ(ierr); 590fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingViewFromOptions(*l2g,NULL,"-matis_nd_l2g_view");CHKERRQ(ierr); 591fabe8965SStefano Zampini break; 592fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_NATURAL: 593fabe8965SStefano Zampini if (ismpiaij) { 594fabe8965SStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 595fabe8965SStefano Zampini } else if (ismpibaij) { 596fabe8965SStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 597c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 598c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 599c9225affSStefano Zampini if (A->rmap->n) { 600fabe8965SStefano Zampini PetscInt dc,oc,stc,*aux; 601c9225affSStefano Zampini 602c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 603c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 604c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 605c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 606c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 607c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 608c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 609c9225affSStefano Zampini } else { 610c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 611c9225affSStefano Zampini } 612c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 613c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 614fabe8965SStefano Zampini break; 615fabe8965SStefano Zampini default: 616fabe8965SStefano Zampini SETERRQ1(comm,PETSC_ERR_ARG_WRONG,"Unsupported l2g disassembling type %D",mode); 617c9225affSStefano Zampini } 618c9225affSStefano Zampini PetscFunctionReturn(0); 619c9225affSStefano Zampini } 620c9225affSStefano Zampini 621c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 622c9225affSStefano Zampini { 623c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 6246989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 6256989cf23SStefano Zampini IS is; 6266989cf23SStefano Zampini MPI_Comm comm; 6276989cf23SStefano Zampini void *ptrs[2]; 6286989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 629c9225affSStefano Zampini const PetscInt *garray; 6306989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 631c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 632c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 6336989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 634c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 635c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 636c9225affSStefano Zampini PetscMPIInt size; 6376989cf23SStefano Zampini PetscErrorCode ierr; 6386989cf23SStefano Zampini 639ab4d48faSStefano Zampini PetscFunctionBegin; 6406989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 641c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 642c9225affSStefano Zampini if (size == 1) { 643c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 644c9225affSStefano Zampini PetscFunctionReturn(0); 645c9225affSStefano Zampini } 646c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 647c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 648c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 649c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 650c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 651c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 652c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 653c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 654c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 655c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 656c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 657c9225affSStefano Zampini } 658c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 659c9225affSStefano Zampini Mat *newlA, lA; 660c9225affSStefano Zampini IS rows, cols; 661c9225affSStefano Zampini const PetscInt *ridx, *cidx; 662c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 663c9225affSStefano Zampini 664c9225affSStefano Zampini if (!B) B = *newmat; 665c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 666c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 667c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 668c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 669c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 670c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 671c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 672c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 673c9225affSStefano Zampini if (rl2g != cl2g) { 674c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 675c9225affSStefano Zampini } else { 676c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 677c9225affSStefano Zampini cols = rows; 678c9225affSStefano Zampini } 679c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 680c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 681c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 682c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 683c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 684c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 685c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 686c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 687c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 688c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 689c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 690c9225affSStefano Zampini } 691c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 692c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 693c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 694c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 695c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 696c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 697c9225affSStefano Zampini else *newmat = B; 698c9225affSStefano Zampini PetscFunctionReturn(0); 699c9225affSStefano Zampini } 700c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 701b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 702b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 703c9225affSStefano Zampini if (ismpiaij) { 704c9225affSStefano Zampini bs = 1; 705c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 706c9225affSStefano Zampini } else if (ismpibaij) { 707c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 708c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 709c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 710c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 711c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 712c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 713c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 714c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 7156989cf23SStefano Zampini 7166989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 7176989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 7186989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 7196989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 720c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 721c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 722c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 723c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 724c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 725c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 726c9225affSStefano Zampini /* store original pointers to be restored later */ 727c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 7286989cf23SStefano Zampini 7296989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 730c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 731c9225affSStefano Zampini if (bs > 1) { 732c9225affSStefano Zampini IS is2; 733c9225affSStefano Zampini 734c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 735c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 736c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 737c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 738c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 739c9225affSStefano Zampini is = is2; 740c9225affSStefano Zampini } 7416989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 7426989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 743e363d98aSStefano Zampini if (dr) { 744c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 745c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 746c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 747c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 748e363d98aSStefano Zampini lc = dc+oc; 749e363d98aSStefano Zampini } else { 750c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 751e363d98aSStefano Zampini lc = 0; 752e363d98aSStefano Zampini } 7536989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 7546989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 7556989cf23SStefano Zampini 7566989cf23SStefano Zampini /* create MATIS object */ 757c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 758c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 759c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 760c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 761c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 7626989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7636989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7646989cf23SStefano Zampini 7656989cf23SStefano Zampini /* merge local matrices */ 7666989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 7676989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 7686989cf23SStefano Zampini ii = aux; 7696989cf23SStefano Zampini jj = aux+dr+1; 7706989cf23SStefano Zampini aa = data; 7716989cf23SStefano Zampini *ii = *(di++) + *(oi++); 7726989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 7736989cf23SStefano Zampini { 7746989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 7756989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 7766989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 7776989cf23SStefano Zampini } 7786989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 779c9225affSStefano Zampini 780c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 781c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 782c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 783c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 784c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 785c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 786c9225affSStefano Zampini 7876989cf23SStefano Zampini ii = aux; 7886989cf23SStefano Zampini jj = aux+dr+1; 7896989cf23SStefano Zampini aa = data; 790e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 7916989cf23SStefano Zampini 7926989cf23SStefano Zampini /* create containers to destroy the data */ 7936989cf23SStefano Zampini ptrs[0] = aux; 7946989cf23SStefano Zampini ptrs[1] = data; 7956989cf23SStefano Zampini for (i=0; i<2; i++) { 7966989cf23SStefano Zampini PetscContainer c; 7976989cf23SStefano Zampini 7986989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 7996989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 800b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 8016989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 8026989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 8036989cf23SStefano Zampini } 804c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 805c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 806c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 807c9225affSStefano Zampini } 8086989cf23SStefano Zampini 8096989cf23SStefano Zampini /* finalize matrix */ 810c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 8116989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 812c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 813c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 814c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 815c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 816c9225affSStefano Zampini } else *newmat = B; 8176989cf23SStefano Zampini PetscFunctionReturn(0); 8186989cf23SStefano Zampini } 8196989cf23SStefano Zampini 8205e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 8215e3038f0Sstefano_zampini { 8225e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 8235e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 8245e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 8255e3038f0Sstefano_zampini MPI_Comm comm; 8265b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 8275b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 8289e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 8295e3038f0Sstefano_zampini PetscErrorCode ierr; 8305e3038f0Sstefano_zampini 831ab4d48faSStefano Zampini PetscFunctionBegin; 8325e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 8335e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 8345e3038f0Sstefano_zampini rnest = NULL; 8355e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 8365e3038f0Sstefano_zampini PetscBool ismatis,isnest; 8375e3038f0Sstefano_zampini 8385e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 839a32993e3SJed Brown if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name); 8405e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 8415e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 8425e3038f0Sstefano_zampini if (isnest) { 8435e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 8445e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 8455e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 8465e3038f0Sstefano_zampini } 8475e3038f0Sstefano_zampini } 8485e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 8495b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 850071fcb05SBarry Smith ierr = PetscCalloc6(nr,&isrow,nc,&iscol,nr,&islrow,nc,&islcol,nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 8515e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 8525e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8535e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8545e3038f0Sstefano_zampini PetscBool ismatis; 8559e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 8565e3038f0Sstefano_zampini 8575e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 8585e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8595e3038f0Sstefano_zampini 8605e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 8619e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 8629e7b2b25Sstefano_zampini if (istrans[ij]) { 8639e7b2b25Sstefano_zampini Mat T,lT; 8649e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8659e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 8669e7b2b25Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) (transposed) is not of type MATIS",i,j); 8679e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 8689e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 8699e7b2b25Sstefano_zampini } else { 8705e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 8715e3038f0Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) is not of type MATIS",i,j); 8729e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 8739e7b2b25Sstefano_zampini } 8745e3038f0Sstefano_zampini 8755e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 8765e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 8779e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 8785e3038f0Sstefano_zampini if (!l1 || !l2) continue; 8795e3038f0Sstefano_zampini if (lr[i] && l1 != lr[i]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lr[i],l1); 8805e3038f0Sstefano_zampini if (lc[j] && l2 != lc[j]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lc[j],l2); 8815e3038f0Sstefano_zampini lr[i] = l1; 8825e3038f0Sstefano_zampini lc[j] = l2; 8835e3038f0Sstefano_zampini 8845e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 8855e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 8865e3038f0Sstefano_zampini } 8875e3038f0Sstefano_zampini } 8885e3038f0Sstefano_zampini 8895e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 8905e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 8915e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8925e3038f0Sstefano_zampini rl2g = NULL; 8935e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8945e3038f0Sstefano_zampini PetscInt n1,n2; 8955e3038f0Sstefano_zampini 8965e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8979e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8989e7b2b25Sstefano_zampini Mat T; 8999e7b2b25Sstefano_zampini 9009e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 9019e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 9029e7b2b25Sstefano_zampini } else { 9035e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 9049e7b2b25Sstefano_zampini } 9055e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9065e3038f0Sstefano_zampini if (!n1) continue; 9075e3038f0Sstefano_zampini if (!rl2g) { 9085e3038f0Sstefano_zampini rl2g = cl2g; 9095e3038f0Sstefano_zampini } else { 9105e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9115e3038f0Sstefano_zampini PetscBool same; 9125e3038f0Sstefano_zampini 9135e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9145e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap size %D != %D",i,j,n1,n2); 9155e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9165e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 917580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9185e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9195e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9205e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap",i,j); 9215e3038f0Sstefano_zampini } 9225e3038f0Sstefano_zampini } 9235e3038f0Sstefano_zampini } 9245e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 9255e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 9265e3038f0Sstefano_zampini rl2g = NULL; 9275e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 9285e3038f0Sstefano_zampini PetscInt n1,n2; 9295e3038f0Sstefano_zampini 9305e3038f0Sstefano_zampini if (!nest[j][i]) continue; 9319e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 9329e7b2b25Sstefano_zampini Mat T; 9339e7b2b25Sstefano_zampini 9349e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 9359e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 9369e7b2b25Sstefano_zampini } else { 9375e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 9389e7b2b25Sstefano_zampini } 9395e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9405e3038f0Sstefano_zampini if (!n1) continue; 9415e3038f0Sstefano_zampini if (!rl2g) { 9425e3038f0Sstefano_zampini rl2g = cl2g; 9435e3038f0Sstefano_zampini } else { 9445e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9455e3038f0Sstefano_zampini PetscBool same; 9465e3038f0Sstefano_zampini 9475e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9485e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap size %D != %D",j,i,n1,n2); 9495e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9505e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 951580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9525e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9535e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9545e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap",j,i); 9555e3038f0Sstefano_zampini } 9565e3038f0Sstefano_zampini } 9575e3038f0Sstefano_zampini } 9585e3038f0Sstefano_zampini #endif 9595e3038f0Sstefano_zampini 9605e3038f0Sstefano_zampini B = NULL; 9615e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 9625b003df0Sstefano_zampini PetscInt stl; 9635b003df0Sstefano_zampini 9645e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 9655e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 9665e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9675b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9685e3038f0Sstefano_zampini Mat usedmat; 9695e3038f0Sstefano_zampini Mat_IS *matis; 9705e3038f0Sstefano_zampini const PetscInt *idxs; 9715e3038f0Sstefano_zampini 9725e3038f0Sstefano_zampini /* local IS for local NEST */ 9735b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9745e3038f0Sstefano_zampini 9755e3038f0Sstefano_zampini /* l2gmap */ 9765e3038f0Sstefano_zampini j = 0; 9775e3038f0Sstefano_zampini usedmat = nest[i][j]; 9789e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 9799e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 9809e7b2b25Sstefano_zampini 9819e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9829e7b2b25Sstefano_zampini Mat T; 9839e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 9849e7b2b25Sstefano_zampini usedmat = T; 9859e7b2b25Sstefano_zampini } 9865e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 9875e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 9889e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9899e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9909e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9919e7b2b25Sstefano_zampini } else { 9925e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9935e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9949e7b2b25Sstefano_zampini } 9955e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 9965e3038f0Sstefano_zampini stl += lr[i]; 9975e3038f0Sstefano_zampini } 9985e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 9995e3038f0Sstefano_zampini 10005e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 10015e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 10025e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 10035b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10045e3038f0Sstefano_zampini Mat usedmat; 10055e3038f0Sstefano_zampini Mat_IS *matis; 10065e3038f0Sstefano_zampini const PetscInt *idxs; 10075e3038f0Sstefano_zampini 10085e3038f0Sstefano_zampini /* local IS for local NEST */ 10095b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10105e3038f0Sstefano_zampini 10115e3038f0Sstefano_zampini /* l2gmap */ 10125e3038f0Sstefano_zampini j = 0; 10135e3038f0Sstefano_zampini usedmat = nest[j][i]; 10149e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 10159e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 10169e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10179e7b2b25Sstefano_zampini Mat T; 10189e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 10199e7b2b25Sstefano_zampini usedmat = T; 10209e7b2b25Sstefano_zampini } 10215e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10225e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 10239e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10249e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10259e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10269e7b2b25Sstefano_zampini } else { 10275e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10285e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10299e7b2b25Sstefano_zampini } 10305e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 10315e3038f0Sstefano_zampini stl += lc[i]; 10325e3038f0Sstefano_zampini } 10335e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 10345e3038f0Sstefano_zampini 10355e3038f0Sstefano_zampini /* Create MATIS */ 10365e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 10375e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 10385e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 10395e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 10405e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 10418546b261SStefano Zampini ierr = MatISSetLocalMatType(B,MATNEST);CHKERRQ(ierr); 10428546b261SStefano Zampini { /* hack : avoid setup of scatters */ 10438546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10448546b261SStefano Zampini matis->islocalref = PETSC_TRUE; 10458546b261SStefano Zampini } 10465e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 10475e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 10485e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 10495e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 10508546b261SStefano Zampini ierr = MatNestSetVecType(lA,VECNEST);CHKERRQ(ierr); 10519e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 10529e7b2b25Sstefano_zampini if (istrans[i]) { 10539e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10549e7b2b25Sstefano_zampini } 10559e7b2b25Sstefano_zampini } 10565e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 10575e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10588546b261SStefano Zampini { /* hack : setup of scatters done here */ 10598546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10608546b261SStefano Zampini 10618546b261SStefano Zampini matis->islocalref = PETSC_FALSE; 10628546b261SStefano Zampini ierr = MatISSetUpScatters_Private(B);CHKERRQ(ierr); 10638546b261SStefano Zampini } 10645e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10655e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10665e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 10675e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 10685e3038f0Sstefano_zampini } else { 10695e3038f0Sstefano_zampini *newmat = B; 10705e3038f0Sstefano_zampini } 10715e3038f0Sstefano_zampini } else { 10725e3038f0Sstefano_zampini if (lreuse) { 10735e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10745e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10755e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 10765e3038f0Sstefano_zampini if (snest[i*nc+j]) { 10775e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 10789e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10799e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 10809e7b2b25Sstefano_zampini } 10815e3038f0Sstefano_zampini } 10825e3038f0Sstefano_zampini } 10835e3038f0Sstefano_zampini } 10845e3038f0Sstefano_zampini } else { 10855b003df0Sstefano_zampini PetscInt stl; 10865b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 10875b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 10885b003df0Sstefano_zampini stl += lr[i]; 10895e3038f0Sstefano_zampini } 10905b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10915b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10925b003df0Sstefano_zampini stl += lc[i]; 10935e3038f0Sstefano_zampini } 10945e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 1095ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 10969e7b2b25Sstefano_zampini if (istrans[i]) { 10979e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10989e7b2b25Sstefano_zampini } 1099ab4d48faSStefano Zampini } 11005e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 11015e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 11025e3038f0Sstefano_zampini } 11035e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11045e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11055e3038f0Sstefano_zampini } 11065e3038f0Sstefano_zampini 11075b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 11085b003df0Sstefano_zampini convert = PETSC_FALSE; 11095b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 11105b003df0Sstefano_zampini if (convert) { 11115b003df0Sstefano_zampini Mat M; 11125b003df0Sstefano_zampini MatISLocalFields lf; 11135b003df0Sstefano_zampini PetscContainer c; 11145b003df0Sstefano_zampini 11155b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 11165b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 11175b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 11185b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 11195b003df0Sstefano_zampini 11205b003df0Sstefano_zampini /* attach local fields to the matrix */ 11215b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 1122071fcb05SBarry Smith ierr = PetscMalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 11235b003df0Sstefano_zampini for (i=0;i<nr;i++) { 11245b003df0Sstefano_zampini PetscInt n,st; 11255b003df0Sstefano_zampini 11265b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 11275b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 11285b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 11295b003df0Sstefano_zampini } 11305b003df0Sstefano_zampini for (i=0;i<nc;i++) { 11315b003df0Sstefano_zampini PetscInt n,st; 11325b003df0Sstefano_zampini 11335b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 11345b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 11355b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 11365b003df0Sstefano_zampini } 11375b003df0Sstefano_zampini lf->nr = nr; 11385b003df0Sstefano_zampini lf->nc = nc; 11395b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 11405b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 11415b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 11425b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 11435b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 11445b003df0Sstefano_zampini } 11455b003df0Sstefano_zampini 11465e3038f0Sstefano_zampini /* Free workspace */ 11475e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 11485e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 11495e3038f0Sstefano_zampini } 11505e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 11515e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 11525e3038f0Sstefano_zampini } 11539e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 11545b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 11555e3038f0Sstefano_zampini PetscFunctionReturn(0); 11565e3038f0Sstefano_zampini } 11575e3038f0Sstefano_zampini 1158ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1159ad219c80Sstefano_zampini { 1160ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1161ad219c80Sstefano_zampini Vec ll,rr; 1162ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1163ad219c80Sstefano_zampini PetscScalar *x,*y; 1164ad219c80Sstefano_zampini PetscErrorCode ierr; 1165ad219c80Sstefano_zampini 1166ad219c80Sstefano_zampini PetscFunctionBegin; 1167ad219c80Sstefano_zampini if (l) { 1168ad219c80Sstefano_zampini ll = matis->y; 1169ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1170ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1171ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1172ad219c80Sstefano_zampini } else { 1173ad219c80Sstefano_zampini ll = NULL; 1174ad219c80Sstefano_zampini } 1175ad219c80Sstefano_zampini if (r) { 1176ad219c80Sstefano_zampini rr = matis->x; 1177ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1178ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1179ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1180ad219c80Sstefano_zampini } else { 1181ad219c80Sstefano_zampini rr = NULL; 1182ad219c80Sstefano_zampini } 1183ad219c80Sstefano_zampini if (ll) { 1184ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1185ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1186ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1187ad219c80Sstefano_zampini } 1188ad219c80Sstefano_zampini if (rr) { 1189ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1190ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1191ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1192ad219c80Sstefano_zampini } 1193ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1194ad219c80Sstefano_zampini PetscFunctionReturn(0); 1195ad219c80Sstefano_zampini } 1196ad219c80Sstefano_zampini 11977fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 11987fa8f2d3SStefano Zampini { 11997fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 12007fa8f2d3SStefano Zampini MatInfo info; 12013966268fSBarry Smith PetscLogDouble isend[6],irecv[6]; 12027fa8f2d3SStefano Zampini PetscInt bs; 12037fa8f2d3SStefano Zampini PetscErrorCode ierr; 12047fa8f2d3SStefano Zampini 12057fa8f2d3SStefano Zampini PetscFunctionBegin; 12067fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1207a2ccb5f9Sstefano_zampini if (matis->A->ops->getinfo) { 12087fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 12097fa8f2d3SStefano Zampini isend[0] = info.nz_used; 12107fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 12117fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 12127fa8f2d3SStefano Zampini isend[3] = info.memory; 12137fa8f2d3SStefano Zampini isend[4] = info.mallocs; 1214a2ccb5f9Sstefano_zampini } else { 1215a2ccb5f9Sstefano_zampini isend[0] = 0.; 1216a2ccb5f9Sstefano_zampini isend[1] = 0.; 1217a2ccb5f9Sstefano_zampini isend[2] = 0.; 1218a2ccb5f9Sstefano_zampini isend[3] = 0.; 1219a2ccb5f9Sstefano_zampini isend[4] = 0.; 1220a2ccb5f9Sstefano_zampini } 1221314ce898Sstefano_zampini isend[5] = matis->A->num_ass; 12227fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 12237fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 12247fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 12257fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 12267fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 12277fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 1228314ce898Sstefano_zampini ginfo->assemblies = isend[5]; 12297fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 12303966268fSBarry Smith ierr = MPIU_Allreduce(isend,irecv,6,MPIU_PETSCLOGDOUBLE,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12317fa8f2d3SStefano Zampini 12327fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12337fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12347fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12357fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12367fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 1237314ce898Sstefano_zampini ginfo->assemblies = irecv[5]; 12387fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 12393966268fSBarry Smith ierr = MPIU_Allreduce(isend,irecv,5,MPIU_PETSCLOGDOUBLE,MPI_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12407fa8f2d3SStefano Zampini 12417fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12427fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12437fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12447fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12457fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12467fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 12477fa8f2d3SStefano Zampini } 12487fa8f2d3SStefano Zampini ginfo->block_size = bs; 12497fa8f2d3SStefano Zampini ginfo->fill_ratio_given = 0; 12507fa8f2d3SStefano Zampini ginfo->fill_ratio_needed = 0; 12517fa8f2d3SStefano Zampini ginfo->factor_mallocs = 0; 12525e3038f0Sstefano_zampini PetscFunctionReturn(0); 12535e3038f0Sstefano_zampini } 12545e3038f0Sstefano_zampini 1255d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1256d7f69cd0SStefano Zampini { 1257d7f69cd0SStefano Zampini Mat C,lC,lA; 1258d7f69cd0SStefano Zampini PetscErrorCode ierr; 1259d7f69cd0SStefano Zampini 1260d7f69cd0SStefano Zampini PetscFunctionBegin; 1261cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1262cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1263d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1264d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1265d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1266d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1267d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1268d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1269cf37664fSBarry Smith } else { 1270cf37664fSBarry Smith C = *B; 1271d7f69cd0SStefano Zampini } 1272d7f69cd0SStefano Zampini 1273d7f69cd0SStefano Zampini /* perform local transposition */ 1274d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1275d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);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 12893fd1c9e7SStefano Zampini 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 13043fd1c9e7SStefano Zampini 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; 1321f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1322f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1323f26d0771SStefano Zampini #endif 1324f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1325f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1326b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1327f26d0771SStefano Zampini PetscFunctionReturn(0); 1328f26d0771SStefano Zampini } 1329f26d0771SStefano Zampini 1330f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1331f26d0771SStefano Zampini { 1332f26d0771SStefano Zampini PetscErrorCode ierr; 1333f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1334f26d0771SStefano Zampini 1335f26d0771SStefano Zampini PetscFunctionBegin; 1336f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1337f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1338f26d0771SStefano Zampini #endif 1339f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1340f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1341b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1342f26d0771SStefano Zampini PetscFunctionReturn(0); 1343f26d0771SStefano Zampini } 1344f26d0771SStefano Zampini 13457dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1346a8116848SStefano Zampini { 1347a8116848SStefano Zampini Mat locmat,newlocmat; 1348a8116848SStefano Zampini Mat_IS *newmatis; 1349a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1350a8116848SStefano Zampini Vec rtest,ltest; 1351a8116848SStefano Zampini const PetscScalar *array; 1352a8116848SStefano Zampini #endif 1353a8116848SStefano Zampini const PetscInt *idxs; 1354a8116848SStefano Zampini PetscInt i,m,n; 1355a8116848SStefano Zampini PetscErrorCode ierr; 1356a8116848SStefano Zampini 1357a8116848SStefano Zampini PetscFunctionBegin; 1358a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1359a8116848SStefano Zampini PetscBool ismatis; 1360a8116848SStefano Zampini 1361a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1362a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1363a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1364a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1365a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1366a8116848SStefano Zampini } 1367a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1368a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1369a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1370a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1371a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1372a8116848SStefano Zampini for (i=0;i<n;i++) { 1373a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1374a8116848SStefano Zampini } 1375a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1376a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1377a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1378a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1379a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1380fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Irow may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1381a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1382a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1383a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1384a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1385a8116848SStefano Zampini for (i=0;i<n;i++) { 1386a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1387a8116848SStefano Zampini } 1388a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1389a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1390a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1391a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1392a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1393fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Icol may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1394a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1395a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1396a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1397a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1398a8116848SStefano Zampini #endif 1399a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1400a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1401a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1402a8116848SStefano Zampini IS is; 1403a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1404306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 140594342113SStefano Zampini PetscBool cong; 1406a8116848SStefano Zampini MPI_Comm comm; 1407a8116848SStefano Zampini 1408a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1409306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1410306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1411306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1412306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1413306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1414a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1415a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1416a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1417a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1418a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1419306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1420a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1421a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1422a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1423a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1424580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,matis->sf->nroots);CHKERRQ(ierr); 1425a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1426a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1427a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1428a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1429a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 14303d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1431a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1432a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14333d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1434a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1435a8116848SStefano Zampini lidxs[newloc] = i; 1436a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1437a8116848SStefano Zampini } 1438a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1439a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1440306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1441a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1442a8116848SStefano Zampini /* local is to extract local submatrix */ 1443a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1444a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 144594342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 144694342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1447a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1448a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1449a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1450a8116848SStefano Zampini } else { 1451a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1452a8116848SStefano Zampini 1453a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1454a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1455a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1456a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1457580bdb30SBarry Smith ierr = PetscArrayzero(matis->csf_rootdata,matis->csf->nroots);CHKERRQ(ierr); 1458a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1459a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1460a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1461a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1462a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 14633d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1464a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1465a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14663d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1467a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1468a8116848SStefano Zampini lidxs[newloc] = i; 1469a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1470a8116848SStefano Zampini } 1471a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1472a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1473306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1474a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1475a8116848SStefano Zampini /* local is to extract local submatrix */ 1476a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1477a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1478a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1479a8116848SStefano Zampini } 1480a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1481a8116848SStefano Zampini } else { 1482a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1483a8116848SStefano Zampini } 1484a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1485a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 14867dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1487a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1488a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1489a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1490a8116848SStefano Zampini } 1491a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1492a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1493a8116848SStefano Zampini PetscFunctionReturn(0); 1494a8116848SStefano Zampini } 1495a8116848SStefano Zampini 1496a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 14972b404112SStefano Zampini { 14982b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 14992b404112SStefano Zampini PetscBool ismatis; 15002b404112SStefano Zampini PetscErrorCode ierr; 15012b404112SStefano Zampini 15022b404112SStefano Zampini PetscFunctionBegin; 15032b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 15042b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 15052b404112SStefano Zampini b = (Mat_IS*)B->data; 15062b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1507cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 15082b404112SStefano Zampini PetscFunctionReturn(0); 15092b404112SStefano Zampini } 15102b404112SStefano Zampini 1511a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 15126bd84002SStefano Zampini { 1513527b2640SStefano Zampini Vec v; 1514527b2640SStefano Zampini const PetscScalar *array; 1515527b2640SStefano Zampini PetscInt i,n; 15166bd84002SStefano Zampini PetscErrorCode ierr; 15176bd84002SStefano Zampini 15186bd84002SStefano Zampini PetscFunctionBegin; 1519527b2640SStefano Zampini *missing = PETSC_FALSE; 1520527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1521527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1522527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1523527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1524527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1525527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1526527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1527527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1528527b2640SStefano Zampini if (d) { 1529527b2640SStefano Zampini *d = -1; 1530527b2640SStefano Zampini if (*missing) { 1531527b2640SStefano Zampini PetscInt rstart; 1532527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1533527b2640SStefano Zampini *d = i+rstart; 1534527b2640SStefano Zampini } 1535527b2640SStefano Zampini } 15366bd84002SStefano Zampini PetscFunctionReturn(0); 15376bd84002SStefano Zampini } 15386bd84002SStefano Zampini 1539cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 154028f4e0baSStefano Zampini { 154128f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 154228f4e0baSStefano Zampini const PetscInt *gidxs; 15434f2d7cafSStefano Zampini PetscInt nleaves; 154428f4e0baSStefano Zampini PetscErrorCode ierr; 154528f4e0baSStefano Zampini 154628f4e0baSStefano Zampini PetscFunctionBegin; 15474f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 154828f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 15493bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 15504f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 15514f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 15523bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 15534f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1554a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 15553d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1556a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1557a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 15583d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1559a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 15603d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1561a8116848SStefano Zampini } else { 1562a8116848SStefano Zampini matis->csf = matis->sf; 1563a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1564a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1565a8116848SStefano Zampini } 156628f4e0baSStefano Zampini PetscFunctionReturn(0); 156728f4e0baSStefano Zampini } 15682e1947a5SStefano Zampini 1569eb82efa4SStefano Zampini /*@ 157075d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 157175d48cdbSStefano Zampini 1572d083f849SBarry Smith Collective 157375d48cdbSStefano Zampini 157475d48cdbSStefano Zampini Input Parameters: 157575d48cdbSStefano Zampini + A - the matrix 157675d48cdbSStefano Zampini - store - the boolean flag 157775d48cdbSStefano Zampini 157875d48cdbSStefano Zampini Level: advanced 157975d48cdbSStefano Zampini 158075d48cdbSStefano Zampini Notes: 158175d48cdbSStefano Zampini 158275d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 158375d48cdbSStefano Zampini @*/ 158475d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 158575d48cdbSStefano Zampini { 158675d48cdbSStefano Zampini PetscErrorCode ierr; 158775d48cdbSStefano Zampini 158875d48cdbSStefano Zampini PetscFunctionBegin; 158975d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 159075d48cdbSStefano Zampini PetscValidType(A,1); 159175d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 159275d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 159375d48cdbSStefano Zampini PetscFunctionReturn(0); 159475d48cdbSStefano Zampini } 159575d48cdbSStefano Zampini 159675d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 159775d48cdbSStefano Zampini { 159875d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 159975d48cdbSStefano Zampini PetscErrorCode ierr; 160075d48cdbSStefano Zampini 160175d48cdbSStefano Zampini PetscFunctionBegin; 160275d48cdbSStefano Zampini matis->storel2l = store; 160375d48cdbSStefano Zampini if (!store) { 160475d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 160575d48cdbSStefano Zampini } 160675d48cdbSStefano Zampini PetscFunctionReturn(0); 160775d48cdbSStefano Zampini } 160875d48cdbSStefano Zampini 160975d48cdbSStefano Zampini /*@ 1610f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1611f03112d0SStefano Zampini 1612d083f849SBarry Smith Collective 1613f03112d0SStefano Zampini 1614f03112d0SStefano Zampini Input Parameters: 1615f03112d0SStefano Zampini + A - the matrix 1616f03112d0SStefano Zampini - fix - the boolean flag 1617f03112d0SStefano Zampini 1618f03112d0SStefano Zampini Level: advanced 1619f03112d0SStefano Zampini 1620f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1621f03112d0SStefano Zampini 1622f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1623f03112d0SStefano Zampini @*/ 1624f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1625f03112d0SStefano Zampini { 1626f03112d0SStefano Zampini PetscErrorCode ierr; 1627f03112d0SStefano Zampini 1628f03112d0SStefano Zampini PetscFunctionBegin; 1629f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1630f03112d0SStefano Zampini PetscValidType(A,1); 1631f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1632f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1633f03112d0SStefano Zampini PetscFunctionReturn(0); 1634f03112d0SStefano Zampini } 1635f03112d0SStefano Zampini 1636f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1637f03112d0SStefano Zampini { 1638f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1639f03112d0SStefano Zampini 1640f03112d0SStefano Zampini PetscFunctionBegin; 1641f03112d0SStefano Zampini matis->locempty = fix; 1642f03112d0SStefano Zampini PetscFunctionReturn(0); 1643f03112d0SStefano Zampini } 1644f03112d0SStefano Zampini 1645f03112d0SStefano Zampini /*@ 1646a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1647a88811baSStefano Zampini 1648d083f849SBarry Smith Collective 1649a88811baSStefano Zampini 1650a88811baSStefano Zampini Input Parameters: 1651a88811baSStefano Zampini + B - the matrix 1652a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1653a88811baSStefano Zampini (same value is used for all local rows) 1654a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1655a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1656a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1657a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1658a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1659a88811baSStefano Zampini the diagonal entry even if it is zero. 1660a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1661a88811baSStefano Zampini submatrix (same value is used for all local rows). 1662a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1663a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1664a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1665a88811baSStefano Zampini structure. The size of this array is equal to the number 1666a88811baSStefano Zampini of local rows, i.e 'm'. 1667a88811baSStefano Zampini 1668a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1669a88811baSStefano Zampini 1670a88811baSStefano Zampini Level: intermediate 1671a88811baSStefano Zampini 167295452b02SPatrick Sanan Notes: 167395452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1674a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1675a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1676a88811baSStefano Zampini 16773c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1678a88811baSStefano Zampini @*/ 16792e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16802e1947a5SStefano Zampini { 16812e1947a5SStefano Zampini PetscErrorCode ierr; 16822e1947a5SStefano Zampini 16832e1947a5SStefano Zampini PetscFunctionBegin; 16842e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 16852e1947a5SStefano Zampini PetscValidType(B,1); 16862e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 16872e1947a5SStefano Zampini PetscFunctionReturn(0); 16882e1947a5SStefano Zampini } 16892e1947a5SStefano Zampini 1690844bd0d7SStefano Zampini /* this is used by DMDA */ 1691844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16922e1947a5SStefano Zampini { 16932e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 169428f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 16952e1947a5SStefano Zampini PetscErrorCode ierr; 16962e1947a5SStefano Zampini 16972e1947a5SStefano Zampini PetscFunctionBegin; 16986c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 16994f2d7cafSStefano Zampini 17004f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 17014f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 17024f2d7cafSStefano Zampini 17034f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 17044f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 17054f2d7cafSStefano Zampini 170628f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 170728f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 170828f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 170928f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17104f2d7cafSStefano Zampini 17114f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 171228f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 17130f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 17140f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 17150f2f62c7SStefano Zampini #endif 17164f2d7cafSStefano Zampini 17174f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 171828f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17194f2d7cafSStefano Zampini 172000a59248SStefano Zampini nlocalcols /= bs; 172100a59248SStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols - i); 172228f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17230f2f62c7SStefano Zampini 17240f2f62c7SStefano Zampini /* for other matrix types */ 17250f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 17262e1947a5SStefano Zampini PetscFunctionReturn(0); 17272e1947a5SStefano Zampini } 1728b4319ba4SBarry Smith 17293927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 17303927de2eSStefano Zampini { 17313927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 17323927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1733ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 17343927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 17353927de2eSStefano Zampini PetscInt lrows,lcols; 17363927de2eSStefano Zampini PetscInt local_rows,local_cols; 1737f03112d0SStefano Zampini PetscMPIInt size; 17383927de2eSStefano Zampini PetscBool isdense,issbaij; 17393927de2eSStefano Zampini PetscErrorCode ierr; 17403927de2eSStefano Zampini 17413927de2eSStefano Zampini PetscFunctionBegin; 1742f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 17433927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 17443927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 17453927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1746b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1747b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1748ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1749ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 17507230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1751ecf5a873SStefano Zampini } else { 1752ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1753ecf5a873SStefano Zampini } 1754ecf5a873SStefano Zampini 17553927de2eSStefano Zampini if (issbaij) { 17563927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 17573927de2eSStefano Zampini } 17583927de2eSStefano Zampini /* 1759ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 17603927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 17613927de2eSStefano Zampini */ 17623927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 17633927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 17643927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 17653927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 17663927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1767f03112d0SStefano Zampini for (i=0;i<size;i++) { 17683927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 17693927de2eSStefano Zampini row_ownership[j] = i; 17703927de2eSStefano Zampini } 17713927de2eSStefano Zampini } 17727230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 17733927de2eSStefano Zampini 17743927de2eSStefano Zampini /* 17753927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 17763927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 17773927de2eSStefano Zampini */ 17783927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 17793927de2eSStefano Zampini /* preallocation as a MATAIJ */ 17803927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 17813927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 178212dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 178312dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1784ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 17853927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1]) { /* diag block */ 17863927de2eSStefano Zampini my_dnz[i] += 1; 17873927de2eSStefano Zampini } else { /* offdiag block */ 17883927de2eSStefano Zampini my_onz[i] += 1; 17893927de2eSStefano Zampini } 17903927de2eSStefano Zampini } 17913927de2eSStefano Zampini } 1792bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1793bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1794bb1015c3SStefano Zampini PetscBool done; 1795bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1796938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1797bb1015c3SStefano Zampini jptr = jj; 1798bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1799bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1800bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1801bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1802bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1803bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1804bb1015c3SStefano Zampini my_dnz[i] += 1; 1805bb1015c3SStefano Zampini } else { /* offdiag block */ 1806bb1015c3SStefano Zampini my_onz[i] += 1; 1807bb1015c3SStefano Zampini } 1808bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1809bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1810bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1811bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1812bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1813bb1015c3SStefano Zampini } else { 1814bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1815bb1015c3SStefano Zampini } 1816bb1015c3SStefano Zampini } 1817bb1015c3SStefano Zampini } 1818bb1015c3SStefano Zampini } 1819bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1820938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1821bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 18223927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 18233927de2eSStefano Zampini const PetscInt *cols; 1824ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 18253927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18263927de2eSStefano Zampini for (j=0;j<ncols;j++) { 18273927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1828ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 18293927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 18303927de2eSStefano Zampini my_dnz[i] += 1; 18313927de2eSStefano Zampini } else { /* offdiag block */ 18323927de2eSStefano Zampini my_onz[i] += 1; 18333927de2eSStefano Zampini } 18343927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1835d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 18363927de2eSStefano Zampini owner = row_ownership[index_col]; 18373927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1838d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 18393927de2eSStefano Zampini } else { 1840d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 18413927de2eSStefano Zampini } 18423927de2eSStefano Zampini } 18433927de2eSStefano Zampini } 18443927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18453927de2eSStefano Zampini } 18463927de2eSStefano Zampini } 1847ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 18487230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1849ecf5a873SStefano Zampini } 18504f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 18513927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1852ecf5a873SStefano Zampini 1853ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 18543927de2eSStefano Zampini if (maxreduce) { 18553927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18563927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1857bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18583927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 18593927de2eSStefano Zampini } else { 18603927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18613927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1862bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18633927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 18643927de2eSStefano Zampini } 18653927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 18663927de2eSStefano Zampini 18673927de2eSStefano Zampini /* Resize preallocation if overestimated */ 18683927de2eSStefano Zampini for (i=0;i<lrows;i++) { 18693927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 18703927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 18713927de2eSStefano Zampini } 18721670daf9Sstefano_zampini 18731670daf9Sstefano_zampini /* Set preallocation */ 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; 1904b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1905b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1906b9ed4604SStefano Zampini #endif 1907f03112d0SStefano Zampini PetscMPIInt size; 19081683a169SBarry Smith const PetscScalar *array; 1909b7ce53b6SStefano Zampini PetscErrorCode ierr; 1910b7ce53b6SStefano Zampini 1911b7ce53b6SStefano Zampini PetscFunctionBegin; 1912f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1913f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 19141670daf9Sstefano_zampini Mat B; 191553b44cf5SStefano Zampini IS irows = NULL,icols = NULL; 1916487b449aSStefano Zampini PetscInt rbs,cbs; 19171670daf9Sstefano_zampini 1918487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 1919487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 192053b44cf5SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { /* check if l2g maps are one-to-one */ 192153b44cf5SStefano Zampini IS rows,cols; 192253b44cf5SStefano Zampini const PetscInt *ridxs,*cidxs; 192353b44cf5SStefano Zampini PetscInt i,nw,*work; 192453b44cf5SStefano Zampini 192553b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 192653b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&nw);CHKERRQ(ierr); 192753b44cf5SStefano Zampini nw = nw/rbs; 192853b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 192953b44cf5SStefano Zampini for (i=0;i<nw;i++) work[ridxs[i]] += 1; 193053b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 193153b44cf5SStefano Zampini if (i == nw) { 193253b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,nw,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 1933acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 193453b44cf5SStefano Zampini ierr = ISInvertPermutation(rows,PETSC_DECIDE,&irows);CHKERRQ(ierr); 1935acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 193653b44cf5SStefano Zampini } 193753b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 193853b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 193953b44cf5SStefano Zampini if (irows && mat->rmap->mapping != mat->cmap->mapping) { 194053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 194153b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->cmap->mapping,&nw);CHKERRQ(ierr); 194253b44cf5SStefano Zampini nw = nw/cbs; 194353b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 194453b44cf5SStefano Zampini for (i=0;i<nw;i++) work[cidxs[i]] += 1; 194553b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 194653b44cf5SStefano Zampini if (i == nw) { 194753b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,nw,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 194853b44cf5SStefano Zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 194953b44cf5SStefano Zampini ierr = ISInvertPermutation(cols,PETSC_DECIDE,&icols);CHKERRQ(ierr); 195053b44cf5SStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 195153b44cf5SStefano Zampini } 195253b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 195353b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 195453b44cf5SStefano Zampini } else if (irows) { 195553b44cf5SStefano Zampini ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); 195653b44cf5SStefano Zampini icols = irows; 195753b44cf5SStefano Zampini } 195853b44cf5SStefano Zampini } else { 195953b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject*)&irows);CHKERRQ(ierr); 196053b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject*)&icols);CHKERRQ(ierr); 196153b44cf5SStefano Zampini if (irows) { ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); } 196253b44cf5SStefano Zampini if (icols) { ierr = PetscObjectReference((PetscObject)icols);CHKERRQ(ierr); } 196353b44cf5SStefano Zampini } 196453b44cf5SStefano Zampini if (!irows || !icols) { 196553b44cf5SStefano Zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 196653b44cf5SStefano Zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 196753b44cf5SStefano Zampini goto general_assembly; 196853b44cf5SStefano Zampini } 1969d8e18881SStefano Zampini ierr = MatConvert(matis->A,mtype,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1970487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 19717dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 197253b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject)irows);CHKERRQ(ierr); 197353b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject)icols);CHKERRQ(ierr); 1974487b449aSStefano Zampini } else { 1975487b449aSStefano Zampini Mat C; 1976487b449aSStefano Zampini 1977487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 1978487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 1979487b449aSStefano Zampini } 1980acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1981acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1982acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 19837c03b4e8SStefano Zampini PetscFunctionReturn(0); 19847c03b4e8SStefano Zampini } 198553b44cf5SStefano Zampini general_assembly: 1986b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 198753b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 198853b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 19893cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1990b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1991b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 19924099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1993b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1994b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1995b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1996b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1997b9ed4604SStefano Zampini lb[0] = isseqdense; 1998b9ed4604SStefano Zampini lb[1] = isseqaij; 1999b9ed4604SStefano Zampini lb[2] = isseqbaij; 2000b9ed4604SStefano Zampini lb[3] = isseqsbaij; 2001b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 2002b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 2003b9ed4604SStefano Zampini #endif 2004b7ce53b6SStefano Zampini 2005487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2006487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 2007487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 2008487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 200953b44cf5SStefano Zampini ierr = MatSetBlockSizes(MT,rbs,cbs);CHKERRQ(ierr); 2010487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 2011b7ce53b6SStefano Zampini } else { 201253b44cf5SStefano Zampini PetscInt mrbs,mcbs,mrows,mcols,mlrows,mlcols; 2013487b449aSStefano Zampini 2014b7ce53b6SStefano Zampini /* some checks */ 2015487b449aSStefano Zampini MT = *M; 201653b44cf5SStefano Zampini ierr = MatGetBlockSizes(MT,&mrbs,&mcbs);CHKERRQ(ierr); 2017487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 2018487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 20196c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 20206c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 20216c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 20226c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 202353b44cf5SStefano Zampini if (mrbs != rbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong row block size (%d != %d)",rbs,mrbs); 202453b44cf5SStefano Zampini if (mcbs != cbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong col block size (%d != %d)",cbs,mcbs); 2025487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 2026b7ce53b6SStefano Zampini } 2027d9a9e74cSStefano Zampini 20288546b261SStefano Zampini if (isseqsbaij || isseqbaij) { 20298546b261SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 20308546b261SStefano Zampini isseqaij = PETSC_TRUE; 2031d9a9e74cSStefano Zampini } else { 2032d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 2033d9a9e74cSStefano Zampini local_mat = matis->A; 2034d9a9e74cSStefano Zampini } 2035686e3a49SStefano Zampini 2036b7ce53b6SStefano Zampini /* Set values */ 2037487b449aSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2038b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 203965066ba5SStefano Zampini PetscInt i,*dummy; 2040ecf5a873SStefano Zampini 204165066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 204265066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 2043487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 20441683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&array);CHKERRQ(ierr); 2045487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 20461683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&array);CHKERRQ(ierr); 204765066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 2048686e3a49SStefano Zampini } else if (isseqaij) { 20496afe12f5SStefano Zampini const PetscInt *blocks; 20506afe12f5SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy, nb; 2051686e3a49SStefano Zampini PetscBool done; 20521683a169SBarry Smith PetscScalar *sarray; 2053686e3a49SStefano Zampini 2054d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2055938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 20561683a169SBarry Smith ierr = MatSeqAIJGetArray(local_mat,&sarray);CHKERRQ(ierr); 20576afe12f5SStefano Zampini ierr = MatGetVariableBlockSizes(local_mat,&nb,&blocks);CHKERRQ(ierr); 20586afe12f5SStefano Zampini if (nb) { /* speed up assembly for special blocked matrices (used by BDDC) */ 20596afe12f5SStefano Zampini PetscInt sum; 20606afe12f5SStefano Zampini 20616afe12f5SStefano Zampini for (i=0,sum=0;i<nb;i++) sum += blocks[i]; 20626afe12f5SStefano Zampini if (sum == nvtxs) { 20636afe12f5SStefano Zampini PetscInt r; 20646afe12f5SStefano Zampini 20656afe12f5SStefano Zampini for (i=0,r=0;i<nb;i++) { 2066d8e18881SStefano Zampini #if defined(PETSC_USE_DEBUG) 20676afe12f5SStefano Zampini if (blocks[i] != xadj[r+1] - xadj[r]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid block sizes prescribed for block %D: expected %D, got %D",i,blocks[i],xadj[r+1] - xadj[r]); 2068d8e18881SStefano Zampini #endif 20691683a169SBarry Smith ierr = MatSetValuesLocal(MT,blocks[i],adjncy+xadj[r],blocks[i],adjncy+xadj[r],sarray+xadj[r],ADD_VALUES);CHKERRQ(ierr); 20706afe12f5SStefano Zampini r += blocks[i]; 20716afe12f5SStefano Zampini } 20726afe12f5SStefano Zampini } else { 2073686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 20741683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 2075686e3a49SStefano Zampini } 20766afe12f5SStefano Zampini } 20776afe12f5SStefano Zampini } else { 20786afe12f5SStefano Zampini for (i=0;i<nvtxs;i++) { 20791683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 20806afe12f5SStefano Zampini } 20816afe12f5SStefano Zampini } 2082d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2083938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 20841683a169SBarry Smith ierr = MatSeqAIJRestoreArray(local_mat,&sarray);CHKERRQ(ierr); 2085686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 2086ecf5a873SStefano Zampini PetscInt i; 2087c0962df8SStefano Zampini 2088686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 2089686e3a49SStefano Zampini PetscInt j; 2090ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 2091686e3a49SStefano Zampini 20921683a169SBarry Smith ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2093487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 20941683a169SBarry Smith ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2095686e3a49SStefano Zampini } 2096b7ce53b6SStefano Zampini } 2097487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2098d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 2099487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2100b9ed4604SStefano Zampini if (isseqdense) { 2101487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 2102487b449aSStefano Zampini } 2103487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 2104487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 2105487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 2106487b449aSStefano Zampini *M = MT; 2107b7ce53b6SStefano Zampini } 2108b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2109b7ce53b6SStefano Zampini } 2110b7ce53b6SStefano Zampini 2111b7ce53b6SStefano Zampini /*@ 2112b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 2113b7ce53b6SStefano Zampini 2114b7ce53b6SStefano Zampini Input Parameter: 2115a2b725a8SWilliam Gropp + mat - the matrix (should be of type MATIS) 2116a2b725a8SWilliam Gropp - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 2117b7ce53b6SStefano Zampini 2118b7ce53b6SStefano Zampini Output Parameter: 2119b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 2120b7ce53b6SStefano Zampini 2121b7ce53b6SStefano Zampini Level: developer 2122b7ce53b6SStefano Zampini 212395452b02SPatrick Sanan Notes: 2124487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 2125b7ce53b6SStefano Zampini 2126487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2127b7ce53b6SStefano Zampini @*/ 2128b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2129b7ce53b6SStefano Zampini { 2130b7ce53b6SStefano Zampini PetscErrorCode ierr; 2131b7ce53b6SStefano Zampini 2132b7ce53b6SStefano Zampini PetscFunctionBegin; 2133b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2134b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2135b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2136487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2137b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2138b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 21396c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2140b7ce53b6SStefano Zampini } 2141487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2142b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2143b7ce53b6SStefano Zampini } 2144b7ce53b6SStefano Zampini 2145ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2146ad6194a2SStefano Zampini { 2147ad6194a2SStefano Zampini PetscErrorCode ierr; 2148ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2149c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2150ad6194a2SStefano Zampini Mat B,localmat; 2151ad6194a2SStefano Zampini 2152ad6194a2SStefano Zampini PetscFunctionBegin; 2153c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2154c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2155ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2156ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 21578546b261SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 21588546b261SStefano Zampini ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 21598546b261SStefano Zampini ierr = MatSetBlockSize(B,rbs == cbs ? rbs : 1);CHKERRQ(ierr); 21608546b261SStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 21618546b261SStefano Zampini ierr = MatISSetLocalMatType(B,matis->lmattype);CHKERRQ(ierr); 21628546b261SStefano Zampini ierr = MatSetLocalToGlobalMapping(B,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2163ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2164ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2165b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2166ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2167ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2168ad6194a2SStefano Zampini *newmat = B; 2169ad6194a2SStefano Zampini PetscFunctionReturn(0); 2170ad6194a2SStefano Zampini } 2171ad6194a2SStefano Zampini 2172a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 217369796d55SStefano Zampini { 217469796d55SStefano Zampini PetscErrorCode ierr; 217569796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 217669796d55SStefano Zampini PetscBool local_sym; 217769796d55SStefano Zampini 217869796d55SStefano Zampini PetscFunctionBegin; 217969796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2180b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 218169796d55SStefano Zampini PetscFunctionReturn(0); 218269796d55SStefano Zampini } 218369796d55SStefano Zampini 2184a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 218569796d55SStefano Zampini { 218669796d55SStefano Zampini PetscErrorCode ierr; 218769796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 218869796d55SStefano Zampini PetscBool local_sym; 218969796d55SStefano Zampini 219069796d55SStefano Zampini PetscFunctionBegin; 219169796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2192b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 219369796d55SStefano Zampini PetscFunctionReturn(0); 219469796d55SStefano Zampini } 219569796d55SStefano Zampini 219645471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 219745471136SStefano Zampini { 219845471136SStefano Zampini PetscErrorCode ierr; 219945471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 220045471136SStefano Zampini PetscBool local_sym; 220145471136SStefano Zampini 220245471136SStefano Zampini PetscFunctionBegin; 220345471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 220445471136SStefano Zampini *flg = PETSC_FALSE; 220545471136SStefano Zampini PetscFunctionReturn(0); 220645471136SStefano Zampini } 220745471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 220845471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 220945471136SStefano Zampini PetscFunctionReturn(0); 221045471136SStefano Zampini } 221145471136SStefano Zampini 2212a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2213b4319ba4SBarry Smith { 2214dfbe8321SBarry Smith PetscErrorCode ierr; 2215b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2216b4319ba4SBarry Smith 2217b4319ba4SBarry Smith PetscFunctionBegin; 2218b89f26deSStefano Zampini ierr = PetscFree(b->bdiag);CHKERRQ(ierr); 22198546b261SStefano Zampini ierr = PetscFree(b->lmattype);CHKERRQ(ierr); 22206bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2221e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2222e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 22236bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 22246bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 22253fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2226a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2227a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2228a8116848SStefano Zampini if (b->sf != b->csf) { 2229a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2230a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2231f03112d0SStefano Zampini } else b->csf = NULL; 223228f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 223328f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2234bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2235dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 22368546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",NULL);CHKERRQ(ierr); 2237bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2238b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2239b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 22402e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 224175d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2242f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2243487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2244487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2245487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2246487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2247487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2248487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2249487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2250b4319ba4SBarry Smith PetscFunctionReturn(0); 2251b4319ba4SBarry Smith } 2252b4319ba4SBarry Smith 2253a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2254b4319ba4SBarry Smith { 2255dfbe8321SBarry Smith PetscErrorCode ierr; 2256b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2257b4319ba4SBarry Smith PetscScalar zero = 0.0; 2258b4319ba4SBarry Smith 2259b4319ba4SBarry Smith PetscFunctionBegin; 2260b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2261e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2262e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2263b4319ba4SBarry Smith 2264b4319ba4SBarry Smith /* multiply the local matrix */ 2265b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2266b4319ba4SBarry Smith 2267b4319ba4SBarry Smith /* scatter product back into global memory */ 22682dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2269e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2270e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2271b4319ba4SBarry Smith PetscFunctionReturn(0); 2272b4319ba4SBarry Smith } 2273b4319ba4SBarry Smith 2274a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 22752e74eeadSLisandro Dalcin { 2276650997f4SStefano Zampini Vec temp_vec; 22772e74eeadSLisandro Dalcin PetscErrorCode ierr; 22782e74eeadSLisandro Dalcin 22792e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2280650997f4SStefano Zampini if (v3 != v2) { 2281650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2282650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2283650997f4SStefano Zampini } else { 2284650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2285650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2286650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2287650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2288650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2289650997f4SStefano Zampini } 22902e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22912e74eeadSLisandro Dalcin } 22922e74eeadSLisandro Dalcin 2293a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 22942e74eeadSLisandro Dalcin { 22952e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 22962e74eeadSLisandro Dalcin PetscErrorCode ierr; 22972e74eeadSLisandro Dalcin 2298e176bc59SStefano Zampini PetscFunctionBegin; 22992e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2300e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2301e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 23022e74eeadSLisandro Dalcin 23032e74eeadSLisandro Dalcin /* multiply the local matrix */ 2304e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 23052e74eeadSLisandro Dalcin 23062e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2307e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2308e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2309e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 23102e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23112e74eeadSLisandro Dalcin } 23122e74eeadSLisandro Dalcin 2313a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 23142e74eeadSLisandro Dalcin { 2315650997f4SStefano Zampini Vec temp_vec; 23162e74eeadSLisandro Dalcin PetscErrorCode ierr; 23172e74eeadSLisandro Dalcin 23182e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2319650997f4SStefano Zampini if (v3 != v2) { 2320650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2321650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2322650997f4SStefano Zampini } else { 2323650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2324650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2325650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2326650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2327650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2328650997f4SStefano Zampini } 23292e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23302e74eeadSLisandro Dalcin } 23312e74eeadSLisandro Dalcin 2332a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2333b4319ba4SBarry Smith { 2334b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2335dfbe8321SBarry Smith PetscErrorCode ierr; 2336b4319ba4SBarry Smith PetscViewer sviewer; 2337ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2338b4319ba4SBarry Smith 2339b4319ba4SBarry Smith PetscFunctionBegin; 2340ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2341ee2491ecSStefano Zampini if (isascii) { 2342ee2491ecSStefano Zampini PetscViewerFormat format; 2343ee2491ecSStefano Zampini 2344ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2345ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2346ee2491ecSStefano Zampini } 2347ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 23483f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2349b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 23503f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 23516e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2352b4319ba4SBarry Smith PetscFunctionReturn(0); 2353b4319ba4SBarry Smith } 2354b4319ba4SBarry Smith 2355b89f26deSStefano Zampini static PetscErrorCode MatInvertBlockDiagonal_IS(Mat mat,const PetscScalar **values) 2356b89f26deSStefano Zampini { 2357b89f26deSStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 2358b89f26deSStefano Zampini MPI_Datatype nodeType; 2359b89f26deSStefano Zampini const PetscScalar *lv; 2360b89f26deSStefano Zampini PetscInt bs; 2361b89f26deSStefano Zampini PetscErrorCode ierr; 2362b89f26deSStefano Zampini 2363b89f26deSStefano Zampini PetscFunctionBegin; 2364b89f26deSStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2365b89f26deSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 2366b89f26deSStefano Zampini ierr = MatInvertBlockDiagonal(is->A,&lv);CHKERRQ(ierr); 2367b89f26deSStefano Zampini if (!is->bdiag) { 2368b89f26deSStefano Zampini ierr = PetscMalloc1(bs*mat->rmap->n,&is->bdiag);CHKERRQ(ierr); 2369b89f26deSStefano Zampini } 2370b89f26deSStefano Zampini ierr = MPI_Type_contiguous(bs,MPIU_SCALAR,&nodeType);CHKERRQ(ierr); 2371b89f26deSStefano Zampini ierr = MPI_Type_commit(&nodeType);CHKERRQ(ierr); 2372b89f26deSStefano Zampini ierr = PetscSFReduceBegin(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2373b89f26deSStefano Zampini ierr = PetscSFReduceEnd(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2374b89f26deSStefano Zampini ierr = MPI_Type_free(&nodeType);CHKERRQ(ierr); 2375b89f26deSStefano Zampini if (values) *values = is->bdiag; 2376b89f26deSStefano Zampini PetscFunctionReturn(0); 2377b89f26deSStefano Zampini } 2378b89f26deSStefano Zampini 23798546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat A) 2380b4319ba4SBarry Smith { 2381e176bc59SStefano Zampini Vec cglobal,rglobal; 23828546b261SStefano Zampini IS from; 23838546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2384b89f26deSStefano Zampini PetscScalar sum; 23858546b261SStefano Zampini const PetscInt *garray; 23868546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 23878546b261SStefano Zampini PetscBool iscuda; 23888546b261SStefano Zampini PetscErrorCode ierr; 2389b4319ba4SBarry Smith 2390b4319ba4SBarry Smith PetscFunctionBegin; 23918546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nr);CHKERRQ(ierr); 23928546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->rmap->mapping,&rbs);CHKERRQ(ierr); 23938546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&nc);CHKERRQ(ierr); 23948546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->cmap->mapping,&cbs);CHKERRQ(ierr); 239570cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 239670cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 23973fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2398e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2399e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 24008546b261SStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2401b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_TRUE);CHKERRQ(ierr); 24028546b261SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)is->y,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 24038546b261SStefano Zampini if (iscuda) { 24048546b261SStefano Zampini ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 24058546b261SStefano Zampini ierr = PetscStrallocpy(VECCUDA,&A->defaultvectype);CHKERRQ(ierr); 24068546b261SStefano Zampini } 24078546b261SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 2408b470e4b4SRichard Tran Mills ierr = VecBindToCPU(rglobal,PETSC_TRUE);CHKERRQ(ierr); 24098546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 24108546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 24119448b7f1SJunchao Zhang ierr = VecScatterCreate(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 24128546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 24138546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24148546b261SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 24158546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 24168546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 24179448b7f1SJunchao Zhang ierr = VecScatterCreate(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 24188546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 24198546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24208546b261SStefano Zampini } else { 24218546b261SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 24228546b261SStefano Zampini is->cctx = is->rctx; 24238546b261SStefano Zampini } 2424b89f26deSStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 2425b89f26deSStefano Zampini 24268546b261SStefano Zampini /* interface counter vector (local) */ 24278546b261SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 2428b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_TRUE);CHKERRQ(ierr); 24298546b261SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 24308546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24318546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24328546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24338546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2434b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_FALSE);CHKERRQ(ierr); 2435b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_FALSE);CHKERRQ(ierr); 2436b89f26deSStefano Zampini 2437b89f26deSStefano Zampini /* special functions for block-diagonal matrices */ 2438b89f26deSStefano Zampini ierr = VecSum(rglobal,&sum);CHKERRQ(ierr); 2439b89f26deSStefano Zampini if ((PetscInt)(PetscRealPart(sum)) == A->rmap->N && A->rmap->N == A->cmap->N && A->rmap->mapping == A->cmap->mapping) { 2440b89f26deSStefano Zampini A->ops->invertblockdiagonal = MatInvertBlockDiagonal_IS; 2441b89f26deSStefano Zampini } else { 2442b89f26deSStefano Zampini A->ops->invertblockdiagonal = NULL; 2443b89f26deSStefano Zampini } 24448546b261SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2445b0cc1f67SStefano Zampini 2446b0cc1f67SStefano Zampini /* setup SF for general purpose shared indices based communications */ 2447b0cc1f67SStefano Zampini ierr = MatISSetUpSF_IS(A);CHKERRQ(ierr); 24488546b261SStefano Zampini PetscFunctionReturn(0); 24498546b261SStefano Zampini } 24508546b261SStefano Zampini 24518546b261SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 24528546b261SStefano Zampini { 24538546b261SStefano Zampini PetscErrorCode ierr; 24548546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 24558546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 24568546b261SStefano Zampini 24578546b261SStefano Zampini PetscFunctionBegin; 24588546b261SStefano Zampini PetscCheckSameComm(A,1,rmapping,2); 24598546b261SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 24601c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2461872cf891SStefano Zampini if (is->csf != is->sf) { 2462872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2463872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2464f03112d0SStefano Zampini } else is->csf = NULL; 246528f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 246628f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 2467b89f26deSStefano Zampini ierr = PetscFree(is->bdiag);CHKERRQ(ierr); 24683bbff08aSStefano Zampini 24693bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2470fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2471fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2472e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2473e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2474e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2475e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 24766625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 24776625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 24786625354bSStefano Zampini PetscBool same,gsame; 24796625354bSStefano Zampini 24806625354bSStefano Zampini same = PETSC_FALSE; 24816625354bSStefano Zampini if (nr == nc && cbs == rbs) { 24826625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 24836625354bSStefano Zampini 24846625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24856625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 2486580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,nr/rbs,&same);CHKERRQ(ierr); 24876625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24886625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 24896625354bSStefano Zampini } 24906625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 24916625354bSStefano Zampini if (gsame) cmapping = rmapping; 24926625354bSStefano Zampini } 249353b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 249453b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 24956625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 24966625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 24976625354bSStefano Zampini 24986625354bSStefano Zampini /* Create the local matrix A */ 2499f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 25008546b261SStefano Zampini ierr = MatSetType(is->A,is->lmattype);CHKERRQ(ierr); 2501e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2502e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 25038546b261SStefano Zampini ierr = MatSetOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 25048546b261SStefano Zampini ierr = MatAppendOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2505c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2506c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2507b4319ba4SBarry Smith 2508f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 25098546b261SStefano Zampini ierr = MatISSetUpScatters_Private(A);CHKERRQ(ierr); 2510f26d0771SStefano Zampini } 251148ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2512b4319ba4SBarry Smith PetscFunctionReturn(0); 2513b4319ba4SBarry Smith } 2514b4319ba4SBarry Smith 2515a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 25162e74eeadSLisandro Dalcin { 25172e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 25182e74eeadSLisandro Dalcin PetscErrorCode ierr; 251997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 252097563a80SStefano Zampini PetscInt i,zm,zn; 252197563a80SStefano Zampini #endif 2522f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 25232e74eeadSLisandro Dalcin 25242e74eeadSLisandro Dalcin PetscFunctionBegin; 25252e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2526f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 252797563a80SStefano Zampini /* count negative indices */ 252897563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 252997563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 25302e74eeadSLisandro Dalcin #endif 253197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 253297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 253397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 253497563a80SStefano Zampini /* count negative indices (should be the same as before) */ 253597563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 253697563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2537b4f971dfSStefano Zampini if (!is->A->rmap->mapping && zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 2538b4f971dfSStefano Zampini if (!is->A->cmap->mapping && zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 253997563a80SStefano Zampini #endif 25402e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 25412e74eeadSLisandro Dalcin PetscFunctionReturn(0); 25422e74eeadSLisandro Dalcin } 25432e74eeadSLisandro Dalcin 2544a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 254597563a80SStefano Zampini { 254697563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 254797563a80SStefano Zampini PetscErrorCode ierr; 254897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 254997563a80SStefano Zampini PetscInt i,zm,zn; 255097563a80SStefano Zampini #endif 2551f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 255297563a80SStefano Zampini 255397563a80SStefano Zampini PetscFunctionBegin; 255497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2555f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 255697563a80SStefano Zampini /* count negative indices */ 255797563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 255897563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 255997563a80SStefano Zampini #endif 256097563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 256197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 256297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 256397563a80SStefano Zampini /* count negative indices (should be the same as before) */ 256497563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 256597563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2566b4f971dfSStefano Zampini if (!is->A->rmap->mapping && zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 2567b4f971dfSStefano Zampini if (!is->A->cmap->mapping && zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 256897563a80SStefano Zampini #endif 2569d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 257097563a80SStefano Zampini PetscFunctionReturn(0); 257197563a80SStefano Zampini } 257297563a80SStefano Zampini 2573a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2574b4319ba4SBarry Smith { 2575dfbe8321SBarry Smith PetscErrorCode ierr; 2576b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2577b4319ba4SBarry Smith 2578b4319ba4SBarry Smith PetscFunctionBegin; 2579b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2580872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2581872cf891SStefano Zampini } else { 2582b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2583872cf891SStefano Zampini } 2584b4319ba4SBarry Smith PetscFunctionReturn(0); 2585b4319ba4SBarry Smith } 2586b4319ba4SBarry Smith 2587a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2588f0006bf2SLisandro Dalcin { 2589f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2590f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2591f0006bf2SLisandro Dalcin 2592f0006bf2SLisandro Dalcin PetscFunctionBegin; 2593b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2594b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2595b4f971dfSStefano Zampini PetscInt ibs,bs; 2596b4f971dfSStefano Zampini 2597b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2598b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2599b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2600b4f971dfSStefano Zampini #endif 2601b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2602b4f971dfSStefano Zampini } else { 2603f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2604b4f971dfSStefano Zampini } 2605f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2606f0006bf2SLisandro Dalcin } 2607f0006bf2SLisandro Dalcin 2608f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2609f0ae7da4SStefano Zampini { 2610f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2611f0ae7da4SStefano Zampini PetscErrorCode ierr; 2612f0ae7da4SStefano Zampini 2613f0ae7da4SStefano Zampini PetscFunctionBegin; 2614f0ae7da4SStefano Zampini if (!n) { 2615f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2616f0ae7da4SStefano Zampini } else { 2617f0ae7da4SStefano Zampini PetscInt i; 2618f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2619f0ae7da4SStefano Zampini 2620f0ae7da4SStefano Zampini if (columns) { 2621f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2622f0ae7da4SStefano Zampini } else { 2623f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2624f0ae7da4SStefano Zampini } 2625f0ae7da4SStefano Zampini if (diag != 0.) { 2626f0ae7da4SStefano Zampini const PetscScalar *array; 2627f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2628f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2629f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2630f0ae7da4SStefano Zampini } 2631f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2632f0ae7da4SStefano Zampini } 2633f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2634f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2635f0ae7da4SStefano Zampini } 2636f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2637f0ae7da4SStefano Zampini } 2638f0ae7da4SStefano Zampini 2639f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 26402e74eeadSLisandro Dalcin { 26416e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 26426e520ac8SStefano Zampini PetscInt nr,nl,len,i; 26436e520ac8SStefano Zampini PetscInt *lrows; 26442e74eeadSLisandro Dalcin PetscErrorCode ierr; 26452e74eeadSLisandro Dalcin 26462e74eeadSLisandro Dalcin PetscFunctionBegin; 2647f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2648f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2649f0ae7da4SStefano Zampini PetscBool cong; 265026b0207aSStefano Zampini 2651f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 265226b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2653268753edSStefano Zampini if (!cong && columns) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Columns can be zeroed if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 2654268753edSStefano Zampini if (!cong && diag != 0.) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Nonzero diagonal value supported if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 2655268753edSStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent, and the l2g maps be the same"); 2656f0ae7da4SStefano Zampini } 2657f0ae7da4SStefano Zampini #endif 26586e520ac8SStefano Zampini /* get locally owned rows */ 2659a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 26606e520ac8SStefano Zampini /* fix right hand side if needed */ 26616e520ac8SStefano Zampini if (x && b) { 26626e520ac8SStefano Zampini const PetscScalar *xx; 26636e520ac8SStefano Zampini PetscScalar *bb; 26646e520ac8SStefano Zampini 26656e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 26666e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 26676e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 26686e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 26696e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 26702e74eeadSLisandro Dalcin } 26716e520ac8SStefano Zampini /* get rows associated to the local matrices */ 26726e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 2673580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,nl);CHKERRQ(ierr); 2674580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,A->rmap->n);CHKERRQ(ierr); 26756e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 26766e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26776e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26786e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26796e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 26806e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2681f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 26826e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26832e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26842e74eeadSLisandro Dalcin } 26852e74eeadSLisandro Dalcin 2686f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2687b4319ba4SBarry Smith { 2688dfbe8321SBarry Smith PetscErrorCode ierr; 2689b4319ba4SBarry Smith 2690b4319ba4SBarry Smith PetscFunctionBegin; 2691f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2692f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2693f0ae7da4SStefano Zampini } 26942205254eSKarl Rupp 2695f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2696f0ae7da4SStefano Zampini { 2697f0ae7da4SStefano Zampini PetscErrorCode ierr; 2698f0ae7da4SStefano Zampini 2699f0ae7da4SStefano Zampini PetscFunctionBegin; 2700f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2701b4319ba4SBarry Smith PetscFunctionReturn(0); 2702b4319ba4SBarry Smith } 2703b4319ba4SBarry Smith 2704a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2705b4319ba4SBarry Smith { 2706b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2707dfbe8321SBarry Smith PetscErrorCode ierr; 2708b4319ba4SBarry Smith 2709b4319ba4SBarry Smith PetscFunctionBegin; 2710b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2711b4319ba4SBarry Smith PetscFunctionReturn(0); 2712b4319ba4SBarry Smith } 2713b4319ba4SBarry Smith 2714a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2715b4319ba4SBarry Smith { 2716b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2717dfbe8321SBarry Smith PetscErrorCode ierr; 2718b4319ba4SBarry Smith 2719b4319ba4SBarry Smith PetscFunctionBegin; 2720b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2721872cf891SStefano Zampini /* fix for local empty rows/cols */ 2722872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2723872cf891SStefano Zampini Mat newlA; 2724f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2725f03112d0SStefano Zampini IS nzr,nzc; 2726f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2727f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2728872cf891SStefano Zampini 2729f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2730f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2731f03112d0SStefano Zampini if (!nzr) { 2732f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2733872cf891SStefano Zampini } 2734f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2735f03112d0SStefano Zampini if (!nzc) { 2736f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2737872cf891SStefano Zampini } 2738f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2739f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2740f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2741f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2742f03112d0SStefano Zampini IS is1,is2; 2743f03112d0SStefano Zampini 2744f03112d0SStefano Zampini /* need new global l2g map */ 2745f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2746f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2747f03112d0SStefano Zampini 2748872cf891SStefano Zampini /* extract valid submatrix */ 2749f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2750f03112d0SStefano Zampini 2751f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2752f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2753f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2754f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2755872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 275672ed36d8SStefano Zampini if (is->A->rmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 275772ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 275872ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 275972ed36d8SStefano Zampini 276072ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->rmap->mapping,&nl);CHKERRQ(ierr); 276172ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 276272ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 276372ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 276472ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 276572ed36d8SStefano Zampini if (j != nr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nr); 276672ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 276772ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 276872ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 276972ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->rmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 277072ed36d8SStefano Zampini } 2771f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2772f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2773f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 277472ed36d8SStefano Zampini 2775f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2776f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2777f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2778f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 277972ed36d8SStefano Zampini if (is->A->cmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 278072ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 278172ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 278272ed36d8SStefano Zampini 278372ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->cmap->mapping,&nl);CHKERRQ(ierr); 278472ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 278572ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 278672ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 278772ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 278872ed36d8SStefano Zampini if (j != nc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nc); 278972ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 279072ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 279172ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 279272ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->cmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 279372ed36d8SStefano Zampini } 2794f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2795f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2796f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 279772ed36d8SStefano Zampini 2798f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 279972ed36d8SStefano Zampini 2800f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2801f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2802f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2803f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2804f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2805f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2806f03112d0SStefano Zampini newlA = is->A; 2807f03112d0SStefano Zampini } 2808f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2809f03112d0SStefano Zampini if (newl2g) { 2810f03112d0SStefano Zampini IS gnzr,gnzc; 2811f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2812f03112d0SStefano Zampini 2813f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2814f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2815f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2816f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2817f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2818f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2819f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2820f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2821f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2822f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2823f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2824f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2825f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2826f03112d0SStefano Zampini } 2827872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2828872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2829f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2830f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2831872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2832f03112d0SStefano Zampini } 2833b4319ba4SBarry Smith PetscFunctionReturn(0); 2834b4319ba4SBarry Smith } 2835b4319ba4SBarry Smith 2836a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2837b4319ba4SBarry Smith { 2838b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2839b4319ba4SBarry Smith 2840b4319ba4SBarry Smith PetscFunctionBegin; 2841b4319ba4SBarry Smith *local = is->A; 2842b4319ba4SBarry Smith PetscFunctionReturn(0); 2843b4319ba4SBarry Smith } 2844b4319ba4SBarry Smith 28453b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 28463b3b1effSJed Brown { 28473b3b1effSJed Brown PetscFunctionBegin; 28483b3b1effSJed Brown *local = NULL; 28493b3b1effSJed Brown PetscFunctionReturn(0); 28503b3b1effSJed Brown } 28513b3b1effSJed Brown 2852b4319ba4SBarry Smith /*@ 2853b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2854b4319ba4SBarry Smith 2855b4319ba4SBarry Smith Input Parameter: 2856b4319ba4SBarry Smith . mat - the matrix 2857b4319ba4SBarry Smith 2858b4319ba4SBarry Smith Output Parameter: 2859eb82efa4SStefano Zampini . local - the local matrix 2860b4319ba4SBarry Smith 2861b4319ba4SBarry Smith Level: advanced 2862b4319ba4SBarry Smith 2863b4319ba4SBarry Smith Notes: 2864b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2865b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2866b4319ba4SBarry Smith of the MatSetValues() operation. 2867b4319ba4SBarry Smith 28683b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 286996a6f129SJed Brown 2870b4319ba4SBarry Smith .seealso: MATIS 2871b4319ba4SBarry Smith @*/ 28727087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2873b4319ba4SBarry Smith { 28744ac538c5SBarry Smith PetscErrorCode ierr; 2875b4319ba4SBarry Smith 2876b4319ba4SBarry Smith PetscFunctionBegin; 28770700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2878b4319ba4SBarry Smith PetscValidPointer(local,2); 28794ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2880b4319ba4SBarry Smith PetscFunctionReturn(0); 2881b4319ba4SBarry Smith } 2882b4319ba4SBarry Smith 28833b3b1effSJed Brown /*@ 28843b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 28853b3b1effSJed Brown 28863b3b1effSJed Brown Input Parameter: 28873b3b1effSJed Brown . mat - the matrix 28883b3b1effSJed Brown 28893b3b1effSJed Brown Output Parameter: 28903b3b1effSJed Brown . local - the local matrix 28913b3b1effSJed Brown 28923b3b1effSJed Brown Level: advanced 28933b3b1effSJed Brown 28943b3b1effSJed Brown .seealso: MATIS 28953b3b1effSJed Brown @*/ 28963b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 28973b3b1effSJed Brown { 28983b3b1effSJed Brown PetscErrorCode ierr; 28993b3b1effSJed Brown 29003b3b1effSJed Brown PetscFunctionBegin; 29013b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29023b3b1effSJed Brown PetscValidPointer(local,2); 29033b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 29043b3b1effSJed Brown PetscFunctionReturn(0); 29053b3b1effSJed Brown } 29063b3b1effSJed Brown 29078546b261SStefano Zampini static PetscErrorCode MatISSetLocalMatType_IS(Mat mat,MatType mtype) 29088546b261SStefano Zampini { 29098546b261SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 29108546b261SStefano Zampini PetscErrorCode ierr; 29118546b261SStefano Zampini 29128546b261SStefano Zampini PetscFunctionBegin; 29138546b261SStefano Zampini if (is->A) { 29148546b261SStefano Zampini ierr = MatSetType(is->A,mtype);CHKERRQ(ierr); 29158546b261SStefano Zampini } 29168546b261SStefano Zampini ierr = PetscFree(is->lmattype);CHKERRQ(ierr); 29178546b261SStefano Zampini ierr = PetscStrallocpy(mtype,&is->lmattype);CHKERRQ(ierr); 29188546b261SStefano Zampini PetscFunctionReturn(0); 29198546b261SStefano Zampini } 29208546b261SStefano Zampini 29218546b261SStefano Zampini /*@ 29228546b261SStefano Zampini MatISSetLocalMatType - Specifies the type of local matrix 29238546b261SStefano Zampini 29248546b261SStefano Zampini Input Parameter: 2925a2b725a8SWilliam Gropp + mat - the matrix 2926a2b725a8SWilliam Gropp - mtype - the local matrix type 29278546b261SStefano Zampini 29288546b261SStefano Zampini Output Parameter: 29298546b261SStefano Zampini 29308546b261SStefano Zampini Level: advanced 29318546b261SStefano Zampini 29328546b261SStefano Zampini .seealso: MATIS, MatSetType(), MatType 29338546b261SStefano Zampini @*/ 29348546b261SStefano Zampini PetscErrorCode MatISSetLocalMatType(Mat mat,MatType mtype) 29358546b261SStefano Zampini { 29368546b261SStefano Zampini PetscErrorCode ierr; 29378546b261SStefano Zampini 29388546b261SStefano Zampini PetscFunctionBegin; 29398546b261SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29408546b261SStefano Zampini ierr = PetscUseMethod(mat,"MatISSetLocalMatType_C",(Mat,MatType),(mat,mtype));CHKERRQ(ierr); 29418546b261SStefano Zampini PetscFunctionReturn(0); 29428546b261SStefano Zampini } 29438546b261SStefano Zampini 2944a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 29453b03a366Sstefano_zampini { 29463b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 29473b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 29483b03a366Sstefano_zampini PetscErrorCode ierr; 29498546b261SStefano Zampini MatType mtype,otype; 29508546b261SStefano Zampini PetscBool sametype = PETSC_TRUE; 29513b03a366Sstefano_zampini 29523b03a366Sstefano_zampini PetscFunctionBegin; 29534e4c7dbeSStefano Zampini if (is->A) { 29543b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 29553b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2956f0ae7da4SStefano Zampini if (orows != nrows || ocols != ncols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local MATIS matrix should be of size %Dx%D (you passed a %Dx%D matrix)",orows,ocols,nrows,ncols); 29578546b261SStefano Zampini ierr = MatGetType(local,&mtype);CHKERRQ(ierr); 29588546b261SStefano Zampini ierr = MatGetType(is->A,&otype);CHKERRQ(ierr); 29598546b261SStefano Zampini ierr = PetscStrcmp(mtype,otype,&sametype);CHKERRQ(ierr); 29604e4c7dbeSStefano Zampini } 29613b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 29623b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 29633b03a366Sstefano_zampini is->A = local; 29648546b261SStefano Zampini ierr = MatGetType(is->A,&mtype);CHKERRQ(ierr); 29658546b261SStefano Zampini ierr = MatISSetLocalMatType(mat,mtype);CHKERRQ(ierr); 29668546b261SStefano Zampini if (!sametype && !is->islocalref) { 29678546b261SStefano Zampini ierr = MatISSetUpScatters_Private(mat);CHKERRQ(ierr); 29688546b261SStefano Zampini } 29693b03a366Sstefano_zampini PetscFunctionReturn(0); 29703b03a366Sstefano_zampini } 29713b03a366Sstefano_zampini 29723b03a366Sstefano_zampini /*@ 2973eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 29743b03a366Sstefano_zampini 29758546b261SStefano Zampini Collective on Mat 29768546b261SStefano Zampini 29773b03a366Sstefano_zampini Input Parameter: 2978a2b725a8SWilliam Gropp + mat - the matrix 2979a2b725a8SWilliam Gropp - local - the local matrix 29803b03a366Sstefano_zampini 29813b03a366Sstefano_zampini Output Parameter: 29823b03a366Sstefano_zampini 29833b03a366Sstefano_zampini Level: advanced 29843b03a366Sstefano_zampini 29853b03a366Sstefano_zampini Notes: 29863b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 29873b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 29883b03a366Sstefano_zampini 29893b03a366Sstefano_zampini .seealso: MATIS 29903b03a366Sstefano_zampini @*/ 29913b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 29923b03a366Sstefano_zampini { 29933b03a366Sstefano_zampini PetscErrorCode ierr; 29943b03a366Sstefano_zampini 29953b03a366Sstefano_zampini PetscFunctionBegin; 29963b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2997b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 29983b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 29993b03a366Sstefano_zampini PetscFunctionReturn(0); 30003b03a366Sstefano_zampini } 30013b03a366Sstefano_zampini 3002a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 30036726f965SBarry Smith { 30046726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30056726f965SBarry Smith PetscErrorCode ierr; 30066726f965SBarry Smith 30076726f965SBarry Smith PetscFunctionBegin; 30086726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 30096726f965SBarry Smith PetscFunctionReturn(0); 30106726f965SBarry Smith } 30116726f965SBarry Smith 3012a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 30132e74eeadSLisandro Dalcin { 30142e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30152e74eeadSLisandro Dalcin PetscErrorCode ierr; 30162e74eeadSLisandro Dalcin 30172e74eeadSLisandro Dalcin PetscFunctionBegin; 30182e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 30192e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30202e74eeadSLisandro Dalcin } 30212e74eeadSLisandro Dalcin 3022a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 30232e74eeadSLisandro Dalcin { 30242e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30252e74eeadSLisandro Dalcin PetscErrorCode ierr; 30262e74eeadSLisandro Dalcin 30272e74eeadSLisandro Dalcin PetscFunctionBegin; 30282e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 3029e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 30302e74eeadSLisandro Dalcin 30312e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 30322e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 3033e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3034e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 30352e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30362e74eeadSLisandro Dalcin } 30372e74eeadSLisandro Dalcin 3038a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 30396726f965SBarry Smith { 30406726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30416726f965SBarry Smith PetscErrorCode ierr; 30426726f965SBarry Smith 30436726f965SBarry Smith PetscFunctionBegin; 30444e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 30456726f965SBarry Smith PetscFunctionReturn(0); 30466726f965SBarry Smith } 30476726f965SBarry Smith 3048f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 3049f26d0771SStefano Zampini { 3050f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 3051f26d0771SStefano Zampini Mat_IS *x; 3052f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3053f26d0771SStefano Zampini PetscBool ismatis; 3054f26d0771SStefano Zampini #endif 3055f26d0771SStefano Zampini PetscErrorCode ierr; 3056f26d0771SStefano Zampini 3057f26d0771SStefano Zampini PetscFunctionBegin; 3058f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3059f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 3060f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 3061f26d0771SStefano Zampini #endif 3062f26d0771SStefano Zampini x = (Mat_IS*)X->data; 3063f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 3064f26d0771SStefano Zampini PetscFunctionReturn(0); 3065f26d0771SStefano Zampini } 3066f26d0771SStefano Zampini 3067f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 3068f26d0771SStefano Zampini { 3069f26d0771SStefano Zampini Mat lA; 3070f26d0771SStefano Zampini Mat_IS *matis; 3071f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 3072f26d0771SStefano Zampini IS is; 3073f26d0771SStefano Zampini const PetscInt *rg,*rl; 3074f26d0771SStefano Zampini PetscInt nrg; 3075f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 3076f26d0771SStefano Zampini PetscErrorCode ierr; 3077f26d0771SStefano Zampini 3078f26d0771SStefano Zampini PetscFunctionBegin; 3079f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3080f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3081f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3082f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 3083f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3084249c8a71SStefano Zampini for (i=0;i<nrl;i++) if (rl[i]>=nrg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row index %D -> %D greater then maximum possible %D",i,rl[i],nrg); 3085f26d0771SStefano Zampini #endif 3086f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3087f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3088f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3089f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3090f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3091f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3092f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3093f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3094f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3095f26d0771SStefano Zampini /* compute new l2g map for columns */ 3096f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 3097f26d0771SStefano Zampini const PetscInt *cg,*cl; 3098f26d0771SStefano Zampini PetscInt ncg; 3099f26d0771SStefano Zampini PetscInt ncl; 3100f26d0771SStefano Zampini 3101f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3102f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3103f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3104f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 3105f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3106249c8a71SStefano Zampini for (i=0;i<ncl;i++) if (cl[i]>=ncg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local column index %D -> %D greater then maximum possible %D",i,cl[i],ncg); 3107f26d0771SStefano Zampini #endif 3108f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3109f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3110f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3111f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3112f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3113f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3114f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3115f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3116f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3117f26d0771SStefano Zampini } else { 3118f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3119f26d0771SStefano Zampini cl2g = rl2g; 3120f26d0771SStefano Zampini } 3121f26d0771SStefano Zampini /* create the MATIS submatrix */ 3122f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3123f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3124f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3125f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3126b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3127f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3128f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3129f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3130f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3131f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3132f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3133f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3134f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3135f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3136f26d0771SStefano Zampini /* remove unsupported ops */ 3137f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3138f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3139f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3140f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3141f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3142f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3143f26d0771SStefano Zampini PetscFunctionReturn(0); 3144f26d0771SStefano Zampini } 3145f26d0771SStefano Zampini 3146872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3147872cf891SStefano Zampini { 3148872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 31498546b261SStefano Zampini char type[256]; 31508546b261SStefano Zampini PetscBool flg; 3151872cf891SStefano Zampini PetscErrorCode ierr; 3152872cf891SStefano Zampini 3153872cf891SStefano Zampini PetscFunctionBegin; 3154872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3155f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 315675d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 31578546b261SStefano Zampini ierr = PetscOptionsFList("-matis_localmat_type","Matrix type","MatISSetLocalMatType",MatList,a->lmattype,type,256,&flg);CHKERRQ(ierr); 31588546b261SStefano Zampini if (flg) { 31598546b261SStefano Zampini ierr = MatISSetLocalMatType(A,type);CHKERRQ(ierr); 31608546b261SStefano Zampini } 31618546b261SStefano Zampini if (a->A) { 31628546b261SStefano Zampini ierr = MatSetFromOptions(a->A);CHKERRQ(ierr); 31638546b261SStefano Zampini } 31640af67c1bSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 3165872cf891SStefano Zampini PetscFunctionReturn(0); 3166872cf891SStefano Zampini } 3167872cf891SStefano Zampini 3168284134d9SBarry Smith /*@ 31693c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3170284134d9SBarry Smith process but not across processes. 3171284134d9SBarry Smith 3172284134d9SBarry Smith Input Parameters: 3173284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3174e176bc59SStefano Zampini . bs - block size of the matrix 3175df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3176e176bc59SStefano Zampini . rmap - local to global map for rows 3177e176bc59SStefano Zampini - cmap - local to global map for cols 3178284134d9SBarry Smith 3179284134d9SBarry Smith Output Parameter: 3180284134d9SBarry Smith . A - the resulting matrix 3181284134d9SBarry Smith 31828e6c10adSSatish Balay Level: advanced 31838e6c10adSSatish Balay 318495452b02SPatrick Sanan Notes: 318595452b02SPatrick Sanan See MATIS for more details. 31866fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 31876fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 31883c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 3189284134d9SBarry Smith 3190284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3191284134d9SBarry Smith @*/ 3192e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3193284134d9SBarry Smith { 3194284134d9SBarry Smith PetscErrorCode ierr; 3195284134d9SBarry Smith 3196284134d9SBarry Smith PetscFunctionBegin; 31976fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 3198284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3199284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 32006fdf41d1SStefano Zampini if (bs > 0) { 3201284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 32026fdf41d1SStefano Zampini } 3203284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3204e176bc59SStefano Zampini if (rmap && cmap) { 3205e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3206e176bc59SStefano Zampini } else if (!rmap) { 3207e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 3208e176bc59SStefano Zampini } else { 3209e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 3210e176bc59SStefano Zampini } 3211284134d9SBarry Smith PetscFunctionReturn(0); 3212284134d9SBarry Smith } 3213284134d9SBarry Smith 3214b4319ba4SBarry Smith /*MC 3215f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3216b89f26deSStefano Zampini This stores the matrices in globally unassembled form. Each processor assembles only its local Neumann problem and the parallel matrix vector 3217b4319ba4SBarry Smith product is handled "implicitly". 3218b4319ba4SBarry Smith 3219b4319ba4SBarry Smith Options Database Keys: 322075d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 322175d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 322275d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3223b4319ba4SBarry Smith 322495452b02SPatrick Sanan Notes: 322595452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3226b4319ba4SBarry Smith 3227b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3228b4319ba4SBarry Smith 3229b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3230eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3231b4319ba4SBarry Smith 3232b4319ba4SBarry Smith Level: advanced 3233b4319ba4SBarry Smith 3234f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3235b4319ba4SBarry Smith 3236b4319ba4SBarry Smith M*/ 3237b4319ba4SBarry Smith 32388cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3239b4319ba4SBarry Smith { 3240dfbe8321SBarry Smith PetscErrorCode ierr; 3241b4319ba4SBarry Smith Mat_IS *b; 3242b4319ba4SBarry Smith 3243b4319ba4SBarry Smith PetscFunctionBegin; 3244b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 32458546b261SStefano Zampini ierr = PetscStrallocpy(MATAIJ,&b->lmattype);CHKERRQ(ierr); 3246b4319ba4SBarry Smith A->data = (void*)b; 3247b4319ba4SBarry Smith 3248e176bc59SStefano Zampini /* matrix ops */ 3249e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3250b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 32512e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 32522e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 32532e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3254b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3255b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 32562e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 325798921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3258b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3259f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 32602e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3261f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3262b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3263b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3264b4319ba4SBarry Smith A->ops->view = MatView_IS; 32656726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 32662e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 32672e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 32686726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 326969796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 327069796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 327145471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3272ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 32736bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 32742b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3275659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 32767dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3277f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 32783fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 32793fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3280d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 32817fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3282ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3283872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3284b4319ba4SBarry Smith 3285b7ce53b6SStefano Zampini /* special MATIS functions */ 32868546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",MatISSetLocalMatType_IS);CHKERRQ(ierr); 3287bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 32883b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3289bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3290487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 32912e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 329275d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3293f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3294487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3295487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3296487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3297487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3298487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3299487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3300487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 330117667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3302b4319ba4SBarry Smith PetscFunctionReturn(0); 3303b4319ba4SBarry Smith } 3304