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) { 7175d48cdbSStefano Zampini 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 16475d48cdbSStefano Zampini 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); 17875d48cdbSStefano Zampini ierr = MatCreate(comm,C);CHKERRQ(ierr); 17975d48cdbSStefano Zampini ierr = MatSetType(*C,MATIS);CHKERRQ(ierr); 1808546b261SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1818546b261SStefano Zampini ierr = MatGetType(lA,&lmtype);CHKERRQ(ierr); 1828546b261SStefano Zampini ierr = MatISSetLocalMatType(*C,lmtype);CHKERRQ(ierr); 18375d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 18475d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 18575d48cdbSStefano Zampini ierr = MatSetSizes(*C,dc,dc,N,N);CHKERRQ(ierr); 18675d48cdbSStefano Zampini /* Not sure about this 18775d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18875d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18975d48cdbSStefano Zampini */ 19075d48cdbSStefano Zampini 19175d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 19275d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 19375d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 19475d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 19575d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(*C),"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19775d48cdbSStefano Zampini ptap->fill = fill; 19875d48cdbSStefano Zampini 19975d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 20075d48cdbSStefano Zampini 20175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 20575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20675d48cdbSStefano Zampini 20775d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20875d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 21075d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 21175d48cdbSStefano Zampini 21275d48cdbSStefano Zampini Crl2g = NULL; 21375d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 21475d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 21575d48cdbSStefano Zampini PetscInt N1,ibs1; 21675d48cdbSStefano Zampini 21775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21875d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 22175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 22275d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 22375d48cdbSStefano Zampini const PetscInt *i1,*i2; 22475d48cdbSStefano Zampini 22575d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22675d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 227580bdb30SBarry Smith ierr = PetscArraycmp(i1,i2,N,&lsame);CHKERRQ(ierr); 22875d48cdbSStefano Zampini } 22975d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 23075d48cdbSStefano Zampini if (same) { 23175d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 23275d48cdbSStefano Zampini } else { 23375d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 23475d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 23575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23675d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini } 23975d48cdbSStefano Zampini /* Not sure about this 24075d48cdbSStefano Zampini if (!Crl2g) { 24175d48cdbSStefano Zampini ierr = MatGetBlockSize(*C,&ibs);CHKERRQ(ierr); 24275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 24375d48cdbSStefano Zampini } 24475d48cdbSStefano Zampini */ 24575d48cdbSStefano Zampini ierr = MatSetLocalToGlobalMapping(*C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24875d48cdbSStefano Zampini 24975d48cdbSStefano Zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 25075d48cdbSStefano Zampini PetscFunctionReturn(0); 25175d48cdbSStefano Zampini } 25275d48cdbSStefano Zampini 25375d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 25475d48cdbSStefano Zampini { 25575d48cdbSStefano Zampini PetscErrorCode ierr; 25675d48cdbSStefano Zampini 25775d48cdbSStefano Zampini PetscFunctionBegin; 25875d48cdbSStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 25975d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 26075d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 26175d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 26275d48cdbSStefano Zampini } 26375d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26475d48cdbSStefano Zampini ierr = ((*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 26575d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26675d48cdbSStefano Zampini PetscFunctionReturn(0); 26775d48cdbSStefano Zampini } 26875d48cdbSStefano Zampini 2695b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2705b003df0Sstefano_zampini { 2715b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2725b003df0Sstefano_zampini PetscInt i; 2735b003df0Sstefano_zampini PetscErrorCode ierr; 2745b003df0Sstefano_zampini 275ab4d48faSStefano Zampini PetscFunctionBegin; 2765b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2775b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2785b003df0Sstefano_zampini } 2795b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2805b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2815b003df0Sstefano_zampini } 2825b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 2835b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 2845b003df0Sstefano_zampini PetscFunctionReturn(0); 2855b003df0Sstefano_zampini } 286a72627d2SStefano Zampini 287c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2886989cf23SStefano Zampini { 289c9225affSStefano Zampini Mat B,lB; 290c9225affSStefano Zampini PetscErrorCode ierr; 291c9225affSStefano Zampini 292c9225affSStefano Zampini PetscFunctionBegin; 293c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 294c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 295c9225affSStefano Zampini PetscInt bs; 296c9225affSStefano Zampini IS is; 297c9225affSStefano Zampini 298c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 299c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 300c9225affSStefano Zampini if (bs > 1) { 301c9225affSStefano Zampini IS is2; 302c9225affSStefano Zampini PetscInt i,*aux; 303c9225affSStefano Zampini 304c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 305c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 306c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 307c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 308c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 309c9225affSStefano Zampini is = is2; 310c9225affSStefano Zampini } 311c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 312c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 313c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 314c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 315c9225affSStefano Zampini if (bs > 1) { 316c9225affSStefano Zampini IS is2; 317c9225affSStefano Zampini PetscInt i,*aux; 318c9225affSStefano Zampini 319c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 320c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 321c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 322c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 323c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 324c9225affSStefano Zampini is = is2; 325c9225affSStefano Zampini } 326c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 327c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 328c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 329c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 330c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 331c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 332c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 333c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 334c9225affSStefano Zampini } else { 335c9225affSStefano Zampini B = *newmat; 336c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 337c9225affSStefano Zampini lB = A; 338c9225affSStefano Zampini } 339c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 340c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 341c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 343c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 344c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 345c9225affSStefano Zampini } 346c9225affSStefano Zampini PetscFunctionReturn(0); 347c9225affSStefano Zampini } 348c9225affSStefano Zampini 349c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 350c9225affSStefano Zampini { 351c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 352c9225affSStefano Zampini PetscScalar *aa; 353c9225affSStefano Zampini const PetscInt *ii,*jj; 354c9225affSStefano Zampini PetscInt i,n,m; 355fabe8965SStefano Zampini PetscInt *ecount,**eneighs; 356c9225affSStefano Zampini PetscBool flg; 357c9225affSStefano Zampini PetscErrorCode ierr; 358c9225affSStefano Zampini 359c9225affSStefano Zampini PetscFunctionBegin; 360c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 361c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 362fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 363c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 364c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 365c9225affSStefano Zampini for (i=0;i<n;i++) { 366fabe8965SStefano Zampini if (ecount[i] > 1) { 367c9225affSStefano Zampini PetscInt j; 368c9225affSStefano Zampini 369c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 370c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 371fabe8965SStefano Zampini PetscReal scal = 0.0; 372c9225affSStefano Zampini 373c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 374c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 375c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 376c9225affSStefano Zampini } 377c9225affSStefano Zampini } 378fabe8965SStefano Zampini if (scal) aa[j] /= scal; 379c9225affSStefano Zampini } 380c9225affSStefano Zampini } 381c9225affSStefano Zampini } 382fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(A->rmap->mapping,&n,&ecount,&eneighs);CHKERRQ(ierr); 383c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 384c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 385c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 386c9225affSStefano Zampini PetscFunctionReturn(0); 387c9225affSStefano Zampini } 388c9225affSStefano Zampini 389fabe8965SStefano Zampini typedef enum {MAT_IS_DISASSEMBLE_L2G_NATURAL,MAT_IS_DISASSEMBLE_L2G_MAT, MAT_IS_DISASSEMBLE_L2G_ND} MatISDisassemblel2gType; 390fabe8965SStefano Zampini 391c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 392c9225affSStefano Zampini { 393fabe8965SStefano Zampini Mat Ad,Ao; 394fabe8965SStefano Zampini IS is,ndmap,ndsub; 395c9225affSStefano Zampini MPI_Comm comm; 396fabe8965SStefano Zampini const PetscInt *garray,*ndmapi; 397fabe8965SStefano Zampini PetscInt bs,i,cnt,nl,*ncount,*ndmapc; 398fabe8965SStefano Zampini PetscBool ismpiaij,ismpibaij; 399fabe8965SStefano Zampini const char *const MatISDisassemblel2gTypes[] = {"NATURAL","MAT","ND","MatISDisassemblel2gType","MAT_IS_DISASSEMBLE_L2G_",0}; 400fabe8965SStefano Zampini MatISDisassemblel2gType mode = MAT_IS_DISASSEMBLE_L2G_NATURAL; 401fabe8965SStefano Zampini MatPartitioning part; 402fabe8965SStefano Zampini PetscSF sf; 403c9225affSStefano Zampini PetscErrorCode ierr; 404c9225affSStefano Zampini 405c9225affSStefano Zampini PetscFunctionBegin; 406fabe8965SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MatIS l2g disassembling options","Mat");CHKERRQ(ierr); 407fabe8965SStefano 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); 408fabe8965SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 409fabe8965SStefano Zampini if (mode == MAT_IS_DISASSEMBLE_L2G_MAT) { 410c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 411c9225affSStefano Zampini PetscFunctionReturn(0); 412c9225affSStefano Zampini } 413c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 414b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 415b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 416c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 417fabe8965SStefano Zampini switch (mode) { 418fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_ND: 419fabe8965SStefano Zampini ierr = MatPartitioningCreate(comm,&part);CHKERRQ(ierr); 420fabe8965SStefano Zampini ierr = MatPartitioningSetAdjacency(part,A);CHKERRQ(ierr); 421fabe8965SStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)part,((PetscObject)A)->prefix);CHKERRQ(ierr); 422fabe8965SStefano Zampini ierr = MatPartitioningSetFromOptions(part);CHKERRQ(ierr); 423fabe8965SStefano Zampini ierr = MatPartitioningApplyND(part,&ndmap);CHKERRQ(ierr); 424fabe8965SStefano Zampini ierr = MatPartitioningDestroy(&part);CHKERRQ(ierr); 425fabe8965SStefano Zampini ierr = ISBuildTwoSided(ndmap,NULL,&ndsub);CHKERRQ(ierr); 426fabe8965SStefano Zampini ierr = MatMPIAIJSetUseScalableIncreaseOverlap(A,PETSC_TRUE);CHKERRQ(ierr); 427fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,1,&ndsub,1);CHKERRQ(ierr); 428fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ndsub,l2g);CHKERRQ(ierr); 429fabe8965SStefano Zampini 430fabe8965SStefano Zampini /* it may happen that a separator node is not properly shared */ 431fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(*l2g,&nl,&ncount,NULL);CHKERRQ(ierr); 432fabe8965SStefano Zampini ierr = PetscSFCreate(comm,&sf);CHKERRQ(ierr); 433fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(*l2g,&garray);CHKERRQ(ierr); 434fabe8965SStefano Zampini ierr = PetscSFSetGraphLayout(sf,A->rmap,nl,NULL,PETSC_OWN_POINTER,garray);CHKERRQ(ierr); 435fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(*l2g,&garray);CHKERRQ(ierr); 436fabe8965SStefano Zampini ierr = PetscCalloc1(A->rmap->n,&ndmapc);CHKERRQ(ierr); 437fabe8965SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 438fabe8965SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,ncount,ndmapc,MPIU_REPLACE);CHKERRQ(ierr); 439fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(*l2g,NULL,&ncount,NULL);CHKERRQ(ierr); 440fabe8965SStefano Zampini ierr = ISGetIndices(ndmap,&ndmapi);CHKERRQ(ierr); 441fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 442fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) 443fabe8965SStefano Zampini cnt++; 444fabe8965SStefano Zampini 445fabe8965SStefano Zampini ierr = MPIU_Allreduce(&cnt,&i,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 446fabe8965SStefano Zampini if (i) { /* we detected isolated separator nodes */ 447fabe8965SStefano Zampini Mat A2,A3; 448fabe8965SStefano Zampini IS *workis,is2; 449fabe8965SStefano Zampini PetscScalar *vals; 450fabe8965SStefano Zampini PetscInt gcnt = i,*dnz,*onz,j,*lndmapi; 451fabe8965SStefano Zampini ISLocalToGlobalMapping ll2g; 452fabe8965SStefano Zampini PetscBool flg; 453fabe8965SStefano Zampini const PetscInt *ii,*jj; 454fabe8965SStefano Zampini 455fabe8965SStefano Zampini /* communicate global id of separators */ 456fabe8965SStefano Zampini ierr = MatPreallocateInitialize(comm,A->rmap->n,A->cmap->n,dnz,onz);CHKERRQ(ierr); 457fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) 458fabe8965SStefano Zampini dnz[i] = ndmapi[i] < 0 ? i + A->rmap->rstart : -1; 459fabe8965SStefano Zampini 460fabe8965SStefano Zampini ierr = PetscMalloc1(nl,&lndmapi);CHKERRQ(ierr); 461fabe8965SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 462fabe8965SStefano Zampini 463fabe8965SStefano Zampini /* compute adjacency of isolated separators node */ 464fabe8965SStefano Zampini ierr = PetscMalloc1(gcnt,&workis);CHKERRQ(ierr); 465fabe8965SStefano Zampini for (i = 0, cnt = 0; i < A->rmap->n; i++) { 466fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 467fabe8965SStefano Zampini ierr = ISCreateStride(comm,1,i+A->rmap->rstart,1,&workis[cnt++]);CHKERRQ(ierr); 468fabe8965SStefano Zampini } 469fabe8965SStefano Zampini } 470fabe8965SStefano Zampini for (i = cnt; i < gcnt; i++) { 471fabe8965SStefano Zampini ierr = ISCreateStride(comm,0,0,1,&workis[i]);CHKERRQ(ierr); 472fabe8965SStefano Zampini } 473fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 474fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"ISOLATED");CHKERRQ(ierr); 475fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 476fabe8965SStefano Zampini } 477fabe8965SStefano Zampini 478fabe8965SStefano Zampini /* no communications since all the ISes correspond to locally owned rows */ 479fabe8965SStefano Zampini ierr = MatIncreaseOverlap(A,gcnt,workis,1);CHKERRQ(ierr); 480fabe8965SStefano Zampini 481fabe8965SStefano Zampini /* end communicate global id of separators */ 482fabe8965SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,dnz,lndmapi);CHKERRQ(ierr); 483fabe8965SStefano Zampini 484fabe8965SStefano Zampini /* communicate new layers : create a matrix and transpose it */ 485580bdb30SBarry Smith ierr = PetscArrayzero(dnz,A->rmap->n);CHKERRQ(ierr); 486580bdb30SBarry Smith ierr = PetscArrayzero(onz,A->rmap->n);CHKERRQ(ierr); 487fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) { 488fabe8965SStefano Zampini if (ndmapi[i] < 0 && ndmapc[i] < 2) { 489fabe8965SStefano Zampini const PetscInt* idxs; 490fabe8965SStefano Zampini PetscInt s; 491fabe8965SStefano Zampini 492fabe8965SStefano Zampini ierr = ISGetLocalSize(workis[j],&s);CHKERRQ(ierr); 493fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 494fabe8965SStefano Zampini ierr = MatPreallocateSet(i+A->rmap->rstart,s,idxs,dnz,onz);CHKERRQ(ierr); 495fabe8965SStefano Zampini j++; 496fabe8965SStefano Zampini } 497fabe8965SStefano Zampini } 498fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 499fabe8965SStefano Zampini 500fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 501fabe8965SStefano Zampini ierr = PetscObjectSetName((PetscObject)workis[i],"EXTENDED");CHKERRQ(ierr); 502fabe8965SStefano Zampini ierr = ISViewFromOptions(workis[i],NULL,"-view_isolated_separators");CHKERRQ(ierr); 503fabe8965SStefano Zampini } 504fabe8965SStefano Zampini 505fabe8965SStefano Zampini for (i = 0, j = 0; i < A->rmap->n; i++) j = PetscMax(j,dnz[i]+onz[i]); 506fabe8965SStefano Zampini ierr = PetscMalloc1(j,&vals);CHKERRQ(ierr); 507fabe8965SStefano Zampini for (i = 0; i < j; i++) vals[i] = 1.0; 508fabe8965SStefano Zampini 509fabe8965SStefano Zampini ierr = MatCreate(comm,&A2);CHKERRQ(ierr); 510fabe8965SStefano Zampini ierr = MatSetType(A2,MATMPIAIJ);CHKERRQ(ierr); 511fabe8965SStefano Zampini ierr = MatSetSizes(A2,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 512fabe8965SStefano Zampini ierr = MatMPIAIJSetPreallocation(A2,0,dnz,0,onz);CHKERRQ(ierr); 513fabe8965SStefano Zampini ierr = MatSetOption(A2,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 514fabe8965SStefano Zampini for (i = 0, j = 0; i < A2->rmap->n; i++) { 515fabe8965SStefano Zampini PetscInt row = i+A2->rmap->rstart,s = dnz[i] + onz[i]; 516fabe8965SStefano Zampini const PetscInt* idxs; 517fabe8965SStefano Zampini 518fabe8965SStefano Zampini if (s) { 519fabe8965SStefano Zampini ierr = ISGetIndices(workis[j],&idxs);CHKERRQ(ierr); 520fabe8965SStefano Zampini ierr = MatSetValues(A2,1,&row,s,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 521fabe8965SStefano Zampini ierr = ISRestoreIndices(workis[j],&idxs);CHKERRQ(ierr); 522fabe8965SStefano Zampini j++; 523fabe8965SStefano Zampini } 524fabe8965SStefano Zampini } 525fabe8965SStefano Zampini if (j != cnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected local count %D != %D",j,cnt); 526fabe8965SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 527fabe8965SStefano Zampini ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 528fabe8965SStefano Zampini ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 529fabe8965SStefano Zampini ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 530fabe8965SStefano Zampini 531fabe8965SStefano Zampini /* extract submatrix corresponding to the coupling "owned separators" x "isolated separators" */ 532fabe8965SStefano Zampini for (i = 0, j = 0; i < nl; i++) 533fabe8965SStefano Zampini if (lndmapi[i] >= 0) lndmapi[j++] = lndmapi[i]; 534fabe8965SStefano Zampini ierr = ISCreateGeneral(comm,j,lndmapi,PETSC_USE_POINTER,&is);CHKERRQ(ierr); 535fabe8965SStefano Zampini ierr = MatMPIAIJGetLocalMatCondensed(A2,MAT_INITIAL_MATRIX,&is,NULL,&A3);CHKERRQ(ierr); 536fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 537fabe8965SStefano Zampini ierr = MatDestroy(&A2);CHKERRQ(ierr); 538fabe8965SStefano Zampini 539fabe8965SStefano Zampini /* extend local to global map to include connected isolated separators */ 540fabe8965SStefano Zampini ierr = PetscObjectQuery((PetscObject)A3,"_petsc_GetLocalMatCondensed_iscol",(PetscObject*)&is);CHKERRQ(ierr); 541fabe8965SStefano Zampini if (!is) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing column map"); 542fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&ll2g);CHKERRQ(ierr); 543fabe8965SStefano Zampini ierr = MatGetRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 544fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 545fabe8965SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,ii[i],jj,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 546fabe8965SStefano Zampini ierr = MatRestoreRowIJ(A3,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&flg);CHKERRQ(ierr); 547fabe8965SStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 548fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(ll2g,is,&is2);CHKERRQ(ierr); 549fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 550fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ll2g);CHKERRQ(ierr); 551fabe8965SStefano Zampini 552fabe8965SStefano Zampini /* add new nodes to the local-to-global map */ 553fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(l2g);CHKERRQ(ierr); 554fabe8965SStefano Zampini ierr = ISExpand(ndsub,is2,&is);CHKERRQ(ierr); 555fabe8965SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 556fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 557fabe8965SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 558fabe8965SStefano Zampini 559fabe8965SStefano Zampini ierr = MatDestroy(&A3);CHKERRQ(ierr); 560fabe8965SStefano Zampini ierr = PetscFree(lndmapi);CHKERRQ(ierr); 561fabe8965SStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 562fabe8965SStefano Zampini for (i = 0; i < gcnt; i++) { 563fabe8965SStefano Zampini ierr = ISDestroy(&workis[i]);CHKERRQ(ierr); 564fabe8965SStefano Zampini } 565fabe8965SStefano Zampini ierr = PetscFree(workis);CHKERRQ(ierr); 566fabe8965SStefano Zampini } 567fabe8965SStefano Zampini ierr = ISRestoreIndices(ndmap,&ndmapi);CHKERRQ(ierr); 568fabe8965SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 569fabe8965SStefano Zampini ierr = PetscFree(ndmapc);CHKERRQ(ierr); 570fabe8965SStefano Zampini ierr = ISDestroy(&ndmap);CHKERRQ(ierr); 571fabe8965SStefano Zampini ierr = ISDestroy(&ndsub);CHKERRQ(ierr); 572fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(*l2g,bs);CHKERRQ(ierr); 573fabe8965SStefano Zampini ierr = ISLocalToGlobalMappingViewFromOptions(*l2g,NULL,"-matis_nd_l2g_view");CHKERRQ(ierr); 574fabe8965SStefano Zampini break; 575fabe8965SStefano Zampini case MAT_IS_DISASSEMBLE_L2G_NATURAL: 576fabe8965SStefano Zampini if (ismpiaij) { 577fabe8965SStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 578fabe8965SStefano Zampini } else if (ismpibaij) { 579fabe8965SStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 580c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 581c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 582c9225affSStefano Zampini if (A->rmap->n) { 583fabe8965SStefano Zampini PetscInt dc,oc,stc,*aux; 584c9225affSStefano Zampini 585c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 586c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 587c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 588c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 589c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 590c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 591c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 592c9225affSStefano Zampini } else { 593c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 594c9225affSStefano Zampini } 595c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 596c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 597fabe8965SStefano Zampini break; 598fabe8965SStefano Zampini default: 599fabe8965SStefano Zampini SETERRQ1(comm,PETSC_ERR_ARG_WRONG,"Unsupported l2g disassembling type %D",mode); 600c9225affSStefano Zampini } 601c9225affSStefano Zampini PetscFunctionReturn(0); 602c9225affSStefano Zampini } 603c9225affSStefano Zampini 604c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 605c9225affSStefano Zampini { 606c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 6076989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 6086989cf23SStefano Zampini IS is; 6096989cf23SStefano Zampini MPI_Comm comm; 6106989cf23SStefano Zampini void *ptrs[2]; 6116989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 612c9225affSStefano Zampini const PetscInt *garray; 6136989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 614c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 615c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 6166989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 617c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 618c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 619c9225affSStefano Zampini PetscMPIInt size; 6206989cf23SStefano Zampini PetscErrorCode ierr; 6216989cf23SStefano Zampini 622ab4d48faSStefano Zampini PetscFunctionBegin; 6236989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 624c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 625c9225affSStefano Zampini if (size == 1) { 626c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 627c9225affSStefano Zampini PetscFunctionReturn(0); 628c9225affSStefano Zampini } 629c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 630c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 631c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 632c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 633c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 634c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 635c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 636c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 637c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 638c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 639c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 640c9225affSStefano Zampini } 641c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 642c9225affSStefano Zampini Mat *newlA, lA; 643c9225affSStefano Zampini IS rows, cols; 644c9225affSStefano Zampini const PetscInt *ridx, *cidx; 645c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 646c9225affSStefano Zampini 647c9225affSStefano Zampini if (!B) B = *newmat; 648c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 649c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 650c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 651c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 652c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 653c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 654c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 655c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 656c9225affSStefano Zampini if (rl2g != cl2g) { 657c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 658c9225affSStefano Zampini } else { 659c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 660c9225affSStefano Zampini cols = rows; 661c9225affSStefano Zampini } 662c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 663c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 664c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 665c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 666c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 667c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 668c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 669c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 670c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 671c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 672c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 673c9225affSStefano Zampini } 674c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 675c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 676c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 677c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 678c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 679c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 680c9225affSStefano Zampini else *newmat = B; 681c9225affSStefano Zampini PetscFunctionReturn(0); 682c9225affSStefano Zampini } 683c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 684b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 685b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 686c9225affSStefano Zampini if (ismpiaij) { 687c9225affSStefano Zampini bs = 1; 688c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 689c9225affSStefano Zampini } else if (ismpibaij) { 690c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 691c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 692c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 693c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 694c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 695c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 696c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 697c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 6986989cf23SStefano Zampini 6996989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 7006989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 7016989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 7026989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 703c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 704c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 705c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 706c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 707c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 708c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 709c9225affSStefano Zampini /* store original pointers to be restored later */ 710c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 7116989cf23SStefano Zampini 7126989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 713c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 714c9225affSStefano Zampini if (bs > 1) { 715c9225affSStefano Zampini IS is2; 716c9225affSStefano Zampini 717c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 718c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 719c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 720c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 721c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 722c9225affSStefano Zampini is = is2; 723c9225affSStefano Zampini } 7246989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 7256989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 726e363d98aSStefano Zampini if (dr) { 727c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 728c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 729c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 730c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 731e363d98aSStefano Zampini lc = dc+oc; 732e363d98aSStefano Zampini } else { 733c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 734e363d98aSStefano Zampini lc = 0; 735e363d98aSStefano Zampini } 7366989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 7376989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 7386989cf23SStefano Zampini 7396989cf23SStefano Zampini /* create MATIS object */ 740c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 741c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 742c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 743c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 744c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 7456989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7466989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7476989cf23SStefano Zampini 7486989cf23SStefano Zampini /* merge local matrices */ 7496989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 7506989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 7516989cf23SStefano Zampini ii = aux; 7526989cf23SStefano Zampini jj = aux+dr+1; 7536989cf23SStefano Zampini aa = data; 7546989cf23SStefano Zampini *ii = *(di++) + *(oi++); 7556989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 7566989cf23SStefano Zampini { 7576989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 7586989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 7596989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 7606989cf23SStefano Zampini } 7616989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 762c9225affSStefano Zampini 763c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 764c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 765c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 766c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 767c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 768c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 769c9225affSStefano Zampini 7706989cf23SStefano Zampini ii = aux; 7716989cf23SStefano Zampini jj = aux+dr+1; 7726989cf23SStefano Zampini aa = data; 773e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 7746989cf23SStefano Zampini 7756989cf23SStefano Zampini /* create containers to destroy the data */ 7766989cf23SStefano Zampini ptrs[0] = aux; 7776989cf23SStefano Zampini ptrs[1] = data; 7786989cf23SStefano Zampini for (i=0; i<2; i++) { 7796989cf23SStefano Zampini PetscContainer c; 7806989cf23SStefano Zampini 7816989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 7826989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 783b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 7846989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 7856989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 7866989cf23SStefano Zampini } 787c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 788c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 789c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 790c9225affSStefano Zampini } 7916989cf23SStefano Zampini 7926989cf23SStefano Zampini /* finalize matrix */ 793c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 7946989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 795c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 796c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 797c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 798c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 799c9225affSStefano Zampini } else *newmat = B; 8006989cf23SStefano Zampini PetscFunctionReturn(0); 8016989cf23SStefano Zampini } 8026989cf23SStefano Zampini 8035e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 8045e3038f0Sstefano_zampini { 8055e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 8065e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 8075e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 8085e3038f0Sstefano_zampini MPI_Comm comm; 8095b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 8105b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 8119e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 8125e3038f0Sstefano_zampini PetscErrorCode ierr; 8135e3038f0Sstefano_zampini 814ab4d48faSStefano Zampini PetscFunctionBegin; 8155e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 8165e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 8175e3038f0Sstefano_zampini rnest = NULL; 8185e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 8195e3038f0Sstefano_zampini PetscBool ismatis,isnest; 8205e3038f0Sstefano_zampini 8215e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 822a32993e3SJed Brown if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name); 8235e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 8245e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 8255e3038f0Sstefano_zampini if (isnest) { 8265e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 8275e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 8285e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 8295e3038f0Sstefano_zampini } 8305e3038f0Sstefano_zampini } 8315e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 8325b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 833071fcb05SBarry Smith ierr = PetscCalloc6(nr,&isrow,nc,&iscol,nr,&islrow,nc,&islcol,nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 8345e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 8355e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8365e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8375e3038f0Sstefano_zampini PetscBool ismatis; 8389e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 8395e3038f0Sstefano_zampini 8405e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 8415e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8425e3038f0Sstefano_zampini 8435e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 8449e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 8459e7b2b25Sstefano_zampini if (istrans[ij]) { 8469e7b2b25Sstefano_zampini Mat T,lT; 8479e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8489e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 8499e7b2b25Sstefano_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); 8509e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 8519e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 8529e7b2b25Sstefano_zampini } else { 8535e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 8545e3038f0Sstefano_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); 8559e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 8569e7b2b25Sstefano_zampini } 8575e3038f0Sstefano_zampini 8585e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 8595e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 8609e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 8615e3038f0Sstefano_zampini if (!l1 || !l2) continue; 8625e3038f0Sstefano_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); 8635e3038f0Sstefano_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); 8645e3038f0Sstefano_zampini lr[i] = l1; 8655e3038f0Sstefano_zampini lc[j] = l2; 8665e3038f0Sstefano_zampini 8675e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 8685e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 8695e3038f0Sstefano_zampini } 8705e3038f0Sstefano_zampini } 8715e3038f0Sstefano_zampini 8725e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 8735e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 8745e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 8755e3038f0Sstefano_zampini rl2g = NULL; 8765e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 8775e3038f0Sstefano_zampini PetscInt n1,n2; 8785e3038f0Sstefano_zampini 8795e3038f0Sstefano_zampini if (!nest[i][j]) continue; 8809e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8819e7b2b25Sstefano_zampini Mat T; 8829e7b2b25Sstefano_zampini 8839e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 8849e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 8859e7b2b25Sstefano_zampini } else { 8865e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 8879e7b2b25Sstefano_zampini } 8885e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 8895e3038f0Sstefano_zampini if (!n1) continue; 8905e3038f0Sstefano_zampini if (!rl2g) { 8915e3038f0Sstefano_zampini rl2g = cl2g; 8925e3038f0Sstefano_zampini } else { 8935e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 8945e3038f0Sstefano_zampini PetscBool same; 8955e3038f0Sstefano_zampini 8965e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 8975e3038f0Sstefano_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); 8985e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 8995e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 900580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9015e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9025e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9035e3038f0Sstefano_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); 9045e3038f0Sstefano_zampini } 9055e3038f0Sstefano_zampini } 9065e3038f0Sstefano_zampini } 9075e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 9085e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 9095e3038f0Sstefano_zampini rl2g = NULL; 9105e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 9115e3038f0Sstefano_zampini PetscInt n1,n2; 9125e3038f0Sstefano_zampini 9135e3038f0Sstefano_zampini if (!nest[j][i]) continue; 9149e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 9159e7b2b25Sstefano_zampini Mat T; 9169e7b2b25Sstefano_zampini 9179e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 9189e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 9199e7b2b25Sstefano_zampini } else { 9205e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 9219e7b2b25Sstefano_zampini } 9225e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 9235e3038f0Sstefano_zampini if (!n1) continue; 9245e3038f0Sstefano_zampini if (!rl2g) { 9255e3038f0Sstefano_zampini rl2g = cl2g; 9265e3038f0Sstefano_zampini } else { 9275e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 9285e3038f0Sstefano_zampini PetscBool same; 9295e3038f0Sstefano_zampini 9305e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 9315e3038f0Sstefano_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); 9325e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 9335e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 934580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,n1,&same);CHKERRQ(ierr); 9355e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 9365e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 9375e3038f0Sstefano_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); 9385e3038f0Sstefano_zampini } 9395e3038f0Sstefano_zampini } 9405e3038f0Sstefano_zampini } 9415e3038f0Sstefano_zampini #endif 9425e3038f0Sstefano_zampini 9435e3038f0Sstefano_zampini B = NULL; 9445e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 9455b003df0Sstefano_zampini PetscInt stl; 9465b003df0Sstefano_zampini 9475e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 9485e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 9495e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9505b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9515e3038f0Sstefano_zampini Mat usedmat; 9525e3038f0Sstefano_zampini Mat_IS *matis; 9535e3038f0Sstefano_zampini const PetscInt *idxs; 9545e3038f0Sstefano_zampini 9555e3038f0Sstefano_zampini /* local IS for local NEST */ 9565b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9575e3038f0Sstefano_zampini 9585e3038f0Sstefano_zampini /* l2gmap */ 9595e3038f0Sstefano_zampini j = 0; 9605e3038f0Sstefano_zampini usedmat = nest[i][j]; 9619e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 9629e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 9639e7b2b25Sstefano_zampini 9649e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9659e7b2b25Sstefano_zampini Mat T; 9669e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 9679e7b2b25Sstefano_zampini usedmat = T; 9689e7b2b25Sstefano_zampini } 9695e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 9705e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 9719e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9729e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9739e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9749e7b2b25Sstefano_zampini } else { 9755e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9765e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9779e7b2b25Sstefano_zampini } 9785e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 9795e3038f0Sstefano_zampini stl += lr[i]; 9805e3038f0Sstefano_zampini } 9815e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 9825e3038f0Sstefano_zampini 9835e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 9845e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 9855e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 9865b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 9875e3038f0Sstefano_zampini Mat usedmat; 9885e3038f0Sstefano_zampini Mat_IS *matis; 9895e3038f0Sstefano_zampini const PetscInt *idxs; 9905e3038f0Sstefano_zampini 9915e3038f0Sstefano_zampini /* local IS for local NEST */ 9925b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 9935e3038f0Sstefano_zampini 9945e3038f0Sstefano_zampini /* l2gmap */ 9955e3038f0Sstefano_zampini j = 0; 9965e3038f0Sstefano_zampini usedmat = nest[j][i]; 9979e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 9989e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 9999e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10009e7b2b25Sstefano_zampini Mat T; 10019e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 10029e7b2b25Sstefano_zampini usedmat = T; 10039e7b2b25Sstefano_zampini } 10045e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 10055e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 10069e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 10079e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10089e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10099e7b2b25Sstefano_zampini } else { 10105e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10115e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 10129e7b2b25Sstefano_zampini } 10135e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 10145e3038f0Sstefano_zampini stl += lc[i]; 10155e3038f0Sstefano_zampini } 10165e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 10175e3038f0Sstefano_zampini 10185e3038f0Sstefano_zampini /* Create MATIS */ 10195e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 10205e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 10215e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 10225e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 10235e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 10248546b261SStefano Zampini ierr = MatISSetLocalMatType(B,MATNEST);CHKERRQ(ierr); 10258546b261SStefano Zampini { /* hack : avoid setup of scatters */ 10268546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10278546b261SStefano Zampini matis->islocalref = PETSC_TRUE; 10288546b261SStefano Zampini } 10295e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 10305e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 10315e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 10325e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 10338546b261SStefano Zampini ierr = MatNestSetVecType(lA,VECNEST);CHKERRQ(ierr); 10349e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 10359e7b2b25Sstefano_zampini if (istrans[i]) { 10369e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10379e7b2b25Sstefano_zampini } 10389e7b2b25Sstefano_zampini } 10395e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 10405e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10418546b261SStefano Zampini { /* hack : setup of scatters done here */ 10428546b261SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 10438546b261SStefano Zampini 10448546b261SStefano Zampini matis->islocalref = PETSC_FALSE; 10458546b261SStefano Zampini ierr = MatISSetUpScatters_Private(B);CHKERRQ(ierr); 10468546b261SStefano Zampini } 10475e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10485e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10495e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 10505e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 10515e3038f0Sstefano_zampini } else { 10525e3038f0Sstefano_zampini *newmat = B; 10535e3038f0Sstefano_zampini } 10545e3038f0Sstefano_zampini } else { 10555e3038f0Sstefano_zampini if (lreuse) { 10565e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10575e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10585e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 10595e3038f0Sstefano_zampini if (snest[i*nc+j]) { 10605e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 10619e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 10629e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 10639e7b2b25Sstefano_zampini } 10645e3038f0Sstefano_zampini } 10655e3038f0Sstefano_zampini } 10665e3038f0Sstefano_zampini } 10675e3038f0Sstefano_zampini } else { 10685b003df0Sstefano_zampini PetscInt stl; 10695b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 10705b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 10715b003df0Sstefano_zampini stl += lr[i]; 10725e3038f0Sstefano_zampini } 10735b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 10745b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 10755b003df0Sstefano_zampini stl += lc[i]; 10765e3038f0Sstefano_zampini } 10775e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 1078ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 10799e7b2b25Sstefano_zampini if (istrans[i]) { 10809e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 10819e7b2b25Sstefano_zampini } 1082ab4d48faSStefano Zampini } 10835e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 10845e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 10855e3038f0Sstefano_zampini } 10865e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10875e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10885e3038f0Sstefano_zampini } 10895e3038f0Sstefano_zampini 10905b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 10915b003df0Sstefano_zampini convert = PETSC_FALSE; 10925b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 10935b003df0Sstefano_zampini if (convert) { 10945b003df0Sstefano_zampini Mat M; 10955b003df0Sstefano_zampini MatISLocalFields lf; 10965b003df0Sstefano_zampini PetscContainer c; 10975b003df0Sstefano_zampini 10985b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 10995b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 11005b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 11015b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 11025b003df0Sstefano_zampini 11035b003df0Sstefano_zampini /* attach local fields to the matrix */ 11045b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 1105071fcb05SBarry Smith ierr = PetscMalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 11065b003df0Sstefano_zampini for (i=0;i<nr;i++) { 11075b003df0Sstefano_zampini PetscInt n,st; 11085b003df0Sstefano_zampini 11095b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 11105b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 11115b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 11125b003df0Sstefano_zampini } 11135b003df0Sstefano_zampini for (i=0;i<nc;i++) { 11145b003df0Sstefano_zampini PetscInt n,st; 11155b003df0Sstefano_zampini 11165b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 11175b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 11185b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 11195b003df0Sstefano_zampini } 11205b003df0Sstefano_zampini lf->nr = nr; 11215b003df0Sstefano_zampini lf->nc = nc; 11225b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 11235b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 11245b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 11255b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 11265b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 11275b003df0Sstefano_zampini } 11285b003df0Sstefano_zampini 11295e3038f0Sstefano_zampini /* Free workspace */ 11305e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 11315e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 11325e3038f0Sstefano_zampini } 11335e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 11345e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 11355e3038f0Sstefano_zampini } 11369e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 11375b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 11385e3038f0Sstefano_zampini PetscFunctionReturn(0); 11395e3038f0Sstefano_zampini } 11405e3038f0Sstefano_zampini 1141ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1142ad219c80Sstefano_zampini { 1143ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1144ad219c80Sstefano_zampini Vec ll,rr; 1145ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1146ad219c80Sstefano_zampini PetscScalar *x,*y; 1147ad219c80Sstefano_zampini PetscErrorCode ierr; 1148ad219c80Sstefano_zampini 1149ad219c80Sstefano_zampini PetscFunctionBegin; 1150ad219c80Sstefano_zampini if (l) { 1151ad219c80Sstefano_zampini ll = matis->y; 1152ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1153ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1154ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1155ad219c80Sstefano_zampini } else { 1156ad219c80Sstefano_zampini ll = NULL; 1157ad219c80Sstefano_zampini } 1158ad219c80Sstefano_zampini if (r) { 1159ad219c80Sstefano_zampini rr = matis->x; 1160ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1161ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1162ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1163ad219c80Sstefano_zampini } else { 1164ad219c80Sstefano_zampini rr = NULL; 1165ad219c80Sstefano_zampini } 1166ad219c80Sstefano_zampini if (ll) { 1167ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1168ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1169ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1170ad219c80Sstefano_zampini } 1171ad219c80Sstefano_zampini if (rr) { 1172ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1173ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1174ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1175ad219c80Sstefano_zampini } 1176ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1177ad219c80Sstefano_zampini PetscFunctionReturn(0); 1178ad219c80Sstefano_zampini } 1179ad219c80Sstefano_zampini 11807fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 11817fa8f2d3SStefano Zampini { 11827fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 11837fa8f2d3SStefano Zampini MatInfo info; 11843966268fSBarry Smith PetscLogDouble isend[6],irecv[6]; 11857fa8f2d3SStefano Zampini PetscInt bs; 11867fa8f2d3SStefano Zampini PetscErrorCode ierr; 11877fa8f2d3SStefano Zampini 11887fa8f2d3SStefano Zampini PetscFunctionBegin; 11897fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1190a2ccb5f9Sstefano_zampini if (matis->A->ops->getinfo) { 11917fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 11927fa8f2d3SStefano Zampini isend[0] = info.nz_used; 11937fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 11947fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 11957fa8f2d3SStefano Zampini isend[3] = info.memory; 11967fa8f2d3SStefano Zampini isend[4] = info.mallocs; 1197a2ccb5f9Sstefano_zampini } else { 1198a2ccb5f9Sstefano_zampini isend[0] = 0.; 1199a2ccb5f9Sstefano_zampini isend[1] = 0.; 1200a2ccb5f9Sstefano_zampini isend[2] = 0.; 1201a2ccb5f9Sstefano_zampini isend[3] = 0.; 1202a2ccb5f9Sstefano_zampini isend[4] = 0.; 1203a2ccb5f9Sstefano_zampini } 1204314ce898Sstefano_zampini isend[5] = matis->A->num_ass; 12057fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 12067fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 12077fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 12087fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 12097fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 12107fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 1211314ce898Sstefano_zampini ginfo->assemblies = isend[5]; 12127fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 12133966268fSBarry Smith ierr = MPIU_Allreduce(isend,irecv,6,MPIU_PETSCLOGDOUBLE,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12147fa8f2d3SStefano Zampini 12157fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12167fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12177fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12187fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12197fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 1220314ce898Sstefano_zampini ginfo->assemblies = irecv[5]; 12217fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 12223966268fSBarry Smith ierr = MPIU_Allreduce(isend,irecv,5,MPIU_PETSCLOGDOUBLE,MPI_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 12237fa8f2d3SStefano Zampini 12247fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 12257fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 12267fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 12277fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 12287fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 12297fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 12307fa8f2d3SStefano Zampini } 12317fa8f2d3SStefano Zampini ginfo->block_size = bs; 12327fa8f2d3SStefano Zampini ginfo->fill_ratio_given = 0; 12337fa8f2d3SStefano Zampini ginfo->fill_ratio_needed = 0; 12347fa8f2d3SStefano Zampini ginfo->factor_mallocs = 0; 12355e3038f0Sstefano_zampini PetscFunctionReturn(0); 12365e3038f0Sstefano_zampini } 12375e3038f0Sstefano_zampini 1238d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1239d7f69cd0SStefano Zampini { 1240d7f69cd0SStefano Zampini Mat C,lC,lA; 1241d7f69cd0SStefano Zampini PetscErrorCode ierr; 1242d7f69cd0SStefano Zampini 1243d7f69cd0SStefano Zampini PetscFunctionBegin; 1244cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1245cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1246d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1247d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1248d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1249d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1250d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1251d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1252cf37664fSBarry Smith } else { 1253cf37664fSBarry Smith C = *B; 1254d7f69cd0SStefano Zampini } 1255d7f69cd0SStefano Zampini 1256d7f69cd0SStefano Zampini /* perform local transposition */ 1257d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1258d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1259d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1260d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1261d7f69cd0SStefano Zampini 1262cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1263d7f69cd0SStefano Zampini *B = C; 1264d7f69cd0SStefano Zampini } else { 1265d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1266d7f69cd0SStefano Zampini } 12677aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12687aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1269d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1270d7f69cd0SStefano Zampini } 1271d7f69cd0SStefano Zampini 12723fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 12733fd1c9e7SStefano Zampini { 12743fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 12753fd1c9e7SStefano Zampini PetscErrorCode ierr; 12763fd1c9e7SStefano Zampini 12773fd1c9e7SStefano Zampini PetscFunctionBegin; 12784b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 12793fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12803fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12813fd1c9e7SStefano Zampini } 12823fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 12833fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 12843fd1c9e7SStefano Zampini PetscFunctionReturn(0); 12853fd1c9e7SStefano Zampini } 12863fd1c9e7SStefano Zampini 12873fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 12883fd1c9e7SStefano Zampini { 12894b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 12903fd1c9e7SStefano Zampini PetscErrorCode ierr; 12913fd1c9e7SStefano Zampini 12923fd1c9e7SStefano Zampini PetscFunctionBegin; 12934b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 12943fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 12953fd1c9e7SStefano Zampini PetscFunctionReturn(0); 12963fd1c9e7SStefano Zampini } 12973fd1c9e7SStefano Zampini 1298f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1299f26d0771SStefano Zampini { 1300f26d0771SStefano Zampini PetscErrorCode ierr; 1301f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1302f26d0771SStefano Zampini 1303f26d0771SStefano Zampini PetscFunctionBegin; 1304f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1305f26d0771SStefano 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); 1306f26d0771SStefano Zampini #endif 1307f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1308f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1309b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1310f26d0771SStefano Zampini PetscFunctionReturn(0); 1311f26d0771SStefano Zampini } 1312f26d0771SStefano Zampini 1313f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1314f26d0771SStefano Zampini { 1315f26d0771SStefano Zampini PetscErrorCode ierr; 1316f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1317f26d0771SStefano Zampini 1318f26d0771SStefano Zampini PetscFunctionBegin; 1319f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1320f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1321f26d0771SStefano Zampini #endif 1322f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1323f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1324b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1325f26d0771SStefano Zampini PetscFunctionReturn(0); 1326f26d0771SStefano Zampini } 1327f26d0771SStefano Zampini 13287dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1329a8116848SStefano Zampini { 1330a8116848SStefano Zampini Mat locmat,newlocmat; 1331a8116848SStefano Zampini Mat_IS *newmatis; 1332a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1333a8116848SStefano Zampini Vec rtest,ltest; 1334a8116848SStefano Zampini const PetscScalar *array; 1335a8116848SStefano Zampini #endif 1336a8116848SStefano Zampini const PetscInt *idxs; 1337a8116848SStefano Zampini PetscInt i,m,n; 1338a8116848SStefano Zampini PetscErrorCode ierr; 1339a8116848SStefano Zampini 1340a8116848SStefano Zampini PetscFunctionBegin; 1341a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1342a8116848SStefano Zampini PetscBool ismatis; 1343a8116848SStefano Zampini 1344a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1345a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1346a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1347a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1348a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1349a8116848SStefano Zampini } 1350a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1351a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1352a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1353a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1354a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1355a8116848SStefano Zampini for (i=0;i<n;i++) { 1356a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1357a8116848SStefano Zampini } 1358a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1359a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1360a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1361a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1362a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1363fd479f66SMatthew 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])); 1364a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1365a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1366a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1367a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1368a8116848SStefano Zampini for (i=0;i<n;i++) { 1369a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1370a8116848SStefano Zampini } 1371a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1372a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1373a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1374a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1375a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1376fd479f66SMatthew 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])); 1377a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1378a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1379a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1380a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1381a8116848SStefano Zampini #endif 1382a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1383a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1384a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1385a8116848SStefano Zampini IS is; 1386a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1387306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 138894342113SStefano Zampini PetscBool cong; 1389a8116848SStefano Zampini MPI_Comm comm; 1390a8116848SStefano Zampini 1391a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1392306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1393306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1394306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1395306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1396306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1397a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1398a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1399a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1400a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1401a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1402306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1403a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1404a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1405a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1406a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1407580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,matis->sf->nroots);CHKERRQ(ierr); 1408a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1409a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1410a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1411a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1412a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 14133d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1414a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1415a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14163d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1417a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1418a8116848SStefano Zampini lidxs[newloc] = i; 1419a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1420a8116848SStefano Zampini } 1421a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1422a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1423306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1424a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1425a8116848SStefano Zampini /* local is to extract local submatrix */ 1426a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1427a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 142894342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 142994342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1430a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1431a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1432a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1433a8116848SStefano Zampini } else { 1434a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1435a8116848SStefano Zampini 1436a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1437a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1438a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1439a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1440580bdb30SBarry Smith ierr = PetscArrayzero(matis->csf_rootdata,matis->csf->nroots);CHKERRQ(ierr); 1441a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1442a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1443a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1444a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1445a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 14463d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1447a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1448a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 14493d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1450a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1451a8116848SStefano Zampini lidxs[newloc] = i; 1452a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1453a8116848SStefano Zampini } 1454a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1455a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1456306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1457a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1458a8116848SStefano Zampini /* local is to extract local submatrix */ 1459a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1460a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1461a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1462a8116848SStefano Zampini } 1463a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1464a8116848SStefano Zampini } else { 1465a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1466a8116848SStefano Zampini } 1467a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1468a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 14697dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1470a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1471a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1472a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1473a8116848SStefano Zampini } 1474a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1475a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1476a8116848SStefano Zampini PetscFunctionReturn(0); 1477a8116848SStefano Zampini } 1478a8116848SStefano Zampini 1479a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 14802b404112SStefano Zampini { 14812b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 14822b404112SStefano Zampini PetscBool ismatis; 14832b404112SStefano Zampini PetscErrorCode ierr; 14842b404112SStefano Zampini 14852b404112SStefano Zampini PetscFunctionBegin; 14862b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 14872b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 14882b404112SStefano Zampini b = (Mat_IS*)B->data; 14892b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1490cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 14912b404112SStefano Zampini PetscFunctionReturn(0); 14922b404112SStefano Zampini } 14932b404112SStefano Zampini 1494a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 14956bd84002SStefano Zampini { 1496527b2640SStefano Zampini Vec v; 1497527b2640SStefano Zampini const PetscScalar *array; 1498527b2640SStefano Zampini PetscInt i,n; 14996bd84002SStefano Zampini PetscErrorCode ierr; 15006bd84002SStefano Zampini 15016bd84002SStefano Zampini PetscFunctionBegin; 1502527b2640SStefano Zampini *missing = PETSC_FALSE; 1503527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1504527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1505527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1506527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1507527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1508527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1509527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1510527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1511527b2640SStefano Zampini if (d) { 1512527b2640SStefano Zampini *d = -1; 1513527b2640SStefano Zampini if (*missing) { 1514527b2640SStefano Zampini PetscInt rstart; 1515527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1516527b2640SStefano Zampini *d = i+rstart; 1517527b2640SStefano Zampini } 1518527b2640SStefano Zampini } 15196bd84002SStefano Zampini PetscFunctionReturn(0); 15206bd84002SStefano Zampini } 15216bd84002SStefano Zampini 1522cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 152328f4e0baSStefano Zampini { 152428f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 152528f4e0baSStefano Zampini const PetscInt *gidxs; 15264f2d7cafSStefano Zampini PetscInt nleaves; 152728f4e0baSStefano Zampini PetscErrorCode ierr; 152828f4e0baSStefano Zampini 152928f4e0baSStefano Zampini PetscFunctionBegin; 15304f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 153128f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 15323bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 15334f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 15344f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 15353bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 15364f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1537a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 15383d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1539a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1540a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 15413d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1542a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 15433d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1544a8116848SStefano Zampini } else { 1545a8116848SStefano Zampini matis->csf = matis->sf; 1546a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1547a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1548a8116848SStefano Zampini } 154928f4e0baSStefano Zampini PetscFunctionReturn(0); 155028f4e0baSStefano Zampini } 15512e1947a5SStefano Zampini 1552eb82efa4SStefano Zampini /*@ 155375d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 155475d48cdbSStefano Zampini 1555d083f849SBarry Smith Collective 155675d48cdbSStefano Zampini 155775d48cdbSStefano Zampini Input Parameters: 155875d48cdbSStefano Zampini + A - the matrix 155975d48cdbSStefano Zampini - store - the boolean flag 156075d48cdbSStefano Zampini 156175d48cdbSStefano Zampini Level: advanced 156275d48cdbSStefano Zampini 156375d48cdbSStefano Zampini Notes: 156475d48cdbSStefano Zampini 156575d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 156675d48cdbSStefano Zampini @*/ 156775d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 156875d48cdbSStefano Zampini { 156975d48cdbSStefano Zampini PetscErrorCode ierr; 157075d48cdbSStefano Zampini 157175d48cdbSStefano Zampini PetscFunctionBegin; 157275d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 157375d48cdbSStefano Zampini PetscValidType(A,1); 157475d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 157575d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 157675d48cdbSStefano Zampini PetscFunctionReturn(0); 157775d48cdbSStefano Zampini } 157875d48cdbSStefano Zampini 157975d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 158075d48cdbSStefano Zampini { 158175d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 158275d48cdbSStefano Zampini PetscErrorCode ierr; 158375d48cdbSStefano Zampini 158475d48cdbSStefano Zampini PetscFunctionBegin; 158575d48cdbSStefano Zampini matis->storel2l = store; 158675d48cdbSStefano Zampini if (!store) { 158775d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 158875d48cdbSStefano Zampini } 158975d48cdbSStefano Zampini PetscFunctionReturn(0); 159075d48cdbSStefano Zampini } 159175d48cdbSStefano Zampini 159275d48cdbSStefano Zampini /*@ 1593f03112d0SStefano Zampini MatISFixLocalEmpty - Compress out zero local rows from the local matrices 1594f03112d0SStefano Zampini 1595d083f849SBarry Smith Collective 1596f03112d0SStefano Zampini 1597f03112d0SStefano Zampini Input Parameters: 1598f03112d0SStefano Zampini + A - the matrix 1599f03112d0SStefano Zampini - fix - the boolean flag 1600f03112d0SStefano Zampini 1601f03112d0SStefano Zampini Level: advanced 1602f03112d0SStefano Zampini 1603f03112d0SStefano Zampini Notes: When fix is true, new local matrices and l2g maps are generated during the final assembly process. 1604f03112d0SStefano Zampini 1605f03112d0SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatAssemblyEnd(), MAT_FINAL_ASSEMBLY 1606f03112d0SStefano Zampini @*/ 1607f03112d0SStefano Zampini PetscErrorCode MatISFixLocalEmpty(Mat A, PetscBool fix) 1608f03112d0SStefano Zampini { 1609f03112d0SStefano Zampini PetscErrorCode ierr; 1610f03112d0SStefano Zampini 1611f03112d0SStefano Zampini PetscFunctionBegin; 1612f03112d0SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1613f03112d0SStefano Zampini PetscValidType(A,1); 1614f03112d0SStefano Zampini PetscValidLogicalCollectiveBool(A,fix,2); 1615f03112d0SStefano Zampini ierr = PetscTryMethod(A,"MatISFixLocalEmpty_C",(Mat,PetscBool),(A,fix));CHKERRQ(ierr); 1616f03112d0SStefano Zampini PetscFunctionReturn(0); 1617f03112d0SStefano Zampini } 1618f03112d0SStefano Zampini 1619f03112d0SStefano Zampini static PetscErrorCode MatISFixLocalEmpty_IS(Mat A, PetscBool fix) 1620f03112d0SStefano Zampini { 1621f03112d0SStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1622f03112d0SStefano Zampini 1623f03112d0SStefano Zampini PetscFunctionBegin; 1624f03112d0SStefano Zampini matis->locempty = fix; 1625f03112d0SStefano Zampini PetscFunctionReturn(0); 1626f03112d0SStefano Zampini } 1627f03112d0SStefano Zampini 1628f03112d0SStefano Zampini /*@ 1629a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1630a88811baSStefano Zampini 1631d083f849SBarry Smith Collective 1632a88811baSStefano Zampini 1633a88811baSStefano Zampini Input Parameters: 1634a88811baSStefano Zampini + B - the matrix 1635a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1636a88811baSStefano Zampini (same value is used for all local rows) 1637a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1638a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1639a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1640a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1641a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1642a88811baSStefano Zampini the diagonal entry even if it is zero. 1643a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1644a88811baSStefano Zampini submatrix (same value is used for all local rows). 1645a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1646a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1647a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1648a88811baSStefano Zampini structure. The size of this array is equal to the number 1649a88811baSStefano Zampini of local rows, i.e 'm'. 1650a88811baSStefano Zampini 1651a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1652a88811baSStefano Zampini 1653a88811baSStefano Zampini Level: intermediate 1654a88811baSStefano Zampini 165595452b02SPatrick Sanan Notes: 165695452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1657a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1658a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1659a88811baSStefano Zampini 16603c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1661a88811baSStefano Zampini @*/ 16622e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16632e1947a5SStefano Zampini { 16642e1947a5SStefano Zampini PetscErrorCode ierr; 16652e1947a5SStefano Zampini 16662e1947a5SStefano Zampini PetscFunctionBegin; 16672e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 16682e1947a5SStefano Zampini PetscValidType(B,1); 16692e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 16702e1947a5SStefano Zampini PetscFunctionReturn(0); 16712e1947a5SStefano Zampini } 16722e1947a5SStefano Zampini 1673844bd0d7SStefano Zampini /* this is used by DMDA */ 1674844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 16752e1947a5SStefano Zampini { 16762e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 167728f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 16782e1947a5SStefano Zampini PetscErrorCode ierr; 16792e1947a5SStefano Zampini 16802e1947a5SStefano Zampini PetscFunctionBegin; 16816c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 16824f2d7cafSStefano Zampini 16834f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 16844f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 16854f2d7cafSStefano Zampini 16864f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 16874f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 16884f2d7cafSStefano Zampini 168928f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 169028f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 169128f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 169228f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 16934f2d7cafSStefano Zampini 16944f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 169528f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 16960f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 16970f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 16980f2f62c7SStefano Zampini #endif 16994f2d7cafSStefano Zampini 17004f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 170128f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17024f2d7cafSStefano Zampini 170300a59248SStefano Zampini nlocalcols /= bs; 170400a59248SStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols - i); 170528f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 17060f2f62c7SStefano Zampini 17070f2f62c7SStefano Zampini /* for other matrix types */ 17080f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 17092e1947a5SStefano Zampini PetscFunctionReturn(0); 17102e1947a5SStefano Zampini } 1711b4319ba4SBarry Smith 17123927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 17133927de2eSStefano Zampini { 17143927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 17153927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1716ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 17173927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 17183927de2eSStefano Zampini PetscInt lrows,lcols; 17193927de2eSStefano Zampini PetscInt local_rows,local_cols; 1720f03112d0SStefano Zampini PetscMPIInt size; 17213927de2eSStefano Zampini PetscBool isdense,issbaij; 17223927de2eSStefano Zampini PetscErrorCode ierr; 17233927de2eSStefano Zampini 17243927de2eSStefano Zampini PetscFunctionBegin; 1725f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 17263927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 17273927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 17283927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1729b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1730b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1731ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1732ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 17337230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1734ecf5a873SStefano Zampini } else { 1735ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1736ecf5a873SStefano Zampini } 1737ecf5a873SStefano Zampini 17383927de2eSStefano Zampini if (issbaij) { 17393927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 17403927de2eSStefano Zampini } 17413927de2eSStefano Zampini /* 1742ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 17433927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 17443927de2eSStefano Zampini */ 17453927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 17463927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 17473927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 17483927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 17493927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1750f03112d0SStefano Zampini for (i=0;i<size;i++) { 17513927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 17523927de2eSStefano Zampini row_ownership[j] = i; 17533927de2eSStefano Zampini } 17543927de2eSStefano Zampini } 17557230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 17563927de2eSStefano Zampini 17573927de2eSStefano Zampini /* 17583927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 17593927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 17603927de2eSStefano Zampini */ 17613927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 17623927de2eSStefano Zampini /* preallocation as a MATAIJ */ 17633927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 17643927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 176512dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 176612dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1767ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 17683927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1]) { /* diag block */ 17693927de2eSStefano Zampini my_dnz[i] += 1; 17703927de2eSStefano Zampini } else { /* offdiag block */ 17713927de2eSStefano Zampini my_onz[i] += 1; 17723927de2eSStefano Zampini } 17733927de2eSStefano Zampini } 17743927de2eSStefano Zampini } 1775bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1776bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1777bb1015c3SStefano Zampini PetscBool done; 1778bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1779938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1780bb1015c3SStefano Zampini jptr = jj; 1781bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1782bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1783bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1784bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1785bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1786bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1787bb1015c3SStefano Zampini my_dnz[i] += 1; 1788bb1015c3SStefano Zampini } else { /* offdiag block */ 1789bb1015c3SStefano Zampini my_onz[i] += 1; 1790bb1015c3SStefano Zampini } 1791bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1792bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1793bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1794bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1795bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1796bb1015c3SStefano Zampini } else { 1797bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1798bb1015c3SStefano Zampini } 1799bb1015c3SStefano Zampini } 1800bb1015c3SStefano Zampini } 1801bb1015c3SStefano Zampini } 1802bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1803938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1804bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 18053927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 18063927de2eSStefano Zampini const PetscInt *cols; 1807ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 18083927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18093927de2eSStefano Zampini for (j=0;j<ncols;j++) { 18103927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1811ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 18123927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 18133927de2eSStefano Zampini my_dnz[i] += 1; 18143927de2eSStefano Zampini } else { /* offdiag block */ 18153927de2eSStefano Zampini my_onz[i] += 1; 18163927de2eSStefano Zampini } 18173927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1818d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 18193927de2eSStefano Zampini owner = row_ownership[index_col]; 18203927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1821d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 18223927de2eSStefano Zampini } else { 1823d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 18243927de2eSStefano Zampini } 18253927de2eSStefano Zampini } 18263927de2eSStefano Zampini } 18273927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 18283927de2eSStefano Zampini } 18293927de2eSStefano Zampini } 1830ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 18317230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1832ecf5a873SStefano Zampini } 18334f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 18343927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1835ecf5a873SStefano Zampini 1836ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 18373927de2eSStefano Zampini if (maxreduce) { 18383927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18393927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1840bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 18413927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 18423927de2eSStefano Zampini } else { 18433927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18443927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1845bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 18463927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 18473927de2eSStefano Zampini } 18483927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 18493927de2eSStefano Zampini 18503927de2eSStefano Zampini /* Resize preallocation if overestimated */ 18513927de2eSStefano Zampini for (i=0;i<lrows;i++) { 18523927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 18533927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 18543927de2eSStefano Zampini } 18551670daf9Sstefano_zampini 18561670daf9Sstefano_zampini /* Set preallocation */ 1857268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 18583927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 185953b44cf5SStefano Zampini for (i=0;i<lrows;i+=bs) { 186053b44cf5SStefano Zampini PetscInt b, d = dnz[i],o = onz[i]; 186153b44cf5SStefano Zampini 186253b44cf5SStefano Zampini for (b=1;b<bs;b++) { 186353b44cf5SStefano Zampini d = PetscMax(d,dnz[i+b]); 186453b44cf5SStefano Zampini o = PetscMax(o,onz[i+b]); 186553b44cf5SStefano Zampini } 186653b44cf5SStefano Zampini dnz[i/bs] = PetscMin(d/bs + d%bs,lcols/bs); 186753b44cf5SStefano Zampini onz[i/bs] = PetscMin(o/bs + o%bs,(cols-lcols)/bs); 18683927de2eSStefano Zampini } 1869268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 18703927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18713927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 18723927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 18733927de2eSStefano Zampini if (issbaij) { 18743927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 18753927de2eSStefano Zampini } 18769be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 18773927de2eSStefano Zampini PetscFunctionReturn(0); 18783927de2eSStefano Zampini } 18793927de2eSStefano Zampini 1880487b449aSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_IS_XAIJ(Mat mat, MatType mtype, MatReuse reuse, Mat *M) 1881b7ce53b6SStefano Zampini { 1882b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1883487b449aSStefano Zampini Mat local_mat,MT; 188453b44cf5SStefano Zampini PetscInt rbs,cbs,rows,cols,lrows,lcols; 1885b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1886b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1887b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1888b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1889b9ed4604SStefano Zampini #endif 1890f03112d0SStefano Zampini PetscMPIInt size; 18911683a169SBarry Smith const PetscScalar *array; 1892b7ce53b6SStefano Zampini PetscErrorCode ierr; 1893b7ce53b6SStefano Zampini 1894b7ce53b6SStefano Zampini PetscFunctionBegin; 1895f03112d0SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1896f03112d0SStefano Zampini if (size == 1 && mat->rmap->N == matis->A->rmap->N && mat->cmap->N == matis->A->cmap->N) { 18971670daf9Sstefano_zampini Mat B; 189853b44cf5SStefano Zampini IS irows = NULL,icols = NULL; 1899487b449aSStefano Zampini PetscInt rbs,cbs; 19001670daf9Sstefano_zampini 1901487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 1902487b449aSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 190353b44cf5SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { /* check if l2g maps are one-to-one */ 190453b44cf5SStefano Zampini IS rows,cols; 190553b44cf5SStefano Zampini const PetscInt *ridxs,*cidxs; 190653b44cf5SStefano Zampini PetscInt i,nw,*work; 190753b44cf5SStefano Zampini 190853b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 190953b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&nw);CHKERRQ(ierr); 191053b44cf5SStefano Zampini nw = nw/rbs; 191153b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 191253b44cf5SStefano Zampini for (i=0;i<nw;i++) work[ridxs[i]] += 1; 191353b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 191453b44cf5SStefano Zampini if (i == nw) { 191553b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,rbs,nw,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 1916acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 191753b44cf5SStefano Zampini ierr = ISInvertPermutation(rows,PETSC_DECIDE,&irows);CHKERRQ(ierr); 1918acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 191953b44cf5SStefano Zampini } 192053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 192153b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 192253b44cf5SStefano Zampini if (irows && mat->rmap->mapping != mat->cmap->mapping) { 192353b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 192453b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->cmap->mapping,&nw);CHKERRQ(ierr); 192553b44cf5SStefano Zampini nw = nw/cbs; 192653b44cf5SStefano Zampini ierr = PetscCalloc1(nw,&work);CHKERRQ(ierr); 192753b44cf5SStefano Zampini for (i=0;i<nw;i++) work[cidxs[i]] += 1; 192853b44cf5SStefano Zampini for (i=0;i<nw;i++) if (!work[i] || work[i] > 1) break; 192953b44cf5SStefano Zampini if (i == nw) { 193053b44cf5SStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,cbs,nw,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 193153b44cf5SStefano Zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 193253b44cf5SStefano Zampini ierr = ISInvertPermutation(cols,PETSC_DECIDE,&icols);CHKERRQ(ierr); 193353b44cf5SStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 193453b44cf5SStefano Zampini } 193553b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 193653b44cf5SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 193753b44cf5SStefano Zampini } else if (irows) { 193853b44cf5SStefano Zampini ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); 193953b44cf5SStefano Zampini icols = irows; 194053b44cf5SStefano Zampini } 194153b44cf5SStefano Zampini } else { 194253b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject*)&irows);CHKERRQ(ierr); 194353b44cf5SStefano Zampini ierr = PetscObjectQuery((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject*)&icols);CHKERRQ(ierr); 194453b44cf5SStefano Zampini if (irows) { ierr = PetscObjectReference((PetscObject)irows);CHKERRQ(ierr); } 194553b44cf5SStefano Zampini if (icols) { ierr = PetscObjectReference((PetscObject)icols);CHKERRQ(ierr); } 194653b44cf5SStefano Zampini } 194753b44cf5SStefano Zampini if (!irows || !icols) { 194853b44cf5SStefano Zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 194953b44cf5SStefano Zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 195053b44cf5SStefano Zampini goto general_assembly; 195153b44cf5SStefano Zampini } 1952d8e18881SStefano Zampini ierr = MatConvert(matis->A,mtype,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1953487b449aSStefano Zampini if (reuse != MAT_INPLACE_MATRIX) { 19547dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 195553b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_irows",(PetscObject)irows);CHKERRQ(ierr); 195653b44cf5SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*M),"_MatIS_IS_XAIJ_icols",(PetscObject)icols);CHKERRQ(ierr); 1957487b449aSStefano Zampini } else { 1958487b449aSStefano Zampini Mat C; 1959487b449aSStefano Zampini 1960487b449aSStefano Zampini ierr = MatCreateSubMatrix(B,irows,icols,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 1961487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&C);CHKERRQ(ierr); 1962487b449aSStefano Zampini } 1963acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1964acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1965acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 19667c03b4e8SStefano Zampini PetscFunctionReturn(0); 19677c03b4e8SStefano Zampini } 196853b44cf5SStefano Zampini general_assembly: 1969b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 197053b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 197153b44cf5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 19723cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1973b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1974b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 19754099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1976b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1977b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1978b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1979b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1980b9ed4604SStefano Zampini lb[0] = isseqdense; 1981b9ed4604SStefano Zampini lb[1] = isseqaij; 1982b9ed4604SStefano Zampini lb[2] = isseqbaij; 1983b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1984b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1985b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1986b9ed4604SStefano Zampini #endif 1987b7ce53b6SStefano Zampini 1988487b449aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1989487b449aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&MT);CHKERRQ(ierr); 1990487b449aSStefano Zampini ierr = MatSetSizes(MT,lrows,lcols,rows,cols);CHKERRQ(ierr); 1991487b449aSStefano Zampini ierr = MatSetType(MT,mtype);CHKERRQ(ierr); 199253b44cf5SStefano Zampini ierr = MatSetBlockSizes(MT,rbs,cbs);CHKERRQ(ierr); 1993487b449aSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,MT,PETSC_FALSE);CHKERRQ(ierr); 1994b7ce53b6SStefano Zampini } else { 199553b44cf5SStefano Zampini PetscInt mrbs,mcbs,mrows,mcols,mlrows,mlcols; 1996487b449aSStefano Zampini 1997b7ce53b6SStefano Zampini /* some checks */ 1998487b449aSStefano Zampini MT = *M; 199953b44cf5SStefano Zampini ierr = MatGetBlockSizes(MT,&mrbs,&mcbs);CHKERRQ(ierr); 2000487b449aSStefano Zampini ierr = MatGetSize(MT,&mrows,&mcols);CHKERRQ(ierr); 2001487b449aSStefano Zampini ierr = MatGetLocalSize(MT,&mlrows,&mlcols);CHKERRQ(ierr); 20026c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 20036c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 20046c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 20056c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 200653b44cf5SStefano Zampini if (mrbs != rbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong row block size (%d != %d)",rbs,mrbs); 200753b44cf5SStefano Zampini if (mcbs != cbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong col block size (%d != %d)",cbs,mcbs); 2008487b449aSStefano Zampini ierr = MatZeroEntries(MT);CHKERRQ(ierr); 2009b7ce53b6SStefano Zampini } 2010d9a9e74cSStefano Zampini 20118546b261SStefano Zampini if (isseqsbaij || isseqbaij) { 20128546b261SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 20138546b261SStefano Zampini isseqaij = PETSC_TRUE; 2014d9a9e74cSStefano Zampini } else { 2015d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 2016d9a9e74cSStefano Zampini local_mat = matis->A; 2017d9a9e74cSStefano Zampini } 2018686e3a49SStefano Zampini 2019b7ce53b6SStefano Zampini /* Set values */ 2020487b449aSStefano Zampini ierr = MatSetLocalToGlobalMapping(MT,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2021b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 202265066ba5SStefano Zampini PetscInt i,*dummy; 2023ecf5a873SStefano Zampini 202465066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 202565066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 2026487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 20271683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&array);CHKERRQ(ierr); 2028487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 20291683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&array);CHKERRQ(ierr); 203065066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 2031686e3a49SStefano Zampini } else if (isseqaij) { 20326afe12f5SStefano Zampini const PetscInt *blocks; 20336afe12f5SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy, nb; 2034686e3a49SStefano Zampini PetscBool done; 20351683a169SBarry Smith PetscScalar *sarray; 2036686e3a49SStefano Zampini 2037d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2038938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 20391683a169SBarry Smith ierr = MatSeqAIJGetArray(local_mat,&sarray);CHKERRQ(ierr); 20406afe12f5SStefano Zampini ierr = MatGetVariableBlockSizes(local_mat,&nb,&blocks);CHKERRQ(ierr); 20416afe12f5SStefano Zampini if (nb) { /* speed up assembly for special blocked matrices (used by BDDC) */ 20426afe12f5SStefano Zampini PetscInt sum; 20436afe12f5SStefano Zampini 20446afe12f5SStefano Zampini for (i=0,sum=0;i<nb;i++) sum += blocks[i]; 20456afe12f5SStefano Zampini if (sum == nvtxs) { 20466afe12f5SStefano Zampini PetscInt r; 20476afe12f5SStefano Zampini 20486afe12f5SStefano Zampini for (i=0,r=0;i<nb;i++) { 2049d8e18881SStefano Zampini #if defined(PETSC_USE_DEBUG) 20506afe12f5SStefano 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]); 2051d8e18881SStefano Zampini #endif 20521683a169SBarry Smith ierr = MatSetValuesLocal(MT,blocks[i],adjncy+xadj[r],blocks[i],adjncy+xadj[r],sarray+xadj[r],ADD_VALUES);CHKERRQ(ierr); 20536afe12f5SStefano Zampini r += blocks[i]; 20546afe12f5SStefano Zampini } 20556afe12f5SStefano Zampini } else { 2056686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 20571683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 2058686e3a49SStefano Zampini } 20596afe12f5SStefano Zampini } 20606afe12f5SStefano Zampini } else { 20616afe12f5SStefano Zampini for (i=0;i<nvtxs;i++) { 20621683a169SBarry Smith ierr = MatSetValuesLocal(MT,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],sarray+xadj[i],ADD_VALUES);CHKERRQ(ierr); 20636afe12f5SStefano Zampini } 20646afe12f5SStefano Zampini } 2065d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 2066938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 20671683a169SBarry Smith ierr = MatSeqAIJRestoreArray(local_mat,&sarray);CHKERRQ(ierr); 2068686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 2069ecf5a873SStefano Zampini PetscInt i; 2070c0962df8SStefano Zampini 2071686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 2072686e3a49SStefano Zampini PetscInt j; 2073ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 2074686e3a49SStefano Zampini 20751683a169SBarry Smith ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2076487b449aSStefano Zampini ierr = MatSetValuesLocal(MT,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 20771683a169SBarry Smith ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,&array);CHKERRQ(ierr); 2078686e3a49SStefano Zampini } 2079b7ce53b6SStefano Zampini } 2080487b449aSStefano Zampini ierr = MatAssemblyBegin(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2081d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 2082487b449aSStefano Zampini ierr = MatAssemblyEnd(MT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2083b9ed4604SStefano Zampini if (isseqdense) { 2084487b449aSStefano Zampini ierr = MatSetOption(MT,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 2085487b449aSStefano Zampini } 2086487b449aSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 2087487b449aSStefano Zampini ierr = MatHeaderReplace(mat,&MT);CHKERRQ(ierr); 2088487b449aSStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 2089487b449aSStefano Zampini *M = MT; 2090b7ce53b6SStefano Zampini } 2091b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2092b7ce53b6SStefano Zampini } 2093b7ce53b6SStefano Zampini 2094b7ce53b6SStefano Zampini /*@ 2095b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 2096b7ce53b6SStefano Zampini 2097b7ce53b6SStefano Zampini Input Parameter: 2098a2b725a8SWilliam Gropp + mat - the matrix (should be of type MATIS) 2099a2b725a8SWilliam Gropp - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 2100b7ce53b6SStefano Zampini 2101b7ce53b6SStefano Zampini Output Parameter: 2102b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 2103b7ce53b6SStefano Zampini 2104b7ce53b6SStefano Zampini Level: developer 2105b7ce53b6SStefano Zampini 210695452b02SPatrick Sanan Notes: 2107487b449aSStefano Zampini This function has been deprecated and it will be removed in future releases. Update your code to use the MatConvert() interface. 2108b7ce53b6SStefano Zampini 2109487b449aSStefano Zampini .seealso: MATIS, MatConvert() 2110b7ce53b6SStefano Zampini @*/ 2111b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 2112b7ce53b6SStefano Zampini { 2113b7ce53b6SStefano Zampini PetscErrorCode ierr; 2114b7ce53b6SStefano Zampini 2115b7ce53b6SStefano Zampini PetscFunctionBegin; 2116b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2117b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 2118b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 2119487b449aSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 2120b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 2121b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 21226c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 2123b7ce53b6SStefano Zampini } 2124487b449aSStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatType,MatReuse,Mat*),(mat,MATAIJ,reuse,newmat));CHKERRQ(ierr); 2125b7ce53b6SStefano Zampini PetscFunctionReturn(0); 2126b7ce53b6SStefano Zampini } 2127b7ce53b6SStefano Zampini 2128ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 2129ad6194a2SStefano Zampini { 2130ad6194a2SStefano Zampini PetscErrorCode ierr; 2131ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 2132c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 2133ad6194a2SStefano Zampini Mat B,localmat; 2134ad6194a2SStefano Zampini 2135ad6194a2SStefano Zampini PetscFunctionBegin; 2136c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 2137c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 2138ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 2139ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 21408546b261SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 21418546b261SStefano Zampini ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 21428546b261SStefano Zampini ierr = MatSetBlockSize(B,rbs == cbs ? rbs : 1);CHKERRQ(ierr); 21438546b261SStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 21448546b261SStefano Zampini ierr = MatISSetLocalMatType(B,matis->lmattype);CHKERRQ(ierr); 21458546b261SStefano Zampini ierr = MatSetLocalToGlobalMapping(B,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 2146ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 2147ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 2148b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 2149ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2150ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2151ad6194a2SStefano Zampini *newmat = B; 2152ad6194a2SStefano Zampini PetscFunctionReturn(0); 2153ad6194a2SStefano Zampini } 2154ad6194a2SStefano Zampini 2155a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 215669796d55SStefano Zampini { 215769796d55SStefano Zampini PetscErrorCode ierr; 215869796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 215969796d55SStefano Zampini PetscBool local_sym; 216069796d55SStefano Zampini 216169796d55SStefano Zampini PetscFunctionBegin; 216269796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2163b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 216469796d55SStefano Zampini PetscFunctionReturn(0); 216569796d55SStefano Zampini } 216669796d55SStefano Zampini 2167a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 216869796d55SStefano Zampini { 216969796d55SStefano Zampini PetscErrorCode ierr; 217069796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 217169796d55SStefano Zampini PetscBool local_sym; 217269796d55SStefano Zampini 217369796d55SStefano Zampini PetscFunctionBegin; 217469796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2175b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 217669796d55SStefano Zampini PetscFunctionReturn(0); 217769796d55SStefano Zampini } 217869796d55SStefano Zampini 217945471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 218045471136SStefano Zampini { 218145471136SStefano Zampini PetscErrorCode ierr; 218245471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 218345471136SStefano Zampini PetscBool local_sym; 218445471136SStefano Zampini 218545471136SStefano Zampini PetscFunctionBegin; 218645471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 218745471136SStefano Zampini *flg = PETSC_FALSE; 218845471136SStefano Zampini PetscFunctionReturn(0); 218945471136SStefano Zampini } 219045471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 219145471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 219245471136SStefano Zampini PetscFunctionReturn(0); 219345471136SStefano Zampini } 219445471136SStefano Zampini 2195a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2196b4319ba4SBarry Smith { 2197dfbe8321SBarry Smith PetscErrorCode ierr; 2198b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2199b4319ba4SBarry Smith 2200b4319ba4SBarry Smith PetscFunctionBegin; 2201b89f26deSStefano Zampini ierr = PetscFree(b->bdiag);CHKERRQ(ierr); 22028546b261SStefano Zampini ierr = PetscFree(b->lmattype);CHKERRQ(ierr); 22036bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2204e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2205e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 22066bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 22076bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 22083fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2209a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2210a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2211a8116848SStefano Zampini if (b->sf != b->csf) { 2212a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2213a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2214f03112d0SStefano Zampini } else b->csf = NULL; 221528f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 221628f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2217bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2218dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 22198546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",NULL);CHKERRQ(ierr); 2220bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2221b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2222b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 22232e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 222475d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2225f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",NULL);CHKERRQ(ierr); 2226487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",NULL);CHKERRQ(ierr); 2227487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",NULL);CHKERRQ(ierr); 2228487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",NULL);CHKERRQ(ierr); 2229487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",NULL);CHKERRQ(ierr); 2230487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",NULL);CHKERRQ(ierr); 2231487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",NULL);CHKERRQ(ierr); 2232487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",NULL);CHKERRQ(ierr); 2233b4319ba4SBarry Smith PetscFunctionReturn(0); 2234b4319ba4SBarry Smith } 2235b4319ba4SBarry Smith 2236a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2237b4319ba4SBarry Smith { 2238dfbe8321SBarry Smith PetscErrorCode ierr; 2239b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2240b4319ba4SBarry Smith PetscScalar zero = 0.0; 2241b4319ba4SBarry Smith 2242b4319ba4SBarry Smith PetscFunctionBegin; 2243b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2244e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2245e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2246b4319ba4SBarry Smith 2247b4319ba4SBarry Smith /* multiply the local matrix */ 2248b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2249b4319ba4SBarry Smith 2250b4319ba4SBarry Smith /* scatter product back into global memory */ 22512dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2252e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2253e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2254b4319ba4SBarry Smith PetscFunctionReturn(0); 2255b4319ba4SBarry Smith } 2256b4319ba4SBarry Smith 2257a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 22582e74eeadSLisandro Dalcin { 2259650997f4SStefano Zampini Vec temp_vec; 22602e74eeadSLisandro Dalcin PetscErrorCode ierr; 22612e74eeadSLisandro Dalcin 22622e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2263650997f4SStefano Zampini if (v3 != v2) { 2264650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2265650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2266650997f4SStefano Zampini } else { 2267650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2268650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2269650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2270650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2271650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2272650997f4SStefano Zampini } 22732e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22742e74eeadSLisandro Dalcin } 22752e74eeadSLisandro Dalcin 2276a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 22772e74eeadSLisandro Dalcin { 22782e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 22792e74eeadSLisandro Dalcin PetscErrorCode ierr; 22802e74eeadSLisandro Dalcin 2281e176bc59SStefano Zampini PetscFunctionBegin; 22822e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2283e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2284e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22852e74eeadSLisandro Dalcin 22862e74eeadSLisandro Dalcin /* multiply the local matrix */ 2287e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 22882e74eeadSLisandro Dalcin 22892e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2290e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2291e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2292e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22932e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22942e74eeadSLisandro Dalcin } 22952e74eeadSLisandro Dalcin 2296a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 22972e74eeadSLisandro Dalcin { 2298650997f4SStefano Zampini Vec temp_vec; 22992e74eeadSLisandro Dalcin PetscErrorCode ierr; 23002e74eeadSLisandro Dalcin 23012e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2302650997f4SStefano Zampini if (v3 != v2) { 2303650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2304650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2305650997f4SStefano Zampini } else { 2306650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2307650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2308650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2309650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2310650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2311650997f4SStefano Zampini } 23122e74eeadSLisandro Dalcin PetscFunctionReturn(0); 23132e74eeadSLisandro Dalcin } 23142e74eeadSLisandro Dalcin 2315a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2316b4319ba4SBarry Smith { 2317b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2318dfbe8321SBarry Smith PetscErrorCode ierr; 2319b4319ba4SBarry Smith PetscViewer sviewer; 2320ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2321b4319ba4SBarry Smith 2322b4319ba4SBarry Smith PetscFunctionBegin; 2323ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2324ee2491ecSStefano Zampini if (isascii) { 2325ee2491ecSStefano Zampini PetscViewerFormat format; 2326ee2491ecSStefano Zampini 2327ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2328ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2329ee2491ecSStefano Zampini } 2330ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 23313f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2332b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 23333f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 23346e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2335b4319ba4SBarry Smith PetscFunctionReturn(0); 2336b4319ba4SBarry Smith } 2337b4319ba4SBarry Smith 2338b89f26deSStefano Zampini static PetscErrorCode MatInvertBlockDiagonal_IS(Mat mat,const PetscScalar **values) 2339b89f26deSStefano Zampini { 2340b89f26deSStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 2341b89f26deSStefano Zampini MPI_Datatype nodeType; 2342b89f26deSStefano Zampini const PetscScalar *lv; 2343b89f26deSStefano Zampini PetscInt bs; 2344b89f26deSStefano Zampini PetscErrorCode ierr; 2345b89f26deSStefano Zampini 2346b89f26deSStefano Zampini PetscFunctionBegin; 2347b89f26deSStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2348b89f26deSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 2349b89f26deSStefano Zampini ierr = MatInvertBlockDiagonal(is->A,&lv);CHKERRQ(ierr); 2350b89f26deSStefano Zampini if (!is->bdiag) { 2351b89f26deSStefano Zampini ierr = PetscMalloc1(bs*mat->rmap->n,&is->bdiag);CHKERRQ(ierr); 2352b89f26deSStefano Zampini } 2353b89f26deSStefano Zampini ierr = MPI_Type_contiguous(bs,MPIU_SCALAR,&nodeType);CHKERRQ(ierr); 2354b89f26deSStefano Zampini ierr = MPI_Type_commit(&nodeType);CHKERRQ(ierr); 2355b89f26deSStefano Zampini ierr = PetscSFReduceBegin(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2356b89f26deSStefano Zampini ierr = PetscSFReduceEnd(is->sf,nodeType,lv,is->bdiag,MPIU_REPLACE);CHKERRQ(ierr); 2357b89f26deSStefano Zampini ierr = MPI_Type_free(&nodeType);CHKERRQ(ierr); 2358b89f26deSStefano Zampini if (values) *values = is->bdiag; 2359b89f26deSStefano Zampini PetscFunctionReturn(0); 2360b89f26deSStefano Zampini } 2361b89f26deSStefano Zampini 23628546b261SStefano Zampini static PetscErrorCode MatISSetUpScatters_Private(Mat A) 2363b4319ba4SBarry Smith { 2364e176bc59SStefano Zampini Vec cglobal,rglobal; 23658546b261SStefano Zampini IS from; 23668546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2367b89f26deSStefano Zampini PetscScalar sum; 23688546b261SStefano Zampini const PetscInt *garray; 23698546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 23708546b261SStefano Zampini PetscBool iscuda; 23718546b261SStefano Zampini PetscErrorCode ierr; 2372b4319ba4SBarry Smith 2373b4319ba4SBarry Smith PetscFunctionBegin; 23748546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nr);CHKERRQ(ierr); 23758546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->rmap->mapping,&rbs);CHKERRQ(ierr); 23768546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&nc);CHKERRQ(ierr); 23778546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(A->cmap->mapping,&cbs);CHKERRQ(ierr); 237870cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 237970cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 23803fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2381e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2382e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 23838546b261SStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2384*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_TRUE);CHKERRQ(ierr); 23858546b261SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)is->y,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 23868546b261SStefano Zampini if (iscuda) { 23878546b261SStefano Zampini ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 23888546b261SStefano Zampini ierr = PetscStrallocpy(VECCUDA,&A->defaultvectype);CHKERRQ(ierr); 23898546b261SStefano Zampini } 23908546b261SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 2391*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(rglobal,PETSC_TRUE);CHKERRQ(ierr); 23928546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 23938546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),rbs,nr/rbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 23949448b7f1SJunchao Zhang ierr = VecScatterCreate(rglobal,from,is->y,NULL,&is->rctx);CHKERRQ(ierr); 23958546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->rmap->mapping,&garray);CHKERRQ(ierr); 23968546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 23978546b261SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 23988546b261SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 23998546b261SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),cbs,nc/cbs,garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 24009448b7f1SJunchao Zhang ierr = VecScatterCreate(cglobal,from,is->x,NULL,&is->cctx);CHKERRQ(ierr); 24018546b261SStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(A->cmap->mapping,&garray);CHKERRQ(ierr); 24028546b261SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 24038546b261SStefano Zampini } else { 24048546b261SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 24058546b261SStefano Zampini is->cctx = is->rctx; 24068546b261SStefano Zampini } 2407b89f26deSStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 2408b89f26deSStefano Zampini 24098546b261SStefano Zampini /* interface counter vector (local) */ 24108546b261SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 2411*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_TRUE);CHKERRQ(ierr); 24128546b261SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 24138546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24148546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24158546b261SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 24168546b261SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2417*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->y,PETSC_FALSE);CHKERRQ(ierr); 2418*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(is->counter,PETSC_FALSE);CHKERRQ(ierr); 2419b89f26deSStefano Zampini 2420b89f26deSStefano Zampini /* special functions for block-diagonal matrices */ 2421b89f26deSStefano Zampini ierr = VecSum(rglobal,&sum);CHKERRQ(ierr); 2422b89f26deSStefano Zampini if ((PetscInt)(PetscRealPart(sum)) == A->rmap->N && A->rmap->N == A->cmap->N && A->rmap->mapping == A->cmap->mapping) { 2423b89f26deSStefano Zampini A->ops->invertblockdiagonal = MatInvertBlockDiagonal_IS; 2424b89f26deSStefano Zampini } else { 2425b89f26deSStefano Zampini A->ops->invertblockdiagonal = NULL; 2426b89f26deSStefano Zampini } 24278546b261SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2428b0cc1f67SStefano Zampini 2429b0cc1f67SStefano Zampini /* setup SF for general purpose shared indices based communications */ 2430b0cc1f67SStefano Zampini ierr = MatISSetUpSF_IS(A);CHKERRQ(ierr); 24318546b261SStefano Zampini PetscFunctionReturn(0); 24328546b261SStefano Zampini } 24338546b261SStefano Zampini 24348546b261SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 24358546b261SStefano Zampini { 24368546b261SStefano Zampini PetscErrorCode ierr; 24378546b261SStefano Zampini PetscInt nr,rbs,nc,cbs; 24388546b261SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 24398546b261SStefano Zampini 24408546b261SStefano Zampini PetscFunctionBegin; 24418546b261SStefano Zampini PetscCheckSameComm(A,1,rmapping,2); 24428546b261SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 24431c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2444872cf891SStefano Zampini if (is->csf != is->sf) { 2445872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2446872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2447f03112d0SStefano Zampini } else is->csf = NULL; 244828f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 244928f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 2450b89f26deSStefano Zampini ierr = PetscFree(is->bdiag);CHKERRQ(ierr); 24513bbff08aSStefano Zampini 24523bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2453fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2454fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2455e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2456e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2457e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2458e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 24596625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 24606625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 24616625354bSStefano Zampini PetscBool same,gsame; 24626625354bSStefano Zampini 24636625354bSStefano Zampini same = PETSC_FALSE; 24646625354bSStefano Zampini if (nr == nc && cbs == rbs) { 24656625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 24666625354bSStefano Zampini 24676625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24686625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 2469580bdb30SBarry Smith ierr = PetscArraycmp(idxs1,idxs2,nr/rbs,&same);CHKERRQ(ierr); 24706625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 24716625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 24726625354bSStefano Zampini } 24736625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 24746625354bSStefano Zampini if (gsame) cmapping = rmapping; 24756625354bSStefano Zampini } 247653b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->rmap,rbs);CHKERRQ(ierr); 247753b44cf5SStefano Zampini ierr = PetscLayoutSetBlockSize(A->cmap,cbs);CHKERRQ(ierr); 24786625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 24796625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 24806625354bSStefano Zampini 24816625354bSStefano Zampini /* Create the local matrix A */ 2482f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 24838546b261SStefano Zampini ierr = MatSetType(is->A,is->lmattype);CHKERRQ(ierr); 2484e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2485e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 24868546b261SStefano Zampini ierr = MatSetOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 24878546b261SStefano Zampini ierr = MatAppendOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2488c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2489c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2490b4319ba4SBarry Smith 2491f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 24928546b261SStefano Zampini ierr = MatISSetUpScatters_Private(A);CHKERRQ(ierr); 2493f26d0771SStefano Zampini } 249448ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2495b4319ba4SBarry Smith PetscFunctionReturn(0); 2496b4319ba4SBarry Smith } 2497b4319ba4SBarry Smith 2498a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 24992e74eeadSLisandro Dalcin { 25002e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 25012e74eeadSLisandro Dalcin PetscErrorCode ierr; 250297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 250397563a80SStefano Zampini PetscInt i,zm,zn; 250497563a80SStefano Zampini #endif 2505f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 25062e74eeadSLisandro Dalcin 25072e74eeadSLisandro Dalcin PetscFunctionBegin; 25082e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2509f26d0771SStefano 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); 251097563a80SStefano Zampini /* count negative indices */ 251197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 251297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 25132e74eeadSLisandro Dalcin #endif 251497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 251597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 251697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 251797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 251897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 251997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2520b4f971dfSStefano 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"); 2521b4f971dfSStefano 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"); 252297563a80SStefano Zampini #endif 25232e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 25242e74eeadSLisandro Dalcin PetscFunctionReturn(0); 25252e74eeadSLisandro Dalcin } 25262e74eeadSLisandro Dalcin 2527a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 252897563a80SStefano Zampini { 252997563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 253097563a80SStefano Zampini PetscErrorCode ierr; 253197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 253297563a80SStefano Zampini PetscInt i,zm,zn; 253397563a80SStefano Zampini #endif 2534f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 253597563a80SStefano Zampini 253697563a80SStefano Zampini PetscFunctionBegin; 253797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2538f26d0771SStefano 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); 253997563a80SStefano Zampini /* count negative indices */ 254097563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 254197563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 254297563a80SStefano Zampini #endif 254397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 254497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 254597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 254697563a80SStefano Zampini /* count negative indices (should be the same as before) */ 254797563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 254897563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2549b4f971dfSStefano 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"); 2550b4f971dfSStefano 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"); 255197563a80SStefano Zampini #endif 2552d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 255397563a80SStefano Zampini PetscFunctionReturn(0); 255497563a80SStefano Zampini } 255597563a80SStefano Zampini 2556a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2557b4319ba4SBarry Smith { 2558dfbe8321SBarry Smith PetscErrorCode ierr; 2559b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2560b4319ba4SBarry Smith 2561b4319ba4SBarry Smith PetscFunctionBegin; 2562b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2563872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2564872cf891SStefano Zampini } else { 2565b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2566872cf891SStefano Zampini } 2567b4319ba4SBarry Smith PetscFunctionReturn(0); 2568b4319ba4SBarry Smith } 2569b4319ba4SBarry Smith 2570a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2571f0006bf2SLisandro Dalcin { 2572f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2573f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2574f0006bf2SLisandro Dalcin 2575f0006bf2SLisandro Dalcin PetscFunctionBegin; 2576b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2577b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2578b4f971dfSStefano Zampini PetscInt ibs,bs; 2579b4f971dfSStefano Zampini 2580b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2581b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2582b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2583b4f971dfSStefano Zampini #endif 2584b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2585b4f971dfSStefano Zampini } else { 2586f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2587b4f971dfSStefano Zampini } 2588f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2589f0006bf2SLisandro Dalcin } 2590f0006bf2SLisandro Dalcin 2591f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2592f0ae7da4SStefano Zampini { 2593f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2594f0ae7da4SStefano Zampini PetscErrorCode ierr; 2595f0ae7da4SStefano Zampini 2596f0ae7da4SStefano Zampini PetscFunctionBegin; 2597f0ae7da4SStefano Zampini if (!n) { 2598f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2599f0ae7da4SStefano Zampini } else { 2600f0ae7da4SStefano Zampini PetscInt i; 2601f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2602f0ae7da4SStefano Zampini 2603f0ae7da4SStefano Zampini if (columns) { 2604f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2605f0ae7da4SStefano Zampini } else { 2606f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2607f0ae7da4SStefano Zampini } 2608f0ae7da4SStefano Zampini if (diag != 0.) { 2609f0ae7da4SStefano Zampini const PetscScalar *array; 2610f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2611f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2612f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2613f0ae7da4SStefano Zampini } 2614f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2615f0ae7da4SStefano Zampini } 2616f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2617f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2618f0ae7da4SStefano Zampini } 2619f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2620f0ae7da4SStefano Zampini } 2621f0ae7da4SStefano Zampini 2622f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 26232e74eeadSLisandro Dalcin { 26246e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 26256e520ac8SStefano Zampini PetscInt nr,nl,len,i; 26266e520ac8SStefano Zampini PetscInt *lrows; 26272e74eeadSLisandro Dalcin PetscErrorCode ierr; 26282e74eeadSLisandro Dalcin 26292e74eeadSLisandro Dalcin PetscFunctionBegin; 2630f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2631f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2632f0ae7da4SStefano Zampini PetscBool cong; 263326b0207aSStefano Zampini 2634f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 263526b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2636268753edSStefano 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"); 2637268753edSStefano 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"); 2638268753edSStefano 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"); 2639f0ae7da4SStefano Zampini } 2640f0ae7da4SStefano Zampini #endif 26416e520ac8SStefano Zampini /* get locally owned rows */ 2642a72d46e8SStefano Zampini ierr = PetscLayoutMapLocal(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 26436e520ac8SStefano Zampini /* fix right hand side if needed */ 26446e520ac8SStefano Zampini if (x && b) { 26456e520ac8SStefano Zampini const PetscScalar *xx; 26466e520ac8SStefano Zampini PetscScalar *bb; 26476e520ac8SStefano Zampini 26486e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 26496e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 26506e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 26516e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 26526e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 26532e74eeadSLisandro Dalcin } 26546e520ac8SStefano Zampini /* get rows associated to the local matrices */ 26556e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 2656580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,nl);CHKERRQ(ierr); 2657580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,A->rmap->n);CHKERRQ(ierr); 26586e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 26596e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26606e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26616e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 26626e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 26636e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2664f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 26656e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 26662e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26672e74eeadSLisandro Dalcin } 26682e74eeadSLisandro Dalcin 2669f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2670b4319ba4SBarry Smith { 2671dfbe8321SBarry Smith PetscErrorCode ierr; 2672b4319ba4SBarry Smith 2673b4319ba4SBarry Smith PetscFunctionBegin; 2674f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2675f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2676f0ae7da4SStefano Zampini } 26772205254eSKarl Rupp 2678f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2679f0ae7da4SStefano Zampini { 2680f0ae7da4SStefano Zampini PetscErrorCode ierr; 2681f0ae7da4SStefano Zampini 2682f0ae7da4SStefano Zampini PetscFunctionBegin; 2683f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2684b4319ba4SBarry Smith PetscFunctionReturn(0); 2685b4319ba4SBarry Smith } 2686b4319ba4SBarry Smith 2687a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2688b4319ba4SBarry Smith { 2689b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2690dfbe8321SBarry Smith PetscErrorCode ierr; 2691b4319ba4SBarry Smith 2692b4319ba4SBarry Smith PetscFunctionBegin; 2693b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2694b4319ba4SBarry Smith PetscFunctionReturn(0); 2695b4319ba4SBarry Smith } 2696b4319ba4SBarry Smith 2697a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2698b4319ba4SBarry Smith { 2699b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2700dfbe8321SBarry Smith PetscErrorCode ierr; 2701b4319ba4SBarry Smith 2702b4319ba4SBarry Smith PetscFunctionBegin; 2703b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2704872cf891SStefano Zampini /* fix for local empty rows/cols */ 2705872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2706872cf891SStefano Zampini Mat newlA; 2707f03112d0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2708f03112d0SStefano Zampini IS nzr,nzc; 2709f03112d0SStefano Zampini PetscInt nr,nc,nnzr,nnzc; 2710f03112d0SStefano Zampini PetscBool lnewl2g,newl2g; 2711872cf891SStefano Zampini 2712f03112d0SStefano Zampini ierr = MatGetSize(is->A,&nr,&nc);CHKERRQ(ierr); 2713f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_FALSE,PETSC_SMALL,&nzr);CHKERRQ(ierr); 2714f03112d0SStefano Zampini if (!nzr) { 2715f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&nzr);CHKERRQ(ierr); 2716872cf891SStefano Zampini } 2717f03112d0SStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(is->A,PETSC_TRUE,PETSC_SMALL,&nzc);CHKERRQ(ierr); 2718f03112d0SStefano Zampini if (!nzc) { 2719f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&nzc);CHKERRQ(ierr); 2720872cf891SStefano Zampini } 2721f03112d0SStefano Zampini ierr = ISGetSize(nzr,&nnzr);CHKERRQ(ierr); 2722f03112d0SStefano Zampini ierr = ISGetSize(nzc,&nnzc);CHKERRQ(ierr); 2723f03112d0SStefano Zampini if (nnzr != nr || nnzc != nc) { 2724f03112d0SStefano Zampini ISLocalToGlobalMapping l2g; 2725f03112d0SStefano Zampini IS is1,is2; 2726f03112d0SStefano Zampini 2727f03112d0SStefano Zampini /* need new global l2g map */ 2728f03112d0SStefano Zampini lnewl2g = PETSC_TRUE; 2729f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2730f03112d0SStefano Zampini 2731872cf891SStefano Zampini /* extract valid submatrix */ 2732f03112d0SStefano Zampini ierr = MatCreateSubMatrix(is->A,nzr,nzc,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2733f03112d0SStefano Zampini 2734f03112d0SStefano Zampini /* attach local l2g maps for successive calls of MatSetValues on the local matrix */ 2735f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzr,&l2g);CHKERRQ(ierr); 2736f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nr,0,1,&is1);CHKERRQ(ierr); 2737f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2738872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 273972ed36d8SStefano Zampini if (is->A->rmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 274072ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 274172ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 274272ed36d8SStefano Zampini 274372ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->rmap->mapping,&nl);CHKERRQ(ierr); 274472ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 274572ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 274672ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 274772ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 274872ed36d8SStefano Zampini if (j != nr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nr); 274972ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->rmap->mapping,&idxs1);CHKERRQ(ierr); 275072ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 275172ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 275272ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->rmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 275372ed36d8SStefano Zampini } 2754f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&rl2g);CHKERRQ(ierr); 2755f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2756f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 275772ed36d8SStefano Zampini 2758f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nzc,&l2g);CHKERRQ(ierr); 2759f03112d0SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is->A),nc,0,1,&is1);CHKERRQ(ierr); 2760f03112d0SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_MASK,is1,&is2);CHKERRQ(ierr); 2761f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 276272ed36d8SStefano Zampini if (is->A->cmap->mapping) { /* the matrix has a local-to-local map already attached (probably DMDA generated) */ 276372ed36d8SStefano Zampini const PetscInt *idxs1,*idxs2; 276472ed36d8SStefano Zampini PetscInt j,i,nl,*tidxs; 276572ed36d8SStefano Zampini 276672ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(is->A->cmap->mapping,&nl);CHKERRQ(ierr); 276772ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 276872ed36d8SStefano Zampini ierr = PetscMalloc1(nl,&tidxs);CHKERRQ(ierr); 276972ed36d8SStefano Zampini ierr = ISGetIndices(is2,&idxs2);CHKERRQ(ierr); 277072ed36d8SStefano Zampini for (i=0,j=0;i<nl;i++) tidxs[i] = idxs1[i] < 0 ? -1 : idxs2[j++]; 277172ed36d8SStefano Zampini if (j != nc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected count %D != %D",j,nc); 277272ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(is->A->cmap->mapping,&idxs1);CHKERRQ(ierr); 277372ed36d8SStefano Zampini ierr = ISRestoreIndices(is2,&idxs2);CHKERRQ(ierr); 277472ed36d8SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 277572ed36d8SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A->cmap->mapping),nl,tidxs,PETSC_OWN_POINTER,&is2);CHKERRQ(ierr); 277672ed36d8SStefano Zampini } 2777f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is2,&cl2g);CHKERRQ(ierr); 2778f03112d0SStefano Zampini ierr = ISDestroy(&is1);CHKERRQ(ierr); 2779f03112d0SStefano Zampini ierr = ISDestroy(&is2);CHKERRQ(ierr); 278072ed36d8SStefano Zampini 2781f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,rl2g,cl2g);CHKERRQ(ierr); 278272ed36d8SStefano Zampini 2783f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2784f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2785f03112d0SStefano Zampini } else { /* local matrix fully populated */ 2786f03112d0SStefano Zampini lnewl2g = PETSC_FALSE; 2787f03112d0SStefano Zampini ierr = MPI_Allreduce(&lnewl2g,&newl2g,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 2788f03112d0SStefano Zampini ierr = PetscObjectReference((PetscObject)is->A);CHKERRQ(ierr); 2789f03112d0SStefano Zampini newlA = is->A; 2790f03112d0SStefano Zampini } 2791f03112d0SStefano Zampini /* attach new global l2g map if needed */ 2792f03112d0SStefano Zampini if (newl2g) { 2793f03112d0SStefano Zampini IS gnzr,gnzc; 2794f03112d0SStefano Zampini const PetscInt *grid,*gcid; 2795f03112d0SStefano Zampini 2796f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->rmap->mapping,nzr,&gnzr);CHKERRQ(ierr); 2797f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(A->cmap->mapping,nzc,&gnzc);CHKERRQ(ierr); 2798f03112d0SStefano Zampini ierr = ISGetIndices(gnzr,&grid);CHKERRQ(ierr); 2799f03112d0SStefano Zampini ierr = ISGetIndices(gnzc,&gcid);CHKERRQ(ierr); 2800f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzr,grid,PETSC_COPY_VALUES,&rl2g);CHKERRQ(ierr); 2801f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,nnzc,gcid,PETSC_COPY_VALUES,&cl2g);CHKERRQ(ierr); 2802f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzr,&grid);CHKERRQ(ierr); 2803f03112d0SStefano Zampini ierr = ISRestoreIndices(gnzc,&gcid);CHKERRQ(ierr); 2804f03112d0SStefano Zampini ierr = ISDestroy(&gnzr);CHKERRQ(ierr); 2805f03112d0SStefano Zampini ierr = ISDestroy(&gnzc);CHKERRQ(ierr); 2806f03112d0SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g);CHKERRQ(ierr); 2807f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2808f03112d0SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2809f03112d0SStefano Zampini } 2810872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2811872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2812f03112d0SStefano Zampini ierr = ISDestroy(&nzr);CHKERRQ(ierr); 2813f03112d0SStefano Zampini ierr = ISDestroy(&nzc);CHKERRQ(ierr); 2814872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2815f03112d0SStefano Zampini } 2816b4319ba4SBarry Smith PetscFunctionReturn(0); 2817b4319ba4SBarry Smith } 2818b4319ba4SBarry Smith 2819a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2820b4319ba4SBarry Smith { 2821b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2822b4319ba4SBarry Smith 2823b4319ba4SBarry Smith PetscFunctionBegin; 2824b4319ba4SBarry Smith *local = is->A; 2825b4319ba4SBarry Smith PetscFunctionReturn(0); 2826b4319ba4SBarry Smith } 2827b4319ba4SBarry Smith 28283b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 28293b3b1effSJed Brown { 28303b3b1effSJed Brown PetscFunctionBegin; 28313b3b1effSJed Brown *local = NULL; 28323b3b1effSJed Brown PetscFunctionReturn(0); 28333b3b1effSJed Brown } 28343b3b1effSJed Brown 2835b4319ba4SBarry Smith /*@ 2836b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2837b4319ba4SBarry Smith 2838b4319ba4SBarry Smith Input Parameter: 2839b4319ba4SBarry Smith . mat - the matrix 2840b4319ba4SBarry Smith 2841b4319ba4SBarry Smith Output Parameter: 2842eb82efa4SStefano Zampini . local - the local matrix 2843b4319ba4SBarry Smith 2844b4319ba4SBarry Smith Level: advanced 2845b4319ba4SBarry Smith 2846b4319ba4SBarry Smith Notes: 2847b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2848b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2849b4319ba4SBarry Smith of the MatSetValues() operation. 2850b4319ba4SBarry Smith 28513b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 285296a6f129SJed Brown 2853b4319ba4SBarry Smith .seealso: MATIS 2854b4319ba4SBarry Smith @*/ 28557087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2856b4319ba4SBarry Smith { 28574ac538c5SBarry Smith PetscErrorCode ierr; 2858b4319ba4SBarry Smith 2859b4319ba4SBarry Smith PetscFunctionBegin; 28600700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2861b4319ba4SBarry Smith PetscValidPointer(local,2); 28624ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2863b4319ba4SBarry Smith PetscFunctionReturn(0); 2864b4319ba4SBarry Smith } 2865b4319ba4SBarry Smith 28663b3b1effSJed Brown /*@ 28673b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 28683b3b1effSJed Brown 28693b3b1effSJed Brown Input Parameter: 28703b3b1effSJed Brown . mat - the matrix 28713b3b1effSJed Brown 28723b3b1effSJed Brown Output Parameter: 28733b3b1effSJed Brown . local - the local matrix 28743b3b1effSJed Brown 28753b3b1effSJed Brown Level: advanced 28763b3b1effSJed Brown 28773b3b1effSJed Brown .seealso: MATIS 28783b3b1effSJed Brown @*/ 28793b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 28803b3b1effSJed Brown { 28813b3b1effSJed Brown PetscErrorCode ierr; 28823b3b1effSJed Brown 28833b3b1effSJed Brown PetscFunctionBegin; 28843b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 28853b3b1effSJed Brown PetscValidPointer(local,2); 28863b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 28873b3b1effSJed Brown PetscFunctionReturn(0); 28883b3b1effSJed Brown } 28893b3b1effSJed Brown 28908546b261SStefano Zampini static PetscErrorCode MatISSetLocalMatType_IS(Mat mat,MatType mtype) 28918546b261SStefano Zampini { 28928546b261SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 28938546b261SStefano Zampini PetscErrorCode ierr; 28948546b261SStefano Zampini 28958546b261SStefano Zampini PetscFunctionBegin; 28968546b261SStefano Zampini if (is->A) { 28978546b261SStefano Zampini ierr = MatSetType(is->A,mtype);CHKERRQ(ierr); 28988546b261SStefano Zampini } 28998546b261SStefano Zampini ierr = PetscFree(is->lmattype);CHKERRQ(ierr); 29008546b261SStefano Zampini ierr = PetscStrallocpy(mtype,&is->lmattype);CHKERRQ(ierr); 29018546b261SStefano Zampini PetscFunctionReturn(0); 29028546b261SStefano Zampini } 29038546b261SStefano Zampini 29048546b261SStefano Zampini /*@ 29058546b261SStefano Zampini MatISSetLocalMatType - Specifies the type of local matrix 29068546b261SStefano Zampini 29078546b261SStefano Zampini Input Parameter: 2908a2b725a8SWilliam Gropp + mat - the matrix 2909a2b725a8SWilliam Gropp - mtype - the local matrix type 29108546b261SStefano Zampini 29118546b261SStefano Zampini Output Parameter: 29128546b261SStefano Zampini 29138546b261SStefano Zampini Level: advanced 29148546b261SStefano Zampini 29158546b261SStefano Zampini .seealso: MATIS, MatSetType(), MatType 29168546b261SStefano Zampini @*/ 29178546b261SStefano Zampini PetscErrorCode MatISSetLocalMatType(Mat mat,MatType mtype) 29188546b261SStefano Zampini { 29198546b261SStefano Zampini PetscErrorCode ierr; 29208546b261SStefano Zampini 29218546b261SStefano Zampini PetscFunctionBegin; 29228546b261SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 29238546b261SStefano Zampini ierr = PetscUseMethod(mat,"MatISSetLocalMatType_C",(Mat,MatType),(mat,mtype));CHKERRQ(ierr); 29248546b261SStefano Zampini PetscFunctionReturn(0); 29258546b261SStefano Zampini } 29268546b261SStefano Zampini 2927a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 29283b03a366Sstefano_zampini { 29293b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 29303b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 29313b03a366Sstefano_zampini PetscErrorCode ierr; 29328546b261SStefano Zampini MatType mtype,otype; 29338546b261SStefano Zampini PetscBool sametype = PETSC_TRUE; 29343b03a366Sstefano_zampini 29353b03a366Sstefano_zampini PetscFunctionBegin; 29364e4c7dbeSStefano Zampini if (is->A) { 29373b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 29383b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2939f0ae7da4SStefano 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); 29408546b261SStefano Zampini ierr = MatGetType(local,&mtype);CHKERRQ(ierr); 29418546b261SStefano Zampini ierr = MatGetType(is->A,&otype);CHKERRQ(ierr); 29428546b261SStefano Zampini ierr = PetscStrcmp(mtype,otype,&sametype);CHKERRQ(ierr); 29434e4c7dbeSStefano Zampini } 29443b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 29453b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 29463b03a366Sstefano_zampini is->A = local; 29478546b261SStefano Zampini ierr = MatGetType(is->A,&mtype);CHKERRQ(ierr); 29488546b261SStefano Zampini ierr = MatISSetLocalMatType(mat,mtype);CHKERRQ(ierr); 29498546b261SStefano Zampini if (!sametype && !is->islocalref) { 29508546b261SStefano Zampini ierr = MatISSetUpScatters_Private(mat);CHKERRQ(ierr); 29518546b261SStefano Zampini } 29523b03a366Sstefano_zampini PetscFunctionReturn(0); 29533b03a366Sstefano_zampini } 29543b03a366Sstefano_zampini 29553b03a366Sstefano_zampini /*@ 2956eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 29573b03a366Sstefano_zampini 29588546b261SStefano Zampini Collective on Mat 29598546b261SStefano Zampini 29603b03a366Sstefano_zampini Input Parameter: 2961a2b725a8SWilliam Gropp + mat - the matrix 2962a2b725a8SWilliam Gropp - local - the local matrix 29633b03a366Sstefano_zampini 29643b03a366Sstefano_zampini Output Parameter: 29653b03a366Sstefano_zampini 29663b03a366Sstefano_zampini Level: advanced 29673b03a366Sstefano_zampini 29683b03a366Sstefano_zampini Notes: 29693b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 29703b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 29713b03a366Sstefano_zampini 29723b03a366Sstefano_zampini .seealso: MATIS 29733b03a366Sstefano_zampini @*/ 29743b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 29753b03a366Sstefano_zampini { 29763b03a366Sstefano_zampini PetscErrorCode ierr; 29773b03a366Sstefano_zampini 29783b03a366Sstefano_zampini PetscFunctionBegin; 29793b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2980b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 29813b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 29823b03a366Sstefano_zampini PetscFunctionReturn(0); 29833b03a366Sstefano_zampini } 29843b03a366Sstefano_zampini 2985a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 29866726f965SBarry Smith { 29876726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 29886726f965SBarry Smith PetscErrorCode ierr; 29896726f965SBarry Smith 29906726f965SBarry Smith PetscFunctionBegin; 29916726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 29926726f965SBarry Smith PetscFunctionReturn(0); 29936726f965SBarry Smith } 29946726f965SBarry Smith 2995a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 29962e74eeadSLisandro Dalcin { 29972e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 29982e74eeadSLisandro Dalcin PetscErrorCode ierr; 29992e74eeadSLisandro Dalcin 30002e74eeadSLisandro Dalcin PetscFunctionBegin; 30012e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 30022e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30032e74eeadSLisandro Dalcin } 30042e74eeadSLisandro Dalcin 3005a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 30062e74eeadSLisandro Dalcin { 30072e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 30082e74eeadSLisandro Dalcin PetscErrorCode ierr; 30092e74eeadSLisandro Dalcin 30102e74eeadSLisandro Dalcin PetscFunctionBegin; 30112e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 3012e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 30132e74eeadSLisandro Dalcin 30142e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 30152e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 3016e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3017e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 30182e74eeadSLisandro Dalcin PetscFunctionReturn(0); 30192e74eeadSLisandro Dalcin } 30202e74eeadSLisandro Dalcin 3021a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 30226726f965SBarry Smith { 30236726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 30246726f965SBarry Smith PetscErrorCode ierr; 30256726f965SBarry Smith 30266726f965SBarry Smith PetscFunctionBegin; 30274e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 30286726f965SBarry Smith PetscFunctionReturn(0); 30296726f965SBarry Smith } 30306726f965SBarry Smith 3031f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 3032f26d0771SStefano Zampini { 3033f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 3034f26d0771SStefano Zampini Mat_IS *x; 3035f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3036f26d0771SStefano Zampini PetscBool ismatis; 3037f26d0771SStefano Zampini #endif 3038f26d0771SStefano Zampini PetscErrorCode ierr; 3039f26d0771SStefano Zampini 3040f26d0771SStefano Zampini PetscFunctionBegin; 3041f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3042f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 3043f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 3044f26d0771SStefano Zampini #endif 3045f26d0771SStefano Zampini x = (Mat_IS*)X->data; 3046f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 3047f26d0771SStefano Zampini PetscFunctionReturn(0); 3048f26d0771SStefano Zampini } 3049f26d0771SStefano Zampini 3050f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 3051f26d0771SStefano Zampini { 3052f26d0771SStefano Zampini Mat lA; 3053f26d0771SStefano Zampini Mat_IS *matis; 3054f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 3055f26d0771SStefano Zampini IS is; 3056f26d0771SStefano Zampini const PetscInt *rg,*rl; 3057f26d0771SStefano Zampini PetscInt nrg; 3058f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 3059f26d0771SStefano Zampini PetscErrorCode ierr; 3060f26d0771SStefano Zampini 3061f26d0771SStefano Zampini PetscFunctionBegin; 3062f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3063f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 3064f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 3065f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 3066f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3067249c8a71SStefano 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); 3068f26d0771SStefano Zampini #endif 3069f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 3070f26d0771SStefano Zampini /* map from [0,nrl) to row */ 3071f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 3072f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 3073f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 3074f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 3075f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3076f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3077f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3078f26d0771SStefano Zampini /* compute new l2g map for columns */ 3079f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 3080f26d0771SStefano Zampini const PetscInt *cg,*cl; 3081f26d0771SStefano Zampini PetscInt ncg; 3082f26d0771SStefano Zampini PetscInt ncl; 3083f26d0771SStefano Zampini 3084f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3085f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 3086f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 3087f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 3088f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 3089249c8a71SStefano 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); 3090f26d0771SStefano Zampini #endif 3091f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 3092f26d0771SStefano Zampini /* map from [0,ncl) to col */ 3093f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 3094f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 3095f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 3096f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 3097f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3098f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3099f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3100f26d0771SStefano Zampini } else { 3101f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 3102f26d0771SStefano Zampini cl2g = rl2g; 3103f26d0771SStefano Zampini } 3104f26d0771SStefano Zampini /* create the MATIS submatrix */ 3105f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 3106f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 3107f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3108f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 3109b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 3110f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 3111f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 3112f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 3113f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 3114f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 3115f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3116f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3117f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3118f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3119f26d0771SStefano Zampini /* remove unsupported ops */ 3120f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3121f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 3122f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 3123f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 3124f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 3125f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 3126f26d0771SStefano Zampini PetscFunctionReturn(0); 3127f26d0771SStefano Zampini } 3128f26d0771SStefano Zampini 3129872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 3130872cf891SStefano Zampini { 3131872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 31328546b261SStefano Zampini char type[256]; 31338546b261SStefano Zampini PetscBool flg; 3134872cf891SStefano Zampini PetscErrorCode ierr; 3135872cf891SStefano Zampini 3136872cf891SStefano Zampini PetscFunctionBegin; 3137872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 3138f03112d0SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns","MatISFixLocalEmpty",a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 313975d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 31408546b261SStefano Zampini ierr = PetscOptionsFList("-matis_localmat_type","Matrix type","MatISSetLocalMatType",MatList,a->lmattype,type,256,&flg);CHKERRQ(ierr); 31418546b261SStefano Zampini if (flg) { 31428546b261SStefano Zampini ierr = MatISSetLocalMatType(A,type);CHKERRQ(ierr); 31438546b261SStefano Zampini } 31448546b261SStefano Zampini if (a->A) { 31458546b261SStefano Zampini ierr = MatSetFromOptions(a->A);CHKERRQ(ierr); 31468546b261SStefano Zampini } 31470af67c1bSStefano Zampini ierr = PetscOptionsTail();CHKERRQ(ierr); 3148872cf891SStefano Zampini PetscFunctionReturn(0); 3149872cf891SStefano Zampini } 3150872cf891SStefano Zampini 3151284134d9SBarry Smith /*@ 31523c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 3153284134d9SBarry Smith process but not across processes. 3154284134d9SBarry Smith 3155284134d9SBarry Smith Input Parameters: 3156284134d9SBarry Smith + comm - MPI communicator that will share the matrix 3157e176bc59SStefano Zampini . bs - block size of the matrix 3158df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 3159e176bc59SStefano Zampini . rmap - local to global map for rows 3160e176bc59SStefano Zampini - cmap - local to global map for cols 3161284134d9SBarry Smith 3162284134d9SBarry Smith Output Parameter: 3163284134d9SBarry Smith . A - the resulting matrix 3164284134d9SBarry Smith 31658e6c10adSSatish Balay Level: advanced 31668e6c10adSSatish Balay 316795452b02SPatrick Sanan Notes: 316895452b02SPatrick Sanan See MATIS for more details. 31696fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 31706fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 31713c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 3172284134d9SBarry Smith 3173284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 3174284134d9SBarry Smith @*/ 3175e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 3176284134d9SBarry Smith { 3177284134d9SBarry Smith PetscErrorCode ierr; 3178284134d9SBarry Smith 3179284134d9SBarry Smith PetscFunctionBegin; 31806fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 3181284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3182284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 31836fdf41d1SStefano Zampini if (bs > 0) { 3184284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 31856fdf41d1SStefano Zampini } 3186284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 3187e176bc59SStefano Zampini if (rmap && cmap) { 3188e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 3189e176bc59SStefano Zampini } else if (!rmap) { 3190e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 3191e176bc59SStefano Zampini } else { 3192e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 3193e176bc59SStefano Zampini } 3194284134d9SBarry Smith PetscFunctionReturn(0); 3195284134d9SBarry Smith } 3196284134d9SBarry Smith 3197b4319ba4SBarry Smith /*MC 3198f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 3199b89f26deSStefano Zampini This stores the matrices in globally unassembled form. Each processor assembles only its local Neumann problem and the parallel matrix vector 3200b4319ba4SBarry Smith product is handled "implicitly". 3201b4319ba4SBarry Smith 3202b4319ba4SBarry Smith Options Database Keys: 320375d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 320475d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 320575d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 3206b4319ba4SBarry Smith 320795452b02SPatrick Sanan Notes: 320895452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 3209b4319ba4SBarry Smith 3210b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 3211b4319ba4SBarry Smith 3212b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 3213eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 3214b4319ba4SBarry Smith 3215b4319ba4SBarry Smith Level: advanced 3216b4319ba4SBarry Smith 3217f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 3218b4319ba4SBarry Smith 3219b4319ba4SBarry Smith M*/ 3220b4319ba4SBarry Smith 32218cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 3222b4319ba4SBarry Smith { 3223dfbe8321SBarry Smith PetscErrorCode ierr; 3224b4319ba4SBarry Smith Mat_IS *b; 3225b4319ba4SBarry Smith 3226b4319ba4SBarry Smith PetscFunctionBegin; 3227b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 32288546b261SStefano Zampini ierr = PetscStrallocpy(MATAIJ,&b->lmattype);CHKERRQ(ierr); 3229b4319ba4SBarry Smith A->data = (void*)b; 3230b4319ba4SBarry Smith 3231e176bc59SStefano Zampini /* matrix ops */ 3232e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 3233b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 32342e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 32352e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 32362e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 3237b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 3238b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 32392e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 324098921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 3241b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 3242f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 32432e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 3244f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 3245b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 3246b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 3247b4319ba4SBarry Smith A->ops->view = MatView_IS; 32486726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 32492e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 32502e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 32516726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 325269796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 325369796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 325445471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 3255ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 32566bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 32572b404112SStefano Zampini A->ops->copy = MatCopy_IS; 3258659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 32597dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 3260f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 32613fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 32623fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 3263d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 32647fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 3265ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 3266872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 3267b4319ba4SBarry Smith 3268b7ce53b6SStefano Zampini /* special MATIS functions */ 32698546b261SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMatType_C",MatISSetLocalMatType_IS);CHKERRQ(ierr); 3270bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 32713b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 3272bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 3273487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 32742e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 327575d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 3276f03112d0SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISFixLocalEmpty_C",MatISFixLocalEmpty_IS);CHKERRQ(ierr); 3277487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpiaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3278487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpibaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3279487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_mpisbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3280487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3281487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3282487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_seqsbaij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 3283487b449aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_is_aij_C",MatConvert_IS_XAIJ);CHKERRQ(ierr); 328417667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 3285b4319ba4SBarry Smith PetscFunctionReturn(0); 3286b4319ba4SBarry Smith } 3287