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*/ 116989cf23SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 124f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1328f4e0baSStefano Zampini 14f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 15f26d0771SStefano Zampini 165b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 175b003df0Sstefano_zampini { 185b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 195b003df0Sstefano_zampini PetscInt i; 205b003df0Sstefano_zampini PetscErrorCode ierr; 215b003df0Sstefano_zampini 225b003df0Sstefano_zampini PetscFunctionBeginUser; 235b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 245b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 255b003df0Sstefano_zampini } 265b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 275b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 285b003df0Sstefano_zampini } 295b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 305b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 315b003df0Sstefano_zampini PetscFunctionReturn(0); 325b003df0Sstefano_zampini } 33a72627d2SStefano Zampini 345b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyArray_Private(void *ptr) 357fa8f2d3SStefano Zampini { 366989cf23SStefano Zampini PetscErrorCode ierr; 376989cf23SStefano Zampini 386989cf23SStefano Zampini PetscFunctionBeginUser; 396989cf23SStefano Zampini ierr = PetscFree(ptr);CHKERRQ(ierr); 406989cf23SStefano Zampini PetscFunctionReturn(0); 416989cf23SStefano Zampini } 426989cf23SStefano Zampini 436989cf23SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 446989cf23SStefano Zampini { 456989cf23SStefano Zampini Mat_MPIAIJ *aij = (Mat_MPIAIJ*)A->data; 466989cf23SStefano Zampini Mat_SeqAIJ *diag = (Mat_SeqAIJ*)(aij->A->data); 476989cf23SStefano Zampini Mat_SeqAIJ *offd = (Mat_SeqAIJ*)(aij->B->data); 486989cf23SStefano Zampini Mat lA; 496989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 506989cf23SStefano Zampini IS is; 516989cf23SStefano Zampini MPI_Comm comm; 526989cf23SStefano Zampini void *ptrs[2]; 536989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 546989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 556989cf23SStefano Zampini PetscInt *di,*dj,*oi,*oj; 566989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 57e363d98aSStefano Zampini PetscInt lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 586989cf23SStefano Zampini PetscErrorCode ierr; 596989cf23SStefano Zampini 606989cf23SStefano Zampini PetscFunctionBeginUser; 616989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 626989cf23SStefano Zampini if (!aij->garray) SETERRQ(comm,PETSC_ERR_SUP,"garray not present"); 636989cf23SStefano Zampini 646989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 656989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 666989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 676989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 686989cf23SStefano Zampini di = diag->i; 696989cf23SStefano Zampini dj = diag->j; 706989cf23SStefano Zampini dd = diag->a; 716989cf23SStefano Zampini oc = aij->B->cmap->n; 726989cf23SStefano Zampini oi = offd->i; 736989cf23SStefano Zampini oj = offd->j; 746989cf23SStefano Zampini od = offd->a; 756989cf23SStefano Zampini nnz = diag->i[dr] + offd->i[dr]; 766989cf23SStefano Zampini 776989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 786989cf23SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 796989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 806989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 81e363d98aSStefano Zampini if (dr) { 826989cf23SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 836989cf23SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 846989cf23SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = aij->garray[i]; 856989cf23SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 86e363d98aSStefano Zampini lc = dc+oc; 87e363d98aSStefano Zampini } else { 88e363d98aSStefano Zampini ierr = ISCreateGeneral(comm,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 89e363d98aSStefano Zampini lc = 0; 90e363d98aSStefano Zampini } 916989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 926989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 936989cf23SStefano Zampini 946989cf23SStefano Zampini /* create MATIS object */ 956989cf23SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 966989cf23SStefano Zampini ierr = MatSetSizes(*newmat,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 976989cf23SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 986989cf23SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 996989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1006989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1016989cf23SStefano Zampini 1026989cf23SStefano Zampini /* merge local matrices */ 1036989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 1046989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 1056989cf23SStefano Zampini ii = aux; 1066989cf23SStefano Zampini jj = aux+dr+1; 1076989cf23SStefano Zampini aa = data; 1086989cf23SStefano Zampini *ii = *(di++) + *(oi++); 1096989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 1106989cf23SStefano Zampini { 1116989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 1126989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 1136989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 1146989cf23SStefano Zampini } 1156989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 1166989cf23SStefano Zampini ii = aux; 1176989cf23SStefano Zampini jj = aux+dr+1; 1186989cf23SStefano Zampini aa = data; 119e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 1206989cf23SStefano Zampini 1216989cf23SStefano Zampini /* create containers to destroy the data */ 1226989cf23SStefano Zampini ptrs[0] = aux; 1236989cf23SStefano Zampini ptrs[1] = data; 1246989cf23SStefano Zampini for (i=0; i<2; i++) { 1256989cf23SStefano Zampini PetscContainer c; 1266989cf23SStefano Zampini 1276989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 1286989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 1295b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyArray_Private);CHKERRQ(ierr); 1306989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 1316989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 1326989cf23SStefano Zampini } 1336989cf23SStefano Zampini 1346989cf23SStefano Zampini /* finalize matrix */ 1356989cf23SStefano Zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 1366989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 1376989cf23SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1386989cf23SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1396989cf23SStefano Zampini PetscFunctionReturn(0); 1406989cf23SStefano Zampini } 1416989cf23SStefano Zampini 142cf0a3239SStefano Zampini /*@ 1433d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 144cf0a3239SStefano Zampini 145cf0a3239SStefano Zampini Collective on MPI_Comm 146cf0a3239SStefano Zampini 147cf0a3239SStefano Zampini Input Parameters: 148cf0a3239SStefano Zampini + A - the matrix 149cf0a3239SStefano Zampini 150cf0a3239SStefano Zampini Level: advanced 151cf0a3239SStefano Zampini 1523d996552SStefano Zampini Notes: This function does not need to be called by the user. 153cf0a3239SStefano Zampini 154cf0a3239SStefano Zampini .keywords: matrix 155cf0a3239SStefano Zampini 156cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 157cf0a3239SStefano Zampini @*/ 158cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 159cf0a3239SStefano Zampini { 1607fa8f2d3SStefano Zampini PetscErrorCode ierr; 1617fa8f2d3SStefano Zampini 1627fa8f2d3SStefano Zampini PetscFunctionBegin; 163cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 164cf0a3239SStefano Zampini PetscValidType(A,1); 165cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 1667fa8f2d3SStefano Zampini PetscFunctionReturn(0); 1677fa8f2d3SStefano Zampini } 1687fa8f2d3SStefano Zampini 1695e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 1705e3038f0Sstefano_zampini { 1715e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 1725e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 1735e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 1745e3038f0Sstefano_zampini MPI_Comm comm; 1755b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 1765b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 1779e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 1785e3038f0Sstefano_zampini PetscErrorCode ierr; 1795e3038f0Sstefano_zampini 1805e3038f0Sstefano_zampini PetscFunctionBeginUser; 1815e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 1825e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 1835e3038f0Sstefano_zampini rnest = NULL; 1845e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 1855e3038f0Sstefano_zampini PetscBool ismatis,isnest; 1865e3038f0Sstefano_zampini 1875e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1885e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 1895e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 1905e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 1915e3038f0Sstefano_zampini if (isnest) { 1925e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 1935e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 1945e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 1955e3038f0Sstefano_zampini } 1965e3038f0Sstefano_zampini } 1975e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 1985b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 1999e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 2005e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 2019e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 2025e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 2035e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 2045e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 2055e3038f0Sstefano_zampini PetscBool ismatis; 2069e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 2075e3038f0Sstefano_zampini 2085e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 2095e3038f0Sstefano_zampini if (!nest[i][j]) continue; 2105e3038f0Sstefano_zampini 2115e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 2129e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 2139e7b2b25Sstefano_zampini if (istrans[ij]) { 2149e7b2b25Sstefano_zampini Mat T,lT; 2159e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 2169e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 2179e7b2b25Sstefano_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); 2189e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 2199e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 2209e7b2b25Sstefano_zampini } else { 2215e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 2225e3038f0Sstefano_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); 2239e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 2249e7b2b25Sstefano_zampini } 2255e3038f0Sstefano_zampini 2265e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 2275e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 2289e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 2295e3038f0Sstefano_zampini if (!l1 || !l2) continue; 2305e3038f0Sstefano_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); 2315e3038f0Sstefano_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); 2325e3038f0Sstefano_zampini lr[i] = l1; 2335e3038f0Sstefano_zampini lc[j] = l2; 2345e3038f0Sstefano_zampini 2355e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 2365e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 2375e3038f0Sstefano_zampini } 2385e3038f0Sstefano_zampini } 2395e3038f0Sstefano_zampini 2405e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 2415e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 2425e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 2435e3038f0Sstefano_zampini rl2g = NULL; 2445e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 2455e3038f0Sstefano_zampini PetscInt n1,n2; 2465e3038f0Sstefano_zampini 2475e3038f0Sstefano_zampini if (!nest[i][j]) continue; 2489e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 2499e7b2b25Sstefano_zampini Mat T; 2509e7b2b25Sstefano_zampini 2519e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 2529e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 2539e7b2b25Sstefano_zampini } else { 2545e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 2559e7b2b25Sstefano_zampini } 2565e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 2575e3038f0Sstefano_zampini if (!n1) continue; 2585e3038f0Sstefano_zampini if (!rl2g) { 2595e3038f0Sstefano_zampini rl2g = cl2g; 2605e3038f0Sstefano_zampini } else { 2615e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 2625e3038f0Sstefano_zampini PetscBool same; 2635e3038f0Sstefano_zampini 2645e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 2655e3038f0Sstefano_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); 2665e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 2675e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 2685e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 2695e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 2705e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 2715e3038f0Sstefano_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); 2725e3038f0Sstefano_zampini } 2735e3038f0Sstefano_zampini } 2745e3038f0Sstefano_zampini } 2755e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 2765e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 2775e3038f0Sstefano_zampini rl2g = NULL; 2785e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 2795e3038f0Sstefano_zampini PetscInt n1,n2; 2805e3038f0Sstefano_zampini 2815e3038f0Sstefano_zampini if (!nest[j][i]) continue; 2829e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 2839e7b2b25Sstefano_zampini Mat T; 2849e7b2b25Sstefano_zampini 2859e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 2869e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 2879e7b2b25Sstefano_zampini } else { 2885e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 2899e7b2b25Sstefano_zampini } 2905e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 2915e3038f0Sstefano_zampini if (!n1) continue; 2925e3038f0Sstefano_zampini if (!rl2g) { 2935e3038f0Sstefano_zampini rl2g = cl2g; 2945e3038f0Sstefano_zampini } else { 2955e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 2965e3038f0Sstefano_zampini PetscBool same; 2975e3038f0Sstefano_zampini 2985e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 2995e3038f0Sstefano_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); 3005e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 3015e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 3025e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 3035e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 3045e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 3055e3038f0Sstefano_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); 3065e3038f0Sstefano_zampini } 3075e3038f0Sstefano_zampini } 3085e3038f0Sstefano_zampini } 3095e3038f0Sstefano_zampini #endif 3105e3038f0Sstefano_zampini 3115e3038f0Sstefano_zampini B = NULL; 3125e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 3135b003df0Sstefano_zampini PetscInt stl; 3145b003df0Sstefano_zampini 3155e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 3165e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 3175e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3185b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 3195e3038f0Sstefano_zampini Mat usedmat; 3205e3038f0Sstefano_zampini Mat_IS *matis; 3215e3038f0Sstefano_zampini const PetscInt *idxs; 3225e3038f0Sstefano_zampini 3235e3038f0Sstefano_zampini /* local IS for local NEST */ 3245b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 3255e3038f0Sstefano_zampini 3265e3038f0Sstefano_zampini /* l2gmap */ 3275e3038f0Sstefano_zampini j = 0; 3285e3038f0Sstefano_zampini usedmat = nest[i][j]; 3299e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 3309e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 3319e7b2b25Sstefano_zampini 3329e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 3339e7b2b25Sstefano_zampini Mat T; 3349e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 3359e7b2b25Sstefano_zampini usedmat = T; 3369e7b2b25Sstefano_zampini } 33782d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3385e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3395e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 3409e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 3419e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3429e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3439e7b2b25Sstefano_zampini } else { 3445e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3455e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3469e7b2b25Sstefano_zampini } 3475e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 3485e3038f0Sstefano_zampini stl += lr[i]; 3495e3038f0Sstefano_zampini } 3505e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 3515e3038f0Sstefano_zampini 3525e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 3535e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 3545e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3555b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 3565e3038f0Sstefano_zampini Mat usedmat; 3575e3038f0Sstefano_zampini Mat_IS *matis; 3585e3038f0Sstefano_zampini const PetscInt *idxs; 3595e3038f0Sstefano_zampini 3605e3038f0Sstefano_zampini /* local IS for local NEST */ 3615b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 3625e3038f0Sstefano_zampini 3635e3038f0Sstefano_zampini /* l2gmap */ 3645e3038f0Sstefano_zampini j = 0; 3655e3038f0Sstefano_zampini usedmat = nest[j][i]; 3669e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 3679e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 3689e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 3699e7b2b25Sstefano_zampini Mat T; 3709e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 3719e7b2b25Sstefano_zampini usedmat = T; 3729e7b2b25Sstefano_zampini } 37382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3745e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3755e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 3769e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 3779e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3789e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3799e7b2b25Sstefano_zampini } else { 3805e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3815e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3829e7b2b25Sstefano_zampini } 3835e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 3845e3038f0Sstefano_zampini stl += lc[i]; 3855e3038f0Sstefano_zampini } 3865e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 3875e3038f0Sstefano_zampini 3885e3038f0Sstefano_zampini /* Create MATIS */ 3895e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 3905e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 3915e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 3925e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 3935e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 3945e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 3955e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3965e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3975e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 3989e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 3999e7b2b25Sstefano_zampini if (istrans[i]) { 4009e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 4019e7b2b25Sstefano_zampini } 4029e7b2b25Sstefano_zampini } 4035e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 4045e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 4055e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4065e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4075e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 4085e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 4095e3038f0Sstefano_zampini } else { 4105e3038f0Sstefano_zampini *newmat = B; 4115e3038f0Sstefano_zampini } 4125e3038f0Sstefano_zampini } else { 4135e3038f0Sstefano_zampini if (lreuse) { 4145e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4155e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4165e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 4175e3038f0Sstefano_zampini if (snest[i*nc+j]) { 4185e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 4199e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 4209e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 4219e7b2b25Sstefano_zampini } 4225e3038f0Sstefano_zampini } 4235e3038f0Sstefano_zampini } 4245e3038f0Sstefano_zampini } 4255e3038f0Sstefano_zampini } else { 4265b003df0Sstefano_zampini PetscInt stl; 4275b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 4285b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 4295b003df0Sstefano_zampini stl += lr[i]; 4305e3038f0Sstefano_zampini } 4315b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 4325b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 4335b003df0Sstefano_zampini stl += lc[i]; 4345e3038f0Sstefano_zampini } 4355e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 4369e7b2b25Sstefano_zampini if (istrans[i]) { 4379e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 4389e7b2b25Sstefano_zampini } 4395e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 4405e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 4415e3038f0Sstefano_zampini } 4425e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4435e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4445e3038f0Sstefano_zampini } 4455e3038f0Sstefano_zampini 4465b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 4475b003df0Sstefano_zampini convert = PETSC_FALSE; 4485b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 4495b003df0Sstefano_zampini if (convert) { 4505b003df0Sstefano_zampini Mat M; 4515b003df0Sstefano_zampini MatISLocalFields lf; 4525b003df0Sstefano_zampini PetscContainer c; 4535b003df0Sstefano_zampini 4545b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4555b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 4565b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 4575b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4585b003df0Sstefano_zampini 4595b003df0Sstefano_zampini /* attach local fields to the matrix */ 4605b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 4615b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 4625b003df0Sstefano_zampini for (i=0;i<nr;i++) { 4635b003df0Sstefano_zampini PetscInt n,st; 4645b003df0Sstefano_zampini 4655b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 4665b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 4675b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 4685b003df0Sstefano_zampini } 4695b003df0Sstefano_zampini for (i=0;i<nc;i++) { 4705b003df0Sstefano_zampini PetscInt n,st; 4715b003df0Sstefano_zampini 4725b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 4735b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 4745b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 4755b003df0Sstefano_zampini } 4765b003df0Sstefano_zampini lf->nr = nr; 4775b003df0Sstefano_zampini lf->nc = nc; 4785b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 4795b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 4805b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 4815b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 4825b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 4835b003df0Sstefano_zampini } 4845b003df0Sstefano_zampini 4855e3038f0Sstefano_zampini /* Free workspace */ 4865e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4875e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 4885e3038f0Sstefano_zampini } 4895e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 4905e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 4915e3038f0Sstefano_zampini } 4929e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 4935b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 4945e3038f0Sstefano_zampini PetscFunctionReturn(0); 4955e3038f0Sstefano_zampini } 4965e3038f0Sstefano_zampini 497ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 498ad219c80Sstefano_zampini { 499ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 500ad219c80Sstefano_zampini Vec ll,rr; 501ad219c80Sstefano_zampini const PetscScalar *Y,*X; 502ad219c80Sstefano_zampini PetscScalar *x,*y; 503ad219c80Sstefano_zampini PetscErrorCode ierr; 504ad219c80Sstefano_zampini 505ad219c80Sstefano_zampini PetscFunctionBegin; 506ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 507ad219c80Sstefano_zampini if (l) { 508ad219c80Sstefano_zampini ll = matis->y; 509ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 510ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 511ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 512ad219c80Sstefano_zampini } else { 513ad219c80Sstefano_zampini ll = NULL; 514ad219c80Sstefano_zampini } 515ad219c80Sstefano_zampini if (r) { 516ad219c80Sstefano_zampini rr = matis->x; 517ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 518ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 519ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 520ad219c80Sstefano_zampini } else { 521ad219c80Sstefano_zampini rr = NULL; 522ad219c80Sstefano_zampini } 523ad219c80Sstefano_zampini if (ll) { 524ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 525ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 526ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 527ad219c80Sstefano_zampini } 528ad219c80Sstefano_zampini if (rr) { 529ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 530ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 531ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 532ad219c80Sstefano_zampini } 533ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 534ad219c80Sstefano_zampini PetscFunctionReturn(0); 535ad219c80Sstefano_zampini } 536ad219c80Sstefano_zampini 5377fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 5387fa8f2d3SStefano Zampini { 5397fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 5407fa8f2d3SStefano Zampini MatInfo info; 5417fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 5427fa8f2d3SStefano Zampini PetscInt bs; 5437fa8f2d3SStefano Zampini PetscErrorCode ierr; 5447fa8f2d3SStefano Zampini 5457fa8f2d3SStefano Zampini PetscFunctionBegin; 5467fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 5477fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 5487fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 5497fa8f2d3SStefano Zampini isend[0] = info.nz_used; 5507fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 5517fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 5527fa8f2d3SStefano Zampini isend[3] = info.memory; 5537fa8f2d3SStefano Zampini isend[4] = info.mallocs; 5547fa8f2d3SStefano Zampini } else { 5557fa8f2d3SStefano Zampini isend[0] = 0.; 5567fa8f2d3SStefano Zampini isend[1] = 0.; 5577fa8f2d3SStefano Zampini isend[2] = 0.; 5587fa8f2d3SStefano Zampini isend[3] = 0.; 5597fa8f2d3SStefano Zampini isend[4] = 0.; 5607fa8f2d3SStefano Zampini } 5617fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 5627fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 5637fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 5647fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 5657fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 5667fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 5677fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 5687fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 5697fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 5707fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 5717fa8f2d3SStefano Zampini 5727fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 5737fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 5747fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 5757fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 5767fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 5777fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 5787fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 5797fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 5807fa8f2d3SStefano Zampini 5817fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 5827fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 5837fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 5847fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 5857fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 5867fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 587d7f69cd0SStefano Zampini } 588d7f69cd0SStefano Zampini ginfo->block_size = bs; 589d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 590d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 591d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 5925e3038f0Sstefano_zampini PetscFunctionReturn(0); 5935e3038f0Sstefano_zampini } 5945e3038f0Sstefano_zampini 595d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 596d7f69cd0SStefano Zampini { 597d7f69cd0SStefano Zampini Mat C,lC,lA; 598d7f69cd0SStefano Zampini PetscErrorCode ierr; 599d7f69cd0SStefano Zampini 600d7f69cd0SStefano Zampini PetscFunctionBegin; 601cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 602cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 603d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 604d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 605d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 606d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 607d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 608d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 609cf37664fSBarry Smith } else { 610cf37664fSBarry Smith C = *B; 611d7f69cd0SStefano Zampini } 612d7f69cd0SStefano Zampini 613d7f69cd0SStefano Zampini /* perform local transposition */ 614d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 615d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 616d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 617d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 618d7f69cd0SStefano Zampini 619cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 620d7f69cd0SStefano Zampini *B = C; 621d7f69cd0SStefano Zampini } else { 622d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 623d7f69cd0SStefano Zampini } 6247aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6257aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 626d7f69cd0SStefano Zampini PetscFunctionReturn(0); 627d7f69cd0SStefano Zampini } 628d7f69cd0SStefano Zampini 6293fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 6303fd1c9e7SStefano Zampini { 6313fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 6323fd1c9e7SStefano Zampini PetscErrorCode ierr; 6333fd1c9e7SStefano Zampini 6343fd1c9e7SStefano Zampini PetscFunctionBegin; 6353fd1c9e7SStefano Zampini if (!D) { /* this code branch is used by MatShift_IS */ 6363fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 6373fd1c9e7SStefano Zampini } else { 6383fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6393fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6403fd1c9e7SStefano Zampini } 6413fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 6423fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 6433fd1c9e7SStefano Zampini PetscFunctionReturn(0); 6443fd1c9e7SStefano Zampini } 6453fd1c9e7SStefano Zampini 6463fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 6473fd1c9e7SStefano Zampini { 6483fd1c9e7SStefano Zampini PetscErrorCode ierr; 6493fd1c9e7SStefano Zampini 6503fd1c9e7SStefano Zampini PetscFunctionBegin; 6513fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 6523fd1c9e7SStefano Zampini PetscFunctionReturn(0); 6533fd1c9e7SStefano Zampini } 6543fd1c9e7SStefano Zampini 655f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 656f26d0771SStefano Zampini { 657f26d0771SStefano Zampini PetscErrorCode ierr; 658f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 659f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 660f26d0771SStefano Zampini 661f26d0771SStefano Zampini PetscFunctionBegin; 662f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 663f26d0771SStefano 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); 664f26d0771SStefano Zampini #endif 665f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 666f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 667f26d0771SStefano Zampini ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 668f26d0771SStefano Zampini PetscFunctionReturn(0); 669f26d0771SStefano Zampini } 670f26d0771SStefano Zampini 671f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 672f26d0771SStefano Zampini { 673f26d0771SStefano Zampini PetscErrorCode ierr; 674f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 675f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 676f26d0771SStefano Zampini 677f26d0771SStefano Zampini PetscFunctionBegin; 678f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 679f26d0771SStefano 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); 680f26d0771SStefano Zampini #endif 681f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 682f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 683f26d0771SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 684f26d0771SStefano Zampini PetscFunctionReturn(0); 685f26d0771SStefano Zampini } 686f26d0771SStefano Zampini 687f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 688a8116848SStefano Zampini { 689a8116848SStefano Zampini PetscInt *owners = map->range; 690a8116848SStefano Zampini PetscInt n = map->n; 691a8116848SStefano Zampini PetscSF sf; 692a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 693a8116848SStefano Zampini PetscSFNode *ridxs; 694a8116848SStefano Zampini PetscMPIInt rank; 695a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 696a8116848SStefano Zampini PetscErrorCode ierr; 697a8116848SStefano Zampini 698a8116848SStefano Zampini PetscFunctionBegin; 699fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 700a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 701a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 702a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 703a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 704a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 705a8116848SStefano Zampini for (r = 0; r < N; ++r) { 706a8116848SStefano Zampini const PetscInt idx = idxs[r]; 707a8116848SStefano 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); 708a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 709a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 710a8116848SStefano Zampini } 711a8116848SStefano Zampini ridxs[r].rank = p; 712a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 713a8116848SStefano Zampini } 714a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 715a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 716a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 717a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 718f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 719a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 720f0ae7da4SStefano Zampini 721f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 722a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 723a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 724a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 725a8116848SStefano Zampini start -= cum; 726a8116848SStefano Zampini cum = 0; 727a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 728a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 729a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 730a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 731a8116848SStefano Zampini } 732a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 733a8116848SStefano Zampini /* Compress and put in indices */ 734a8116848SStefano Zampini for (r = 0; r < n; ++r) 735a8116848SStefano Zampini if (lidxs[r] >= 0) { 736a8116848SStefano Zampini if (work) work[len] = work[r]; 737a8116848SStefano Zampini lidxs[len++] = r; 738a8116848SStefano Zampini } 739a8116848SStefano Zampini if (on) *on = len; 740a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 741a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 742a8116848SStefano Zampini PetscFunctionReturn(0); 743a8116848SStefano Zampini } 744a8116848SStefano Zampini 745*7dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 746a8116848SStefano Zampini { 747a8116848SStefano Zampini Mat locmat,newlocmat; 748a8116848SStefano Zampini Mat_IS *newmatis; 749a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 750a8116848SStefano Zampini Vec rtest,ltest; 751a8116848SStefano Zampini const PetscScalar *array; 752a8116848SStefano Zampini #endif 753a8116848SStefano Zampini const PetscInt *idxs; 754a8116848SStefano Zampini PetscInt i,m,n; 755a8116848SStefano Zampini PetscErrorCode ierr; 756a8116848SStefano Zampini 757a8116848SStefano Zampini PetscFunctionBegin; 758a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 759a8116848SStefano Zampini PetscBool ismatis; 760a8116848SStefano Zampini 761a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 762a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 763a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 764a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 765a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 766a8116848SStefano Zampini } 767a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 768a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 769a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 770a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 771a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 772a8116848SStefano Zampini for (i=0;i<n;i++) { 773a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 774a8116848SStefano Zampini } 775a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 776a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 777a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 778a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 779a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 780fd479f66SMatthew 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])); 781a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 782a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 783a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 784a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 785a8116848SStefano Zampini for (i=0;i<n;i++) { 786a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 787a8116848SStefano Zampini } 788a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 789a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 790a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 791a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 792a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 793fd479f66SMatthew 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])); 794a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 795a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 796a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 797a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 798a8116848SStefano Zampini #endif 799a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 800a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 801a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 802a8116848SStefano Zampini IS is; 803a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 8046dd40735SStefano Zampini PetscInt ll,newloc; 805a8116848SStefano Zampini MPI_Comm comm; 806a8116848SStefano Zampini 807a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 808a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 809a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 810a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 811a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 812a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 813a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 814a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 815f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 816a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 8173d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 8183d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 819a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 820a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 821a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 822a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 823a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 8243d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 825a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 826a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8273d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 828a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 829a8116848SStefano Zampini lidxs[newloc] = i; 830a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 831a8116848SStefano Zampini } 832a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 833a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 834a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 835a8116848SStefano Zampini /* local is to extract local submatrix */ 836a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 837a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 838a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 839a8116848SStefano Zampini PetscBool cong; 840a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 841a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 842a8116848SStefano Zampini else mat->congruentlayouts = 0; 843a8116848SStefano Zampini } 844a8116848SStefano Zampini if (mat->congruentlayouts && irow == icol) { 845a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 846a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 847a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 848a8116848SStefano Zampini } else { 849a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 850a8116848SStefano Zampini 851a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 852a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 853f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 854a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 8553d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 856a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 857a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 858a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 859a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 860a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 8613d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 862a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 863a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8643d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 865a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 866a8116848SStefano Zampini lidxs[newloc] = i; 867a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 868a8116848SStefano Zampini } 869a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 870a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 871a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 872a8116848SStefano Zampini /* local is to extract local submatrix */ 873a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 874a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 875a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 876a8116848SStefano Zampini } 877a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 878a8116848SStefano Zampini } else { 879a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 880a8116848SStefano Zampini } 881a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 882a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 883*7dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 884a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 885a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 886a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 887a8116848SStefano Zampini } 888a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 889a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 890a8116848SStefano Zampini PetscFunctionReturn(0); 891a8116848SStefano Zampini } 892a8116848SStefano Zampini 893a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 8942b404112SStefano Zampini { 8952b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 8962b404112SStefano Zampini PetscBool ismatis; 8972b404112SStefano Zampini PetscErrorCode ierr; 8982b404112SStefano Zampini 8992b404112SStefano Zampini PetscFunctionBegin; 9002b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 9012b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 9022b404112SStefano Zampini b = (Mat_IS*)B->data; 9032b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 9042b404112SStefano Zampini PetscFunctionReturn(0); 9052b404112SStefano Zampini } 9062b404112SStefano Zampini 907a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 9086bd84002SStefano Zampini { 909527b2640SStefano Zampini Vec v; 910527b2640SStefano Zampini const PetscScalar *array; 911527b2640SStefano Zampini PetscInt i,n; 9126bd84002SStefano Zampini PetscErrorCode ierr; 9136bd84002SStefano Zampini 9146bd84002SStefano Zampini PetscFunctionBegin; 915527b2640SStefano Zampini *missing = PETSC_FALSE; 916527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 917527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 918527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 919527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 920527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 921527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 922527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 923527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 924527b2640SStefano Zampini if (d) { 925527b2640SStefano Zampini *d = -1; 926527b2640SStefano Zampini if (*missing) { 927527b2640SStefano Zampini PetscInt rstart; 928527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 929527b2640SStefano Zampini *d = i+rstart; 930527b2640SStefano Zampini } 931527b2640SStefano Zampini } 9326bd84002SStefano Zampini PetscFunctionReturn(0); 9336bd84002SStefano Zampini } 9346bd84002SStefano Zampini 935cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 93628f4e0baSStefano Zampini { 93728f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 93828f4e0baSStefano Zampini const PetscInt *gidxs; 9394f2d7cafSStefano Zampini PetscInt nleaves; 94028f4e0baSStefano Zampini PetscErrorCode ierr; 94128f4e0baSStefano Zampini 94228f4e0baSStefano Zampini PetscFunctionBegin; 9434f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 94428f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 9453bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9464f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 9474f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 9483bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9494f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 950a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 9513d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 952a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 953a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9543d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 955a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9563d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 957a8116848SStefano Zampini } else { 958a8116848SStefano Zampini matis->csf = matis->sf; 959a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 960a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 961a8116848SStefano Zampini } 96228f4e0baSStefano Zampini PetscFunctionReturn(0); 96328f4e0baSStefano Zampini } 9642e1947a5SStefano Zampini 965eb82efa4SStefano Zampini /*@ 966a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 967a88811baSStefano Zampini 968a88811baSStefano Zampini Collective on MPI_Comm 969a88811baSStefano Zampini 970a88811baSStefano Zampini Input Parameters: 971a88811baSStefano Zampini + B - the matrix 972a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 973a88811baSStefano Zampini (same value is used for all local rows) 974a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 975a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 976a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 977a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 978a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 979a88811baSStefano Zampini the diagonal entry even if it is zero. 980a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 981a88811baSStefano Zampini submatrix (same value is used for all local rows). 982a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 983a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 984a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 985a88811baSStefano Zampini structure. The size of this array is equal to the number 986a88811baSStefano Zampini of local rows, i.e 'm'. 987a88811baSStefano Zampini 988a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 989a88811baSStefano Zampini 990a88811baSStefano Zampini Level: intermediate 991a88811baSStefano Zampini 992a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 993a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 994a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 995a88811baSStefano Zampini 996a88811baSStefano Zampini .keywords: matrix 997a88811baSStefano Zampini 9983c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 999a88811baSStefano Zampini @*/ 10002e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10012e1947a5SStefano Zampini { 10022e1947a5SStefano Zampini PetscErrorCode ierr; 10032e1947a5SStefano Zampini 10042e1947a5SStefano Zampini PetscFunctionBegin; 10052e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10062e1947a5SStefano Zampini PetscValidType(B,1); 10072e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 10082e1947a5SStefano Zampini PetscFunctionReturn(0); 10092e1947a5SStefano Zampini } 10102e1947a5SStefano Zampini 10117230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10122e1947a5SStefano Zampini { 10132e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 101428f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 10152e1947a5SStefano Zampini PetscErrorCode ierr; 10162e1947a5SStefano Zampini 10172e1947a5SStefano Zampini PetscFunctionBegin; 10186c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1019cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 10204f2d7cafSStefano Zampini 10214f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 10224f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 10234f2d7cafSStefano Zampini 10244f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 10254f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 10264f2d7cafSStefano Zampini 102728f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 102828f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 102928f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 103028f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 10314f2d7cafSStefano Zampini 10324f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 103328f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 10344f2d7cafSStefano Zampini 10354f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 103628f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10374f2d7cafSStefano Zampini 10384f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 103928f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10402e1947a5SStefano Zampini PetscFunctionReturn(0); 10412e1947a5SStefano Zampini } 1042b4319ba4SBarry Smith 10433927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 10443927de2eSStefano Zampini { 10453927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 10463927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1047ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 10483927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 10493927de2eSStefano Zampini PetscInt lrows,lcols; 10503927de2eSStefano Zampini PetscInt local_rows,local_cols; 10513927de2eSStefano Zampini PetscMPIInt nsubdomains; 10523927de2eSStefano Zampini PetscBool isdense,issbaij; 10533927de2eSStefano Zampini PetscErrorCode ierr; 10543927de2eSStefano Zampini 10553927de2eSStefano Zampini PetscFunctionBegin; 10563927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 10573927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 10583927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10593927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 10603927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 10613927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1062ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1063ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 10647230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1065ecf5a873SStefano Zampini } else { 1066ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1067ecf5a873SStefano Zampini } 1068ecf5a873SStefano Zampini 10693927de2eSStefano Zampini if (issbaij) { 10703927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 10713927de2eSStefano Zampini } 10723927de2eSStefano Zampini /* 1073ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 10743927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 10753927de2eSStefano Zampini */ 1076cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 10773927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 10783927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 10793927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 10803927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 10813927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 10823927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 10833927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 10843927de2eSStefano Zampini row_ownership[j] = i; 10853927de2eSStefano Zampini } 10863927de2eSStefano Zampini } 10877230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 10883927de2eSStefano Zampini 10893927de2eSStefano Zampini /* 10903927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 10913927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 10923927de2eSStefano Zampini */ 10933927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 10943927de2eSStefano Zampini /* preallocation as a MATAIJ */ 10953927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 10963927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 1097ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 10983927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 10993927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1100ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 11013927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11023927de2eSStefano Zampini my_dnz[i] += 1; 11033927de2eSStefano Zampini } else { /* offdiag block */ 11043927de2eSStefano Zampini my_onz[i] += 1; 11053927de2eSStefano Zampini } 11063927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 11073927de2eSStefano Zampini if (i != j) { 11083927de2eSStefano Zampini owner = row_ownership[index_col]; 11093927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 11103927de2eSStefano Zampini my_dnz[j] += 1; 11113927de2eSStefano Zampini } else { 11123927de2eSStefano Zampini my_onz[j] += 1; 11133927de2eSStefano Zampini } 11143927de2eSStefano Zampini } 11153927de2eSStefano Zampini } 11163927de2eSStefano Zampini } 1117bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1118bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1119bb1015c3SStefano Zampini PetscBool done; 1120bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1121938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1122bb1015c3SStefano Zampini jptr = jj; 1123bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1124bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1125bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1126bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1127bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1128bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1129bb1015c3SStefano Zampini my_dnz[i] += 1; 1130bb1015c3SStefano Zampini } else { /* offdiag block */ 1131bb1015c3SStefano Zampini my_onz[i] += 1; 1132bb1015c3SStefano Zampini } 1133bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1134bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1135bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1136bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1137bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1138bb1015c3SStefano Zampini } else { 1139bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1140bb1015c3SStefano Zampini } 1141bb1015c3SStefano Zampini } 1142bb1015c3SStefano Zampini } 1143bb1015c3SStefano Zampini } 1144bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1145938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1146bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 11473927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 11483927de2eSStefano Zampini const PetscInt *cols; 1149ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 11503927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 11513927de2eSStefano Zampini for (j=0;j<ncols;j++) { 11523927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1153ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 11543927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11553927de2eSStefano Zampini my_dnz[i] += 1; 11563927de2eSStefano Zampini } else { /* offdiag block */ 11573927de2eSStefano Zampini my_onz[i] += 1; 11583927de2eSStefano Zampini } 11593927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1160d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 11613927de2eSStefano Zampini owner = row_ownership[index_col]; 11623927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1163d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 11643927de2eSStefano Zampini } else { 1165d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 11663927de2eSStefano Zampini } 11673927de2eSStefano Zampini } 11683927de2eSStefano Zampini } 11693927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 11703927de2eSStefano Zampini } 11713927de2eSStefano Zampini } 1172ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 11737230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1174ecf5a873SStefano Zampini } 11754f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 11763927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1177ecf5a873SStefano Zampini 1178ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 11793927de2eSStefano Zampini if (maxreduce) { 11803927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 11813927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1182bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 11833927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 11843927de2eSStefano Zampini } else { 11853927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 11863927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1187bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 11883927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 11893927de2eSStefano Zampini } 11903927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 11913927de2eSStefano Zampini 11923927de2eSStefano Zampini /* Resize preallocation if overestimated */ 11933927de2eSStefano Zampini for (i=0;i<lrows;i++) { 11943927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 11953927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 11963927de2eSStefano Zampini } 11971670daf9Sstefano_zampini 11981670daf9Sstefano_zampini /* Set preallocation */ 11993927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 12003927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 12013927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 12023927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 12033927de2eSStefano Zampini } 12043927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12053927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12063927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 12073927de2eSStefano Zampini if (issbaij) { 12083927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 12093927de2eSStefano Zampini } 12103927de2eSStefano Zampini PetscFunctionReturn(0); 12113927de2eSStefano Zampini } 12123927de2eSStefano Zampini 12137230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1214b7ce53b6SStefano Zampini { 1215b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1216d9a9e74cSStefano Zampini Mat local_mat; 1217b7ce53b6SStefano Zampini /* info on mat */ 12183cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1219b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1220b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1221b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1222b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1223b9ed4604SStefano Zampini #endif 12247c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1225b7ce53b6SStefano Zampini /* values insertion */ 1226b7ce53b6SStefano Zampini PetscScalar *array; 1227b7ce53b6SStefano Zampini /* work */ 1228b7ce53b6SStefano Zampini PetscErrorCode ierr; 1229b7ce53b6SStefano Zampini 1230b7ce53b6SStefano Zampini PetscFunctionBegin; 1231b7ce53b6SStefano Zampini /* get info from mat */ 12327c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 12337c03b4e8SStefano Zampini if (nsubdomains == 1) { 12341670daf9Sstefano_zampini Mat B; 12351670daf9Sstefano_zampini IS rows,cols; 1236acdf38a7Sstefano_zampini IS irows,icols; 12371670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 12381670daf9Sstefano_zampini 12391670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 12401670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 12411670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 12421670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 12431670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 12441670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1245acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1246acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1247acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1248acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1249acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1250acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 1251acdf38a7Sstefano_zampini ierr = MatConvert(matis->A,MATAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1252*7dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1253acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1254acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1255acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 12567c03b4e8SStefano Zampini PetscFunctionReturn(0); 12577c03b4e8SStefano Zampini } 1258b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1259b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 12603cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1261b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1262b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 1263686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1264b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1265b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1266b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1267b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1268b9ed4604SStefano Zampini lb[0] = isseqdense; 1269b9ed4604SStefano Zampini lb[1] = isseqaij; 1270b9ed4604SStefano Zampini lb[2] = isseqbaij; 1271b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1272b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1273b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1274b9ed4604SStefano Zampini #endif 1275b7ce53b6SStefano Zampini 1276b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 12773927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 12783cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 12793927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 1280b9ed4604SStefano Zampini if (!isseqsbaij) { 1281b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1282b9ed4604SStefano Zampini } else { 1283b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1284b9ed4604SStefano Zampini } 12853927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1286b7ce53b6SStefano Zampini } else { 12873cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1288b7ce53b6SStefano Zampini /* some checks */ 1289b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1290b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 12913cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 12926c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 12936c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 12946c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 12956c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 12966c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1297b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1298b7ce53b6SStefano Zampini } 1299d9a9e74cSStefano Zampini 1300b9ed4604SStefano Zampini if (isseqsbaij) { 1301d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1302d9a9e74cSStefano Zampini } else { 1303d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1304d9a9e74cSStefano Zampini local_mat = matis->A; 1305d9a9e74cSStefano Zampini } 1306686e3a49SStefano Zampini 1307b7ce53b6SStefano Zampini /* Set values */ 1308ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1309b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 1310ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 1311ecf5a873SStefano Zampini 1312ecf5a873SStefano Zampini if (local_rows != local_cols) { 1313ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 1314ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1315ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 1316ecf5a873SStefano Zampini } else { 1317ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 1318ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1319ecf5a873SStefano Zampini dummy_cols = dummy_rows; 1320ecf5a873SStefano Zampini } 1321b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1322d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 1323ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 1324d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 1325ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 1326ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 1327ecf5a873SStefano Zampini } else { 1328ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 1329ecf5a873SStefano Zampini } 1330686e3a49SStefano Zampini } else if (isseqaij) { 1331ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1332686e3a49SStefano Zampini PetscBool done; 1333686e3a49SStefano Zampini 1334d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1335938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1336d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1337686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1338ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1339686e3a49SStefano Zampini } 1340d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1341938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1342d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1343686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1344ecf5a873SStefano Zampini PetscInt i; 1345c0962df8SStefano Zampini 1346686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1347686e3a49SStefano Zampini PetscInt j; 1348ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1349686e3a49SStefano Zampini 1350ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1351ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1352ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1353686e3a49SStefano Zampini } 1354b7ce53b6SStefano Zampini } 1355b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1356d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1357b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1358b9ed4604SStefano Zampini if (isseqdense) { 1359b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1360b7ce53b6SStefano Zampini } 1361b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1362b7ce53b6SStefano Zampini } 1363b7ce53b6SStefano Zampini 1364b7ce53b6SStefano Zampini /*@ 1365b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1366b7ce53b6SStefano Zampini 1367b7ce53b6SStefano Zampini Input Parameter: 1368b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1369b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1370b7ce53b6SStefano Zampini 1371b7ce53b6SStefano Zampini Output Parameter: 1372b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1373b7ce53b6SStefano Zampini 1374b7ce53b6SStefano Zampini Level: developer 1375b7ce53b6SStefano Zampini 1376eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1377b7ce53b6SStefano Zampini 1378b7ce53b6SStefano Zampini .seealso: MATIS 1379b7ce53b6SStefano Zampini @*/ 1380b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1381b7ce53b6SStefano Zampini { 1382b7ce53b6SStefano Zampini PetscErrorCode ierr; 1383b7ce53b6SStefano Zampini 1384b7ce53b6SStefano Zampini PetscFunctionBegin; 1385b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1386b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1387b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1388b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1389b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1390b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 13916c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1392b7ce53b6SStefano Zampini } 1393b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1394b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1395b7ce53b6SStefano Zampini } 1396b7ce53b6SStefano Zampini 1397ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1398ad6194a2SStefano Zampini { 1399ad6194a2SStefano Zampini PetscErrorCode ierr; 1400ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1401ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1402ad6194a2SStefano Zampini Mat B,localmat; 1403ad6194a2SStefano Zampini 1404ad6194a2SStefano Zampini PetscFunctionBegin; 1405ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1406ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1407ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1408e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1409ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1410ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1411b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1412ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1413ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1414ad6194a2SStefano Zampini *newmat = B; 1415ad6194a2SStefano Zampini PetscFunctionReturn(0); 1416ad6194a2SStefano Zampini } 1417ad6194a2SStefano Zampini 1418a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 141969796d55SStefano Zampini { 142069796d55SStefano Zampini PetscErrorCode ierr; 142169796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 142269796d55SStefano Zampini PetscBool local_sym; 142369796d55SStefano Zampini 142469796d55SStefano Zampini PetscFunctionBegin; 142569796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1426b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 142769796d55SStefano Zampini PetscFunctionReturn(0); 142869796d55SStefano Zampini } 142969796d55SStefano Zampini 1430a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 143169796d55SStefano Zampini { 143269796d55SStefano Zampini PetscErrorCode ierr; 143369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 143469796d55SStefano Zampini PetscBool local_sym; 143569796d55SStefano Zampini 143669796d55SStefano Zampini PetscFunctionBegin; 143769796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1438b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 143969796d55SStefano Zampini PetscFunctionReturn(0); 144069796d55SStefano Zampini } 144169796d55SStefano Zampini 144245471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 144345471136SStefano Zampini { 144445471136SStefano Zampini PetscErrorCode ierr; 144545471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 144645471136SStefano Zampini PetscBool local_sym; 144745471136SStefano Zampini 144845471136SStefano Zampini PetscFunctionBegin; 144945471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 145045471136SStefano Zampini *flg = PETSC_FALSE; 145145471136SStefano Zampini PetscFunctionReturn(0); 145245471136SStefano Zampini } 145345471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 145445471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 145545471136SStefano Zampini PetscFunctionReturn(0); 145645471136SStefano Zampini } 145745471136SStefano Zampini 1458a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1459b4319ba4SBarry Smith { 1460dfbe8321SBarry Smith PetscErrorCode ierr; 1461b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1462b4319ba4SBarry Smith 1463b4319ba4SBarry Smith PetscFunctionBegin; 14646bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1465e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1466e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 14676bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 14686bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 14693fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1470a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1471a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1472a8116848SStefano Zampini if (b->sf != b->csf) { 1473a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1474a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1475a8116848SStefano Zampini } 147628f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 147728f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1478bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1479dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1480bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1481b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1482b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 14832e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1484cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 1485b4319ba4SBarry Smith PetscFunctionReturn(0); 1486b4319ba4SBarry Smith } 1487b4319ba4SBarry Smith 1488a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1489b4319ba4SBarry Smith { 1490dfbe8321SBarry Smith PetscErrorCode ierr; 1491b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1492b4319ba4SBarry Smith PetscScalar zero = 0.0; 1493b4319ba4SBarry Smith 1494b4319ba4SBarry Smith PetscFunctionBegin; 1495b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1496e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1497e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1498b4319ba4SBarry Smith 1499b4319ba4SBarry Smith /* multiply the local matrix */ 1500b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1501b4319ba4SBarry Smith 1502b4319ba4SBarry Smith /* scatter product back into global memory */ 15032dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1504e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1505e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1506b4319ba4SBarry Smith PetscFunctionReturn(0); 1507b4319ba4SBarry Smith } 1508b4319ba4SBarry Smith 1509a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 15102e74eeadSLisandro Dalcin { 1511650997f4SStefano Zampini Vec temp_vec; 15122e74eeadSLisandro Dalcin PetscErrorCode ierr; 15132e74eeadSLisandro Dalcin 15142e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1515650997f4SStefano Zampini if (v3 != v2) { 1516650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1517650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1518650997f4SStefano Zampini } else { 1519650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1520650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1521650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1522650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1523650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1524650997f4SStefano Zampini } 15252e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15262e74eeadSLisandro Dalcin } 15272e74eeadSLisandro Dalcin 1528a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 15292e74eeadSLisandro Dalcin { 15302e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 15312e74eeadSLisandro Dalcin PetscErrorCode ierr; 15322e74eeadSLisandro Dalcin 1533e176bc59SStefano Zampini PetscFunctionBegin; 15342e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1535e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1536e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15372e74eeadSLisandro Dalcin 15382e74eeadSLisandro Dalcin /* multiply the local matrix */ 1539e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 15402e74eeadSLisandro Dalcin 15412e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1542e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1543e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1544e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15452e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15462e74eeadSLisandro Dalcin } 15472e74eeadSLisandro Dalcin 1548a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 15492e74eeadSLisandro Dalcin { 1550650997f4SStefano Zampini Vec temp_vec; 15512e74eeadSLisandro Dalcin PetscErrorCode ierr; 15522e74eeadSLisandro Dalcin 15532e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1554650997f4SStefano Zampini if (v3 != v2) { 1555650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1556650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1557650997f4SStefano Zampini } else { 1558650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1559650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1560650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1561650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1562650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1563650997f4SStefano Zampini } 15642e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15652e74eeadSLisandro Dalcin } 15662e74eeadSLisandro Dalcin 1567a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1568b4319ba4SBarry Smith { 1569b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1570dfbe8321SBarry Smith PetscErrorCode ierr; 1571b4319ba4SBarry Smith PetscViewer sviewer; 1572ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1573b4319ba4SBarry Smith 1574b4319ba4SBarry Smith PetscFunctionBegin; 1575ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1576ee2491ecSStefano Zampini if (isascii) { 1577ee2491ecSStefano Zampini PetscViewerFormat format; 1578ee2491ecSStefano Zampini 1579ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1580ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1581ee2491ecSStefano Zampini } 1582ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 15833f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1584b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 15853f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 15866e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1587b4319ba4SBarry Smith PetscFunctionReturn(0); 1588b4319ba4SBarry Smith } 1589b4319ba4SBarry Smith 1590a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1591b4319ba4SBarry Smith { 1592dfbe8321SBarry Smith PetscErrorCode ierr; 1593e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1594b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1595b4319ba4SBarry Smith IS from,to; 1596e176bc59SStefano Zampini Vec cglobal,rglobal; 1597b4319ba4SBarry Smith 1598b4319ba4SBarry Smith PetscFunctionBegin; 1599784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1600e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 16013bbff08aSStefano Zampini /* Destroy any previous data */ 160270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 160370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 16043fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1605e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1606e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 16071c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 160828f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 160928f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 16103bbff08aSStefano Zampini 16113bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1612fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1613fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1614fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1615fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1616b4319ba4SBarry Smith 1617b4319ba4SBarry Smith /* Create the local matrix A */ 1618e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1619e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1620e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1621e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1622f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1623e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1624e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1625e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1626ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1627ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1628b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1629b4319ba4SBarry Smith 1630f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1631b4319ba4SBarry Smith /* Create the local work vectors */ 16323bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1633b4319ba4SBarry Smith 1634e176bc59SStefano Zampini /* setup the global to local scatters */ 1635e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1636e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1637784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1638e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1639e176bc59SStefano Zampini if (rmapping != cmapping) { 1640e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1641e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1642e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1643e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1644e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1645e176bc59SStefano Zampini } else { 1646e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1647e176bc59SStefano Zampini is->cctx = is->rctx; 1648e176bc59SStefano Zampini } 16493fd1c9e7SStefano Zampini 16503fd1c9e7SStefano Zampini /* interface counter vector (local) */ 16513fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 16523fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 16533fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16543fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16553fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16563fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16573fd1c9e7SStefano Zampini 16583fd1c9e7SStefano Zampini /* free workspace */ 1659e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1660e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 16616bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 16626bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1663f26d0771SStefano Zampini } 166448ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1665b4319ba4SBarry Smith PetscFunctionReturn(0); 1666b4319ba4SBarry Smith } 1667b4319ba4SBarry Smith 1668a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 16692e74eeadSLisandro Dalcin { 16702e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 16712e74eeadSLisandro Dalcin PetscErrorCode ierr; 167297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 167397563a80SStefano Zampini PetscInt i,zm,zn; 167497563a80SStefano Zampini #endif 1675f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 16762e74eeadSLisandro Dalcin 16772e74eeadSLisandro Dalcin PetscFunctionBegin; 16782e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1679f26d0771SStefano 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); 168097563a80SStefano Zampini /* count negative indices */ 168197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 168297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 16832e74eeadSLisandro Dalcin #endif 168497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 168597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 168697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 168797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 168897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 168997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 169097563a80SStefano Zampini if (zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 169197563a80SStefano Zampini if (zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 169297563a80SStefano Zampini #endif 16932e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 16942e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16952e74eeadSLisandro Dalcin } 16962e74eeadSLisandro Dalcin 1697a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 169897563a80SStefano Zampini { 169997563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 170097563a80SStefano Zampini PetscErrorCode ierr; 170197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 170297563a80SStefano Zampini PetscInt i,zm,zn; 170397563a80SStefano Zampini #endif 1704f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 170597563a80SStefano Zampini 170697563a80SStefano Zampini PetscFunctionBegin; 170797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1708f26d0771SStefano 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); 170997563a80SStefano Zampini /* count negative indices */ 171097563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 171197563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 171297563a80SStefano Zampini #endif 171397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 171497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 171597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 171697563a80SStefano Zampini /* count negative indices (should be the same as before) */ 171797563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 171897563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 171997563a80SStefano Zampini if (zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 172097563a80SStefano Zampini if (zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 172197563a80SStefano Zampini #endif 172297563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 172397563a80SStefano Zampini PetscFunctionReturn(0); 172497563a80SStefano Zampini } 172597563a80SStefano Zampini 1726a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1727b4319ba4SBarry Smith { 1728dfbe8321SBarry Smith PetscErrorCode ierr; 1729b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1730b4319ba4SBarry Smith 1731b4319ba4SBarry Smith PetscFunctionBegin; 1732b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1733b4319ba4SBarry Smith PetscFunctionReturn(0); 1734b4319ba4SBarry Smith } 1735b4319ba4SBarry Smith 1736a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1737f0006bf2SLisandro Dalcin { 1738f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1739f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1740f0006bf2SLisandro Dalcin 1741f0006bf2SLisandro Dalcin PetscFunctionBegin; 1742f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1743f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1744f0006bf2SLisandro Dalcin } 1745f0006bf2SLisandro Dalcin 1746f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 1747f0ae7da4SStefano Zampini { 1748f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1749f0ae7da4SStefano Zampini PetscErrorCode ierr; 1750f0ae7da4SStefano Zampini 1751f0ae7da4SStefano Zampini PetscFunctionBegin; 1752f0ae7da4SStefano Zampini if (!n) { 1753f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1754f0ae7da4SStefano Zampini } else { 1755f0ae7da4SStefano Zampini PetscInt i; 1756f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1757f0ae7da4SStefano Zampini 1758f0ae7da4SStefano Zampini if (columns) { 1759f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1760f0ae7da4SStefano Zampini } else { 1761f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1762f0ae7da4SStefano Zampini } 1763f0ae7da4SStefano Zampini if (diag != 0.) { 1764f0ae7da4SStefano Zampini const PetscScalar *array; 1765f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1766f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1767f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1768f0ae7da4SStefano Zampini } 1769f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1770f0ae7da4SStefano Zampini } 1771f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1772f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1773f0ae7da4SStefano Zampini } 1774f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1775f0ae7da4SStefano Zampini } 1776f0ae7da4SStefano Zampini 1777f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 17782e74eeadSLisandro Dalcin { 17796e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 17806e520ac8SStefano Zampini PetscInt nr,nl,len,i; 17816e520ac8SStefano Zampini PetscInt *lrows; 17822e74eeadSLisandro Dalcin PetscErrorCode ierr; 17832e74eeadSLisandro Dalcin 17842e74eeadSLisandro Dalcin PetscFunctionBegin; 1785f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1786f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1787f0ae7da4SStefano Zampini PetscBool cong; 1788f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1789f0ae7da4SStefano 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 for MATIS"); 1790f0ae7da4SStefano 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 for MATIS"); 1791f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1792f0ae7da4SStefano Zampini } 1793f0ae7da4SStefano Zampini #endif 17946e520ac8SStefano Zampini /* get locally owned rows */ 1795f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 17966e520ac8SStefano Zampini /* fix right hand side if needed */ 17976e520ac8SStefano Zampini if (x && b) { 17986e520ac8SStefano Zampini const PetscScalar *xx; 17996e520ac8SStefano Zampini PetscScalar *bb; 18006e520ac8SStefano Zampini 18016e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 18026e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 18036e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 18046e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 18056e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 18062e74eeadSLisandro Dalcin } 18076e520ac8SStefano Zampini /* get rows associated to the local matrices */ 18083d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 18096e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 18106e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 18116e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 18126e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 18136e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18146e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18156e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18166e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 18176e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1818f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 18196e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18202e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18212e74eeadSLisandro Dalcin } 18222e74eeadSLisandro Dalcin 1823f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1824b4319ba4SBarry Smith { 1825dfbe8321SBarry Smith PetscErrorCode ierr; 1826b4319ba4SBarry Smith 1827b4319ba4SBarry Smith PetscFunctionBegin; 1828f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1829f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1830f0ae7da4SStefano Zampini } 18312205254eSKarl Rupp 1832f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1833f0ae7da4SStefano Zampini { 1834f0ae7da4SStefano Zampini PetscErrorCode ierr; 1835f0ae7da4SStefano Zampini 1836f0ae7da4SStefano Zampini PetscFunctionBegin; 1837f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1838b4319ba4SBarry Smith PetscFunctionReturn(0); 1839b4319ba4SBarry Smith } 1840b4319ba4SBarry Smith 1841a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1842b4319ba4SBarry Smith { 1843b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1844dfbe8321SBarry Smith PetscErrorCode ierr; 1845b4319ba4SBarry Smith 1846b4319ba4SBarry Smith PetscFunctionBegin; 1847b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1848b4319ba4SBarry Smith PetscFunctionReturn(0); 1849b4319ba4SBarry Smith } 1850b4319ba4SBarry Smith 1851a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1852b4319ba4SBarry Smith { 1853b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1854dfbe8321SBarry Smith PetscErrorCode ierr; 1855b4319ba4SBarry Smith 1856b4319ba4SBarry Smith PetscFunctionBegin; 1857b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1858b4319ba4SBarry Smith PetscFunctionReturn(0); 1859b4319ba4SBarry Smith } 1860b4319ba4SBarry Smith 1861a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1862b4319ba4SBarry Smith { 1863b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1864b4319ba4SBarry Smith 1865b4319ba4SBarry Smith PetscFunctionBegin; 1866b4319ba4SBarry Smith *local = is->A; 1867b4319ba4SBarry Smith PetscFunctionReturn(0); 1868b4319ba4SBarry Smith } 1869b4319ba4SBarry Smith 1870b4319ba4SBarry Smith /*@ 1871b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1872b4319ba4SBarry Smith 1873b4319ba4SBarry Smith Input Parameter: 1874b4319ba4SBarry Smith . mat - the matrix 1875b4319ba4SBarry Smith 1876b4319ba4SBarry Smith Output Parameter: 1877eb82efa4SStefano Zampini . local - the local matrix 1878b4319ba4SBarry Smith 1879b4319ba4SBarry Smith Level: advanced 1880b4319ba4SBarry Smith 1881b4319ba4SBarry Smith Notes: 1882b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1883b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1884b4319ba4SBarry Smith of the MatSetValues() operation. 1885b4319ba4SBarry Smith 1886b4319ba4SBarry Smith .seealso: MATIS 1887b4319ba4SBarry Smith @*/ 18887087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1889b4319ba4SBarry Smith { 18904ac538c5SBarry Smith PetscErrorCode ierr; 1891b4319ba4SBarry Smith 1892b4319ba4SBarry Smith PetscFunctionBegin; 18930700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1894b4319ba4SBarry Smith PetscValidPointer(local,2); 18954ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1896b4319ba4SBarry Smith PetscFunctionReturn(0); 1897b4319ba4SBarry Smith } 1898b4319ba4SBarry Smith 1899a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 19003b03a366Sstefano_zampini { 19013b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 19023b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 19033b03a366Sstefano_zampini PetscErrorCode ierr; 19043b03a366Sstefano_zampini 19053b03a366Sstefano_zampini PetscFunctionBegin; 19064e4c7dbeSStefano Zampini if (is->A) { 19073b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 19083b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1909f0ae7da4SStefano 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); 19104e4c7dbeSStefano Zampini } 19113b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 19123b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 19133b03a366Sstefano_zampini is->A = local; 19143b03a366Sstefano_zampini PetscFunctionReturn(0); 19153b03a366Sstefano_zampini } 19163b03a366Sstefano_zampini 19173b03a366Sstefano_zampini /*@ 1918eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 19193b03a366Sstefano_zampini 19203b03a366Sstefano_zampini Input Parameter: 19213b03a366Sstefano_zampini . mat - the matrix 1922eb82efa4SStefano Zampini . local - the local matrix 19233b03a366Sstefano_zampini 19243b03a366Sstefano_zampini Output Parameter: 19253b03a366Sstefano_zampini 19263b03a366Sstefano_zampini Level: advanced 19273b03a366Sstefano_zampini 19283b03a366Sstefano_zampini Notes: 19293b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 19303b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 19313b03a366Sstefano_zampini 19323b03a366Sstefano_zampini .seealso: MATIS 19333b03a366Sstefano_zampini @*/ 19343b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 19353b03a366Sstefano_zampini { 19363b03a366Sstefano_zampini PetscErrorCode ierr; 19373b03a366Sstefano_zampini 19383b03a366Sstefano_zampini PetscFunctionBegin; 19393b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1940b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 19413b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 19423b03a366Sstefano_zampini PetscFunctionReturn(0); 19433b03a366Sstefano_zampini } 19443b03a366Sstefano_zampini 1945a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 19466726f965SBarry Smith { 19476726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 19486726f965SBarry Smith PetscErrorCode ierr; 19496726f965SBarry Smith 19506726f965SBarry Smith PetscFunctionBegin; 19516726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 19526726f965SBarry Smith PetscFunctionReturn(0); 19536726f965SBarry Smith } 19546726f965SBarry Smith 1955a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 19562e74eeadSLisandro Dalcin { 19572e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19582e74eeadSLisandro Dalcin PetscErrorCode ierr; 19592e74eeadSLisandro Dalcin 19602e74eeadSLisandro Dalcin PetscFunctionBegin; 19612e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 19622e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19632e74eeadSLisandro Dalcin } 19642e74eeadSLisandro Dalcin 1965a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 19662e74eeadSLisandro Dalcin { 19672e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19682e74eeadSLisandro Dalcin PetscErrorCode ierr; 19692e74eeadSLisandro Dalcin 19702e74eeadSLisandro Dalcin PetscFunctionBegin; 19712e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 1972e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 19732e74eeadSLisandro Dalcin 19742e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 19752e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 1976e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1977e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19782e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19792e74eeadSLisandro Dalcin } 19802e74eeadSLisandro Dalcin 1981a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 19826726f965SBarry Smith { 19836726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 19846726f965SBarry Smith PetscErrorCode ierr; 19856726f965SBarry Smith 19866726f965SBarry Smith PetscFunctionBegin; 19874e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 19886726f965SBarry Smith PetscFunctionReturn(0); 19896726f965SBarry Smith } 19906726f965SBarry Smith 1991f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 1992f26d0771SStefano Zampini { 1993f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 1994f26d0771SStefano Zampini Mat_IS *x; 1995f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1996f26d0771SStefano Zampini PetscBool ismatis; 1997f26d0771SStefano Zampini #endif 1998f26d0771SStefano Zampini PetscErrorCode ierr; 1999f26d0771SStefano Zampini 2000f26d0771SStefano Zampini PetscFunctionBegin; 2001f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2002f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2003f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2004f26d0771SStefano Zampini #endif 2005f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2006f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2007f26d0771SStefano Zampini PetscFunctionReturn(0); 2008f26d0771SStefano Zampini } 2009f26d0771SStefano Zampini 2010f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2011f26d0771SStefano Zampini { 2012f26d0771SStefano Zampini Mat lA; 2013f26d0771SStefano Zampini Mat_IS *matis; 2014f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2015f26d0771SStefano Zampini IS is; 2016f26d0771SStefano Zampini const PetscInt *rg,*rl; 2017f26d0771SStefano Zampini PetscInt nrg; 2018f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2019f26d0771SStefano Zampini PetscErrorCode ierr; 2020f26d0771SStefano Zampini 2021f26d0771SStefano Zampini PetscFunctionBegin; 2022f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2023f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2024f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2025f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2026f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2027f0ae7da4SStefano 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); 2028f26d0771SStefano Zampini #endif 2029f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2030f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2031f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2032f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2033f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2034f26d0771SStefano Zampini #else 2035f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2036f26d0771SStefano Zampini #endif 2037f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2038f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2039f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2040f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2041f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2042f26d0771SStefano Zampini /* compute new l2g map for columns */ 2043f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2044f26d0771SStefano Zampini const PetscInt *cg,*cl; 2045f26d0771SStefano Zampini PetscInt ncg; 2046f26d0771SStefano Zampini PetscInt ncl; 2047f26d0771SStefano Zampini 2048f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2049f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2050f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2051f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2052f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2053f0ae7da4SStefano 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); 2054f26d0771SStefano Zampini #endif 2055f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2056f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2057f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2058f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2059f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2060f26d0771SStefano Zampini #else 2061f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2062f26d0771SStefano Zampini #endif 2063f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2064f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2065f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2066f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2067f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2068f26d0771SStefano Zampini } else { 2069f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2070f26d0771SStefano Zampini cl2g = rl2g; 2071f26d0771SStefano Zampini } 2072f26d0771SStefano Zampini /* create the MATIS submatrix */ 2073f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2074f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2075f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2076f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2077b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2078f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2079f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2080f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2081f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2082f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2083f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2084f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2085f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2086f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2087f26d0771SStefano Zampini /* remove unsupported ops */ 2088f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2089f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2090f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2091f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2092f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2093f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2094f26d0771SStefano Zampini PetscFunctionReturn(0); 2095f26d0771SStefano Zampini } 2096f26d0771SStefano Zampini 2097284134d9SBarry Smith /*@ 20983c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2099284134d9SBarry Smith process but not across processes. 2100284134d9SBarry Smith 2101284134d9SBarry Smith Input Parameters: 2102284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2103e176bc59SStefano Zampini . bs - block size of the matrix 2104df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2105e176bc59SStefano Zampini . rmap - local to global map for rows 2106e176bc59SStefano Zampini - cmap - local to global map for cols 2107284134d9SBarry Smith 2108284134d9SBarry Smith Output Parameter: 2109284134d9SBarry Smith . A - the resulting matrix 2110284134d9SBarry Smith 21118e6c10adSSatish Balay Level: advanced 21128e6c10adSSatish Balay 21133c212e90SHong Zhang Notes: See MATIS for more details. 21146fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 21156fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 21163c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2117284134d9SBarry Smith 2118284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2119284134d9SBarry Smith @*/ 2120e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2121284134d9SBarry Smith { 2122284134d9SBarry Smith PetscErrorCode ierr; 2123284134d9SBarry Smith 2124284134d9SBarry Smith PetscFunctionBegin; 21256fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2126284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 2127284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 21286fdf41d1SStefano Zampini if (bs > 0) { 2129284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 21306fdf41d1SStefano Zampini } 2131284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2132e176bc59SStefano Zampini if (rmap && cmap) { 2133e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2134e176bc59SStefano Zampini } else if (!rmap) { 2135e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2136e176bc59SStefano Zampini } else { 2137e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2138e176bc59SStefano Zampini } 2139284134d9SBarry Smith PetscFunctionReturn(0); 2140284134d9SBarry Smith } 2141284134d9SBarry Smith 2142b4319ba4SBarry Smith /*MC 2143f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2144b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2145b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2146b4319ba4SBarry Smith product is handled "implicitly". 2147b4319ba4SBarry Smith 2148b4319ba4SBarry Smith Operations Provided: 21496726f965SBarry Smith + MatMult() 21502e74eeadSLisandro Dalcin . MatMultAdd() 21512e74eeadSLisandro Dalcin . MatMultTranspose() 21522e74eeadSLisandro Dalcin . MatMultTransposeAdd() 21536726f965SBarry Smith . MatZeroEntries() 21546726f965SBarry Smith . MatSetOption() 21552e74eeadSLisandro Dalcin . MatZeroRows() 21562e74eeadSLisandro Dalcin . MatSetValues() 215797563a80SStefano Zampini . MatSetValuesBlocked() 21586726f965SBarry Smith . MatSetValuesLocal() 215997563a80SStefano Zampini . MatSetValuesBlockedLocal() 21602e74eeadSLisandro Dalcin . MatScale() 21612e74eeadSLisandro Dalcin . MatGetDiagonal() 21622b404112SStefano Zampini . MatMissingDiagonal() 21632b404112SStefano Zampini . MatDuplicate() 21642b404112SStefano Zampini . MatCopy() 2165f26d0771SStefano Zampini . MatAXPY() 2166*7dae84e0SHong Zhang . MatCreateSubMatrix() 2167f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2168d7f69cd0SStefano Zampini . MatTranspose() 21696726f965SBarry Smith - MatSetLocalToGlobalMapping() 2170b4319ba4SBarry Smith 2171b4319ba4SBarry Smith Options Database Keys: 2172b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 2173b4319ba4SBarry Smith 2174b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 2175b4319ba4SBarry Smith 2176b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2177b4319ba4SBarry Smith 2178b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2179eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2180b4319ba4SBarry Smith 2181b4319ba4SBarry Smith Level: advanced 2182b4319ba4SBarry Smith 2183f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2184b4319ba4SBarry Smith 2185b4319ba4SBarry Smith M*/ 2186b4319ba4SBarry Smith 21878cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2188b4319ba4SBarry Smith { 2189dfbe8321SBarry Smith PetscErrorCode ierr; 2190b4319ba4SBarry Smith Mat_IS *b; 2191b4319ba4SBarry Smith 2192b4319ba4SBarry Smith PetscFunctionBegin; 2193b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2194b4319ba4SBarry Smith A->data = (void*)b; 2195b4319ba4SBarry Smith 2196e176bc59SStefano Zampini /* matrix ops */ 2197e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2198b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 21992e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 22002e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 22012e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2202b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2203b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 22042e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 220598921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2206b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2207f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 22082e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2209f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2210b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2211b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2212b4319ba4SBarry Smith A->ops->view = MatView_IS; 22136726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 22142e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 22152e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 22166726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 221769796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 221869796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 221945471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2220ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 22216bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 22222b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2223659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 2224*7dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 2225f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 22263fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 22273fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2228d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 22297fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 2230ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 2231b4319ba4SBarry Smith 2232b7ce53b6SStefano Zampini /* special MATIS functions */ 2233bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 2234bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2235b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 22362e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2237cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 223817667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2239b4319ba4SBarry Smith PetscFunctionReturn(0); 2240b4319ba4SBarry Smith } 2241