1b4319ba4SBarry Smith /* 2b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 3b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 4b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 5b4319ba4SBarry Smith product is handled "implicitly". 6b4319ba4SBarry Smith 7b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 8b4319ba4SBarry Smith */ 9b4319ba4SBarry Smith 10c6db04a5SJed Brown #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 114f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1228f4e0baSStefano Zampini 13f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 14b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 15b4f971dfSStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const PetscScalar*,InsertMode); 16f26d0771SStefano Zampini 1775d48cdbSStefano Zampini static PetscErrorCode MatISContainerDestroyPtAP_Private(void *ptr) 1875d48cdbSStefano Zampini { 1975d48cdbSStefano Zampini MatISPtAP ptap = (MatISPtAP)ptr; 2075d48cdbSStefano Zampini PetscErrorCode ierr; 2175d48cdbSStefano Zampini 2275d48cdbSStefano Zampini PetscFunctionBegin; 2375d48cdbSStefano Zampini ierr = MatDestroySubMatrices(ptap->ris1 ? 2 : 1,&ptap->lP);CHKERRQ(ierr); 2475d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis0);CHKERRQ(ierr); 2575d48cdbSStefano Zampini ierr = ISDestroy(&ptap->cis1);CHKERRQ(ierr); 2675d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris0);CHKERRQ(ierr); 2775d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 2875d48cdbSStefano Zampini ierr = PetscFree(ptap);CHKERRQ(ierr); 2975d48cdbSStefano Zampini PetscFunctionReturn(0); 3075d48cdbSStefano Zampini } 3175d48cdbSStefano Zampini 3275d48cdbSStefano Zampini static PetscErrorCode MatPtAPNumeric_IS_XAIJ(Mat A, Mat P, Mat C) 3375d48cdbSStefano Zampini { 3475d48cdbSStefano Zampini MatISPtAP ptap; 3575d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 3675d48cdbSStefano Zampini Mat lA,lC; 3775d48cdbSStefano Zampini MatReuse reuse; 3875d48cdbSStefano Zampini IS ris[2],cis[2]; 3975d48cdbSStefano Zampini PetscContainer c; 4075d48cdbSStefano Zampini PetscInt n; 4175d48cdbSStefano Zampini PetscErrorCode ierr; 4275d48cdbSStefano Zampini 4375d48cdbSStefano Zampini PetscFunctionBegin; 4475d48cdbSStefano Zampini ierr = PetscObjectQuery((PetscObject)(C),"_MatIS_PtAP",(PetscObject*)&c);CHKERRQ(ierr); 4575d48cdbSStefano Zampini if (!c) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing PtAP information"); 4675d48cdbSStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&ptap);CHKERRQ(ierr); 4775d48cdbSStefano Zampini ris[0] = ptap->ris0; 4875d48cdbSStefano Zampini ris[1] = ptap->ris1; 4975d48cdbSStefano Zampini cis[0] = ptap->cis0; 5075d48cdbSStefano Zampini cis[1] = ptap->cis1; 5175d48cdbSStefano Zampini n = ptap->ris1 ? 2 : 1; 5275d48cdbSStefano Zampini reuse = ptap->lP ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX; 5375d48cdbSStefano Zampini ierr = MatCreateSubMatrices(P,n,ris,cis,reuse,&ptap->lP);CHKERRQ(ierr); 5475d48cdbSStefano Zampini 5575d48cdbSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 5675d48cdbSStefano Zampini ierr = MatISGetLocalMat(C,&lC);CHKERRQ(ierr); 5775d48cdbSStefano Zampini if (ptap->ris1) { /* unsymmetric A mapping */ 5875d48cdbSStefano Zampini Mat lPt; 5975d48cdbSStefano Zampini 6075d48cdbSStefano Zampini ierr = MatTranspose(ptap->lP[1],MAT_INITIAL_MATRIX,&lPt);CHKERRQ(ierr); 6175d48cdbSStefano Zampini ierr = MatMatMatMult(lPt,lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6275d48cdbSStefano Zampini if (matis->storel2l) { 6375d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",(PetscObject)lPt);CHKERRQ(ierr); 6475d48cdbSStefano Zampini } 6575d48cdbSStefano Zampini ierr = MatDestroy(&lPt);CHKERRQ(ierr); 6675d48cdbSStefano Zampini } else { 6775d48cdbSStefano Zampini ierr = MatPtAP(lA,ptap->lP[0],reuse,ptap->fill,&lC);CHKERRQ(ierr); 6875d48cdbSStefano Zampini if (matis->storel2l) { 6975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(C),"_MatIS_PtAP_l2l",(PetscObject)ptap->lP[0]);CHKERRQ(ierr); 7075d48cdbSStefano Zampini } 7175d48cdbSStefano Zampini } 7275d48cdbSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7375d48cdbSStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 7475d48cdbSStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 7575d48cdbSStefano Zampini } 7675d48cdbSStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7775d48cdbSStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7875d48cdbSStefano Zampini PetscFunctionReturn(0); 7975d48cdbSStefano Zampini } 8075d48cdbSStefano Zampini 8175d48cdbSStefano Zampini static PetscErrorCode MatGetNonzeroColumnsLocal_Private(Mat PT,IS *cis) 8275d48cdbSStefano Zampini { 8375d48cdbSStefano Zampini Mat Po,Pd; 8475d48cdbSStefano Zampini IS zd,zo; 8575d48cdbSStefano Zampini const PetscInt *garray; 8675d48cdbSStefano Zampini PetscInt *aux,i,bs; 8775d48cdbSStefano Zampini PetscInt dc,stc,oc,ctd,cto; 8875d48cdbSStefano Zampini PetscBool ismpiaij,ismpibaij,isseqaij,isseqbaij; 8975d48cdbSStefano Zampini MPI_Comm comm; 9075d48cdbSStefano Zampini PetscErrorCode ierr; 9175d48cdbSStefano Zampini 9275d48cdbSStefano Zampini PetscFunctionBegin; 9375d48cdbSStefano Zampini PetscValidHeaderSpecific(PT,MAT_CLASSID,1); 9475d48cdbSStefano Zampini PetscValidPointer(cis,2); 9575d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)PT,&comm);CHKERRQ(ierr); 9675d48cdbSStefano Zampini bs = 1; 9775d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 9875d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 9904637862SRichard Tran Mills ierr = PetscObjectBaseTypeCompare((PetscObject)PT,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 10075d48cdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)PT,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 10175d48cdbSStefano Zampini if (isseqaij || isseqbaij) { 10275d48cdbSStefano Zampini Pd = PT; 10375d48cdbSStefano Zampini Po = NULL; 10475d48cdbSStefano Zampini garray = NULL; 10575d48cdbSStefano Zampini } else if (ismpiaij) { 10675d48cdbSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10775d48cdbSStefano Zampini } else if (ismpibaij) { 10875d48cdbSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(PT,&Pd,&Po,&garray);CHKERRQ(ierr); 10975d48cdbSStefano Zampini ierr = MatGetBlockSize(PT,&bs);CHKERRQ(ierr); 11075d48cdbSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(PT))->type_name); 11175d48cdbSStefano Zampini 11275d48cdbSStefano Zampini /* identify any null columns in Pd or Po */ 11322f7620eSStefano Zampini /* We use a tolerance comparison since it may happen that, with geometric multigrid, 11422f7620eSStefano Zampini some of the columns are not really zero, but very close to */ 11575d48cdbSStefano Zampini zo = zd = NULL; 11675d48cdbSStefano Zampini if (Po) { 11722f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Po,PETSC_TRUE,PETSC_SMALL,&zo);CHKERRQ(ierr); 11875d48cdbSStefano Zampini } 11922f7620eSStefano Zampini ierr = MatFindNonzeroRowsOrCols_Basic(Pd,PETSC_TRUE,PETSC_SMALL,&zd);CHKERRQ(ierr); 12075d48cdbSStefano Zampini 12175d48cdbSStefano Zampini ierr = MatGetLocalSize(PT,NULL,&dc);CHKERRQ(ierr); 12275d48cdbSStefano Zampini ierr = MatGetOwnershipRangeColumn(PT,&stc,NULL);CHKERRQ(ierr); 12375d48cdbSStefano Zampini if (Po) { ierr = MatGetLocalSize(Po,NULL,&oc);CHKERRQ(ierr); } 12475d48cdbSStefano Zampini else oc = 0; 12575d48cdbSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 12675d48cdbSStefano Zampini if (zd) { 12775d48cdbSStefano Zampini const PetscInt *idxs; 12875d48cdbSStefano Zampini PetscInt nz; 12975d48cdbSStefano Zampini 13075d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 13175d48cdbSStefano Zampini ierr = ISSetBlockSize(zd,bs);CHKERRQ(ierr); 13275d48cdbSStefano Zampini ierr = ISGetLocalSize(zd,&nz);CHKERRQ(ierr); 13375d48cdbSStefano Zampini ierr = ISGetIndices(zd,&idxs);CHKERRQ(ierr); 13475d48cdbSStefano Zampini ctd = nz/bs; 13575d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = (idxs[bs*i]+stc)/bs; 13675d48cdbSStefano Zampini ierr = ISRestoreIndices(zd,&idxs);CHKERRQ(ierr); 13775d48cdbSStefano Zampini } else { 13875d48cdbSStefano Zampini ctd = dc/bs; 13975d48cdbSStefano Zampini for (i=0; i<ctd; i++) aux[i] = i+stc/bs; 14075d48cdbSStefano Zampini } 14175d48cdbSStefano Zampini if (zo) { 14275d48cdbSStefano Zampini const PetscInt *idxs; 14375d48cdbSStefano Zampini PetscInt nz; 14475d48cdbSStefano Zampini 14575d48cdbSStefano Zampini /* this will throw an error if bs is not valid */ 14675d48cdbSStefano Zampini ierr = ISSetBlockSize(zo,bs);CHKERRQ(ierr); 14775d48cdbSStefano Zampini ierr = ISGetLocalSize(zo,&nz);CHKERRQ(ierr); 14875d48cdbSStefano Zampini ierr = ISGetIndices(zo,&idxs);CHKERRQ(ierr); 14975d48cdbSStefano Zampini cto = nz/bs; 15075d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[idxs[bs*i]/bs]; 15175d48cdbSStefano Zampini ierr = ISRestoreIndices(zo,&idxs);CHKERRQ(ierr); 15275d48cdbSStefano Zampini } else { 15375d48cdbSStefano Zampini cto = oc/bs; 15475d48cdbSStefano Zampini for (i=0; i<cto; i++) aux[i+ctd] = garray[i]; 15575d48cdbSStefano Zampini } 15675d48cdbSStefano Zampini ierr = ISCreateBlock(comm,bs,ctd+cto,aux,PETSC_OWN_POINTER,cis);CHKERRQ(ierr); 15775d48cdbSStefano Zampini ierr = ISDestroy(&zd);CHKERRQ(ierr); 15875d48cdbSStefano Zampini ierr = ISDestroy(&zo);CHKERRQ(ierr); 15975d48cdbSStefano Zampini PetscFunctionReturn(0); 16075d48cdbSStefano Zampini } 16175d48cdbSStefano Zampini 16275d48cdbSStefano Zampini static PetscErrorCode MatPtAPSymbolic_IS_XAIJ(Mat A,Mat P,PetscReal fill,Mat *C) 16375d48cdbSStefano Zampini { 16475d48cdbSStefano Zampini Mat PT; 16575d48cdbSStefano Zampini MatISPtAP ptap; 16675d48cdbSStefano Zampini ISLocalToGlobalMapping Crl2g,Ccl2g,rl2g,cl2g; 16775d48cdbSStefano Zampini PetscContainer c; 16875d48cdbSStefano Zampini const PetscInt *garray; 16975d48cdbSStefano Zampini PetscInt ibs,N,dc; 17075d48cdbSStefano Zampini MPI_Comm comm; 17175d48cdbSStefano Zampini PetscErrorCode ierr; 17275d48cdbSStefano Zampini 17375d48cdbSStefano Zampini PetscFunctionBegin; 17475d48cdbSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 17575d48cdbSStefano Zampini ierr = MatCreate(comm,C);CHKERRQ(ierr); 17675d48cdbSStefano Zampini ierr = MatSetType(*C,MATIS);CHKERRQ(ierr); 17775d48cdbSStefano Zampini ierr = MatGetSize(P,NULL,&N);CHKERRQ(ierr); 17875d48cdbSStefano Zampini ierr = MatGetLocalSize(P,NULL,&dc);CHKERRQ(ierr); 17975d48cdbSStefano Zampini ierr = MatSetSizes(*C,dc,dc,N,N);CHKERRQ(ierr); 18075d48cdbSStefano Zampini /* Not sure about this 18175d48cdbSStefano Zampini ierr = MatGetBlockSizes(P,NULL,&ibs);CHKERRQ(ierr); 18275d48cdbSStefano Zampini ierr = MatSetBlockSize(*C,ibs);CHKERRQ(ierr); 18375d48cdbSStefano Zampini */ 18475d48cdbSStefano Zampini 18575d48cdbSStefano Zampini ierr = PetscNew(&ptap);CHKERRQ(ierr); 18675d48cdbSStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 18775d48cdbSStefano Zampini ierr = PetscContainerSetPointer(c,ptap);CHKERRQ(ierr); 18875d48cdbSStefano Zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyPtAP_Private);CHKERRQ(ierr); 18975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(*C),"_MatIS_PtAP",(PetscObject)c);CHKERRQ(ierr); 19075d48cdbSStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 19175d48cdbSStefano Zampini ptap->fill = fill; 19275d48cdbSStefano Zampini 19375d48cdbSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 19475d48cdbSStefano Zampini 19575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&ibs);CHKERRQ(ierr); 19675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&N);CHKERRQ(ierr); 19775d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&garray);CHKERRQ(ierr); 19875d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris0);CHKERRQ(ierr); 19975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&garray);CHKERRQ(ierr); 20075d48cdbSStefano Zampini 20175d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris0,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 20275d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis0);CHKERRQ(ierr); 20375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis0,&Ccl2g);CHKERRQ(ierr); 20475d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 20575d48cdbSStefano Zampini 20675d48cdbSStefano Zampini Crl2g = NULL; 20775d48cdbSStefano Zampini if (rl2g != cl2g) { /* unsymmetric A mapping */ 20875d48cdbSStefano Zampini PetscBool same,lsame = PETSC_FALSE; 20975d48cdbSStefano Zampini PetscInt N1,ibs1; 21075d48cdbSStefano Zampini 21175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&N1);CHKERRQ(ierr); 21275d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&ibs1);CHKERRQ(ierr); 21375d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21475d48cdbSStefano Zampini ierr = ISCreateBlock(comm,ibs,N/ibs,garray,PETSC_COPY_VALUES,&ptap->ris1);CHKERRQ(ierr); 21575d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&garray);CHKERRQ(ierr); 21675d48cdbSStefano Zampini if (ibs1 == ibs && N1 == N) { /* check if the l2gmaps are the same */ 21775d48cdbSStefano Zampini const PetscInt *i1,*i2; 21875d48cdbSStefano Zampini 21975d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris0,&i1);CHKERRQ(ierr); 22075d48cdbSStefano Zampini ierr = ISBlockGetIndices(ptap->ris1,&i2);CHKERRQ(ierr); 22175d48cdbSStefano Zampini ierr = PetscMemcmp(i1,i2,N*sizeof(*i1),&lsame);CHKERRQ(ierr); 22275d48cdbSStefano Zampini } 22375d48cdbSStefano Zampini ierr = MPIU_Allreduce(&lsame,&same,1,MPIU_BOOL,MPI_LAND,comm);CHKERRQ(ierr); 22475d48cdbSStefano Zampini if (same) { 22575d48cdbSStefano Zampini ierr = ISDestroy(&ptap->ris1);CHKERRQ(ierr); 22675d48cdbSStefano Zampini } else { 22775d48cdbSStefano Zampini ierr = MatCreateSubMatrix(P,ptap->ris1,NULL,MAT_INITIAL_MATRIX,&PT);CHKERRQ(ierr); 22875d48cdbSStefano Zampini ierr = MatGetNonzeroColumnsLocal_Private(PT,&ptap->cis1);CHKERRQ(ierr); 22975d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(ptap->cis1,&Crl2g);CHKERRQ(ierr); 23075d48cdbSStefano Zampini ierr = MatDestroy(&PT);CHKERRQ(ierr); 23175d48cdbSStefano Zampini } 23275d48cdbSStefano Zampini } 23375d48cdbSStefano Zampini /* Not sure about this 23475d48cdbSStefano Zampini if (!Crl2g) { 23575d48cdbSStefano Zampini ierr = MatGetBlockSize(*C,&ibs);CHKERRQ(ierr); 23675d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(Ccl2g,ibs);CHKERRQ(ierr); 23775d48cdbSStefano Zampini } 23875d48cdbSStefano Zampini */ 23975d48cdbSStefano Zampini ierr = MatSetLocalToGlobalMapping(*C,Crl2g ? Crl2g : Ccl2g,Ccl2g);CHKERRQ(ierr); 24075d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Crl2g);CHKERRQ(ierr); 24175d48cdbSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&Ccl2g);CHKERRQ(ierr); 24275d48cdbSStefano Zampini 24375d48cdbSStefano Zampini (*C)->ops->ptapnumeric = MatPtAPNumeric_IS_XAIJ; 24475d48cdbSStefano Zampini PetscFunctionReturn(0); 24575d48cdbSStefano Zampini } 24675d48cdbSStefano Zampini 24775d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 24875d48cdbSStefano Zampini { 24975d48cdbSStefano Zampini PetscErrorCode ierr; 25075d48cdbSStefano Zampini 25175d48cdbSStefano Zampini PetscFunctionBegin; 25275d48cdbSStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 25375d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25475d48cdbSStefano Zampini ierr = MatPtAPSymbolic_IS_XAIJ(A,P,fill,C);CHKERRQ(ierr); 25575d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 25675d48cdbSStefano Zampini } 25775d48cdbSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 25875d48cdbSStefano Zampini ierr = ((*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 25975d48cdbSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 26075d48cdbSStefano Zampini PetscFunctionReturn(0); 26175d48cdbSStefano Zampini } 26275d48cdbSStefano Zampini 2635b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 2645b003df0Sstefano_zampini { 2655b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 2665b003df0Sstefano_zampini PetscInt i; 2675b003df0Sstefano_zampini PetscErrorCode ierr; 2685b003df0Sstefano_zampini 269ab4d48faSStefano Zampini PetscFunctionBegin; 2705b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 2715b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 2725b003df0Sstefano_zampini } 2735b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 2745b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 2755b003df0Sstefano_zampini } 2765b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 2775b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 2785b003df0Sstefano_zampini PetscFunctionReturn(0); 2795b003df0Sstefano_zampini } 280a72627d2SStefano Zampini 281*c9225affSStefano Zampini static PetscErrorCode MatConvert_SeqXAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2826989cf23SStefano Zampini { 283*c9225affSStefano Zampini Mat B,lB; 284*c9225affSStefano Zampini PetscErrorCode ierr; 285*c9225affSStefano Zampini 286*c9225affSStefano Zampini PetscFunctionBegin; 287*c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 288*c9225affSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 289*c9225affSStefano Zampini PetscInt bs; 290*c9225affSStefano Zampini IS is; 291*c9225affSStefano Zampini 292*c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 293*c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->rmap->n/bs,0,1,&is);CHKERRQ(ierr); 294*c9225affSStefano Zampini if (bs > 1) { 295*c9225affSStefano Zampini IS is2; 296*c9225affSStefano Zampini PetscInt i,*aux; 297*c9225affSStefano Zampini 298*c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 299*c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 300*c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 301*c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 302*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 303*c9225affSStefano Zampini is = is2; 304*c9225affSStefano Zampini } 305*c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 306*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 307*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 308*c9225affSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),A->cmap->n/bs,0,1,&is);CHKERRQ(ierr); 309*c9225affSStefano Zampini if (bs > 1) { 310*c9225affSStefano Zampini IS is2; 311*c9225affSStefano Zampini PetscInt i,*aux; 312*c9225affSStefano Zampini 313*c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 314*c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 315*c9225affSStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)A),bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 316*c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 317*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 318*c9225affSStefano Zampini is = is2; 319*c9225affSStefano Zampini } 320*c9225affSStefano Zampini ierr = ISSetIdentity(is);CHKERRQ(ierr); 321*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 322*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 323*c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)A),bs,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,rl2g,cl2g,&B);CHKERRQ(ierr); 324*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 325*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 326*c9225affSStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&lB);CHKERRQ(ierr); 327*c9225affSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *newmat = B; 328*c9225affSStefano Zampini } else { 329*c9225affSStefano Zampini B = *newmat; 330*c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 331*c9225affSStefano Zampini lB = A; 332*c9225affSStefano Zampini } 333*c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lB);CHKERRQ(ierr); 334*c9225affSStefano Zampini ierr = MatDestroy(&lB);CHKERRQ(ierr); 335*c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 336*c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 337*c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 338*c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 339*c9225affSStefano Zampini } 340*c9225affSStefano Zampini PetscFunctionReturn(0); 341*c9225affSStefano Zampini } 342*c9225affSStefano Zampini 343*c9225affSStefano Zampini static PetscErrorCode MatISScaleDisassembling_Private(Mat A) 344*c9225affSStefano Zampini { 345*c9225affSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 346*c9225affSStefano Zampini const PetscScalar *sc; 347*c9225affSStefano Zampini PetscScalar *aa; 348*c9225affSStefano Zampini const PetscInt *ii,*jj; 349*c9225affSStefano Zampini PetscInt i,n,m; 350*c9225affSStefano Zampini PetscInt *ecount,**eneighs,n_neigh,*neigh,*n_shared,**shared; 351*c9225affSStefano Zampini PetscBool flg; 352*c9225affSStefano Zampini PetscErrorCode ierr; 353*c9225affSStefano Zampini 354*c9225affSStefano Zampini PetscFunctionBegin; 355*c9225affSStefano Zampini ierr = VecGetLocalSize(matis->counter,&n);CHKERRQ(ierr); 356*c9225affSStefano Zampini ierr = PetscCalloc1(n,&ecount);CHKERRQ(ierr); 357*c9225affSStefano Zampini ierr = PetscMalloc1(n,&eneighs);CHKERRQ(ierr); 358*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(A->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 359*c9225affSStefano Zampini for (i=1,m=0;i<n_neigh;i++) { 360*c9225affSStefano Zampini PetscInt j; 361*c9225affSStefano Zampini 362*c9225affSStefano Zampini m += n_shared[i]; 363*c9225affSStefano Zampini for (j=0;j<n_shared[i];j++) ecount[shared[i][j]]++; 364*c9225affSStefano Zampini } 365*c9225affSStefano Zampini if (n) { ierr = PetscMalloc1(m,&eneighs[0]);CHKERRQ(ierr); } 366*c9225affSStefano Zampini for (i=1;i<n;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 367*c9225affSStefano Zampini ierr = PetscMemzero(ecount,n*sizeof(PetscInt));CHKERRQ(ierr); 368*c9225affSStefano Zampini for (i=1;i<n_neigh;i++) { 369*c9225affSStefano Zampini PetscInt j; 370*c9225affSStefano Zampini 371*c9225affSStefano Zampini for (j=0;j<n_shared[i];j++) { 372*c9225affSStefano Zampini PetscInt k = shared[i][j]; 373*c9225affSStefano Zampini 374*c9225affSStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 375*c9225affSStefano Zampini ecount[k]++; 376*c9225affSStefano Zampini } 377*c9225affSStefano Zampini } 378*c9225affSStefano Zampini for (i=0;i<n;i++) { ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); } 379*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(A->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 380*c9225affSStefano Zampini ierr = VecGetArrayRead(matis->counter,&sc);CHKERRQ(ierr); 381*c9225affSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 382*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 383*c9225affSStefano Zampini if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",m,n); 384*c9225affSStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&aa);CHKERRQ(ierr); 385*c9225affSStefano Zampini for (i=0;i<n;i++) { 386*c9225affSStefano Zampini if (PetscUnlikely(ecount[i])) { 387*c9225affSStefano Zampini PetscInt j; 388*c9225affSStefano Zampini 389*c9225affSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 390*c9225affSStefano Zampini PetscInt i2 = jj[j],p,p2; 391*c9225affSStefano Zampini PetscScalar scal = 1.0; 392*c9225affSStefano Zampini 393*c9225affSStefano Zampini for (p=0;p<ecount[i];p++) { 394*c9225affSStefano Zampini for (p2=0;p2<ecount[i2];p2++) { 395*c9225affSStefano Zampini if (eneighs[i][p] == eneighs[i2][p2]) { scal += 1.0; break; } 396*c9225affSStefano Zampini } 397*c9225affSStefano Zampini } 398*c9225affSStefano Zampini aa[j] /= scal; 399*c9225affSStefano Zampini } 400*c9225affSStefano Zampini } 401*c9225affSStefano Zampini } 402*c9225affSStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 403*c9225affSStefano Zampini if (n) { 404*c9225affSStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 405*c9225affSStefano Zampini } 406*c9225affSStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 407*c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&aa);CHKERRQ(ierr); 408*c9225affSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&m,&ii,&jj,&flg);CHKERRQ(ierr); 409*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 410*c9225affSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&sc);CHKERRQ(ierr); 411*c9225affSStefano Zampini PetscFunctionReturn(0); 412*c9225affSStefano Zampini } 413*c9225affSStefano Zampini 414*c9225affSStefano Zampini static PetscErrorCode MatMPIXAIJComputeLocalToGlobalMapping_Private(Mat A, ISLocalToGlobalMapping *l2g) 415*c9225affSStefano Zampini { 416*c9225affSStefano Zampini Mat /*Ad,*/Ao; 417*c9225affSStefano Zampini IS is; 418*c9225affSStefano Zampini MPI_Comm comm; 419*c9225affSStefano Zampini const PetscInt *garray; 420*c9225affSStefano Zampini PetscInt bs, mode = 0; 421*c9225affSStefano Zampini PetscBool ismpiaij,ismpibaij,useAl2g = PETSC_FALSE; 422*c9225affSStefano Zampini PetscErrorCode ierr; 423*c9225affSStefano Zampini 424*c9225affSStefano Zampini PetscFunctionBegin; 425*c9225affSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-mat_aij_is_usel2g",&useAl2g,NULL);CHKERRQ(ierr); 426*c9225affSStefano Zampini if (useAl2g) { 427*c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(A,l2g,NULL);CHKERRQ(ierr); 428*c9225affSStefano Zampini PetscFunctionReturn(0); 429*c9225affSStefano Zampini } 430*c9225affSStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 431*c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 432*c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 433*c9225affSStefano Zampini if (ismpiaij) { 434*c9225affSStefano Zampini bs = 1; 435*c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,NULL,&Ao,&garray);CHKERRQ(ierr); 436*c9225affSStefano Zampini } else if (ismpibaij) { 437*c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 438*c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,NULL,&Ao,&garray);CHKERRQ(ierr); 439*c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 440*c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 441*c9225affSStefano Zampini switch(mode) { 442*c9225affSStefano Zampini default: 443*c9225affSStefano Zampini if (A->rmap->n) { 444*c9225affSStefano Zampini PetscInt i,dc,oc,stc,*aux; 445*c9225affSStefano Zampini 446*c9225affSStefano Zampini ierr = MatGetLocalSize(A,NULL,&dc);CHKERRQ(ierr); 447*c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 448*c9225affSStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 449*c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 450*c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 451*c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 452*c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 453*c9225affSStefano Zampini } else { 454*c9225affSStefano Zampini ierr = ISCreateBlock(comm,1,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 455*c9225affSStefano Zampini } 456*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,l2g);CHKERRQ(ierr); 457*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 458*c9225affSStefano Zampini } 459*c9225affSStefano Zampini PetscFunctionReturn(0); 460*c9225affSStefano Zampini } 461*c9225affSStefano Zampini 462*c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 463*c9225affSStefano Zampini { 464*c9225affSStefano Zampini Mat lA,Ad,Ao,B = NULL; 4656989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 4666989cf23SStefano Zampini IS is; 4676989cf23SStefano Zampini MPI_Comm comm; 4686989cf23SStefano Zampini void *ptrs[2]; 4696989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 470*c9225affSStefano Zampini const PetscInt *garray; 4716989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 472*c9225affSStefano Zampini const PetscInt *di,*dj,*oi,*oj; 473*c9225affSStefano Zampini const PetscInt *odi,*odj,*ooi,*ooj; 4746989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 475*c9225affSStefano Zampini PetscInt bs,lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 476*c9225affSStefano Zampini PetscBool flg,ismpiaij,ismpibaij,was_inplace = PETSC_FALSE; 477*c9225affSStefano Zampini PetscMPIInt size; 4786989cf23SStefano Zampini PetscErrorCode ierr; 4796989cf23SStefano Zampini 480ab4d48faSStefano Zampini PetscFunctionBegin; 4816989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 482*c9225affSStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 483*c9225affSStefano Zampini if (size == 1) { 484*c9225affSStefano Zampini ierr = MatConvert_SeqXAIJ_IS(A,type,reuse,newmat);CHKERRQ(ierr); 485*c9225affSStefano Zampini PetscFunctionReturn(0); 486*c9225affSStefano Zampini } 487*c9225affSStefano Zampini if (reuse != MAT_REUSE_MATRIX && A->cmap->N == A->rmap->N) { 488*c9225affSStefano Zampini ierr = MatMPIXAIJComputeLocalToGlobalMapping_Private(A,&rl2g);CHKERRQ(ierr); 489*c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 490*c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 491*c9225affSStefano Zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 492*c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,rl2g);CHKERRQ(ierr); 493*c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 494*c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 495*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 496*c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) was_inplace = PETSC_TRUE; 497*c9225affSStefano Zampini reuse = MAT_REUSE_MATRIX; 498*c9225affSStefano Zampini } 499*c9225affSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 500*c9225affSStefano Zampini Mat *newlA, lA; 501*c9225affSStefano Zampini IS rows, cols; 502*c9225affSStefano Zampini const PetscInt *ridx, *cidx; 503*c9225affSStefano Zampini PetscInt rbs, cbs, nr, nc; 504*c9225affSStefano Zampini 505*c9225affSStefano Zampini if (!B) B = *newmat; 506*c9225affSStefano Zampini ierr = MatGetLocalToGlobalMapping(B,&rl2g,&cl2g);CHKERRQ(ierr); 507*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 508*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 509*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&nr);CHKERRQ(ierr); 510*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&nc);CHKERRQ(ierr); 511*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rl2g,&rbs);CHKERRQ(ierr); 512*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cl2g,&cbs);CHKERRQ(ierr); 513*c9225affSStefano Zampini ierr = ISCreateBlock(comm,rbs,nr/rbs,ridx,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 514*c9225affSStefano Zampini if (rl2g != cl2g) { 515*c9225affSStefano Zampini ierr = ISCreateBlock(comm,cbs,nc/cbs,cidx,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 516*c9225affSStefano Zampini } else { 517*c9225affSStefano Zampini ierr = PetscObjectReference((PetscObject)rows);CHKERRQ(ierr); 518*c9225affSStefano Zampini cols = rows; 519*c9225affSStefano Zampini } 520*c9225affSStefano Zampini ierr = MatISGetLocalMat(B,&lA);CHKERRQ(ierr); 521*c9225affSStefano Zampini ierr = MatCreateSubMatrices(A,1,&rows,&cols,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 522*c9225affSStefano Zampini ierr = MatConvert(newlA[0],MATSEQAIJ,MAT_INPLACE_MATRIX,&newlA[0]);CHKERRQ(ierr); 523*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rl2g,&ridx);CHKERRQ(ierr); 524*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cl2g,&cidx);CHKERRQ(ierr); 525*c9225affSStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 526*c9225affSStefano Zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 527*c9225affSStefano Zampini if (!lA->preallocated) { /* first time */ 528*c9225affSStefano Zampini ierr = MatDuplicate(newlA[0],MAT_COPY_VALUES,&lA);CHKERRQ(ierr); 529*c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 530*c9225affSStefano Zampini ierr = PetscObjectDereference((PetscObject)lA);CHKERRQ(ierr); 531*c9225affSStefano Zampini } 532*c9225affSStefano Zampini ierr = MatCopy(newlA[0],lA,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 533*c9225affSStefano Zampini ierr = MatDestroySubMatrices(1,&newlA);CHKERRQ(ierr); 534*c9225affSStefano Zampini ierr = MatISScaleDisassembling_Private(B);CHKERRQ(ierr); 535*c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 536*c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 537*c9225affSStefano Zampini if (was_inplace) { ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); } 538*c9225affSStefano Zampini else *newmat = B; 539*c9225affSStefano Zampini PetscFunctionReturn(0); 540*c9225affSStefano Zampini } 541*c9225affSStefano Zampini /* rectangular case, just compress out the column space */ 542*c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ ,&ismpiaij);CHKERRQ(ierr); 543*c9225affSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr); 544*c9225affSStefano Zampini if (ismpiaij) { 545*c9225affSStefano Zampini bs = 1; 546*c9225affSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 547*c9225affSStefano Zampini } else if (ismpibaij) { 548*c9225affSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 549*c9225affSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&Ad,&Ao,&garray);CHKERRQ(ierr); 550*c9225affSStefano Zampini ierr = MatConvert(Ad,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ad);CHKERRQ(ierr); 551*c9225affSStefano Zampini ierr = MatConvert(Ao,MATSEQAIJ,MAT_INITIAL_MATRIX,&Ao);CHKERRQ(ierr); 552*c9225affSStefano Zampini } else SETERRQ1(comm,PETSC_ERR_SUP,"Type %s",((PetscObject)A)->type_name); 553*c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ad,&dd);CHKERRQ(ierr); 554*c9225affSStefano Zampini ierr = MatSeqAIJGetArray(Ao,&od);CHKERRQ(ierr); 555*c9225affSStefano Zampini if (!garray) SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"garray not present"); 5566989cf23SStefano Zampini 5576989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 5586989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 5596989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 5606989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 561*c9225affSStefano Zampini ierr = MatGetLocalSize(Ao,NULL,&oc);CHKERRQ(ierr); 562*c9225affSStefano Zampini ierr = MatGetRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&di,&dj,&flg);CHKERRQ(ierr); 563*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 564*c9225affSStefano Zampini ierr = MatGetRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&oi,&oj,&flg);CHKERRQ(ierr); 565*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get IJ structure"); 566*c9225affSStefano Zampini nnz = di[dr] + oi[dr]; 567*c9225affSStefano Zampini /* store original pointers to be restored later */ 568*c9225affSStefano Zampini odi = di; odj = dj; ooi = oi; ooj = oj; 5696989cf23SStefano Zampini 5706989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 571*c9225affSStefano Zampini ierr = ISCreateStride(comm,dr/bs,str/bs,1,&is);CHKERRQ(ierr); 572*c9225affSStefano Zampini if (bs > 1) { 573*c9225affSStefano Zampini IS is2; 574*c9225affSStefano Zampini 575*c9225affSStefano Zampini ierr = ISGetLocalSize(is,&i);CHKERRQ(ierr); 576*c9225affSStefano Zampini ierr = ISGetIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 577*c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,i,aux,PETSC_COPY_VALUES,&is2);CHKERRQ(ierr); 578*c9225affSStefano Zampini ierr = ISRestoreIndices(is,(const PetscInt**)&aux);CHKERRQ(ierr); 579*c9225affSStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 580*c9225affSStefano Zampini is = is2; 581*c9225affSStefano Zampini } 5826989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 5836989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 584e363d98aSStefano Zampini if (dr) { 585*c9225affSStefano Zampini ierr = PetscMalloc1((dc+oc)/bs,&aux);CHKERRQ(ierr); 586*c9225affSStefano Zampini for (i=0; i<dc/bs; i++) aux[i] = i+stc/bs; 587*c9225affSStefano Zampini for (i=0; i<oc/bs; i++) aux[i+dc/bs] = garray[i]; 588*c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,(dc+oc)/bs,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 589e363d98aSStefano Zampini lc = dc+oc; 590e363d98aSStefano Zampini } else { 591*c9225affSStefano Zampini ierr = ISCreateBlock(comm,bs,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 592e363d98aSStefano Zampini lc = 0; 593e363d98aSStefano Zampini } 5946989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 5956989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 5966989cf23SStefano Zampini 5976989cf23SStefano Zampini /* create MATIS object */ 598*c9225affSStefano Zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 599*c9225affSStefano Zampini ierr = MatSetSizes(B,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 600*c9225affSStefano Zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 601*c9225affSStefano Zampini ierr = MatSetBlockSize(B,bs);CHKERRQ(ierr); 602*c9225affSStefano Zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 6036989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6046989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6056989cf23SStefano Zampini 6066989cf23SStefano Zampini /* merge local matrices */ 6076989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 6086989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 6096989cf23SStefano Zampini ii = aux; 6106989cf23SStefano Zampini jj = aux+dr+1; 6116989cf23SStefano Zampini aa = data; 6126989cf23SStefano Zampini *ii = *(di++) + *(oi++); 6136989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 6146989cf23SStefano Zampini { 6156989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 6166989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 6176989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 6186989cf23SStefano Zampini } 6196989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 620*c9225affSStefano Zampini 621*c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ad,0,PETSC_FALSE,PETSC_FALSE,&i,&odi,&odj,&flg);CHKERRQ(ierr); 622*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 623*c9225affSStefano Zampini ierr = MatRestoreRowIJ(Ao,0,PETSC_FALSE,PETSC_FALSE,&i,&ooi,&ooj,&flg);CHKERRQ(ierr); 624*c9225affSStefano Zampini if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore IJ structure"); 625*c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ad,&dd);CHKERRQ(ierr); 626*c9225affSStefano Zampini ierr = MatSeqAIJRestoreArray(Ao,&od);CHKERRQ(ierr); 627*c9225affSStefano Zampini 6286989cf23SStefano Zampini ii = aux; 6296989cf23SStefano Zampini jj = aux+dr+1; 6306989cf23SStefano Zampini aa = data; 631e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 6326989cf23SStefano Zampini 6336989cf23SStefano Zampini /* create containers to destroy the data */ 6346989cf23SStefano Zampini ptrs[0] = aux; 6356989cf23SStefano Zampini ptrs[1] = data; 6366989cf23SStefano Zampini for (i=0; i<2; i++) { 6376989cf23SStefano Zampini PetscContainer c; 6386989cf23SStefano Zampini 6396989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 6406989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 641b81c21eeSStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 6426989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 6436989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 6446989cf23SStefano Zampini } 645*c9225affSStefano Zampini if (ismpibaij) { /* destroy converted local matrices */ 646*c9225affSStefano Zampini ierr = MatDestroy(&Ad);CHKERRQ(ierr); 647*c9225affSStefano Zampini ierr = MatDestroy(&Ao);CHKERRQ(ierr); 648*c9225affSStefano Zampini } 6496989cf23SStefano Zampini 6506989cf23SStefano Zampini /* finalize matrix */ 651*c9225affSStefano Zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 6526989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 653*c9225affSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 654*c9225affSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 655*c9225affSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 656*c9225affSStefano Zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 657*c9225affSStefano Zampini } else *newmat = B; 6586989cf23SStefano Zampini PetscFunctionReturn(0); 6596989cf23SStefano Zampini } 6606989cf23SStefano Zampini 661cf0a3239SStefano Zampini /*@ 6623d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 663cf0a3239SStefano Zampini 664cf0a3239SStefano Zampini Collective on MPI_Comm 665cf0a3239SStefano Zampini 666cf0a3239SStefano Zampini Input Parameters: 667cf0a3239SStefano Zampini + A - the matrix 668cf0a3239SStefano Zampini 669cf0a3239SStefano Zampini Level: advanced 670cf0a3239SStefano Zampini 67195452b02SPatrick Sanan Notes: 67295452b02SPatrick Sanan This function does not need to be called by the user. 673cf0a3239SStefano Zampini 674cf0a3239SStefano Zampini .keywords: matrix 675cf0a3239SStefano Zampini 676cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 677cf0a3239SStefano Zampini @*/ 678cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 679cf0a3239SStefano Zampini { 6807fa8f2d3SStefano Zampini PetscErrorCode ierr; 6817fa8f2d3SStefano Zampini 6827fa8f2d3SStefano Zampini PetscFunctionBegin; 683cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 684cf0a3239SStefano Zampini PetscValidType(A,1); 685cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 6867fa8f2d3SStefano Zampini PetscFunctionReturn(0); 6877fa8f2d3SStefano Zampini } 6887fa8f2d3SStefano Zampini 6895e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 6905e3038f0Sstefano_zampini { 6915e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 6925e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 6935e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 6945e3038f0Sstefano_zampini MPI_Comm comm; 6955b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 6965b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 6979e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 6985e3038f0Sstefano_zampini PetscErrorCode ierr; 6995e3038f0Sstefano_zampini 700ab4d48faSStefano Zampini PetscFunctionBegin; 7015e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 7025e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 7035e3038f0Sstefano_zampini rnest = NULL; 7045e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 7055e3038f0Sstefano_zampini PetscBool ismatis,isnest; 7065e3038f0Sstefano_zampini 7075e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 7085e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 7095e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 7105e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 7115e3038f0Sstefano_zampini if (isnest) { 7125e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 7135e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 7145e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 7155e3038f0Sstefano_zampini } 7165e3038f0Sstefano_zampini } 7175e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 7185b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 7199e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 7205e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 7219e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 7225e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 7235e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 7245e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 7255e3038f0Sstefano_zampini PetscBool ismatis; 7269e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 7275e3038f0Sstefano_zampini 7285e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 7295e3038f0Sstefano_zampini if (!nest[i][j]) continue; 7305e3038f0Sstefano_zampini 7315e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 7329e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 7339e7b2b25Sstefano_zampini if (istrans[ij]) { 7349e7b2b25Sstefano_zampini Mat T,lT; 7359e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 7369e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 7379e7b2b25Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) (transposed) is not of type MATIS",i,j); 7389e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 7399e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 7409e7b2b25Sstefano_zampini } else { 7415e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 7425e3038f0Sstefano_zampini if (!ismatis) SETERRQ2(comm,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) is not of type MATIS",i,j); 7439e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 7449e7b2b25Sstefano_zampini } 7455e3038f0Sstefano_zampini 7465e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 7475e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 7489e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 7495e3038f0Sstefano_zampini if (!l1 || !l2) continue; 7505e3038f0Sstefano_zampini if (lr[i] && l1 != lr[i]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lr[i],l1); 7515e3038f0Sstefano_zampini if (lc[j] && l2 != lc[j]) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid local size %D != %D",i,j,lc[j],l2); 7525e3038f0Sstefano_zampini lr[i] = l1; 7535e3038f0Sstefano_zampini lc[j] = l2; 7545e3038f0Sstefano_zampini 7555e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 7565e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 7575e3038f0Sstefano_zampini } 7585e3038f0Sstefano_zampini } 7595e3038f0Sstefano_zampini 7605e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 7615e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 7625e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 7635e3038f0Sstefano_zampini rl2g = NULL; 7645e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 7655e3038f0Sstefano_zampini PetscInt n1,n2; 7665e3038f0Sstefano_zampini 7675e3038f0Sstefano_zampini if (!nest[i][j]) continue; 7689e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 7699e7b2b25Sstefano_zampini Mat T; 7709e7b2b25Sstefano_zampini 7719e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 7729e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 7739e7b2b25Sstefano_zampini } else { 7745e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 7759e7b2b25Sstefano_zampini } 7765e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 7775e3038f0Sstefano_zampini if (!n1) continue; 7785e3038f0Sstefano_zampini if (!rl2g) { 7795e3038f0Sstefano_zampini rl2g = cl2g; 7805e3038f0Sstefano_zampini } else { 7815e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 7825e3038f0Sstefano_zampini PetscBool same; 7835e3038f0Sstefano_zampini 7845e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 7855e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap size %D != %D",i,j,n1,n2); 7865e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 7875e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 7885e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 7895e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 7905e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 7915e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid row l2gmap",i,j); 7925e3038f0Sstefano_zampini } 7935e3038f0Sstefano_zampini } 7945e3038f0Sstefano_zampini } 7955e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 7965e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 7975e3038f0Sstefano_zampini rl2g = NULL; 7985e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 7995e3038f0Sstefano_zampini PetscInt n1,n2; 8005e3038f0Sstefano_zampini 8015e3038f0Sstefano_zampini if (!nest[j][i]) continue; 8029e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8039e7b2b25Sstefano_zampini Mat T; 8049e7b2b25Sstefano_zampini 8059e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 8069e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 8079e7b2b25Sstefano_zampini } else { 8085e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 8099e7b2b25Sstefano_zampini } 8105e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 8115e3038f0Sstefano_zampini if (!n1) continue; 8125e3038f0Sstefano_zampini if (!rl2g) { 8135e3038f0Sstefano_zampini rl2g = cl2g; 8145e3038f0Sstefano_zampini } else { 8155e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 8165e3038f0Sstefano_zampini PetscBool same; 8175e3038f0Sstefano_zampini 8185e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 8195e3038f0Sstefano_zampini if (n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap size %D != %D",j,i,n1,n2); 8205e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 8215e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 8225e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 8235e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 8245e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 8255e3038f0Sstefano_zampini if (!same) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot convert from MATNEST to MATIS! Matrix block (%D,%D) has invalid column l2gmap",j,i); 8265e3038f0Sstefano_zampini } 8275e3038f0Sstefano_zampini } 8285e3038f0Sstefano_zampini } 8295e3038f0Sstefano_zampini #endif 8305e3038f0Sstefano_zampini 8315e3038f0Sstefano_zampini B = NULL; 8325e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 8335b003df0Sstefano_zampini PetscInt stl; 8345b003df0Sstefano_zampini 8355e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 8365e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 8375e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 8385b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 8395e3038f0Sstefano_zampini Mat usedmat; 8405e3038f0Sstefano_zampini Mat_IS *matis; 8415e3038f0Sstefano_zampini const PetscInt *idxs; 8425e3038f0Sstefano_zampini 8435e3038f0Sstefano_zampini /* local IS for local NEST */ 8445b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 8455e3038f0Sstefano_zampini 8465e3038f0Sstefano_zampini /* l2gmap */ 8475e3038f0Sstefano_zampini j = 0; 8485e3038f0Sstefano_zampini usedmat = nest[i][j]; 8499e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 8509e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 8519e7b2b25Sstefano_zampini 8529e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8539e7b2b25Sstefano_zampini Mat T; 8549e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 8559e7b2b25Sstefano_zampini usedmat = T; 8569e7b2b25Sstefano_zampini } 85782d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 8585e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 8595e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 8609e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 8619e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8629e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8639e7b2b25Sstefano_zampini } else { 8645e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8655e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8669e7b2b25Sstefano_zampini } 8675e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 8685e3038f0Sstefano_zampini stl += lr[i]; 8695e3038f0Sstefano_zampini } 8705e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 8715e3038f0Sstefano_zampini 8725e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 8735e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 8745e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 8755b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 8765e3038f0Sstefano_zampini Mat usedmat; 8775e3038f0Sstefano_zampini Mat_IS *matis; 8785e3038f0Sstefano_zampini const PetscInt *idxs; 8795e3038f0Sstefano_zampini 8805e3038f0Sstefano_zampini /* local IS for local NEST */ 8815b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 8825e3038f0Sstefano_zampini 8835e3038f0Sstefano_zampini /* l2gmap */ 8845e3038f0Sstefano_zampini j = 0; 8855e3038f0Sstefano_zampini usedmat = nest[j][i]; 8869e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 8879e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 8889e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8899e7b2b25Sstefano_zampini Mat T; 8909e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 8919e7b2b25Sstefano_zampini usedmat = T; 8929e7b2b25Sstefano_zampini } 89382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 8945e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 8955e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 8969e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 8979e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8989e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 8999e7b2b25Sstefano_zampini } else { 9005e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9015e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 9029e7b2b25Sstefano_zampini } 9035e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 9045e3038f0Sstefano_zampini stl += lc[i]; 9055e3038f0Sstefano_zampini } 9065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 9075e3038f0Sstefano_zampini 9085e3038f0Sstefano_zampini /* Create MATIS */ 9095e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 9105e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 9115e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 9125e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 9135e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 9145e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 9155e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 9165e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 9175e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 9189e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 9199e7b2b25Sstefano_zampini if (istrans[i]) { 9209e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 9219e7b2b25Sstefano_zampini } 9229e7b2b25Sstefano_zampini } 9235e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 9245e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 9255e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9265e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9275e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 9285e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 9295e3038f0Sstefano_zampini } else { 9305e3038f0Sstefano_zampini *newmat = B; 9315e3038f0Sstefano_zampini } 9325e3038f0Sstefano_zampini } else { 9335e3038f0Sstefano_zampini if (lreuse) { 9345e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 9355e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 9365e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 9375e3038f0Sstefano_zampini if (snest[i*nc+j]) { 9385e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 9399e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 9409e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 9419e7b2b25Sstefano_zampini } 9425e3038f0Sstefano_zampini } 9435e3038f0Sstefano_zampini } 9445e3038f0Sstefano_zampini } 9455e3038f0Sstefano_zampini } else { 9465b003df0Sstefano_zampini PetscInt stl; 9475b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 9485b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 9495b003df0Sstefano_zampini stl += lr[i]; 9505e3038f0Sstefano_zampini } 9515b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 9525b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 9535b003df0Sstefano_zampini stl += lc[i]; 9545e3038f0Sstefano_zampini } 9555e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 956ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 9579e7b2b25Sstefano_zampini if (istrans[i]) { 9589e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 9599e7b2b25Sstefano_zampini } 960ab4d48faSStefano Zampini } 9615e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 9625e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 9635e3038f0Sstefano_zampini } 9645e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9655e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9665e3038f0Sstefano_zampini } 9675e3038f0Sstefano_zampini 9685b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 9695b003df0Sstefano_zampini convert = PETSC_FALSE; 9705b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 9715b003df0Sstefano_zampini if (convert) { 9725b003df0Sstefano_zampini Mat M; 9735b003df0Sstefano_zampini MatISLocalFields lf; 9745b003df0Sstefano_zampini PetscContainer c; 9755b003df0Sstefano_zampini 9765b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 9775b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 9785b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 9795b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 9805b003df0Sstefano_zampini 9815b003df0Sstefano_zampini /* attach local fields to the matrix */ 9825b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 9835b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 9845b003df0Sstefano_zampini for (i=0;i<nr;i++) { 9855b003df0Sstefano_zampini PetscInt n,st; 9865b003df0Sstefano_zampini 9875b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 9885b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 9895b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 9905b003df0Sstefano_zampini } 9915b003df0Sstefano_zampini for (i=0;i<nc;i++) { 9925b003df0Sstefano_zampini PetscInt n,st; 9935b003df0Sstefano_zampini 9945b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 9955b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 9965b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 9975b003df0Sstefano_zampini } 9985b003df0Sstefano_zampini lf->nr = nr; 9995b003df0Sstefano_zampini lf->nc = nc; 10005b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 10015b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 10025b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 10035b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 10045b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 10055b003df0Sstefano_zampini } 10065b003df0Sstefano_zampini 10075e3038f0Sstefano_zampini /* Free workspace */ 10085e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 10095e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 10105e3038f0Sstefano_zampini } 10115e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 10125e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 10135e3038f0Sstefano_zampini } 10149e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 10155b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 10165e3038f0Sstefano_zampini PetscFunctionReturn(0); 10175e3038f0Sstefano_zampini } 10185e3038f0Sstefano_zampini 1019ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 1020ad219c80Sstefano_zampini { 1021ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 1022ad219c80Sstefano_zampini Vec ll,rr; 1023ad219c80Sstefano_zampini const PetscScalar *Y,*X; 1024ad219c80Sstefano_zampini PetscScalar *x,*y; 1025ad219c80Sstefano_zampini PetscErrorCode ierr; 1026ad219c80Sstefano_zampini 1027ad219c80Sstefano_zampini PetscFunctionBegin; 1028ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 1029ad219c80Sstefano_zampini if (l) { 1030ad219c80Sstefano_zampini ll = matis->y; 1031ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 1032ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 1033ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1034ad219c80Sstefano_zampini } else { 1035ad219c80Sstefano_zampini ll = NULL; 1036ad219c80Sstefano_zampini } 1037ad219c80Sstefano_zampini if (r) { 1038ad219c80Sstefano_zampini rr = matis->x; 1039ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 1040ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 1041ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1042ad219c80Sstefano_zampini } else { 1043ad219c80Sstefano_zampini rr = NULL; 1044ad219c80Sstefano_zampini } 1045ad219c80Sstefano_zampini if (ll) { 1046ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 1047ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 1048ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 1049ad219c80Sstefano_zampini } 1050ad219c80Sstefano_zampini if (rr) { 1051ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 1052ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 1053ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 1054ad219c80Sstefano_zampini } 1055ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 1056ad219c80Sstefano_zampini PetscFunctionReturn(0); 1057ad219c80Sstefano_zampini } 1058ad219c80Sstefano_zampini 10597fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 10607fa8f2d3SStefano Zampini { 10617fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 10627fa8f2d3SStefano Zampini MatInfo info; 10637fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 10647fa8f2d3SStefano Zampini PetscInt bs; 10657fa8f2d3SStefano Zampini PetscErrorCode ierr; 10667fa8f2d3SStefano Zampini 10677fa8f2d3SStefano Zampini PetscFunctionBegin; 10687fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10697fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 10707fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 10717fa8f2d3SStefano Zampini isend[0] = info.nz_used; 10727fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 10737fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 10747fa8f2d3SStefano Zampini isend[3] = info.memory; 10757fa8f2d3SStefano Zampini isend[4] = info.mallocs; 10767fa8f2d3SStefano Zampini } else { 10777fa8f2d3SStefano Zampini isend[0] = 0.; 10787fa8f2d3SStefano Zampini isend[1] = 0.; 10797fa8f2d3SStefano Zampini isend[2] = 0.; 10807fa8f2d3SStefano Zampini isend[3] = 0.; 10817fa8f2d3SStefano Zampini isend[4] = 0.; 10827fa8f2d3SStefano Zampini } 10837fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 10847fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 10857fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 10867fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 10877fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 10887fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 10897fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 10907fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 10917fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 10927fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 10937fa8f2d3SStefano Zampini 10947fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 10957fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 10967fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 10977fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 10987fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 10997fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 11007fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 11017fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 11027fa8f2d3SStefano Zampini 11037fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 11047fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 11057fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 11067fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 11077fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 11087fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 1109d7f69cd0SStefano Zampini } 1110d7f69cd0SStefano Zampini ginfo->block_size = bs; 1111d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 1112d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 1113d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 11145e3038f0Sstefano_zampini PetscFunctionReturn(0); 11155e3038f0Sstefano_zampini } 11165e3038f0Sstefano_zampini 1117d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 1118d7f69cd0SStefano Zampini { 1119d7f69cd0SStefano Zampini Mat C,lC,lA; 1120d7f69cd0SStefano Zampini PetscErrorCode ierr; 1121d7f69cd0SStefano Zampini 1122d7f69cd0SStefano Zampini PetscFunctionBegin; 1123cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1124cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 1125d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1126d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 1127d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1128d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 1129d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 1130d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 1131cf37664fSBarry Smith } else { 1132cf37664fSBarry Smith C = *B; 1133d7f69cd0SStefano Zampini } 1134d7f69cd0SStefano Zampini 1135d7f69cd0SStefano Zampini /* perform local transposition */ 1136d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1137d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 1138d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 1139d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 1140d7f69cd0SStefano Zampini 1141cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 1142d7f69cd0SStefano Zampini *B = C; 1143d7f69cd0SStefano Zampini } else { 1144d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 1145d7f69cd0SStefano Zampini } 11467aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 11477aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1148d7f69cd0SStefano Zampini PetscFunctionReturn(0); 1149d7f69cd0SStefano Zampini } 1150d7f69cd0SStefano Zampini 11513fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 11523fd1c9e7SStefano Zampini { 11533fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 11543fd1c9e7SStefano Zampini PetscErrorCode ierr; 11553fd1c9e7SStefano Zampini 11563fd1c9e7SStefano Zampini PetscFunctionBegin; 11574b89b9cdSStefano Zampini if (D) { /* MatShift_IS pass D = NULL */ 11583fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11593fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11603fd1c9e7SStefano Zampini } 11613fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 11623fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 11633fd1c9e7SStefano Zampini PetscFunctionReturn(0); 11643fd1c9e7SStefano Zampini } 11653fd1c9e7SStefano Zampini 11663fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 11673fd1c9e7SStefano Zampini { 11684b89b9cdSStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 11693fd1c9e7SStefano Zampini PetscErrorCode ierr; 11703fd1c9e7SStefano Zampini 11713fd1c9e7SStefano Zampini PetscFunctionBegin; 11724b89b9cdSStefano Zampini ierr = VecSet(is->y,a);CHKERRQ(ierr); 11733fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 11743fd1c9e7SStefano Zampini PetscFunctionReturn(0); 11753fd1c9e7SStefano Zampini } 11763fd1c9e7SStefano Zampini 1177f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1178f26d0771SStefano Zampini { 1179f26d0771SStefano Zampini PetscErrorCode ierr; 1180f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1181f26d0771SStefano Zampini 1182f26d0771SStefano Zampini PetscFunctionBegin; 1183f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1184f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1185f26d0771SStefano Zampini #endif 1186f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1187f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1188b4f971dfSStefano Zampini ierr = MatSetValuesLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1189f26d0771SStefano Zampini PetscFunctionReturn(0); 1190f26d0771SStefano Zampini } 1191f26d0771SStefano Zampini 1192f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1193f26d0771SStefano Zampini { 1194f26d0771SStefano Zampini PetscErrorCode ierr; 1195f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 1196f26d0771SStefano Zampini 1197f26d0771SStefano Zampini PetscFunctionBegin; 1198f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1199f26d0771SStefano Zampini if (m > MATIS_MAX_ENTRIES_INSERTION || n > MATIS_MAX_ENTRIES_INSERTION) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column block indices must be <= %D: they are %D %D",MATIS_MAX_ENTRIES_INSERTION,m,n); 1200f26d0771SStefano Zampini #endif 1201f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 1202f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 1203b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal_IS(A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1204f26d0771SStefano Zampini PetscFunctionReturn(0); 1205f26d0771SStefano Zampini } 1206f26d0771SStefano Zampini 1207f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 1208a8116848SStefano Zampini { 1209a8116848SStefano Zampini PetscInt *owners = map->range; 1210a8116848SStefano Zampini PetscInt n = map->n; 1211a8116848SStefano Zampini PetscSF sf; 1212a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 1213a8116848SStefano Zampini PetscSFNode *ridxs; 1214a8116848SStefano Zampini PetscMPIInt rank; 1215a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 1216a8116848SStefano Zampini PetscErrorCode ierr; 1217a8116848SStefano Zampini 1218a8116848SStefano Zampini PetscFunctionBegin; 1219fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 1220a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 1221a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 1222a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 1223a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 1224a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 1225a8116848SStefano Zampini for (r = 0; r < N; ++r) { 1226a8116848SStefano Zampini const PetscInt idx = idxs[r]; 1227a8116848SStefano Zampini if (idx < 0 || map->N <= idx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Index %D out of range [0,%D)",idx,map->N); 1228a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 1229a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 1230a8116848SStefano Zampini } 1231a8116848SStefano Zampini ridxs[r].rank = p; 1232a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 1233a8116848SStefano Zampini } 1234a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 1235a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 1236a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1237a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 1238f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 1239a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 1240f0ae7da4SStefano Zampini 1241f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1242a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 1243a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 1244a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1245a8116848SStefano Zampini start -= cum; 1246a8116848SStefano Zampini cum = 0; 1247a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 1248a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1249a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 1250a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 1251a8116848SStefano Zampini } 1252a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1253a8116848SStefano Zampini /* Compress and put in indices */ 1254a8116848SStefano Zampini for (r = 0; r < n; ++r) 1255a8116848SStefano Zampini if (lidxs[r] >= 0) { 1256a8116848SStefano Zampini if (work) work[len] = work[r]; 1257a8116848SStefano Zampini lidxs[len++] = r; 1258a8116848SStefano Zampini } 1259a8116848SStefano Zampini if (on) *on = len; 1260a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 1261a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 1262a8116848SStefano Zampini PetscFunctionReturn(0); 1263a8116848SStefano Zampini } 1264a8116848SStefano Zampini 12657dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 1266a8116848SStefano Zampini { 1267a8116848SStefano Zampini Mat locmat,newlocmat; 1268a8116848SStefano Zampini Mat_IS *newmatis; 1269a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1270a8116848SStefano Zampini Vec rtest,ltest; 1271a8116848SStefano Zampini const PetscScalar *array; 1272a8116848SStefano Zampini #endif 1273a8116848SStefano Zampini const PetscInt *idxs; 1274a8116848SStefano Zampini PetscInt i,m,n; 1275a8116848SStefano Zampini PetscErrorCode ierr; 1276a8116848SStefano Zampini 1277a8116848SStefano Zampini PetscFunctionBegin; 1278a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 1279a8116848SStefano Zampini PetscBool ismatis; 1280a8116848SStefano Zampini 1281a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1282a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 1283a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1284a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 1285a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 1286a8116848SStefano Zampini } 1287a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 1288a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 1289a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 1290a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 1291a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1292a8116848SStefano Zampini for (i=0;i<n;i++) { 1293a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1294a8116848SStefano Zampini } 1295a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 1296a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 1297a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 1298a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 1299a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 1300fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Irow may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1301a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 1302a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 1303a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1304a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1305a8116848SStefano Zampini for (i=0;i<n;i++) { 1306a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 1307a8116848SStefano Zampini } 1308a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 1309a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 1310a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 1311a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 1312a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 1313fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Icol may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 1314a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 1315a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 1316a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 1317a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 1318a8116848SStefano Zampini #endif 1319a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1320a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 1321a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 1322a8116848SStefano Zampini IS is; 1323a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 1324306cf5c7SStefano Zampini PetscInt ll,newloc,irbs,icbs,arbs,acbs,rbs,cbs; 132594342113SStefano Zampini PetscBool cong; 1326a8116848SStefano Zampini MPI_Comm comm; 1327a8116848SStefano Zampini 1328a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 1329306cf5c7SStefano Zampini ierr = MatGetBlockSizes(mat,&arbs,&acbs);CHKERRQ(ierr); 1330306cf5c7SStefano Zampini ierr = ISGetBlockSize(irow,&irbs);CHKERRQ(ierr); 1331306cf5c7SStefano Zampini ierr = ISGetBlockSize(icol,&icbs);CHKERRQ(ierr); 1332306cf5c7SStefano Zampini rbs = arbs == irbs ? irbs : 1; 1333306cf5c7SStefano Zampini cbs = acbs == icbs ? icbs : 1; 1334a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 1335a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 1336a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1337a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1338a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1339306cf5c7SStefano Zampini ierr = MatSetBlockSizes(*newmat,rbs,cbs);CHKERRQ(ierr); 1340a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 1341a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 1342f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1343a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 13443d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 13453d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1346a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 1347a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1348a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1349a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 1350a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13513d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 1352a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1353a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 13543d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 1355a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 1356a8116848SStefano Zampini lidxs[newloc] = i; 1357a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 1358a8116848SStefano Zampini } 1359a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1360a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1361306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(rl2g,rbs);CHKERRQ(ierr); 1362a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1363a8116848SStefano Zampini /* local is to extract local submatrix */ 1364a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 1365a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 136694342113SStefano Zampini ierr = MatHasCongruentLayouts(mat,&cong);CHKERRQ(ierr); 136794342113SStefano Zampini if (cong && irow == icol && matis->csf == matis->sf) { 1368a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 1369a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 1370a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 1371a8116848SStefano Zampini } else { 1372a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 1373a8116848SStefano Zampini 1374a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 1375a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 1376f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 1377a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 13783d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 1379a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 1380a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 1381a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 1382a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 1383a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 13843d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 1385a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 1386a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 13873d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 1388a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 1389a8116848SStefano Zampini lidxs[newloc] = i; 1390a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 1391a8116848SStefano Zampini } 1392a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1393a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1394306cf5c7SStefano Zampini ierr = ISLocalToGlobalMappingSetBlockSize(cl2g,cbs);CHKERRQ(ierr); 1395a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1396a8116848SStefano Zampini /* local is to extract local submatrix */ 1397a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 1398a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1399a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1400a8116848SStefano Zampini } 1401a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1402a8116848SStefano Zampini } else { 1403a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 1404a8116848SStefano Zampini } 1405a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 1406a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 14077dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 1408a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1409a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 1410a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 1411a8116848SStefano Zampini } 1412a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1413a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1414a8116848SStefano Zampini PetscFunctionReturn(0); 1415a8116848SStefano Zampini } 1416a8116848SStefano Zampini 1417a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 14182b404112SStefano Zampini { 14192b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 14202b404112SStefano Zampini PetscBool ismatis; 14212b404112SStefano Zampini PetscErrorCode ierr; 14222b404112SStefano Zampini 14232b404112SStefano Zampini PetscFunctionBegin; 14242b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 14252b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 14262b404112SStefano Zampini b = (Mat_IS*)B->data; 14272b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 1428cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 14292b404112SStefano Zampini PetscFunctionReturn(0); 14302b404112SStefano Zampini } 14312b404112SStefano Zampini 1432a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 14336bd84002SStefano Zampini { 1434527b2640SStefano Zampini Vec v; 1435527b2640SStefano Zampini const PetscScalar *array; 1436527b2640SStefano Zampini PetscInt i,n; 14376bd84002SStefano Zampini PetscErrorCode ierr; 14386bd84002SStefano Zampini 14396bd84002SStefano Zampini PetscFunctionBegin; 1440527b2640SStefano Zampini *missing = PETSC_FALSE; 1441527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 1442527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 1443527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1444527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 1445527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 1446527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 1447527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1448527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 1449527b2640SStefano Zampini if (d) { 1450527b2640SStefano Zampini *d = -1; 1451527b2640SStefano Zampini if (*missing) { 1452527b2640SStefano Zampini PetscInt rstart; 1453527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 1454527b2640SStefano Zampini *d = i+rstart; 1455527b2640SStefano Zampini } 1456527b2640SStefano Zampini } 14576bd84002SStefano Zampini PetscFunctionReturn(0); 14586bd84002SStefano Zampini } 14596bd84002SStefano Zampini 1460cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 146128f4e0baSStefano Zampini { 146228f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 146328f4e0baSStefano Zampini const PetscInt *gidxs; 14644f2d7cafSStefano Zampini PetscInt nleaves; 146528f4e0baSStefano Zampini PetscErrorCode ierr; 146628f4e0baSStefano Zampini 146728f4e0baSStefano Zampini PetscFunctionBegin; 14684f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 146975d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 147075d48cdbSStefano Zampini ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 147128f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 14723bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 14734f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 14744f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 14753bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 14764f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 1477a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 14783d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 1479a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 1480a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 14813d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 1482a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 14833d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 1484a8116848SStefano Zampini } else { 1485a8116848SStefano Zampini matis->csf = matis->sf; 1486a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 1487a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 1488a8116848SStefano Zampini } 148928f4e0baSStefano Zampini PetscFunctionReturn(0); 149028f4e0baSStefano Zampini } 14912e1947a5SStefano Zampini 1492eb82efa4SStefano Zampini /*@ 149375d48cdbSStefano Zampini MatISStoreL2L - Store local-to-local operators during the Galerkin process of MatPtAP. 149475d48cdbSStefano Zampini 149575d48cdbSStefano Zampini Collective on MPI_Comm 149675d48cdbSStefano Zampini 149775d48cdbSStefano Zampini Input Parameters: 149875d48cdbSStefano Zampini + A - the matrix 149975d48cdbSStefano Zampini - store - the boolean flag 150075d48cdbSStefano Zampini 150175d48cdbSStefano Zampini Level: advanced 150275d48cdbSStefano Zampini 150375d48cdbSStefano Zampini Notes: 150475d48cdbSStefano Zampini 150575d48cdbSStefano Zampini .keywords: matrix 150675d48cdbSStefano Zampini 150775d48cdbSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatPtAP() 150875d48cdbSStefano Zampini @*/ 150975d48cdbSStefano Zampini PetscErrorCode MatISStoreL2L(Mat A, PetscBool store) 151075d48cdbSStefano Zampini { 151175d48cdbSStefano Zampini PetscErrorCode ierr; 151275d48cdbSStefano Zampini 151375d48cdbSStefano Zampini PetscFunctionBegin; 151475d48cdbSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 151575d48cdbSStefano Zampini PetscValidType(A,1); 151675d48cdbSStefano Zampini PetscValidLogicalCollectiveBool(A,store,2); 151775d48cdbSStefano Zampini ierr = PetscTryMethod(A,"MatISStoreL2L_C",(Mat,PetscBool),(A,store));CHKERRQ(ierr); 151875d48cdbSStefano Zampini PetscFunctionReturn(0); 151975d48cdbSStefano Zampini } 152075d48cdbSStefano Zampini 152175d48cdbSStefano Zampini static PetscErrorCode MatISStoreL2L_IS(Mat A, PetscBool store) 152275d48cdbSStefano Zampini { 152375d48cdbSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 152475d48cdbSStefano Zampini PetscErrorCode ierr; 152575d48cdbSStefano Zampini 152675d48cdbSStefano Zampini PetscFunctionBegin; 152775d48cdbSStefano Zampini matis->storel2l = store; 152875d48cdbSStefano Zampini if (!store) { 152975d48cdbSStefano Zampini ierr = PetscObjectCompose((PetscObject)(A),"_MatIS_PtAP_l2l",NULL);CHKERRQ(ierr); 153075d48cdbSStefano Zampini } 153175d48cdbSStefano Zampini PetscFunctionReturn(0); 153275d48cdbSStefano Zampini } 153375d48cdbSStefano Zampini 153475d48cdbSStefano Zampini /*@ 1535a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1536a88811baSStefano Zampini 1537a88811baSStefano Zampini Collective on MPI_Comm 1538a88811baSStefano Zampini 1539a88811baSStefano Zampini Input Parameters: 1540a88811baSStefano Zampini + B - the matrix 1541a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1542a88811baSStefano Zampini (same value is used for all local rows) 1543a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1544a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1545a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1546a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1547a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1548a88811baSStefano Zampini the diagonal entry even if it is zero. 1549a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1550a88811baSStefano Zampini submatrix (same value is used for all local rows). 1551a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1552a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1553a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1554a88811baSStefano Zampini structure. The size of this array is equal to the number 1555a88811baSStefano Zampini of local rows, i.e 'm'. 1556a88811baSStefano Zampini 1557a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1558a88811baSStefano Zampini 1559a88811baSStefano Zampini Level: intermediate 1560a88811baSStefano Zampini 156195452b02SPatrick Sanan Notes: 156295452b02SPatrick Sanan This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1563a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1564a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1565a88811baSStefano Zampini 1566a88811baSStefano Zampini .keywords: matrix 1567a88811baSStefano Zampini 15683c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1569a88811baSStefano Zampini @*/ 15702e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 15712e1947a5SStefano Zampini { 15722e1947a5SStefano Zampini PetscErrorCode ierr; 15732e1947a5SStefano Zampini 15742e1947a5SStefano Zampini PetscFunctionBegin; 15752e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 15762e1947a5SStefano Zampini PetscValidType(B,1); 15772e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 15782e1947a5SStefano Zampini PetscFunctionReturn(0); 15792e1947a5SStefano Zampini } 15802e1947a5SStefano Zampini 1581844bd0d7SStefano Zampini /* this is used by DMDA */ 1582844bd0d7SStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 15832e1947a5SStefano Zampini { 15842e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 158528f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 15862e1947a5SStefano Zampini PetscErrorCode ierr; 15872e1947a5SStefano Zampini 15882e1947a5SStefano Zampini PetscFunctionBegin; 15896c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1590cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 15914f2d7cafSStefano Zampini 15924f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 15934f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 15944f2d7cafSStefano Zampini 15954f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 15964f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 15974f2d7cafSStefano Zampini 159828f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 159928f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 160028f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 160128f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 16024f2d7cafSStefano Zampini 16034f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 160428f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 16050f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 16060f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 16070f2f62c7SStefano Zampini #endif 16084f2d7cafSStefano Zampini 16094f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 161028f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 16114f2d7cafSStefano Zampini 16124f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 161328f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 16140f2f62c7SStefano Zampini 16150f2f62c7SStefano Zampini /* for other matrix types */ 16160f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 16172e1947a5SStefano Zampini PetscFunctionReturn(0); 16182e1947a5SStefano Zampini } 1619b4319ba4SBarry Smith 16203927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 16213927de2eSStefano Zampini { 16223927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 16233927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1624ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 16253927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 16263927de2eSStefano Zampini PetscInt lrows,lcols; 16273927de2eSStefano Zampini PetscInt local_rows,local_cols; 16283927de2eSStefano Zampini PetscMPIInt nsubdomains; 16293927de2eSStefano Zampini PetscBool isdense,issbaij; 16303927de2eSStefano Zampini PetscErrorCode ierr; 16313927de2eSStefano Zampini 16323927de2eSStefano Zampini PetscFunctionBegin; 16333927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 16343927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 16353927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 16363927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 16373927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 16383927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1639ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1640ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 16417230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1642ecf5a873SStefano Zampini } else { 1643ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1644ecf5a873SStefano Zampini } 1645ecf5a873SStefano Zampini 16463927de2eSStefano Zampini if (issbaij) { 16473927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 16483927de2eSStefano Zampini } 16493927de2eSStefano Zampini /* 1650ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 16513927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 16523927de2eSStefano Zampini */ 1653cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 16543927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 16553927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 16563927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 16573927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 16583927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 16593927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 16603927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 16613927de2eSStefano Zampini row_ownership[j] = i; 16623927de2eSStefano Zampini } 16633927de2eSStefano Zampini } 16647230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 16653927de2eSStefano Zampini 16663927de2eSStefano Zampini /* 16673927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 16683927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 16693927de2eSStefano Zampini */ 16703927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 16713927de2eSStefano Zampini /* preallocation as a MATAIJ */ 16723927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 16733927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 167412dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 167512dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1676ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 16773927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 16783927de2eSStefano Zampini my_dnz[i] += 1; 16793927de2eSStefano Zampini } else { /* offdiag block */ 16803927de2eSStefano Zampini my_onz[i] += 1; 16813927de2eSStefano Zampini } 16823927de2eSStefano Zampini } 16833927de2eSStefano Zampini } 1684bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1685bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1686bb1015c3SStefano Zampini PetscBool done; 1687bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1688938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1689bb1015c3SStefano Zampini jptr = jj; 1690bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1691bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1692bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1693bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1694bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1695bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1696bb1015c3SStefano Zampini my_dnz[i] += 1; 1697bb1015c3SStefano Zampini } else { /* offdiag block */ 1698bb1015c3SStefano Zampini my_onz[i] += 1; 1699bb1015c3SStefano Zampini } 1700bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1701bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1702bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1703bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1704bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1705bb1015c3SStefano Zampini } else { 1706bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1707bb1015c3SStefano Zampini } 1708bb1015c3SStefano Zampini } 1709bb1015c3SStefano Zampini } 1710bb1015c3SStefano Zampini } 1711bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1712938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1713bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 17143927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 17153927de2eSStefano Zampini const PetscInt *cols; 1716ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 17173927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 17183927de2eSStefano Zampini for (j=0;j<ncols;j++) { 17193927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1720ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 17213927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 17223927de2eSStefano Zampini my_dnz[i] += 1; 17233927de2eSStefano Zampini } else { /* offdiag block */ 17243927de2eSStefano Zampini my_onz[i] += 1; 17253927de2eSStefano Zampini } 17263927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1727d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 17283927de2eSStefano Zampini owner = row_ownership[index_col]; 17293927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1730d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 17313927de2eSStefano Zampini } else { 1732d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 17333927de2eSStefano Zampini } 17343927de2eSStefano Zampini } 17353927de2eSStefano Zampini } 17363927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 17373927de2eSStefano Zampini } 17383927de2eSStefano Zampini } 1739ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 17407230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1741ecf5a873SStefano Zampini } 17424f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 17433927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1744ecf5a873SStefano Zampini 1745ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 17463927de2eSStefano Zampini if (maxreduce) { 17473927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 17483927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1749bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 17503927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 17513927de2eSStefano Zampini } else { 17523927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 17533927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1754bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 17553927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 17563927de2eSStefano Zampini } 17573927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 17583927de2eSStefano Zampini 17593927de2eSStefano Zampini /* Resize preallocation if overestimated */ 17603927de2eSStefano Zampini for (i=0;i<lrows;i++) { 17613927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 17623927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 17633927de2eSStefano Zampini } 17641670daf9Sstefano_zampini 17651670daf9Sstefano_zampini /* Set preallocation */ 1766268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 17673927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 17683927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 17693927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 17703927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 17713927de2eSStefano Zampini } 1772268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 17733927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 17743927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 17753927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 17763927de2eSStefano Zampini if (issbaij) { 17773927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 17783927de2eSStefano Zampini } 17799be90c3fSStefano Zampini ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 17803927de2eSStefano Zampini PetscFunctionReturn(0); 17813927de2eSStefano Zampini } 17823927de2eSStefano Zampini 17837230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1784b7ce53b6SStefano Zampini { 1785b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1786d9a9e74cSStefano Zampini Mat local_mat; 1787b7ce53b6SStefano Zampini /* info on mat */ 17883cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1789b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1790b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1791b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1792b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1793b9ed4604SStefano Zampini #endif 17947c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1795b7ce53b6SStefano Zampini /* values insertion */ 1796b7ce53b6SStefano Zampini PetscScalar *array; 1797b7ce53b6SStefano Zampini /* work */ 1798b7ce53b6SStefano Zampini PetscErrorCode ierr; 1799b7ce53b6SStefano Zampini 1800b7ce53b6SStefano Zampini PetscFunctionBegin; 1801b7ce53b6SStefano Zampini /* get info from mat */ 18027c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 18037c03b4e8SStefano Zampini if (nsubdomains == 1) { 18041670daf9Sstefano_zampini Mat B; 18051670daf9Sstefano_zampini IS rows,cols; 1806acdf38a7Sstefano_zampini IS irows,icols; 18071670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 18081670daf9Sstefano_zampini 18091670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 18101670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 18111670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 18121670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 1813acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1814acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1815acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1816acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1817268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 1818268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1819acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1820acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 18216104e0f1Sstefano_zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 18227dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1823acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1824acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1825acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 18267c03b4e8SStefano Zampini PetscFunctionReturn(0); 18277c03b4e8SStefano Zampini } 1828b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1829b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 18303cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1831b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1832b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 18334099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1834b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1835b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1836b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1837b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1838b9ed4604SStefano Zampini lb[0] = isseqdense; 1839b9ed4604SStefano Zampini lb[1] = isseqaij; 1840b9ed4604SStefano Zampini lb[2] = isseqbaij; 1841b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1842b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1843b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1844b9ed4604SStefano Zampini #endif 1845b7ce53b6SStefano Zampini 1846b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18473927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 18483cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 1849b9ed4604SStefano Zampini if (!isseqsbaij) { 1850b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1851b9ed4604SStefano Zampini } else { 1852b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1853b9ed4604SStefano Zampini } 1854d59cf9ebSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 18553927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1856b7ce53b6SStefano Zampini } else { 18573cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1858b7ce53b6SStefano Zampini /* some checks */ 1859b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1860b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 18613cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 18626c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 18636c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 18646c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 18656c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 18666c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1867b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1868b7ce53b6SStefano Zampini } 1869d9a9e74cSStefano Zampini 1870b9ed4604SStefano Zampini if (isseqsbaij) { 1871d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1872d9a9e74cSStefano Zampini } else { 1873d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1874d9a9e74cSStefano Zampini local_mat = matis->A; 1875d9a9e74cSStefano Zampini } 1876686e3a49SStefano Zampini 1877b7ce53b6SStefano Zampini /* Set values */ 1878ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1879b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 188065066ba5SStefano Zampini PetscInt i,*dummy; 1881ecf5a873SStefano Zampini 188265066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 188365066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 1884b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1885d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 188665066ba5SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 1887d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 188865066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 1889686e3a49SStefano Zampini } else if (isseqaij) { 1890ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1891686e3a49SStefano Zampini PetscBool done; 1892686e3a49SStefano Zampini 1893d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1894938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1895d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1896686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1897ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1898686e3a49SStefano Zampini } 1899d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1900938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1901d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1902686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1903ecf5a873SStefano Zampini PetscInt i; 1904c0962df8SStefano Zampini 1905686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1906686e3a49SStefano Zampini PetscInt j; 1907ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1908686e3a49SStefano Zampini 1909ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1910ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1911ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1912686e3a49SStefano Zampini } 1913b7ce53b6SStefano Zampini } 1914b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1915d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1916b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1917b9ed4604SStefano Zampini if (isseqdense) { 1918b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1919b7ce53b6SStefano Zampini } 1920b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1921b7ce53b6SStefano Zampini } 1922b7ce53b6SStefano Zampini 1923b7ce53b6SStefano Zampini /*@ 1924b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1925b7ce53b6SStefano Zampini 1926b7ce53b6SStefano Zampini Input Parameter: 1927b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1928b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1929b7ce53b6SStefano Zampini 1930b7ce53b6SStefano Zampini Output Parameter: 1931b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1932b7ce53b6SStefano Zampini 1933b7ce53b6SStefano Zampini Level: developer 1934b7ce53b6SStefano Zampini 193595452b02SPatrick Sanan Notes: 193695452b02SPatrick Sanan mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1937b7ce53b6SStefano Zampini 1938b7ce53b6SStefano Zampini .seealso: MATIS 1939b7ce53b6SStefano Zampini @*/ 1940b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1941b7ce53b6SStefano Zampini { 1942b7ce53b6SStefano Zampini PetscErrorCode ierr; 1943b7ce53b6SStefano Zampini 1944b7ce53b6SStefano Zampini PetscFunctionBegin; 1945b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1946b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1947b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1948b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1949b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1950b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 19516c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1952b7ce53b6SStefano Zampini } 1953b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1954b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1955b7ce53b6SStefano Zampini } 1956b7ce53b6SStefano Zampini 1957ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1958ad6194a2SStefano Zampini { 1959ad6194a2SStefano Zampini PetscErrorCode ierr; 1960ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1961*c9225affSStefano Zampini PetscInt rbs,cbs,m,n,M,N; 1962ad6194a2SStefano Zampini Mat B,localmat; 1963ad6194a2SStefano Zampini 1964ad6194a2SStefano Zampini PetscFunctionBegin; 1965*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&rbs);CHKERRQ(ierr); 1966*c9225affSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&cbs);CHKERRQ(ierr); 1967ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1968ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1969*c9225affSStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),rbs == cbs ? rbs : 1,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1970ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1971ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1972b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1973b0f2910eSStefano Zampini if (matis->sf) { 1974b0f2910eSStefano Zampini Mat_IS *bmatis = (Mat_IS*)(B->data); 1975b0f2910eSStefano Zampini 1976b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->sf);CHKERRQ(ierr); 1977b0f2910eSStefano Zampini bmatis->sf = matis->sf; 1978b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&bmatis->sf_rootdata,matis->sf->nleaves,&bmatis->sf_leafdata);CHKERRQ(ierr); 1979b0f2910eSStefano Zampini if (matis->sf != matis->csf) { 1980b0f2910eSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->csf);CHKERRQ(ierr); 1981b0f2910eSStefano Zampini bmatis->csf = matis->csf; 1982b0f2910eSStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&bmatis->csf_rootdata,matis->csf->nleaves,&bmatis->csf_leafdata);CHKERRQ(ierr); 1983b0f2910eSStefano Zampini } else { 1984b0f2910eSStefano Zampini bmatis->csf = bmatis->sf; 1985b0f2910eSStefano Zampini bmatis->csf_leafdata = bmatis->sf_leafdata; 1986b0f2910eSStefano Zampini bmatis->csf_rootdata = bmatis->sf_rootdata; 1987b0f2910eSStefano Zampini } 1988b0f2910eSStefano Zampini } 1989ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1990ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1991ad6194a2SStefano Zampini *newmat = B; 1992ad6194a2SStefano Zampini PetscFunctionReturn(0); 1993ad6194a2SStefano Zampini } 1994ad6194a2SStefano Zampini 1995a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 199669796d55SStefano Zampini { 199769796d55SStefano Zampini PetscErrorCode ierr; 199869796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 199969796d55SStefano Zampini PetscBool local_sym; 200069796d55SStefano Zampini 200169796d55SStefano Zampini PetscFunctionBegin; 200269796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 2003b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 200469796d55SStefano Zampini PetscFunctionReturn(0); 200569796d55SStefano Zampini } 200669796d55SStefano Zampini 2007a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 200869796d55SStefano Zampini { 200969796d55SStefano Zampini PetscErrorCode ierr; 201069796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 201169796d55SStefano Zampini PetscBool local_sym; 201269796d55SStefano Zampini 201369796d55SStefano Zampini PetscFunctionBegin; 201469796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 2015b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 201669796d55SStefano Zampini PetscFunctionReturn(0); 201769796d55SStefano Zampini } 201869796d55SStefano Zampini 201945471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 202045471136SStefano Zampini { 202145471136SStefano Zampini PetscErrorCode ierr; 202245471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 202345471136SStefano Zampini PetscBool local_sym; 202445471136SStefano Zampini 202545471136SStefano Zampini PetscFunctionBegin; 202645471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 202745471136SStefano Zampini *flg = PETSC_FALSE; 202845471136SStefano Zampini PetscFunctionReturn(0); 202945471136SStefano Zampini } 203045471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 203145471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 203245471136SStefano Zampini PetscFunctionReturn(0); 203345471136SStefano Zampini } 203445471136SStefano Zampini 2035a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 2036b4319ba4SBarry Smith { 2037dfbe8321SBarry Smith PetscErrorCode ierr; 2038b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 2039b4319ba4SBarry Smith 2040b4319ba4SBarry Smith PetscFunctionBegin; 20416bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 2042e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 2043e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 20446bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 20456bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 20463fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 2047a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 2048a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 2049a8116848SStefano Zampini if (b->sf != b->csf) { 2050a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 2051a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 2052a8116848SStefano Zampini } 205328f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 205428f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 2055bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 2056dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 2057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 2058b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 2059b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 20602e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 2061cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 206275d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",NULL);CHKERRQ(ierr); 2063b4319ba4SBarry Smith PetscFunctionReturn(0); 2064b4319ba4SBarry Smith } 2065b4319ba4SBarry Smith 2066a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 2067b4319ba4SBarry Smith { 2068dfbe8321SBarry Smith PetscErrorCode ierr; 2069b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2070b4319ba4SBarry Smith PetscScalar zero = 0.0; 2071b4319ba4SBarry Smith 2072b4319ba4SBarry Smith PetscFunctionBegin; 2073b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 2074e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2075e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2076b4319ba4SBarry Smith 2077b4319ba4SBarry Smith /* multiply the local matrix */ 2078b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 2079b4319ba4SBarry Smith 2080b4319ba4SBarry Smith /* scatter product back into global memory */ 20812dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 2082e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2083e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2084b4319ba4SBarry Smith PetscFunctionReturn(0); 2085b4319ba4SBarry Smith } 2086b4319ba4SBarry Smith 2087a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 20882e74eeadSLisandro Dalcin { 2089650997f4SStefano Zampini Vec temp_vec; 20902e74eeadSLisandro Dalcin PetscErrorCode ierr; 20912e74eeadSLisandro Dalcin 20922e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 2093650997f4SStefano Zampini if (v3 != v2) { 2094650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 2095650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2096650997f4SStefano Zampini } else { 2097650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2098650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 2099650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2100650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2101650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2102650997f4SStefano Zampini } 21032e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21042e74eeadSLisandro Dalcin } 21052e74eeadSLisandro Dalcin 2106a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 21072e74eeadSLisandro Dalcin { 21082e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 21092e74eeadSLisandro Dalcin PetscErrorCode ierr; 21102e74eeadSLisandro Dalcin 2111e176bc59SStefano Zampini PetscFunctionBegin; 21122e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 2113e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2114e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 21152e74eeadSLisandro Dalcin 21162e74eeadSLisandro Dalcin /* multiply the local matrix */ 2117e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 21182e74eeadSLisandro Dalcin 21192e74eeadSLisandro Dalcin /* scatter product back into global vector */ 2120e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 2121e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2122e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 21232e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21242e74eeadSLisandro Dalcin } 21252e74eeadSLisandro Dalcin 2126a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 21272e74eeadSLisandro Dalcin { 2128650997f4SStefano Zampini Vec temp_vec; 21292e74eeadSLisandro Dalcin PetscErrorCode ierr; 21302e74eeadSLisandro Dalcin 21312e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 2132650997f4SStefano Zampini if (v3 != v2) { 2133650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 2134650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 2135650997f4SStefano Zampini } else { 2136650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 2137650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 2138650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 2139650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 2140650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 2141650997f4SStefano Zampini } 21422e74eeadSLisandro Dalcin PetscFunctionReturn(0); 21432e74eeadSLisandro Dalcin } 21442e74eeadSLisandro Dalcin 2145a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 2146b4319ba4SBarry Smith { 2147b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 2148dfbe8321SBarry Smith PetscErrorCode ierr; 2149b4319ba4SBarry Smith PetscViewer sviewer; 2150ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 2151b4319ba4SBarry Smith 2152b4319ba4SBarry Smith PetscFunctionBegin; 2153ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 2154ee2491ecSStefano Zampini if (isascii) { 2155ee2491ecSStefano Zampini PetscViewerFormat format; 2156ee2491ecSStefano Zampini 2157ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2158ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 2159ee2491ecSStefano Zampini } 2160ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 21613f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 2162b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 21633f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 21646e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2165b4319ba4SBarry Smith PetscFunctionReturn(0); 2166b4319ba4SBarry Smith } 2167b4319ba4SBarry Smith 2168a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2169b4319ba4SBarry Smith { 2170dfbe8321SBarry Smith PetscErrorCode ierr; 2171e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 2172b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2173b4319ba4SBarry Smith IS from,to; 2174e176bc59SStefano Zampini Vec cglobal,rglobal; 2175b4319ba4SBarry Smith 2176b4319ba4SBarry Smith PetscFunctionBegin; 2177784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 2178e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 21793bbff08aSStefano Zampini /* Destroy any previous data */ 218070cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 218170cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 21823fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 2183e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 2184e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 21851c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 2186872cf891SStefano Zampini if (is->csf != is->sf) { 2187872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 2188872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 2189872cf891SStefano Zampini } 219028f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 219128f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 21923bbff08aSStefano Zampini 21933bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 2194fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 2195fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2196e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 2197e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 2198e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 2199e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 22006625354bSStefano Zampini /* check if the two mappings are actually the same for square matrices (DOLFIN passes 2 different objects) */ 22016625354bSStefano Zampini if (rmapping != cmapping && A->rmap->N == A->cmap->N) { 22026625354bSStefano Zampini PetscBool same,gsame; 22036625354bSStefano Zampini 22046625354bSStefano Zampini same = PETSC_FALSE; 22056625354bSStefano Zampini if (nr == nc && cbs == rbs) { 22066625354bSStefano Zampini const PetscInt *idxs1,*idxs2; 22076625354bSStefano Zampini 22086625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 22096625354bSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 22106625354bSStefano Zampini ierr = PetscMemcmp(idxs1,idxs2,(nr/rbs)*sizeof(PetscInt),&same);CHKERRQ(ierr); 22116625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(rmapping,&idxs1);CHKERRQ(ierr); 22126625354bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreBlockIndices(cmapping,&idxs2);CHKERRQ(ierr); 22136625354bSStefano Zampini } 22146625354bSStefano Zampini ierr = MPIU_Allreduce(&same,&gsame,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 22156625354bSStefano Zampini if (gsame) cmapping = rmapping; 22166625354bSStefano Zampini } 22176625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 22186625354bSStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 22196625354bSStefano Zampini 22206625354bSStefano Zampini /* Create the local matrix A */ 2221f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 2222e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 2223e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 2224e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 2225ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 2226ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 2227b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 2228c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 2229c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 2230b4319ba4SBarry Smith 2231f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 2232b4319ba4SBarry Smith /* Create the local work vectors */ 22333bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 2234b4319ba4SBarry Smith 2235e176bc59SStefano Zampini /* setup the global to local scatters */ 2236e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 2237e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 2238784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 2239e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 2240e176bc59SStefano Zampini if (rmapping != cmapping) { 2241e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 2242e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 2243e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 2244e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 2245e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 2246e176bc59SStefano Zampini } else { 2247e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 2248e176bc59SStefano Zampini is->cctx = is->rctx; 2249e176bc59SStefano Zampini } 22503fd1c9e7SStefano Zampini 22513fd1c9e7SStefano Zampini /* interface counter vector (local) */ 22523fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 22533fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 22543fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22553fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 22563fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22573fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 22583fd1c9e7SStefano Zampini 22593fd1c9e7SStefano Zampini /* free workspace */ 2260e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 2261e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 22626bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 22636bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 2264f26d0771SStefano Zampini } 226548ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 2266b4319ba4SBarry Smith PetscFunctionReturn(0); 2267b4319ba4SBarry Smith } 2268b4319ba4SBarry Smith 2269a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 22702e74eeadSLisandro Dalcin { 22712e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 22722e74eeadSLisandro Dalcin PetscErrorCode ierr; 227397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 227497563a80SStefano Zampini PetscInt i,zm,zn; 227597563a80SStefano Zampini #endif 2276f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 22772e74eeadSLisandro Dalcin 22782e74eeadSLisandro Dalcin PetscFunctionBegin; 22792e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2280f26d0771SStefano 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); 228197563a80SStefano Zampini /* count negative indices */ 228297563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 228397563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 22842e74eeadSLisandro Dalcin #endif 228597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 228697563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 228797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 228897563a80SStefano Zampini /* count negative indices (should be the same as before) */ 228997563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 229097563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2291b4f971dfSStefano 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"); 2292b4f971dfSStefano 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"); 229397563a80SStefano Zampini #endif 22942e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 22952e74eeadSLisandro Dalcin PetscFunctionReturn(0); 22962e74eeadSLisandro Dalcin } 22972e74eeadSLisandro Dalcin 2298a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 229997563a80SStefano Zampini { 230097563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 230197563a80SStefano Zampini PetscErrorCode ierr; 230297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 230397563a80SStefano Zampini PetscInt i,zm,zn; 230497563a80SStefano Zampini #endif 2305f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 230697563a80SStefano Zampini 230797563a80SStefano Zampini PetscFunctionBegin; 230897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 2309f26d0771SStefano 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); 231097563a80SStefano Zampini /* count negative indices */ 231197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 231297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 231397563a80SStefano Zampini #endif 231497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 231597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 231697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 231797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 231897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 231997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 2320b4f971dfSStefano 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"); 2321b4f971dfSStefano 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"); 232297563a80SStefano Zampini #endif 2323d59cf9ebSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 232497563a80SStefano Zampini PetscFunctionReturn(0); 232597563a80SStefano Zampini } 232697563a80SStefano Zampini 2327a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2328b4319ba4SBarry Smith { 2329dfbe8321SBarry Smith PetscErrorCode ierr; 2330b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2331b4319ba4SBarry Smith 2332b4319ba4SBarry Smith PetscFunctionBegin; 2333b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2334872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2335872cf891SStefano Zampini } else { 2336b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2337872cf891SStefano Zampini } 2338b4319ba4SBarry Smith PetscFunctionReturn(0); 2339b4319ba4SBarry Smith } 2340b4319ba4SBarry Smith 2341a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 2342f0006bf2SLisandro Dalcin { 2343f0006bf2SLisandro Dalcin PetscErrorCode ierr; 2344f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 2345f0006bf2SLisandro Dalcin 2346f0006bf2SLisandro Dalcin PetscFunctionBegin; 2347b4f971dfSStefano Zampini if (is->A->rmap->mapping) { 2348b4f971dfSStefano Zampini #if defined(PETSC_USE_DEBUG) 2349b4f971dfSStefano Zampini PetscInt ibs,bs; 2350b4f971dfSStefano Zampini 2351b4f971dfSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(is->A->rmap->mapping,&ibs);CHKERRQ(ierr); 2352b4f971dfSStefano Zampini ierr = MatGetBlockSize(is->A,&bs);CHKERRQ(ierr); 2353b4f971dfSStefano Zampini if (ibs != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Different block sizes! local mat %D, local l2g map %D",bs,ibs); 2354b4f971dfSStefano Zampini #endif 2355b4f971dfSStefano Zampini ierr = MatSetValuesBlockedLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2356b4f971dfSStefano Zampini } else { 2357f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 2358b4f971dfSStefano Zampini } 2359f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 2360f0006bf2SLisandro Dalcin } 2361f0006bf2SLisandro Dalcin 2362f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 2363f0ae7da4SStefano Zampini { 2364f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 2365f0ae7da4SStefano Zampini PetscErrorCode ierr; 2366f0ae7da4SStefano Zampini 2367f0ae7da4SStefano Zampini PetscFunctionBegin; 2368f0ae7da4SStefano Zampini if (!n) { 2369f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 2370f0ae7da4SStefano Zampini } else { 2371f0ae7da4SStefano Zampini PetscInt i; 2372f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 2373f0ae7da4SStefano Zampini 2374f0ae7da4SStefano Zampini if (columns) { 2375f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2376f0ae7da4SStefano Zampini } else { 2377f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 2378f0ae7da4SStefano Zampini } 2379f0ae7da4SStefano Zampini if (diag != 0.) { 2380f0ae7da4SStefano Zampini const PetscScalar *array; 2381f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 2382f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 2383f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 2384f0ae7da4SStefano Zampini } 2385f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 2386f0ae7da4SStefano Zampini } 2387f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2388f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2389f0ae7da4SStefano Zampini } 2390f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2391f0ae7da4SStefano Zampini } 2392f0ae7da4SStefano Zampini 2393f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 23942e74eeadSLisandro Dalcin { 23956e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 23966e520ac8SStefano Zampini PetscInt nr,nl,len,i; 23976e520ac8SStefano Zampini PetscInt *lrows; 23982e74eeadSLisandro Dalcin PetscErrorCode ierr; 23992e74eeadSLisandro Dalcin 24002e74eeadSLisandro Dalcin PetscFunctionBegin; 2401f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 2402f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 2403f0ae7da4SStefano Zampini PetscBool cong; 240426b0207aSStefano Zampini 2405f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 240626b0207aSStefano Zampini cong = (PetscBool)(cong && matis->sf == matis->csf); 2407268753edSStefano 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"); 2408268753edSStefano 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"); 2409268753edSStefano 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"); 2410f0ae7da4SStefano Zampini } 2411f0ae7da4SStefano Zampini #endif 24126e520ac8SStefano Zampini /* get locally owned rows */ 2413f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 24146e520ac8SStefano Zampini /* fix right hand side if needed */ 24156e520ac8SStefano Zampini if (x && b) { 24166e520ac8SStefano Zampini const PetscScalar *xx; 24176e520ac8SStefano Zampini PetscScalar *bb; 24186e520ac8SStefano Zampini 24196e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 24206e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 24216e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 24226e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 24236e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 24242e74eeadSLisandro Dalcin } 24256e520ac8SStefano Zampini /* get rows associated to the local matrices */ 24263d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 24276e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 24286e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 24296e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 24306e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 24316e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 24326e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 24336e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 24346e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 24356e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 2436f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 24376e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 24382e74eeadSLisandro Dalcin PetscFunctionReturn(0); 24392e74eeadSLisandro Dalcin } 24402e74eeadSLisandro Dalcin 2441f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2442b4319ba4SBarry Smith { 2443dfbe8321SBarry Smith PetscErrorCode ierr; 2444b4319ba4SBarry Smith 2445b4319ba4SBarry Smith PetscFunctionBegin; 2446f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 2447f0ae7da4SStefano Zampini PetscFunctionReturn(0); 2448f0ae7da4SStefano Zampini } 24492205254eSKarl Rupp 2450f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 2451f0ae7da4SStefano Zampini { 2452f0ae7da4SStefano Zampini PetscErrorCode ierr; 2453f0ae7da4SStefano Zampini 2454f0ae7da4SStefano Zampini PetscFunctionBegin; 2455f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 2456b4319ba4SBarry Smith PetscFunctionReturn(0); 2457b4319ba4SBarry Smith } 2458b4319ba4SBarry Smith 2459a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 2460b4319ba4SBarry Smith { 2461b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2462dfbe8321SBarry Smith PetscErrorCode ierr; 2463b4319ba4SBarry Smith 2464b4319ba4SBarry Smith PetscFunctionBegin; 2465b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 2466b4319ba4SBarry Smith PetscFunctionReturn(0); 2467b4319ba4SBarry Smith } 2468b4319ba4SBarry Smith 2469a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 2470b4319ba4SBarry Smith { 2471b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 2472dfbe8321SBarry Smith PetscErrorCode ierr; 2473b4319ba4SBarry Smith 2474b4319ba4SBarry Smith PetscFunctionBegin; 2475b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 2476872cf891SStefano Zampini /* fix for local empty rows/cols */ 2477872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 2478872cf891SStefano Zampini Mat newlA; 2479872cf891SStefano Zampini ISLocalToGlobalMapping l2g; 2480872cf891SStefano Zampini IS tis; 2481872cf891SStefano Zampini const PetscScalar *v; 2482872cf891SStefano Zampini PetscInt i,n,cf,*loce,*locf; 2483872cf891SStefano Zampini PetscBool sym; 2484872cf891SStefano Zampini 2485872cf891SStefano Zampini ierr = MatGetRowMaxAbs(is->A,is->y,NULL);CHKERRQ(ierr); 2486872cf891SStefano Zampini ierr = MatIsSymmetric(is->A,PETSC_SMALL,&sym);CHKERRQ(ierr); 2487872cf891SStefano Zampini if (!sym) SETERRQ(PetscObjectComm((PetscObject)is->A),PETSC_ERR_SUP,"Not yet implemented for unsymmetric case"); 2488872cf891SStefano Zampini ierr = VecGetLocalSize(is->y,&n);CHKERRQ(ierr); 2489872cf891SStefano Zampini ierr = PetscMalloc1(n,&loce);CHKERRQ(ierr); 2490872cf891SStefano Zampini ierr = PetscMalloc1(n,&locf);CHKERRQ(ierr); 2491872cf891SStefano Zampini ierr = VecGetArrayRead(is->y,&v);CHKERRQ(ierr); 2492872cf891SStefano Zampini for (i=0,cf=0;i<n;i++) { 2493872cf891SStefano Zampini if (v[i] == 0.0) { 2494872cf891SStefano Zampini loce[i] = -1; 2495872cf891SStefano Zampini } else { 2496872cf891SStefano Zampini loce[i] = cf; 2497872cf891SStefano Zampini locf[cf++] = i; 2498872cf891SStefano Zampini } 2499872cf891SStefano Zampini } 2500872cf891SStefano Zampini ierr = VecRestoreArrayRead(is->y,&v);CHKERRQ(ierr); 2501872cf891SStefano Zampini /* extract valid submatrix */ 2502872cf891SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A),cf,locf,PETSC_USE_POINTER,&tis);CHKERRQ(ierr); 2503e5b89577SStefano Zampini ierr = MatCreateSubMatrix(is->A,tis,tis,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 2504872cf891SStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2505872cf891SStefano Zampini /* attach local l2g map for successive calls of MatSetValues */ 2506872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)is->A),1,n,loce,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 2507872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,l2g,l2g);CHKERRQ(ierr); 2508872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2509872cf891SStefano Zampini /* attach new global l2g map */ 2510872cf891SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,cf,locf,locf);CHKERRQ(ierr); 2511872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,cf,locf,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 2512872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,l2g,l2g);CHKERRQ(ierr); 2513872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 2514872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 2515872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 2516872cf891SStefano Zampini } 2517872cf891SStefano Zampini is->locempty = PETSC_FALSE; 2518b4319ba4SBarry Smith PetscFunctionReturn(0); 2519b4319ba4SBarry Smith } 2520b4319ba4SBarry Smith 2521a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 2522b4319ba4SBarry Smith { 2523b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 2524b4319ba4SBarry Smith 2525b4319ba4SBarry Smith PetscFunctionBegin; 2526b4319ba4SBarry Smith *local = is->A; 2527b4319ba4SBarry Smith PetscFunctionReturn(0); 2528b4319ba4SBarry Smith } 2529b4319ba4SBarry Smith 25303b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 25313b3b1effSJed Brown { 25323b3b1effSJed Brown PetscFunctionBegin; 25333b3b1effSJed Brown *local = NULL; 25343b3b1effSJed Brown PetscFunctionReturn(0); 25353b3b1effSJed Brown } 25363b3b1effSJed Brown 2537b4319ba4SBarry Smith /*@ 2538b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 2539b4319ba4SBarry Smith 2540b4319ba4SBarry Smith Input Parameter: 2541b4319ba4SBarry Smith . mat - the matrix 2542b4319ba4SBarry Smith 2543b4319ba4SBarry Smith Output Parameter: 2544eb82efa4SStefano Zampini . local - the local matrix 2545b4319ba4SBarry Smith 2546b4319ba4SBarry Smith Level: advanced 2547b4319ba4SBarry Smith 2548b4319ba4SBarry Smith Notes: 2549b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 2550b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 2551b4319ba4SBarry Smith of the MatSetValues() operation. 2552b4319ba4SBarry Smith 25533b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 255496a6f129SJed Brown 2555b4319ba4SBarry Smith .seealso: MATIS 2556b4319ba4SBarry Smith @*/ 25577087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 2558b4319ba4SBarry Smith { 25594ac538c5SBarry Smith PetscErrorCode ierr; 2560b4319ba4SBarry Smith 2561b4319ba4SBarry Smith PetscFunctionBegin; 25620700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2563b4319ba4SBarry Smith PetscValidPointer(local,2); 25644ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 2565b4319ba4SBarry Smith PetscFunctionReturn(0); 2566b4319ba4SBarry Smith } 2567b4319ba4SBarry Smith 25683b3b1effSJed Brown /*@ 25693b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 25703b3b1effSJed Brown 25713b3b1effSJed Brown Input Parameter: 25723b3b1effSJed Brown . mat - the matrix 25733b3b1effSJed Brown 25743b3b1effSJed Brown Output Parameter: 25753b3b1effSJed Brown . local - the local matrix 25763b3b1effSJed Brown 25773b3b1effSJed Brown Level: advanced 25783b3b1effSJed Brown 25793b3b1effSJed Brown .seealso: MATIS 25803b3b1effSJed Brown @*/ 25813b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 25823b3b1effSJed Brown { 25833b3b1effSJed Brown PetscErrorCode ierr; 25843b3b1effSJed Brown 25853b3b1effSJed Brown PetscFunctionBegin; 25863b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 25873b3b1effSJed Brown PetscValidPointer(local,2); 25883b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 25893b3b1effSJed Brown PetscFunctionReturn(0); 25903b3b1effSJed Brown } 25913b3b1effSJed Brown 2592a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 25933b03a366Sstefano_zampini { 25943b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 25953b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 25963b03a366Sstefano_zampini PetscErrorCode ierr; 25973b03a366Sstefano_zampini 25983b03a366Sstefano_zampini PetscFunctionBegin; 25994e4c7dbeSStefano Zampini if (is->A) { 26003b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 26013b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 2602f0ae7da4SStefano 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); 26034e4c7dbeSStefano Zampini } 26043b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 26053b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 26063b03a366Sstefano_zampini is->A = local; 26073b03a366Sstefano_zampini PetscFunctionReturn(0); 26083b03a366Sstefano_zampini } 26093b03a366Sstefano_zampini 26103b03a366Sstefano_zampini /*@ 2611eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 26123b03a366Sstefano_zampini 26133b03a366Sstefano_zampini Input Parameter: 26143b03a366Sstefano_zampini . mat - the matrix 2615eb82efa4SStefano Zampini . local - the local matrix 26163b03a366Sstefano_zampini 26173b03a366Sstefano_zampini Output Parameter: 26183b03a366Sstefano_zampini 26193b03a366Sstefano_zampini Level: advanced 26203b03a366Sstefano_zampini 26213b03a366Sstefano_zampini Notes: 26223b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 26233b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 26243b03a366Sstefano_zampini 26253b03a366Sstefano_zampini .seealso: MATIS 26263b03a366Sstefano_zampini @*/ 26273b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 26283b03a366Sstefano_zampini { 26293b03a366Sstefano_zampini PetscErrorCode ierr; 26303b03a366Sstefano_zampini 26313b03a366Sstefano_zampini PetscFunctionBegin; 26323b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2633b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 26343b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 26353b03a366Sstefano_zampini PetscFunctionReturn(0); 26363b03a366Sstefano_zampini } 26373b03a366Sstefano_zampini 2638a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 26396726f965SBarry Smith { 26406726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 26416726f965SBarry Smith PetscErrorCode ierr; 26426726f965SBarry Smith 26436726f965SBarry Smith PetscFunctionBegin; 26446726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 26456726f965SBarry Smith PetscFunctionReturn(0); 26466726f965SBarry Smith } 26476726f965SBarry Smith 2648a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 26492e74eeadSLisandro Dalcin { 26502e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 26512e74eeadSLisandro Dalcin PetscErrorCode ierr; 26522e74eeadSLisandro Dalcin 26532e74eeadSLisandro Dalcin PetscFunctionBegin; 26542e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 26552e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26562e74eeadSLisandro Dalcin } 26572e74eeadSLisandro Dalcin 2658a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 26592e74eeadSLisandro Dalcin { 26602e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 26612e74eeadSLisandro Dalcin PetscErrorCode ierr; 26622e74eeadSLisandro Dalcin 26632e74eeadSLisandro Dalcin PetscFunctionBegin; 26642e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2665e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 26662e74eeadSLisandro Dalcin 26672e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 26682e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2669e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2670e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 26712e74eeadSLisandro Dalcin PetscFunctionReturn(0); 26722e74eeadSLisandro Dalcin } 26732e74eeadSLisandro Dalcin 2674a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 26756726f965SBarry Smith { 26766726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 26776726f965SBarry Smith PetscErrorCode ierr; 26786726f965SBarry Smith 26796726f965SBarry Smith PetscFunctionBegin; 26804e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 26816726f965SBarry Smith PetscFunctionReturn(0); 26826726f965SBarry Smith } 26836726f965SBarry Smith 2684f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2685f26d0771SStefano Zampini { 2686f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2687f26d0771SStefano Zampini Mat_IS *x; 2688f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2689f26d0771SStefano Zampini PetscBool ismatis; 2690f26d0771SStefano Zampini #endif 2691f26d0771SStefano Zampini PetscErrorCode ierr; 2692f26d0771SStefano Zampini 2693f26d0771SStefano Zampini PetscFunctionBegin; 2694f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2695f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2696f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2697f26d0771SStefano Zampini #endif 2698f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2699f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2700f26d0771SStefano Zampini PetscFunctionReturn(0); 2701f26d0771SStefano Zampini } 2702f26d0771SStefano Zampini 2703f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2704f26d0771SStefano Zampini { 2705f26d0771SStefano Zampini Mat lA; 2706f26d0771SStefano Zampini Mat_IS *matis; 2707f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2708f26d0771SStefano Zampini IS is; 2709f26d0771SStefano Zampini const PetscInt *rg,*rl; 2710f26d0771SStefano Zampini PetscInt nrg; 2711f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2712f26d0771SStefano Zampini PetscErrorCode ierr; 2713f26d0771SStefano Zampini 2714f26d0771SStefano Zampini PetscFunctionBegin; 2715f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2716f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2717f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2718f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2719f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2720f0ae7da4SStefano Zampini for (i=0;i<nrl;i++) if (rl[i]>=nrg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local row index %D -> %D greater than maximum possible %D",i,rl[i],nrg); 2721f26d0771SStefano Zampini #endif 2722f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2723f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2724f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2725f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2726f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2727f26d0771SStefano Zampini #else 2728f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2729f26d0771SStefano Zampini #endif 2730f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2731f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2732f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2733f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2734f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2735f26d0771SStefano Zampini /* compute new l2g map for columns */ 2736f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2737f26d0771SStefano Zampini const PetscInt *cg,*cl; 2738f26d0771SStefano Zampini PetscInt ncg; 2739f26d0771SStefano Zampini PetscInt ncl; 2740f26d0771SStefano Zampini 2741f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2742f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2743f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2744f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2745f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2746f0ae7da4SStefano Zampini for (i=0;i<ncl;i++) if (cl[i]>=ncg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Local column index %D -> %D greater than maximum possible %D",i,cl[i],ncg); 2747f26d0771SStefano Zampini #endif 2748f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2749f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2750f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2751f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2752f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2753f26d0771SStefano Zampini #else 2754f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2755f26d0771SStefano Zampini #endif 2756f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2757f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2758f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2759f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2760f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2761f26d0771SStefano Zampini } else { 2762f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2763f26d0771SStefano Zampini cl2g = rl2g; 2764f26d0771SStefano Zampini } 2765f26d0771SStefano Zampini /* create the MATIS submatrix */ 2766f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2767f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2768f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2769f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2770b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2771f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2772f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2773f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2774f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2775f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2776f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2777f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2778f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2779f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2780f26d0771SStefano Zampini /* remove unsupported ops */ 2781f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2782f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2783f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2784f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2785f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2786f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2787f26d0771SStefano Zampini PetscFunctionReturn(0); 2788f26d0771SStefano Zampini } 2789f26d0771SStefano Zampini 2790872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 2791872cf891SStefano Zampini { 2792872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 2793872cf891SStefano Zampini PetscErrorCode ierr; 2794872cf891SStefano Zampini 2795872cf891SStefano Zampini PetscFunctionBegin; 2796872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 2797872cf891SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)A); 2798872cf891SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns",NULL,a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 279975d48cdbSStefano Zampini ierr = PetscOptionsBool("-matis_storel2l","Store local-to-local matrices generated from PtAP operations","MatISStoreL2L",a->storel2l,&a->storel2l,NULL);CHKERRQ(ierr); 2800872cf891SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 2801872cf891SStefano Zampini PetscFunctionReturn(0); 2802872cf891SStefano Zampini } 2803872cf891SStefano Zampini 2804284134d9SBarry Smith /*@ 28053c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2806284134d9SBarry Smith process but not across processes. 2807284134d9SBarry Smith 2808284134d9SBarry Smith Input Parameters: 2809284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2810e176bc59SStefano Zampini . bs - block size of the matrix 2811df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2812e176bc59SStefano Zampini . rmap - local to global map for rows 2813e176bc59SStefano Zampini - cmap - local to global map for cols 2814284134d9SBarry Smith 2815284134d9SBarry Smith Output Parameter: 2816284134d9SBarry Smith . A - the resulting matrix 2817284134d9SBarry Smith 28188e6c10adSSatish Balay Level: advanced 28198e6c10adSSatish Balay 282095452b02SPatrick Sanan Notes: 282195452b02SPatrick Sanan See MATIS for more details. 28226fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 28236fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 28243c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2825284134d9SBarry Smith 2826284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2827284134d9SBarry Smith @*/ 2828e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2829284134d9SBarry Smith { 2830284134d9SBarry Smith PetscErrorCode ierr; 2831284134d9SBarry Smith 2832284134d9SBarry Smith PetscFunctionBegin; 28336fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2834284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 2835284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 28366fdf41d1SStefano Zampini if (bs > 0) { 2837284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 28386fdf41d1SStefano Zampini } 2839284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2840e176bc59SStefano Zampini if (rmap && cmap) { 2841e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2842e176bc59SStefano Zampini } else if (!rmap) { 2843e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2844e176bc59SStefano Zampini } else { 2845e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2846e176bc59SStefano Zampini } 2847284134d9SBarry Smith PetscFunctionReturn(0); 2848284134d9SBarry Smith } 2849284134d9SBarry Smith 2850b4319ba4SBarry Smith /*MC 2851f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2852b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2853b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2854b4319ba4SBarry Smith product is handled "implicitly". 2855b4319ba4SBarry Smith 2856b4319ba4SBarry Smith Operations Provided: 28576726f965SBarry Smith + MatMult() 28582e74eeadSLisandro Dalcin . MatMultAdd() 28592e74eeadSLisandro Dalcin . MatMultTranspose() 28602e74eeadSLisandro Dalcin . MatMultTransposeAdd() 28616726f965SBarry Smith . MatZeroEntries() 28626726f965SBarry Smith . MatSetOption() 28632e74eeadSLisandro Dalcin . MatZeroRows() 28642e74eeadSLisandro Dalcin . MatSetValues() 286597563a80SStefano Zampini . MatSetValuesBlocked() 28666726f965SBarry Smith . MatSetValuesLocal() 286797563a80SStefano Zampini . MatSetValuesBlockedLocal() 28682e74eeadSLisandro Dalcin . MatScale() 28692e74eeadSLisandro Dalcin . MatGetDiagonal() 28702b404112SStefano Zampini . MatMissingDiagonal() 28712b404112SStefano Zampini . MatDuplicate() 28722b404112SStefano Zampini . MatCopy() 2873f26d0771SStefano Zampini . MatAXPY() 28747dae84e0SHong Zhang . MatCreateSubMatrix() 2875f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2876d7f69cd0SStefano Zampini . MatTranspose() 287775d48cdbSStefano Zampini . MatPtAP() (with P of AIJ type) 28786726f965SBarry Smith - MatSetLocalToGlobalMapping() 2879b4319ba4SBarry Smith 2880b4319ba4SBarry Smith Options Database Keys: 288175d48cdbSStefano Zampini + -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 288275d48cdbSStefano Zampini . -matis_fixempty - Fixes local matrices in case of empty local rows/columns. 288375d48cdbSStefano Zampini - -matis_storel2l - stores the local-to-local operators generated by the Galerkin process of MatPtAP(). 2884b4319ba4SBarry Smith 288595452b02SPatrick Sanan Notes: 288695452b02SPatrick Sanan Options prefix for the inner matrix are given by -is_mat_xxx 2887b4319ba4SBarry Smith 2888b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2889b4319ba4SBarry Smith 2890b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2891eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2892b4319ba4SBarry Smith 2893b4319ba4SBarry Smith Level: advanced 2894b4319ba4SBarry Smith 2895f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2896b4319ba4SBarry Smith 2897b4319ba4SBarry Smith M*/ 2898b4319ba4SBarry Smith 28998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2900b4319ba4SBarry Smith { 2901dfbe8321SBarry Smith PetscErrorCode ierr; 2902b4319ba4SBarry Smith Mat_IS *b; 2903b4319ba4SBarry Smith 2904b4319ba4SBarry Smith PetscFunctionBegin; 2905b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2906b4319ba4SBarry Smith A->data = (void*)b; 2907b4319ba4SBarry Smith 2908e176bc59SStefano Zampini /* matrix ops */ 2909e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2910b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 29112e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 29122e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 29132e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2914b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2915b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 29162e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 291798921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2918b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2919f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 29202e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2921f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2922b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2923b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2924b4319ba4SBarry Smith A->ops->view = MatView_IS; 29256726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 29262e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 29272e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 29286726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 292969796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 293069796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 293145471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2932ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 29336bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 29342b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2935659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 29367dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 2937f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 29383fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 29393fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2940d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 29417fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 2942ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 2943872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 2944b4319ba4SBarry Smith 2945b7ce53b6SStefano Zampini /* special MATIS functions */ 2946bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 29473b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 2948bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2949b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 29502e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2951cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 295275d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISStoreL2L_C",MatISStoreL2L_IS);CHKERRQ(ierr); 295317667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2954b4319ba4SBarry Smith PetscFunctionReturn(0); 2955b4319ba4SBarry Smith } 2956