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 22ab4d48faSStefano Zampini PetscFunctionBegin; 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 60ab4d48faSStefano Zampini PetscFunctionBegin; 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 180ab4d48faSStefano Zampini PetscFunctionBegin; 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); 436ab4d48faSStefano Zampini for (i=0;i<nr*nc;i++) { 4379e7b2b25Sstefano_zampini if (istrans[i]) { 4389e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 4399e7b2b25Sstefano_zampini } 440ab4d48faSStefano Zampini } 4415e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 4425e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 4435e3038f0Sstefano_zampini } 4445e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4455e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4465e3038f0Sstefano_zampini } 4475e3038f0Sstefano_zampini 4485b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 4495b003df0Sstefano_zampini convert = PETSC_FALSE; 4505b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 4515b003df0Sstefano_zampini if (convert) { 4525b003df0Sstefano_zampini Mat M; 4535b003df0Sstefano_zampini MatISLocalFields lf; 4545b003df0Sstefano_zampini PetscContainer c; 4555b003df0Sstefano_zampini 4565b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4575b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 4585b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 4595b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4605b003df0Sstefano_zampini 4615b003df0Sstefano_zampini /* attach local fields to the matrix */ 4625b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 4635b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 4645b003df0Sstefano_zampini for (i=0;i<nr;i++) { 4655b003df0Sstefano_zampini PetscInt n,st; 4665b003df0Sstefano_zampini 4675b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 4685b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 4695b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 4705b003df0Sstefano_zampini } 4715b003df0Sstefano_zampini for (i=0;i<nc;i++) { 4725b003df0Sstefano_zampini PetscInt n,st; 4735b003df0Sstefano_zampini 4745b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 4755b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 4765b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 4775b003df0Sstefano_zampini } 4785b003df0Sstefano_zampini lf->nr = nr; 4795b003df0Sstefano_zampini lf->nc = nc; 4805b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 4815b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 4825b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 4835b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 4845b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 4855b003df0Sstefano_zampini } 4865b003df0Sstefano_zampini 4875e3038f0Sstefano_zampini /* Free workspace */ 4885e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4895e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 4905e3038f0Sstefano_zampini } 4915e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 4925e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 4935e3038f0Sstefano_zampini } 4949e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 4955b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 4965e3038f0Sstefano_zampini PetscFunctionReturn(0); 4975e3038f0Sstefano_zampini } 4985e3038f0Sstefano_zampini 499ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 500ad219c80Sstefano_zampini { 501ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 502ad219c80Sstefano_zampini Vec ll,rr; 503ad219c80Sstefano_zampini const PetscScalar *Y,*X; 504ad219c80Sstefano_zampini PetscScalar *x,*y; 505ad219c80Sstefano_zampini PetscErrorCode ierr; 506ad219c80Sstefano_zampini 507ad219c80Sstefano_zampini PetscFunctionBegin; 508ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 509ad219c80Sstefano_zampini if (l) { 510ad219c80Sstefano_zampini ll = matis->y; 511ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 512ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 513ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 514ad219c80Sstefano_zampini } else { 515ad219c80Sstefano_zampini ll = NULL; 516ad219c80Sstefano_zampini } 517ad219c80Sstefano_zampini if (r) { 518ad219c80Sstefano_zampini rr = matis->x; 519ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 520ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 521ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 522ad219c80Sstefano_zampini } else { 523ad219c80Sstefano_zampini rr = NULL; 524ad219c80Sstefano_zampini } 525ad219c80Sstefano_zampini if (ll) { 526ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 527ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 528ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 529ad219c80Sstefano_zampini } 530ad219c80Sstefano_zampini if (rr) { 531ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 532ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 533ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 534ad219c80Sstefano_zampini } 535ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 536ad219c80Sstefano_zampini PetscFunctionReturn(0); 537ad219c80Sstefano_zampini } 538ad219c80Sstefano_zampini 5397fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 5407fa8f2d3SStefano Zampini { 5417fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 5427fa8f2d3SStefano Zampini MatInfo info; 5437fa8f2d3SStefano Zampini PetscReal isend[6],irecv[6]; 5447fa8f2d3SStefano Zampini PetscInt bs; 5457fa8f2d3SStefano Zampini PetscErrorCode ierr; 5467fa8f2d3SStefano Zampini 5477fa8f2d3SStefano Zampini PetscFunctionBegin; 5487fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 5497fa8f2d3SStefano Zampini if (matis->A->ops->getinfo) { 5507fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 5517fa8f2d3SStefano Zampini isend[0] = info.nz_used; 5527fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 5537fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 5547fa8f2d3SStefano Zampini isend[3] = info.memory; 5557fa8f2d3SStefano Zampini isend[4] = info.mallocs; 5567fa8f2d3SStefano Zampini } else { 5577fa8f2d3SStefano Zampini isend[0] = 0.; 5587fa8f2d3SStefano Zampini isend[1] = 0.; 5597fa8f2d3SStefano Zampini isend[2] = 0.; 5607fa8f2d3SStefano Zampini isend[3] = 0.; 5617fa8f2d3SStefano Zampini isend[4] = 0.; 5627fa8f2d3SStefano Zampini } 5637fa8f2d3SStefano Zampini isend[5] = matis->A->num_ass; 5647fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 5657fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 5667fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 5677fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 5687fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 5697fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 5707fa8f2d3SStefano Zampini ginfo->assemblies = isend[5]; 5717fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 5727fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 5737fa8f2d3SStefano Zampini 5747fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 5757fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 5767fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 5777fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 5787fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 5797fa8f2d3SStefano Zampini ginfo->assemblies = irecv[5]; 5807fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 5817fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 5827fa8f2d3SStefano Zampini 5837fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 5847fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 5857fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 5867fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 5877fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 5887fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 589d7f69cd0SStefano Zampini } 590d7f69cd0SStefano Zampini ginfo->block_size = bs; 591d7f69cd0SStefano Zampini ginfo->fill_ratio_given = 0; 592d7f69cd0SStefano Zampini ginfo->fill_ratio_needed = 0; 593d7f69cd0SStefano Zampini ginfo->factor_mallocs = 0; 5945e3038f0Sstefano_zampini PetscFunctionReturn(0); 5955e3038f0Sstefano_zampini } 5965e3038f0Sstefano_zampini 597d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 598d7f69cd0SStefano Zampini { 599d7f69cd0SStefano Zampini Mat C,lC,lA; 600d7f69cd0SStefano Zampini PetscErrorCode ierr; 601d7f69cd0SStefano Zampini 602d7f69cd0SStefano Zampini PetscFunctionBegin; 603cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 604cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 605d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 606d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 607d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 608d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 609d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 610d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 611cf37664fSBarry Smith } else { 612cf37664fSBarry Smith C = *B; 613d7f69cd0SStefano Zampini } 614d7f69cd0SStefano Zampini 615d7f69cd0SStefano Zampini /* perform local transposition */ 616d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 617d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 618d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 619d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 620d7f69cd0SStefano Zampini 621cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 622d7f69cd0SStefano Zampini *B = C; 623d7f69cd0SStefano Zampini } else { 624d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 625d7f69cd0SStefano Zampini } 6267aa7aec5Sstefano_zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6277aa7aec5Sstefano_zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 628d7f69cd0SStefano Zampini PetscFunctionReturn(0); 629d7f69cd0SStefano Zampini } 630d7f69cd0SStefano Zampini 6313fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 6323fd1c9e7SStefano Zampini { 6333fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 6343fd1c9e7SStefano Zampini PetscErrorCode ierr; 6353fd1c9e7SStefano Zampini 6363fd1c9e7SStefano Zampini PetscFunctionBegin; 6373fd1c9e7SStefano Zampini if (!D) { /* this code branch is used by MatShift_IS */ 6383fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 6393fd1c9e7SStefano Zampini } else { 6403fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6413fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6423fd1c9e7SStefano Zampini } 6433fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 6443fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 6453fd1c9e7SStefano Zampini PetscFunctionReturn(0); 6463fd1c9e7SStefano Zampini } 6473fd1c9e7SStefano Zampini 6483fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 6493fd1c9e7SStefano Zampini { 6503fd1c9e7SStefano Zampini PetscErrorCode ierr; 6513fd1c9e7SStefano Zampini 6523fd1c9e7SStefano Zampini PetscFunctionBegin; 6533fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 6543fd1c9e7SStefano Zampini PetscFunctionReturn(0); 6553fd1c9e7SStefano Zampini } 6563fd1c9e7SStefano Zampini 657f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 658f26d0771SStefano Zampini { 659f26d0771SStefano Zampini PetscErrorCode ierr; 660f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 661f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 662f26d0771SStefano Zampini 663f26d0771SStefano Zampini PetscFunctionBegin; 664f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 665f26d0771SStefano 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); 666f26d0771SStefano Zampini #endif 667f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 668f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 669f26d0771SStefano Zampini ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 670f26d0771SStefano Zampini PetscFunctionReturn(0); 671f26d0771SStefano Zampini } 672f26d0771SStefano Zampini 673f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 674f26d0771SStefano Zampini { 675f26d0771SStefano Zampini PetscErrorCode ierr; 676f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 677f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 678f26d0771SStefano Zampini 679f26d0771SStefano Zampini PetscFunctionBegin; 680f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 681f26d0771SStefano 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); 682f26d0771SStefano Zampini #endif 683f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 684f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 685f26d0771SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 686f26d0771SStefano Zampini PetscFunctionReturn(0); 687f26d0771SStefano Zampini } 688f26d0771SStefano Zampini 689f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 690a8116848SStefano Zampini { 691a8116848SStefano Zampini PetscInt *owners = map->range; 692a8116848SStefano Zampini PetscInt n = map->n; 693a8116848SStefano Zampini PetscSF sf; 694a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 695a8116848SStefano Zampini PetscSFNode *ridxs; 696a8116848SStefano Zampini PetscMPIInt rank; 697a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 698a8116848SStefano Zampini PetscErrorCode ierr; 699a8116848SStefano Zampini 700a8116848SStefano Zampini PetscFunctionBegin; 701fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 702a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 703a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 704a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 705a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 706a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 707a8116848SStefano Zampini for (r = 0; r < N; ++r) { 708a8116848SStefano Zampini const PetscInt idx = idxs[r]; 709a8116848SStefano 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); 710a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 711a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 712a8116848SStefano Zampini } 713a8116848SStefano Zampini ridxs[r].rank = p; 714a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 715a8116848SStefano Zampini } 716a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 717a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 718a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 719a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 720f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 721a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 722f0ae7da4SStefano Zampini 723f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 724a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 725a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 726a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 727a8116848SStefano Zampini start -= cum; 728a8116848SStefano Zampini cum = 0; 729a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 730a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 731a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 732a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 733a8116848SStefano Zampini } 734a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 735a8116848SStefano Zampini /* Compress and put in indices */ 736a8116848SStefano Zampini for (r = 0; r < n; ++r) 737a8116848SStefano Zampini if (lidxs[r] >= 0) { 738a8116848SStefano Zampini if (work) work[len] = work[r]; 739a8116848SStefano Zampini lidxs[len++] = r; 740a8116848SStefano Zampini } 741a8116848SStefano Zampini if (on) *on = len; 742a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 743a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 744a8116848SStefano Zampini PetscFunctionReturn(0); 745a8116848SStefano Zampini } 746a8116848SStefano Zampini 7477dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 748a8116848SStefano Zampini { 749a8116848SStefano Zampini Mat locmat,newlocmat; 750a8116848SStefano Zampini Mat_IS *newmatis; 751a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 752a8116848SStefano Zampini Vec rtest,ltest; 753a8116848SStefano Zampini const PetscScalar *array; 754a8116848SStefano Zampini #endif 755a8116848SStefano Zampini const PetscInt *idxs; 756a8116848SStefano Zampini PetscInt i,m,n; 757a8116848SStefano Zampini PetscErrorCode ierr; 758a8116848SStefano Zampini 759a8116848SStefano Zampini PetscFunctionBegin; 760a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 761a8116848SStefano Zampini PetscBool ismatis; 762a8116848SStefano Zampini 763a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 764a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 765a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 766a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 767a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 768a8116848SStefano Zampini } 769a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 770a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 771a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 772a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 773a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 774a8116848SStefano Zampini for (i=0;i<n;i++) { 775a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 776a8116848SStefano Zampini } 777a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 778a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 779a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 780a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 781a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 782fd479f66SMatthew 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])); 783a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 784a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 785a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 786a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 787a8116848SStefano Zampini for (i=0;i<n;i++) { 788a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 789a8116848SStefano Zampini } 790a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 791a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 792a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 793a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 794a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 795fd479f66SMatthew 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])); 796a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 797a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 798a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 799a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 800a8116848SStefano Zampini #endif 801a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 802a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 803a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 804a8116848SStefano Zampini IS is; 805a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 8066dd40735SStefano Zampini PetscInt ll,newloc; 807a8116848SStefano Zampini MPI_Comm comm; 808a8116848SStefano Zampini 809a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 810a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 811a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 812a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 813a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 814a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 815a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 816a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 817f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 818a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 8193d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 8203d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 821a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 822a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 823a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 824a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 825a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 8263d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 827a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 828a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8293d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 830a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 831a8116848SStefano Zampini lidxs[newloc] = i; 832a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 833a8116848SStefano Zampini } 834a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 835a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 836a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 837a8116848SStefano Zampini /* local is to extract local submatrix */ 838a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 839a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 840a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 841a8116848SStefano Zampini PetscBool cong; 842a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 843a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 844a8116848SStefano Zampini else mat->congruentlayouts = 0; 845a8116848SStefano Zampini } 846*268753edSStefano Zampini if (mat->congruentlayouts && irow == icol && matis->csf == matis->sf) { 847a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 848a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 849a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 850a8116848SStefano Zampini } else { 851a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 852a8116848SStefano Zampini 853a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 854a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 855f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 856a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 8573d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 858a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 859a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 860a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 861a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 862a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 8633d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 864a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 865a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8663d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 867a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 868a8116848SStefano Zampini lidxs[newloc] = i; 869a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 870a8116848SStefano Zampini } 871a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 872a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 873a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 874a8116848SStefano Zampini /* local is to extract local submatrix */ 875a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 876a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 877a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 878a8116848SStefano Zampini } 879a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 880a8116848SStefano Zampini } else { 881a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 882a8116848SStefano Zampini } 883a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 884a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 8857dae84e0SHong Zhang ierr = MatCreateSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 886a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 887a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 888a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 889a8116848SStefano Zampini } 890a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 891a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 892a8116848SStefano Zampini PetscFunctionReturn(0); 893a8116848SStefano Zampini } 894a8116848SStefano Zampini 895a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 8962b404112SStefano Zampini { 8972b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 8982b404112SStefano Zampini PetscBool ismatis; 8992b404112SStefano Zampini PetscErrorCode ierr; 9002b404112SStefano Zampini 9012b404112SStefano Zampini PetscFunctionBegin; 9022b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 9032b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 9042b404112SStefano Zampini b = (Mat_IS*)B->data; 9052b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 906cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 9072b404112SStefano Zampini PetscFunctionReturn(0); 9082b404112SStefano Zampini } 9092b404112SStefano Zampini 910a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 9116bd84002SStefano Zampini { 912527b2640SStefano Zampini Vec v; 913527b2640SStefano Zampini const PetscScalar *array; 914527b2640SStefano Zampini PetscInt i,n; 9156bd84002SStefano Zampini PetscErrorCode ierr; 9166bd84002SStefano Zampini 9176bd84002SStefano Zampini PetscFunctionBegin; 918527b2640SStefano Zampini *missing = PETSC_FALSE; 919527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 920527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 921527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 922527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 923527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 924527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 925527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 926527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 927527b2640SStefano Zampini if (d) { 928527b2640SStefano Zampini *d = -1; 929527b2640SStefano Zampini if (*missing) { 930527b2640SStefano Zampini PetscInt rstart; 931527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 932527b2640SStefano Zampini *d = i+rstart; 933527b2640SStefano Zampini } 934527b2640SStefano Zampini } 9356bd84002SStefano Zampini PetscFunctionReturn(0); 9366bd84002SStefano Zampini } 9376bd84002SStefano Zampini 938cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 93928f4e0baSStefano Zampini { 94028f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 94128f4e0baSStefano Zampini const PetscInt *gidxs; 9424f2d7cafSStefano Zampini PetscInt nleaves; 94328f4e0baSStefano Zampini PetscErrorCode ierr; 94428f4e0baSStefano Zampini 94528f4e0baSStefano Zampini PetscFunctionBegin; 9464f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 94728f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 9483bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9494f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 9504f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 9513bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9524f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 953a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 9543d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 955a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 956a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9573d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 958a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9593d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 960a8116848SStefano Zampini } else { 961a8116848SStefano Zampini matis->csf = matis->sf; 962a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 963a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 964a8116848SStefano Zampini } 96528f4e0baSStefano Zampini PetscFunctionReturn(0); 96628f4e0baSStefano Zampini } 9672e1947a5SStefano Zampini 968eb82efa4SStefano Zampini /*@ 969a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 970a88811baSStefano Zampini 971a88811baSStefano Zampini Collective on MPI_Comm 972a88811baSStefano Zampini 973a88811baSStefano Zampini Input Parameters: 974a88811baSStefano Zampini + B - the matrix 975a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 976a88811baSStefano Zampini (same value is used for all local rows) 977a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 978a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 979a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 980a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 981a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 982a88811baSStefano Zampini the diagonal entry even if it is zero. 983a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 984a88811baSStefano Zampini submatrix (same value is used for all local rows). 985a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 986a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 987a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 988a88811baSStefano Zampini structure. The size of this array is equal to the number 989a88811baSStefano Zampini of local rows, i.e 'm'. 990a88811baSStefano Zampini 991a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 992a88811baSStefano Zampini 993a88811baSStefano Zampini Level: intermediate 994a88811baSStefano Zampini 995a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 996a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 997a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 998a88811baSStefano Zampini 999a88811baSStefano Zampini .keywords: matrix 1000a88811baSStefano Zampini 10013c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1002a88811baSStefano Zampini @*/ 10032e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10042e1947a5SStefano Zampini { 10052e1947a5SStefano Zampini PetscErrorCode ierr; 10062e1947a5SStefano Zampini 10072e1947a5SStefano Zampini PetscFunctionBegin; 10082e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10092e1947a5SStefano Zampini PetscValidType(B,1); 10102e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 10112e1947a5SStefano Zampini PetscFunctionReturn(0); 10122e1947a5SStefano Zampini } 10132e1947a5SStefano Zampini 10147230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10152e1947a5SStefano Zampini { 10162e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 101728f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 10182e1947a5SStefano Zampini PetscErrorCode ierr; 10192e1947a5SStefano Zampini 10202e1947a5SStefano Zampini PetscFunctionBegin; 10216c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1022cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 10234f2d7cafSStefano Zampini 10244f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 10254f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 10264f2d7cafSStefano Zampini 10274f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 10284f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 10294f2d7cafSStefano Zampini 103028f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 103128f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 103228f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 103328f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 10344f2d7cafSStefano Zampini 10354f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 103628f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 10370f2f62c7SStefano Zampini #if defined(PETSC_HAVE_HYPRE) 10380f2f62c7SStefano Zampini ierr = MatHYPRESetPreallocation(matis->A,0,matis->sf_leafdata,0,NULL);CHKERRQ(ierr); 10390f2f62c7SStefano Zampini #endif 10404f2d7cafSStefano Zampini 10414f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 104228f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10434f2d7cafSStefano Zampini 10444f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 104528f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10460f2f62c7SStefano Zampini 10470f2f62c7SStefano Zampini /* for other matrix types */ 10480f2f62c7SStefano Zampini ierr = MatSetUp(matis->A);CHKERRQ(ierr); 10492e1947a5SStefano Zampini PetscFunctionReturn(0); 10502e1947a5SStefano Zampini } 1051b4319ba4SBarry Smith 10523927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 10533927de2eSStefano Zampini { 10543927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 10553927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1056ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 10573927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 10583927de2eSStefano Zampini PetscInt lrows,lcols; 10593927de2eSStefano Zampini PetscInt local_rows,local_cols; 10603927de2eSStefano Zampini PetscMPIInt nsubdomains; 10613927de2eSStefano Zampini PetscBool isdense,issbaij; 10623927de2eSStefano Zampini PetscErrorCode ierr; 10633927de2eSStefano Zampini 10643927de2eSStefano Zampini PetscFunctionBegin; 10653927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 10663927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 10673927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10683927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 10693927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 10703927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1071ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1072ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 10737230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1074ecf5a873SStefano Zampini } else { 1075ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1076ecf5a873SStefano Zampini } 1077ecf5a873SStefano Zampini 10783927de2eSStefano Zampini if (issbaij) { 10793927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 10803927de2eSStefano Zampini } 10813927de2eSStefano Zampini /* 1082ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 10833927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 10843927de2eSStefano Zampini */ 1085cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 10863927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 10873927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 10883927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 10893927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 10903927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 10913927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 10923927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 10933927de2eSStefano Zampini row_ownership[j] = i; 10943927de2eSStefano Zampini } 10953927de2eSStefano Zampini } 10967230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 10973927de2eSStefano Zampini 10983927de2eSStefano Zampini /* 10993927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 11003927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 11013927de2eSStefano Zampini */ 11023927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 11033927de2eSStefano Zampini /* preallocation as a MATAIJ */ 11043927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 11053927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 110612dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 110712dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 1108ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 11093927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11103927de2eSStefano Zampini my_dnz[i] += 1; 11113927de2eSStefano Zampini } else { /* offdiag block */ 11123927de2eSStefano Zampini my_onz[i] += 1; 11133927de2eSStefano Zampini } 11143927de2eSStefano Zampini } 11153927de2eSStefano Zampini } 1116bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1117bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1118bb1015c3SStefano Zampini PetscBool done; 1119bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1120938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1121bb1015c3SStefano Zampini jptr = jj; 1122bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1123bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1124bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1125bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1126bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1127bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1128bb1015c3SStefano Zampini my_dnz[i] += 1; 1129bb1015c3SStefano Zampini } else { /* offdiag block */ 1130bb1015c3SStefano Zampini my_onz[i] += 1; 1131bb1015c3SStefano Zampini } 1132bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1133bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1134bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1135bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1136bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1137bb1015c3SStefano Zampini } else { 1138bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1139bb1015c3SStefano Zampini } 1140bb1015c3SStefano Zampini } 1141bb1015c3SStefano Zampini } 1142bb1015c3SStefano Zampini } 1143bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1144938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1145bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 11463927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 11473927de2eSStefano Zampini const PetscInt *cols; 1148ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 11493927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 11503927de2eSStefano Zampini for (j=0;j<ncols;j++) { 11513927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1152ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 11533927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11543927de2eSStefano Zampini my_dnz[i] += 1; 11553927de2eSStefano Zampini } else { /* offdiag block */ 11563927de2eSStefano Zampini my_onz[i] += 1; 11573927de2eSStefano Zampini } 11583927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1159d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 11603927de2eSStefano Zampini owner = row_ownership[index_col]; 11613927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1162d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 11633927de2eSStefano Zampini } else { 1164d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 11653927de2eSStefano Zampini } 11663927de2eSStefano Zampini } 11673927de2eSStefano Zampini } 11683927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 11693927de2eSStefano Zampini } 11703927de2eSStefano Zampini } 1171ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 11727230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1173ecf5a873SStefano Zampini } 11744f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 11753927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1176ecf5a873SStefano Zampini 1177ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 11783927de2eSStefano Zampini if (maxreduce) { 11793927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 11803927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1181bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 11823927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 11833927de2eSStefano Zampini } else { 11843927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 11853927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1186bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 11873927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 11883927de2eSStefano Zampini } 11893927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 11903927de2eSStefano Zampini 11913927de2eSStefano Zampini /* Resize preallocation if overestimated */ 11923927de2eSStefano Zampini for (i=0;i<lrows;i++) { 11933927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 11943927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 11953927de2eSStefano Zampini } 11961670daf9Sstefano_zampini 11971670daf9Sstefano_zampini /* Set preallocation */ 1198*268753edSStefano Zampini ierr = MatSeqAIJSetPreallocation(B,0,dnz);CHKERRQ(ierr); 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 } 1204*268753edSStefano Zampini ierr = MatSeqBAIJSetPreallocation(B,bs,0,dnz);CHKERRQ(ierr); 12053927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12063927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12073927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 12083927de2eSStefano Zampini if (issbaij) { 12093927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 12103927de2eSStefano Zampini } 12113927de2eSStefano Zampini PetscFunctionReturn(0); 12123927de2eSStefano Zampini } 12133927de2eSStefano Zampini 12147230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1215b7ce53b6SStefano Zampini { 1216b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1217d9a9e74cSStefano Zampini Mat local_mat; 1218b7ce53b6SStefano Zampini /* info on mat */ 12193cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1220b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1221b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1222b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1223b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1224b9ed4604SStefano Zampini #endif 12257c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1226b7ce53b6SStefano Zampini /* values insertion */ 1227b7ce53b6SStefano Zampini PetscScalar *array; 1228b7ce53b6SStefano Zampini /* work */ 1229b7ce53b6SStefano Zampini PetscErrorCode ierr; 1230b7ce53b6SStefano Zampini 1231b7ce53b6SStefano Zampini PetscFunctionBegin; 1232b7ce53b6SStefano Zampini /* get info from mat */ 12337c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 12347c03b4e8SStefano Zampini if (nsubdomains == 1) { 12351670daf9Sstefano_zampini Mat B; 12361670daf9Sstefano_zampini IS rows,cols; 1237acdf38a7Sstefano_zampini IS irows,icols; 12381670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 12391670daf9Sstefano_zampini 12401670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 12411670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 12421670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 12431670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 1244acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1245acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1246acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1247acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1248*268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 1249*268753edSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1250acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1251acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 12526104e0f1Sstefano_zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 12537dae84e0SHong Zhang ierr = MatCreateSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1254acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1255acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1256acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 12577c03b4e8SStefano Zampini PetscFunctionReturn(0); 12587c03b4e8SStefano Zampini } 1259b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1260b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 12613cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1262b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1263b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 12644099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1265b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1266b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1267b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1268b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1269b9ed4604SStefano Zampini lb[0] = isseqdense; 1270b9ed4604SStefano Zampini lb[1] = isseqaij; 1271b9ed4604SStefano Zampini lb[2] = isseqbaij; 1272b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1273b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1274b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1275b9ed4604SStefano Zampini #endif 1276b7ce53b6SStefano Zampini 1277b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 12783927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 12793cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 12803927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 1281b9ed4604SStefano Zampini if (!isseqsbaij) { 1282b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1283b9ed4604SStefano Zampini } else { 1284b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1285b9ed4604SStefano Zampini } 12863927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1287b7ce53b6SStefano Zampini } else { 12883cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1289b7ce53b6SStefano Zampini /* some checks */ 1290b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1291b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 12923cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 12936c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 12946c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 12956c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 12966c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 12976c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1298b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1299b7ce53b6SStefano Zampini } 1300d9a9e74cSStefano Zampini 1301b9ed4604SStefano Zampini if (isseqsbaij) { 1302d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1303d9a9e74cSStefano Zampini } else { 1304d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1305d9a9e74cSStefano Zampini local_mat = matis->A; 1306d9a9e74cSStefano Zampini } 1307686e3a49SStefano Zampini 1308b7ce53b6SStefano Zampini /* Set values */ 1309ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1310b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 131165066ba5SStefano Zampini PetscInt i,*dummy; 1312ecf5a873SStefano Zampini 131365066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 131465066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 1315b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1316d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 131765066ba5SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 1318d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 131965066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 1320686e3a49SStefano Zampini } else if (isseqaij) { 1321ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1322686e3a49SStefano Zampini PetscBool done; 1323686e3a49SStefano Zampini 1324d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1325938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ"); 1326d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1327686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1328ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1329686e3a49SStefano Zampini } 1330d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1331938e1ff8SStefano Zampini if (!done) SETERRQ(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ"); 1332d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1333686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1334ecf5a873SStefano Zampini PetscInt i; 1335c0962df8SStefano Zampini 1336686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1337686e3a49SStefano Zampini PetscInt j; 1338ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1339686e3a49SStefano Zampini 1340ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1341ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1342ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1343686e3a49SStefano Zampini } 1344b7ce53b6SStefano Zampini } 1345b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1346d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1347b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1348b9ed4604SStefano Zampini if (isseqdense) { 1349b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1350b7ce53b6SStefano Zampini } 1351b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1352b7ce53b6SStefano Zampini } 1353b7ce53b6SStefano Zampini 1354b7ce53b6SStefano Zampini /*@ 1355b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1356b7ce53b6SStefano Zampini 1357b7ce53b6SStefano Zampini Input Parameter: 1358b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1359b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1360b7ce53b6SStefano Zampini 1361b7ce53b6SStefano Zampini Output Parameter: 1362b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1363b7ce53b6SStefano Zampini 1364b7ce53b6SStefano Zampini Level: developer 1365b7ce53b6SStefano Zampini 1366eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1367b7ce53b6SStefano Zampini 1368b7ce53b6SStefano Zampini .seealso: MATIS 1369b7ce53b6SStefano Zampini @*/ 1370b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1371b7ce53b6SStefano Zampini { 1372b7ce53b6SStefano Zampini PetscErrorCode ierr; 1373b7ce53b6SStefano Zampini 1374b7ce53b6SStefano Zampini PetscFunctionBegin; 1375b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1376b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1377b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1378b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1379b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1380b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 13816c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1382b7ce53b6SStefano Zampini } 1383b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1384b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1385b7ce53b6SStefano Zampini } 1386b7ce53b6SStefano Zampini 1387ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1388ad6194a2SStefano Zampini { 1389ad6194a2SStefano Zampini PetscErrorCode ierr; 1390ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1391ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1392ad6194a2SStefano Zampini Mat B,localmat; 1393ad6194a2SStefano Zampini 1394ad6194a2SStefano Zampini PetscFunctionBegin; 1395ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1396ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1397ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1398e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1399ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1400ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1401b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1402ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1403ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1404ad6194a2SStefano Zampini *newmat = B; 1405ad6194a2SStefano Zampini PetscFunctionReturn(0); 1406ad6194a2SStefano Zampini } 1407ad6194a2SStefano Zampini 1408a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 140969796d55SStefano Zampini { 141069796d55SStefano Zampini PetscErrorCode ierr; 141169796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 141269796d55SStefano Zampini PetscBool local_sym; 141369796d55SStefano Zampini 141469796d55SStefano Zampini PetscFunctionBegin; 141569796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1416b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 141769796d55SStefano Zampini PetscFunctionReturn(0); 141869796d55SStefano Zampini } 141969796d55SStefano Zampini 1420a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 142169796d55SStefano Zampini { 142269796d55SStefano Zampini PetscErrorCode ierr; 142369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 142469796d55SStefano Zampini PetscBool local_sym; 142569796d55SStefano Zampini 142669796d55SStefano Zampini PetscFunctionBegin; 142769796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1428b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 142969796d55SStefano Zampini PetscFunctionReturn(0); 143069796d55SStefano Zampini } 143169796d55SStefano Zampini 143245471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 143345471136SStefano Zampini { 143445471136SStefano Zampini PetscErrorCode ierr; 143545471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 143645471136SStefano Zampini PetscBool local_sym; 143745471136SStefano Zampini 143845471136SStefano Zampini PetscFunctionBegin; 143945471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 144045471136SStefano Zampini *flg = PETSC_FALSE; 144145471136SStefano Zampini PetscFunctionReturn(0); 144245471136SStefano Zampini } 144345471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 144445471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 144545471136SStefano Zampini PetscFunctionReturn(0); 144645471136SStefano Zampini } 144745471136SStefano Zampini 1448a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1449b4319ba4SBarry Smith { 1450dfbe8321SBarry Smith PetscErrorCode ierr; 1451b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1452b4319ba4SBarry Smith 1453b4319ba4SBarry Smith PetscFunctionBegin; 14546bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1455e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1456e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 14576bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 14586bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 14593fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1460a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1461a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1462a8116848SStefano Zampini if (b->sf != b->csf) { 1463a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1464a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1465a8116848SStefano Zampini } 146628f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 146728f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1468bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1469dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1470bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1471b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1472b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 14732e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1474cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 1475b4319ba4SBarry Smith PetscFunctionReturn(0); 1476b4319ba4SBarry Smith } 1477b4319ba4SBarry Smith 1478a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1479b4319ba4SBarry Smith { 1480dfbe8321SBarry Smith PetscErrorCode ierr; 1481b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1482b4319ba4SBarry Smith PetscScalar zero = 0.0; 1483b4319ba4SBarry Smith 1484b4319ba4SBarry Smith PetscFunctionBegin; 1485b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1486e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1487e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1488b4319ba4SBarry Smith 1489b4319ba4SBarry Smith /* multiply the local matrix */ 1490b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1491b4319ba4SBarry Smith 1492b4319ba4SBarry Smith /* scatter product back into global memory */ 14932dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1494e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1495e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1496b4319ba4SBarry Smith PetscFunctionReturn(0); 1497b4319ba4SBarry Smith } 1498b4319ba4SBarry Smith 1499a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 15002e74eeadSLisandro Dalcin { 1501650997f4SStefano Zampini Vec temp_vec; 15022e74eeadSLisandro Dalcin PetscErrorCode ierr; 15032e74eeadSLisandro Dalcin 15042e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1505650997f4SStefano Zampini if (v3 != v2) { 1506650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1507650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1508650997f4SStefano Zampini } else { 1509650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1510650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1511650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1512650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1513650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1514650997f4SStefano Zampini } 15152e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15162e74eeadSLisandro Dalcin } 15172e74eeadSLisandro Dalcin 1518a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 15192e74eeadSLisandro Dalcin { 15202e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 15212e74eeadSLisandro Dalcin PetscErrorCode ierr; 15222e74eeadSLisandro Dalcin 1523e176bc59SStefano Zampini PetscFunctionBegin; 15242e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1525e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1526e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15272e74eeadSLisandro Dalcin 15282e74eeadSLisandro Dalcin /* multiply the local matrix */ 1529e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 15302e74eeadSLisandro Dalcin 15312e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1532e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1533e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1534e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15352e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15362e74eeadSLisandro Dalcin } 15372e74eeadSLisandro Dalcin 1538a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 15392e74eeadSLisandro Dalcin { 1540650997f4SStefano Zampini Vec temp_vec; 15412e74eeadSLisandro Dalcin PetscErrorCode ierr; 15422e74eeadSLisandro Dalcin 15432e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1544650997f4SStefano Zampini if (v3 != v2) { 1545650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1546650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1547650997f4SStefano Zampini } else { 1548650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1549650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1550650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1551650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1552650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1553650997f4SStefano Zampini } 15542e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15552e74eeadSLisandro Dalcin } 15562e74eeadSLisandro Dalcin 1557a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1558b4319ba4SBarry Smith { 1559b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1560dfbe8321SBarry Smith PetscErrorCode ierr; 1561b4319ba4SBarry Smith PetscViewer sviewer; 1562ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1563b4319ba4SBarry Smith 1564b4319ba4SBarry Smith PetscFunctionBegin; 1565ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1566ee2491ecSStefano Zampini if (isascii) { 1567ee2491ecSStefano Zampini PetscViewerFormat format; 1568ee2491ecSStefano Zampini 1569ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1570ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1571ee2491ecSStefano Zampini } 1572ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 15733f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1574b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 15753f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 15766e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1577b4319ba4SBarry Smith PetscFunctionReturn(0); 1578b4319ba4SBarry Smith } 1579b4319ba4SBarry Smith 1580a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1581b4319ba4SBarry Smith { 1582dfbe8321SBarry Smith PetscErrorCode ierr; 1583e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1584b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1585b4319ba4SBarry Smith IS from,to; 1586e176bc59SStefano Zampini Vec cglobal,rglobal; 1587b4319ba4SBarry Smith 1588b4319ba4SBarry Smith PetscFunctionBegin; 1589784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1590e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 15913bbff08aSStefano Zampini /* Destroy any previous data */ 159270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 159370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 15943fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1595e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1596e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 15971c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 1598872cf891SStefano Zampini if (is->csf != is->sf) { 1599872cf891SStefano Zampini ierr = PetscSFDestroy(&is->csf);CHKERRQ(ierr); 1600872cf891SStefano Zampini ierr = PetscFree2(is->csf_rootdata,is->csf_leafdata);CHKERRQ(ierr); 1601872cf891SStefano Zampini } 160228f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 160328f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 16043bbff08aSStefano Zampini 16053bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1606fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1607fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1608fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1609fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1610b4319ba4SBarry Smith 1611b4319ba4SBarry Smith /* Create the local matrix A */ 1612e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1613e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1614e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1615e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1616f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1617e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1618e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1619e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1620ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1621ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1622b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1623c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 1624c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 1625b4319ba4SBarry Smith 1626f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1627b4319ba4SBarry Smith /* Create the local work vectors */ 16283bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1629b4319ba4SBarry Smith 1630e176bc59SStefano Zampini /* setup the global to local scatters */ 1631e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1632e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1633784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1634e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1635e176bc59SStefano Zampini if (rmapping != cmapping) { 1636e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1637e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1638e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1639e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1640e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1641e176bc59SStefano Zampini } else { 1642e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1643e176bc59SStefano Zampini is->cctx = is->rctx; 1644e176bc59SStefano Zampini } 16453fd1c9e7SStefano Zampini 16463fd1c9e7SStefano Zampini /* interface counter vector (local) */ 16473fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 16483fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 16493fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16503fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16513fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16523fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16533fd1c9e7SStefano Zampini 16543fd1c9e7SStefano Zampini /* free workspace */ 1655e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1656e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 16576bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 16586bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1659f26d0771SStefano Zampini } 166048ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1661b4319ba4SBarry Smith PetscFunctionReturn(0); 1662b4319ba4SBarry Smith } 1663b4319ba4SBarry Smith 1664a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 16652e74eeadSLisandro Dalcin { 16662e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 16672e74eeadSLisandro Dalcin PetscErrorCode ierr; 166897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 166997563a80SStefano Zampini PetscInt i,zm,zn; 167097563a80SStefano Zampini #endif 1671f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 16722e74eeadSLisandro Dalcin 16732e74eeadSLisandro Dalcin PetscFunctionBegin; 16742e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1675f26d0771SStefano 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); 167697563a80SStefano Zampini /* count negative indices */ 167797563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 167897563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 16792e74eeadSLisandro Dalcin #endif 168097563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 168197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 168297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 168397563a80SStefano Zampini /* count negative indices (should be the same as before) */ 168497563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 168597563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 1686872cf891SStefano Zampini /* disable check when usesetlocal is true */ 1687872cf891SStefano Zampini if (!is->usesetlocal && zm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the row indices can not be mapped! Maybe you should not use MATIS"); 1688872cf891SStefano Zampini if (!is->usesetlocal && zn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Some of the column indices can not be mapped! Maybe you should not use MATIS"); 168997563a80SStefano Zampini #endif 1690872cf891SStefano Zampini if (is->usesetlocal) { 1691872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1692872cf891SStefano Zampini } else { 16932e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 1694872cf891SStefano Zampini } 16952e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16962e74eeadSLisandro Dalcin } 16972e74eeadSLisandro Dalcin 1698a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 169997563a80SStefano Zampini { 170097563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 170197563a80SStefano Zampini PetscErrorCode ierr; 170297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 170397563a80SStefano Zampini PetscInt i,zm,zn; 170497563a80SStefano Zampini #endif 1705f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 170697563a80SStefano Zampini 170797563a80SStefano Zampini PetscFunctionBegin; 170897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1709f26d0771SStefano 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); 171097563a80SStefano Zampini /* count negative indices */ 171197563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 171297563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 171397563a80SStefano Zampini #endif 171497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 171597563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 171697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 171797563a80SStefano Zampini /* count negative indices (should be the same as before) */ 171897563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 171997563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 172097563a80SStefano 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"); 172197563a80SStefano 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"); 172297563a80SStefano Zampini #endif 172397563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 172497563a80SStefano Zampini PetscFunctionReturn(0); 172597563a80SStefano Zampini } 172697563a80SStefano Zampini 1727a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1728b4319ba4SBarry Smith { 1729dfbe8321SBarry Smith PetscErrorCode ierr; 1730b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1731b4319ba4SBarry Smith 1732b4319ba4SBarry Smith PetscFunctionBegin; 1733872cf891SStefano Zampini if (is->usesetlocal) { 1734872cf891SStefano Zampini ierr = MatSetValuesLocal(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1735872cf891SStefano Zampini } else { 1736b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1737872cf891SStefano Zampini } 1738b4319ba4SBarry Smith PetscFunctionReturn(0); 1739b4319ba4SBarry Smith } 1740b4319ba4SBarry Smith 1741a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1742f0006bf2SLisandro Dalcin { 1743f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1744f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1745f0006bf2SLisandro Dalcin 1746f0006bf2SLisandro Dalcin PetscFunctionBegin; 1747f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1748f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1749f0006bf2SLisandro Dalcin } 1750f0006bf2SLisandro Dalcin 1751f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 1752f0ae7da4SStefano Zampini { 1753f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1754f0ae7da4SStefano Zampini PetscErrorCode ierr; 1755f0ae7da4SStefano Zampini 1756f0ae7da4SStefano Zampini PetscFunctionBegin; 1757f0ae7da4SStefano Zampini if (!n) { 1758f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1759f0ae7da4SStefano Zampini } else { 1760f0ae7da4SStefano Zampini PetscInt i; 1761f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1762f0ae7da4SStefano Zampini 1763f0ae7da4SStefano Zampini if (columns) { 1764f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1765f0ae7da4SStefano Zampini } else { 1766f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1767f0ae7da4SStefano Zampini } 1768f0ae7da4SStefano Zampini if (diag != 0.) { 1769f0ae7da4SStefano Zampini const PetscScalar *array; 1770f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1771f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1772f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1773f0ae7da4SStefano Zampini } 1774f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1775f0ae7da4SStefano Zampini } 1776f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1777f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1778f0ae7da4SStefano Zampini } 1779f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1780f0ae7da4SStefano Zampini } 1781f0ae7da4SStefano Zampini 1782f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 17832e74eeadSLisandro Dalcin { 17846e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 17856e520ac8SStefano Zampini PetscInt nr,nl,len,i; 17866e520ac8SStefano Zampini PetscInt *lrows; 17872e74eeadSLisandro Dalcin PetscErrorCode ierr; 17882e74eeadSLisandro Dalcin 17892e74eeadSLisandro Dalcin PetscFunctionBegin; 1790f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1791f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1792f0ae7da4SStefano Zampini PetscBool cong; 1793f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1794*268753edSStefano Zampini cong = (cong && matis->sf == matis->csf); 1795*268753edSStefano Zampini if (!cong && columns) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Columns can be zeroed if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 1796*268753edSStefano Zampini if (!cong && diag != 0.) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Nonzero diagonal value supported if and only if A->rmap and A->cmap are congruent and the l2g maps are the same for MATIS"); 1797*268753edSStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent, and the l2g maps be the same"); 1798f0ae7da4SStefano Zampini } 1799f0ae7da4SStefano Zampini #endif 18006e520ac8SStefano Zampini /* get locally owned rows */ 1801f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 18026e520ac8SStefano Zampini /* fix right hand side if needed */ 18036e520ac8SStefano Zampini if (x && b) { 18046e520ac8SStefano Zampini const PetscScalar *xx; 18056e520ac8SStefano Zampini PetscScalar *bb; 18066e520ac8SStefano Zampini 18076e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 18086e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 18096e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 18106e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 18116e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 18122e74eeadSLisandro Dalcin } 18136e520ac8SStefano Zampini /* get rows associated to the local matrices */ 18143d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 18156e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 18166e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 18176e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 18186e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 18196e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18206e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18216e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18226e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 18236e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1824f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 18256e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18262e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18272e74eeadSLisandro Dalcin } 18282e74eeadSLisandro Dalcin 1829f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1830b4319ba4SBarry Smith { 1831dfbe8321SBarry Smith PetscErrorCode ierr; 1832b4319ba4SBarry Smith 1833b4319ba4SBarry Smith PetscFunctionBegin; 1834f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1835f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1836f0ae7da4SStefano Zampini } 18372205254eSKarl Rupp 1838f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1839f0ae7da4SStefano Zampini { 1840f0ae7da4SStefano Zampini PetscErrorCode ierr; 1841f0ae7da4SStefano Zampini 1842f0ae7da4SStefano Zampini PetscFunctionBegin; 1843f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1844b4319ba4SBarry Smith PetscFunctionReturn(0); 1845b4319ba4SBarry Smith } 1846b4319ba4SBarry Smith 1847a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1848b4319ba4SBarry Smith { 1849b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1850dfbe8321SBarry Smith PetscErrorCode ierr; 1851b4319ba4SBarry Smith 1852b4319ba4SBarry Smith PetscFunctionBegin; 1853b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1854b4319ba4SBarry Smith PetscFunctionReturn(0); 1855b4319ba4SBarry Smith } 1856b4319ba4SBarry Smith 1857a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1858b4319ba4SBarry Smith { 1859b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1860dfbe8321SBarry Smith PetscErrorCode ierr; 1861b4319ba4SBarry Smith 1862b4319ba4SBarry Smith PetscFunctionBegin; 1863b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1864872cf891SStefano Zampini /* fix for local empty rows/cols */ 1865872cf891SStefano Zampini if (is->locempty && type == MAT_FINAL_ASSEMBLY) { 1866872cf891SStefano Zampini Mat newlA; 1867872cf891SStefano Zampini ISLocalToGlobalMapping l2g; 1868872cf891SStefano Zampini IS tis; 1869872cf891SStefano Zampini const PetscScalar *v; 1870872cf891SStefano Zampini PetscInt i,n,cf,*loce,*locf; 1871872cf891SStefano Zampini PetscBool sym; 1872872cf891SStefano Zampini 1873872cf891SStefano Zampini ierr = MatGetRowMaxAbs(is->A,is->y,NULL);CHKERRQ(ierr); 1874872cf891SStefano Zampini ierr = MatIsSymmetric(is->A,PETSC_SMALL,&sym);CHKERRQ(ierr); 1875872cf891SStefano Zampini if (!sym) SETERRQ(PetscObjectComm((PetscObject)is->A),PETSC_ERR_SUP,"Not yet implemented for unsymmetric case"); 1876872cf891SStefano Zampini ierr = VecGetLocalSize(is->y,&n);CHKERRQ(ierr); 1877872cf891SStefano Zampini ierr = PetscMalloc1(n,&loce);CHKERRQ(ierr); 1878872cf891SStefano Zampini ierr = PetscMalloc1(n,&locf);CHKERRQ(ierr); 1879872cf891SStefano Zampini ierr = VecGetArrayRead(is->y,&v);CHKERRQ(ierr); 1880872cf891SStefano Zampini for (i=0,cf=0;i<n;i++) { 1881872cf891SStefano Zampini if (v[i] == 0.0) { 1882872cf891SStefano Zampini loce[i] = -1; 1883872cf891SStefano Zampini } else { 1884872cf891SStefano Zampini loce[i] = cf; 1885872cf891SStefano Zampini locf[cf++] = i; 1886872cf891SStefano Zampini } 1887872cf891SStefano Zampini } 1888872cf891SStefano Zampini ierr = VecRestoreArrayRead(is->y,&v);CHKERRQ(ierr); 1889872cf891SStefano Zampini /* extract valid submatrix */ 1890872cf891SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is->A),cf,locf,PETSC_USE_POINTER,&tis);CHKERRQ(ierr); 1891e5b89577SStefano Zampini ierr = MatCreateSubMatrix(is->A,tis,tis,MAT_INITIAL_MATRIX,&newlA);CHKERRQ(ierr); 1892872cf891SStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 1893872cf891SStefano Zampini /* attach local l2g map for successive calls of MatSetValues */ 1894872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)is->A),1,n,loce,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 1895872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(newlA,l2g,l2g);CHKERRQ(ierr); 1896872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 1897872cf891SStefano Zampini /* flag MatSetValues */ 1898872cf891SStefano Zampini is->usesetlocal = PETSC_TRUE; 1899872cf891SStefano Zampini /* attach new global l2g map */ 1900872cf891SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,cf,locf,locf);CHKERRQ(ierr); 1901872cf891SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)A),1,cf,locf,PETSC_OWN_POINTER,&l2g);CHKERRQ(ierr); 1902872cf891SStefano Zampini ierr = MatSetLocalToGlobalMapping(A,l2g,l2g);CHKERRQ(ierr); 1903872cf891SStefano Zampini ierr = MatISSetLocalMat(A,newlA);CHKERRQ(ierr); 1904872cf891SStefano Zampini ierr = MatDestroy(&newlA);CHKERRQ(ierr); 1905872cf891SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 1906872cf891SStefano Zampini } 1907872cf891SStefano Zampini is->locempty = PETSC_FALSE; 1908b4319ba4SBarry Smith PetscFunctionReturn(0); 1909b4319ba4SBarry Smith } 1910b4319ba4SBarry Smith 1911a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1912b4319ba4SBarry Smith { 1913b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1914b4319ba4SBarry Smith 1915b4319ba4SBarry Smith PetscFunctionBegin; 1916b4319ba4SBarry Smith *local = is->A; 1917b4319ba4SBarry Smith PetscFunctionReturn(0); 1918b4319ba4SBarry Smith } 1919b4319ba4SBarry Smith 19203b3b1effSJed Brown static PetscErrorCode MatISRestoreLocalMat_IS(Mat mat,Mat *local) 19213b3b1effSJed Brown { 19223b3b1effSJed Brown PetscFunctionBegin; 19233b3b1effSJed Brown *local = NULL; 19243b3b1effSJed Brown PetscFunctionReturn(0); 19253b3b1effSJed Brown } 19263b3b1effSJed Brown 1927b4319ba4SBarry Smith /*@ 1928b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1929b4319ba4SBarry Smith 1930b4319ba4SBarry Smith Input Parameter: 1931b4319ba4SBarry Smith . mat - the matrix 1932b4319ba4SBarry Smith 1933b4319ba4SBarry Smith Output Parameter: 1934eb82efa4SStefano Zampini . local - the local matrix 1935b4319ba4SBarry Smith 1936b4319ba4SBarry Smith Level: advanced 1937b4319ba4SBarry Smith 1938b4319ba4SBarry Smith Notes: 1939b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1940b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1941b4319ba4SBarry Smith of the MatSetValues() operation. 1942b4319ba4SBarry Smith 19433b3b1effSJed Brown Call MatISRestoreLocalMat() when finished with the local matrix. 194496a6f129SJed Brown 1945b4319ba4SBarry Smith .seealso: MATIS 1946b4319ba4SBarry Smith @*/ 19477087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1948b4319ba4SBarry Smith { 19494ac538c5SBarry Smith PetscErrorCode ierr; 1950b4319ba4SBarry Smith 1951b4319ba4SBarry Smith PetscFunctionBegin; 19520700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1953b4319ba4SBarry Smith PetscValidPointer(local,2); 19544ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1955b4319ba4SBarry Smith PetscFunctionReturn(0); 1956b4319ba4SBarry Smith } 1957b4319ba4SBarry Smith 19583b3b1effSJed Brown /*@ 19593b3b1effSJed Brown MatISRestoreLocalMat - Restores the local matrix obtained with MatISGetLocalMat() 19603b3b1effSJed Brown 19613b3b1effSJed Brown Input Parameter: 19623b3b1effSJed Brown . mat - the matrix 19633b3b1effSJed Brown 19643b3b1effSJed Brown Output Parameter: 19653b3b1effSJed Brown . local - the local matrix 19663b3b1effSJed Brown 19673b3b1effSJed Brown Level: advanced 19683b3b1effSJed Brown 19693b3b1effSJed Brown .seealso: MATIS 19703b3b1effSJed Brown @*/ 19713b3b1effSJed Brown PetscErrorCode MatISRestoreLocalMat(Mat mat,Mat *local) 19723b3b1effSJed Brown { 19733b3b1effSJed Brown PetscErrorCode ierr; 19743b3b1effSJed Brown 19753b3b1effSJed Brown PetscFunctionBegin; 19763b3b1effSJed Brown PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 19773b3b1effSJed Brown PetscValidPointer(local,2); 19783b3b1effSJed Brown ierr = PetscUseMethod(mat,"MatISRestoreLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 19793b3b1effSJed Brown PetscFunctionReturn(0); 19803b3b1effSJed Brown } 19813b3b1effSJed Brown 1982a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 19833b03a366Sstefano_zampini { 19843b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 19853b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 19863b03a366Sstefano_zampini PetscErrorCode ierr; 19873b03a366Sstefano_zampini 19883b03a366Sstefano_zampini PetscFunctionBegin; 19894e4c7dbeSStefano Zampini if (is->A) { 19903b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 19913b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1992f0ae7da4SStefano 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); 19934e4c7dbeSStefano Zampini } 19943b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 19953b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 19963b03a366Sstefano_zampini is->A = local; 19973b03a366Sstefano_zampini PetscFunctionReturn(0); 19983b03a366Sstefano_zampini } 19993b03a366Sstefano_zampini 20003b03a366Sstefano_zampini /*@ 2001eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 20023b03a366Sstefano_zampini 20033b03a366Sstefano_zampini Input Parameter: 20043b03a366Sstefano_zampini . mat - the matrix 2005eb82efa4SStefano Zampini . local - the local matrix 20063b03a366Sstefano_zampini 20073b03a366Sstefano_zampini Output Parameter: 20083b03a366Sstefano_zampini 20093b03a366Sstefano_zampini Level: advanced 20103b03a366Sstefano_zampini 20113b03a366Sstefano_zampini Notes: 20123b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 20133b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 20143b03a366Sstefano_zampini 20153b03a366Sstefano_zampini .seealso: MATIS 20163b03a366Sstefano_zampini @*/ 20173b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 20183b03a366Sstefano_zampini { 20193b03a366Sstefano_zampini PetscErrorCode ierr; 20203b03a366Sstefano_zampini 20213b03a366Sstefano_zampini PetscFunctionBegin; 20223b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2023b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 20243b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 20253b03a366Sstefano_zampini PetscFunctionReturn(0); 20263b03a366Sstefano_zampini } 20273b03a366Sstefano_zampini 2028a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 20296726f965SBarry Smith { 20306726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 20316726f965SBarry Smith PetscErrorCode ierr; 20326726f965SBarry Smith 20336726f965SBarry Smith PetscFunctionBegin; 20346726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 20356726f965SBarry Smith PetscFunctionReturn(0); 20366726f965SBarry Smith } 20376726f965SBarry Smith 2038a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 20392e74eeadSLisandro Dalcin { 20402e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 20412e74eeadSLisandro Dalcin PetscErrorCode ierr; 20422e74eeadSLisandro Dalcin 20432e74eeadSLisandro Dalcin PetscFunctionBegin; 20442e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 20452e74eeadSLisandro Dalcin PetscFunctionReturn(0); 20462e74eeadSLisandro Dalcin } 20472e74eeadSLisandro Dalcin 2048a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 20492e74eeadSLisandro Dalcin { 20502e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 20512e74eeadSLisandro Dalcin PetscErrorCode ierr; 20522e74eeadSLisandro Dalcin 20532e74eeadSLisandro Dalcin PetscFunctionBegin; 20542e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2055e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 20562e74eeadSLisandro Dalcin 20572e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 20582e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2059e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2060e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20612e74eeadSLisandro Dalcin PetscFunctionReturn(0); 20622e74eeadSLisandro Dalcin } 20632e74eeadSLisandro Dalcin 2064a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 20656726f965SBarry Smith { 20666726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 20676726f965SBarry Smith PetscErrorCode ierr; 20686726f965SBarry Smith 20696726f965SBarry Smith PetscFunctionBegin; 20704e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 20716726f965SBarry Smith PetscFunctionReturn(0); 20726726f965SBarry Smith } 20736726f965SBarry Smith 2074f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2075f26d0771SStefano Zampini { 2076f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2077f26d0771SStefano Zampini Mat_IS *x; 2078f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2079f26d0771SStefano Zampini PetscBool ismatis; 2080f26d0771SStefano Zampini #endif 2081f26d0771SStefano Zampini PetscErrorCode ierr; 2082f26d0771SStefano Zampini 2083f26d0771SStefano Zampini PetscFunctionBegin; 2084f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2085f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2086f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2087f26d0771SStefano Zampini #endif 2088f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2089f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2090f26d0771SStefano Zampini PetscFunctionReturn(0); 2091f26d0771SStefano Zampini } 2092f26d0771SStefano Zampini 2093f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2094f26d0771SStefano Zampini { 2095f26d0771SStefano Zampini Mat lA; 2096f26d0771SStefano Zampini Mat_IS *matis; 2097f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2098f26d0771SStefano Zampini IS is; 2099f26d0771SStefano Zampini const PetscInt *rg,*rl; 2100f26d0771SStefano Zampini PetscInt nrg; 2101f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2102f26d0771SStefano Zampini PetscErrorCode ierr; 2103f26d0771SStefano Zampini 2104f26d0771SStefano Zampini PetscFunctionBegin; 2105f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2106f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2107f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2108f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2109f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2110f0ae7da4SStefano 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); 2111f26d0771SStefano Zampini #endif 2112f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2113f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2114f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2115f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2116f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2117f26d0771SStefano Zampini #else 2118f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2119f26d0771SStefano Zampini #endif 2120f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2121f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2122f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2123f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2124f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2125f26d0771SStefano Zampini /* compute new l2g map for columns */ 2126f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2127f26d0771SStefano Zampini const PetscInt *cg,*cl; 2128f26d0771SStefano Zampini PetscInt ncg; 2129f26d0771SStefano Zampini PetscInt ncl; 2130f26d0771SStefano Zampini 2131f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2132f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2133f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2134f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2135f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2136f0ae7da4SStefano 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); 2137f26d0771SStefano Zampini #endif 2138f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2139f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2140f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2141f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2142f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2143f26d0771SStefano Zampini #else 2144f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2145f26d0771SStefano Zampini #endif 2146f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2147f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2148f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2149f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2150f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2151f26d0771SStefano Zampini } else { 2152f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2153f26d0771SStefano Zampini cl2g = rl2g; 2154f26d0771SStefano Zampini } 2155f26d0771SStefano Zampini /* create the MATIS submatrix */ 2156f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2157f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2158f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2159f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2160b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2161f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2162f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2163f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2164f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2165f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2166f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2167f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2168f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2169f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2170f26d0771SStefano Zampini /* remove unsupported ops */ 2171f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2172f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2173f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2174f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2175f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2176f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2177f26d0771SStefano Zampini PetscFunctionReturn(0); 2178f26d0771SStefano Zampini } 2179f26d0771SStefano Zampini 2180872cf891SStefano Zampini static PetscErrorCode MatSetFromOptions_IS(PetscOptionItems *PetscOptionsObject, Mat A) 2181872cf891SStefano Zampini { 2182872cf891SStefano Zampini Mat_IS *a = (Mat_IS*)A->data; 2183872cf891SStefano Zampini PetscErrorCode ierr; 2184872cf891SStefano Zampini 2185872cf891SStefano Zampini PetscFunctionBegin; 2186872cf891SStefano Zampini ierr = PetscOptionsHead(PetscOptionsObject,"MATIS options");CHKERRQ(ierr); 2187872cf891SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)A); 2188872cf891SStefano Zampini ierr = PetscOptionsBool("-matis_fixempty","Fix local matrices in case of empty local rows/columns",NULL,a->locempty,&a->locempty,NULL);CHKERRQ(ierr); 2189872cf891SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 2190872cf891SStefano Zampini PetscFunctionReturn(0); 2191872cf891SStefano Zampini } 2192872cf891SStefano Zampini 2193284134d9SBarry Smith /*@ 21943c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2195284134d9SBarry Smith process but not across processes. 2196284134d9SBarry Smith 2197284134d9SBarry Smith Input Parameters: 2198284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2199e176bc59SStefano Zampini . bs - block size of the matrix 2200df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2201e176bc59SStefano Zampini . rmap - local to global map for rows 2202e176bc59SStefano Zampini - cmap - local to global map for cols 2203284134d9SBarry Smith 2204284134d9SBarry Smith Output Parameter: 2205284134d9SBarry Smith . A - the resulting matrix 2206284134d9SBarry Smith 22078e6c10adSSatish Balay Level: advanced 22088e6c10adSSatish Balay 22093c212e90SHong Zhang Notes: See MATIS for more details. 22106fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 22116fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 22123c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2213284134d9SBarry Smith 2214284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2215284134d9SBarry Smith @*/ 2216e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2217284134d9SBarry Smith { 2218284134d9SBarry Smith PetscErrorCode ierr; 2219284134d9SBarry Smith 2220284134d9SBarry Smith PetscFunctionBegin; 22216fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2222284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 2223284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 22246fdf41d1SStefano Zampini if (bs > 0) { 2225284134d9SBarry Smith ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 22266fdf41d1SStefano Zampini } 2227284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2228e176bc59SStefano Zampini if (rmap && cmap) { 2229e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2230e176bc59SStefano Zampini } else if (!rmap) { 2231e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2232e176bc59SStefano Zampini } else { 2233e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2234e176bc59SStefano Zampini } 2235284134d9SBarry Smith PetscFunctionReturn(0); 2236284134d9SBarry Smith } 2237284134d9SBarry Smith 2238b4319ba4SBarry Smith /*MC 2239f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2240b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2241b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2242b4319ba4SBarry Smith product is handled "implicitly". 2243b4319ba4SBarry Smith 2244b4319ba4SBarry Smith Operations Provided: 22456726f965SBarry Smith + MatMult() 22462e74eeadSLisandro Dalcin . MatMultAdd() 22472e74eeadSLisandro Dalcin . MatMultTranspose() 22482e74eeadSLisandro Dalcin . MatMultTransposeAdd() 22496726f965SBarry Smith . MatZeroEntries() 22506726f965SBarry Smith . MatSetOption() 22512e74eeadSLisandro Dalcin . MatZeroRows() 22522e74eeadSLisandro Dalcin . MatSetValues() 225397563a80SStefano Zampini . MatSetValuesBlocked() 22546726f965SBarry Smith . MatSetValuesLocal() 225597563a80SStefano Zampini . MatSetValuesBlockedLocal() 22562e74eeadSLisandro Dalcin . MatScale() 22572e74eeadSLisandro Dalcin . MatGetDiagonal() 22582b404112SStefano Zampini . MatMissingDiagonal() 22592b404112SStefano Zampini . MatDuplicate() 22602b404112SStefano Zampini . MatCopy() 2261f26d0771SStefano Zampini . MatAXPY() 22627dae84e0SHong Zhang . MatCreateSubMatrix() 2263f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2264d7f69cd0SStefano Zampini . MatTranspose() 22656726f965SBarry Smith - MatSetLocalToGlobalMapping() 2266b4319ba4SBarry Smith 2267b4319ba4SBarry Smith Options Database Keys: 2268b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 2269b4319ba4SBarry Smith 2270b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 2271b4319ba4SBarry Smith 2272b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2273b4319ba4SBarry Smith 2274b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2275eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2276b4319ba4SBarry Smith 2277b4319ba4SBarry Smith Level: advanced 2278b4319ba4SBarry Smith 2279f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2280b4319ba4SBarry Smith 2281b4319ba4SBarry Smith M*/ 2282b4319ba4SBarry Smith 22838cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2284b4319ba4SBarry Smith { 2285dfbe8321SBarry Smith PetscErrorCode ierr; 2286b4319ba4SBarry Smith Mat_IS *b; 2287b4319ba4SBarry Smith 2288b4319ba4SBarry Smith PetscFunctionBegin; 2289b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2290b4319ba4SBarry Smith A->data = (void*)b; 2291b4319ba4SBarry Smith 2292e176bc59SStefano Zampini /* matrix ops */ 2293e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2294b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 22952e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 22962e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 22972e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2298b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2299b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 23002e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 230198921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2302b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2303f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 23042e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2305f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2306b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2307b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2308b4319ba4SBarry Smith A->ops->view = MatView_IS; 23096726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 23102e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 23112e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 23126726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 231369796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 231469796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 231545471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2316ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 23176bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 23182b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2319659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 23207dae84e0SHong Zhang A->ops->createsubmatrix = MatCreateSubMatrix_IS; 2321f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 23223fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 23233fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2324d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 23257fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 2326ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 2327872cf891SStefano Zampini A->ops->setfromoptions = MatSetFromOptions_IS; 2328b4319ba4SBarry Smith 2329b7ce53b6SStefano Zampini /* special MATIS functions */ 2330bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 23313b3b1effSJed Brown ierr = PetscObjectComposeFunction((PetscObject)A,"MatISRestoreLocalMat_C",MatISRestoreLocalMat_IS);CHKERRQ(ierr); 2332bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2333b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 23342e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2335cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 233617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2337b4319ba4SBarry Smith PetscFunctionReturn(0); 2338b4319ba4SBarry Smith } 2339