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 16cf0a3239SStefano Zampini #undef __FUNCT__ 175b003df0Sstefano_zampini #define __FUNCT__ "MatISContainerDestroyFields_Private" 185b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 195b003df0Sstefano_zampini { 205b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 215b003df0Sstefano_zampini PetscInt i; 225b003df0Sstefano_zampini PetscErrorCode ierr; 235b003df0Sstefano_zampini 245b003df0Sstefano_zampini PetscFunctionBeginUser; 255b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 265b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 275b003df0Sstefano_zampini } 285b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 295b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 305b003df0Sstefano_zampini } 315b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 325b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 335b003df0Sstefano_zampini PetscFunctionReturn(0); 345b003df0Sstefano_zampini } 35a72627d2SStefano Zampini 3628f4e0baSStefano Zampini #undef __FUNCT__ 375b003df0Sstefano_zampini #define __FUNCT__ "MatISContainerDestroyArray_Private" 385b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyArray_Private(void *ptr) 397fa8f2d3SStefano Zampini { 406989cf23SStefano Zampini PetscErrorCode ierr; 416989cf23SStefano Zampini 426989cf23SStefano Zampini PetscFunctionBeginUser; 436989cf23SStefano Zampini ierr = PetscFree(ptr);CHKERRQ(ierr); 446989cf23SStefano Zampini PetscFunctionReturn(0); 456989cf23SStefano Zampini } 466989cf23SStefano Zampini 476989cf23SStefano Zampini #undef __FUNCT__ 486989cf23SStefano Zampini #define __FUNCT__ "MatConvert_MPIAIJ_IS" 496989cf23SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 506989cf23SStefano Zampini { 516989cf23SStefano Zampini Mat_MPIAIJ *aij = (Mat_MPIAIJ*)A->data; 526989cf23SStefano Zampini Mat_SeqAIJ *diag = (Mat_SeqAIJ*)(aij->A->data); 536989cf23SStefano Zampini Mat_SeqAIJ *offd = (Mat_SeqAIJ*)(aij->B->data); 546989cf23SStefano Zampini Mat lA; 556989cf23SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 566989cf23SStefano Zampini IS is; 576989cf23SStefano Zampini MPI_Comm comm; 586989cf23SStefano Zampini void *ptrs[2]; 596989cf23SStefano Zampini const char *names[2] = {"_convert_csr_aux","_convert_csr_data"}; 606989cf23SStefano Zampini PetscScalar *dd,*od,*aa,*data; 616989cf23SStefano Zampini PetscInt *di,*dj,*oi,*oj; 626989cf23SStefano Zampini PetscInt *aux,*ii,*jj; 63e363d98aSStefano Zampini PetscInt lc,dr,dc,oc,str,stc,nnz,i,jd,jo,cum; 646989cf23SStefano Zampini PetscErrorCode ierr; 656989cf23SStefano Zampini 666989cf23SStefano Zampini PetscFunctionBeginUser; 676989cf23SStefano Zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 686989cf23SStefano Zampini if (!aij->garray) SETERRQ(comm,PETSC_ERR_SUP,"garray not present"); 696989cf23SStefano Zampini 706989cf23SStefano Zampini /* access relevant information from MPIAIJ */ 716989cf23SStefano Zampini ierr = MatGetOwnershipRange(A,&str,NULL);CHKERRQ(ierr); 726989cf23SStefano Zampini ierr = MatGetOwnershipRangeColumn(A,&stc,NULL);CHKERRQ(ierr); 736989cf23SStefano Zampini ierr = MatGetLocalSize(A,&dr,&dc);CHKERRQ(ierr); 746989cf23SStefano Zampini di = diag->i; 756989cf23SStefano Zampini dj = diag->j; 766989cf23SStefano Zampini dd = diag->a; 776989cf23SStefano Zampini oc = aij->B->cmap->n; 786989cf23SStefano Zampini oi = offd->i; 796989cf23SStefano Zampini oj = offd->j; 806989cf23SStefano Zampini od = offd->a; 816989cf23SStefano Zampini nnz = diag->i[dr] + offd->i[dr]; 826989cf23SStefano Zampini 836989cf23SStefano Zampini /* generate l2g maps for rows and cols */ 846989cf23SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 856989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 866989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 87e363d98aSStefano Zampini if (dr) { 886989cf23SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 896989cf23SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 906989cf23SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = aij->garray[i]; 916989cf23SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 92e363d98aSStefano Zampini lc = dc+oc; 93e363d98aSStefano Zampini } else { 94e363d98aSStefano Zampini ierr = ISCreateGeneral(comm,0,NULL,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 95e363d98aSStefano Zampini lc = 0; 96e363d98aSStefano Zampini } 976989cf23SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 986989cf23SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 996989cf23SStefano Zampini 1006989cf23SStefano Zampini /* create MATIS object */ 1016989cf23SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 1026989cf23SStefano Zampini ierr = MatSetSizes(*newmat,dr,dc,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1036989cf23SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 1046989cf23SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 1056989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1066989cf23SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1076989cf23SStefano Zampini 1086989cf23SStefano Zampini /* merge local matrices */ 1096989cf23SStefano Zampini ierr = PetscMalloc1(nnz+dr+1,&aux);CHKERRQ(ierr); 1106989cf23SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 1116989cf23SStefano Zampini ii = aux; 1126989cf23SStefano Zampini jj = aux+dr+1; 1136989cf23SStefano Zampini aa = data; 1146989cf23SStefano Zampini *ii = *(di++) + *(oi++); 1156989cf23SStefano Zampini for (jd=0,jo=0,cum=0;*ii<nnz;cum++) 1166989cf23SStefano Zampini { 1176989cf23SStefano Zampini for (;jd<*di;jd++) { *jj++ = *dj++; *aa++ = *dd++; } 1186989cf23SStefano Zampini for (;jo<*oi;jo++) { *jj++ = *oj++ + dc; *aa++ = *od++; } 1196989cf23SStefano Zampini *(++ii) = *(di++) + *(oi++); 1206989cf23SStefano Zampini } 1216989cf23SStefano Zampini for (;cum<dr;cum++) *(++ii) = nnz; 1226989cf23SStefano Zampini ii = aux; 1236989cf23SStefano Zampini jj = aux+dr+1; 1246989cf23SStefano Zampini aa = data; 125e363d98aSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,lc,ii,jj,aa,&lA);CHKERRQ(ierr); 1266989cf23SStefano Zampini 1276989cf23SStefano Zampini /* create containers to destroy the data */ 1286989cf23SStefano Zampini ptrs[0] = aux; 1296989cf23SStefano Zampini ptrs[1] = data; 1306989cf23SStefano Zampini for (i=0; i<2; i++) { 1316989cf23SStefano Zampini PetscContainer c; 1326989cf23SStefano Zampini 1336989cf23SStefano Zampini ierr = PetscContainerCreate(PETSC_COMM_SELF,&c);CHKERRQ(ierr); 1346989cf23SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 1355b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyArray_Private);CHKERRQ(ierr); 1366989cf23SStefano Zampini ierr = PetscObjectCompose((PetscObject)lA,names[i],(PetscObject)c);CHKERRQ(ierr); 1376989cf23SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 1386989cf23SStefano Zampini } 1396989cf23SStefano Zampini 1406989cf23SStefano Zampini /* finalize matrix */ 1416989cf23SStefano Zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 1426989cf23SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 1436989cf23SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1446989cf23SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1456989cf23SStefano Zampini PetscFunctionReturn(0); 1466989cf23SStefano Zampini } 1476989cf23SStefano Zampini 1486989cf23SStefano Zampini #undef __FUNCT__ 149cf0a3239SStefano Zampini #define __FUNCT__ "MatISSetUpSF" 150cf0a3239SStefano Zampini /*@ 1513d996552SStefano Zampini MatISSetUpSF - Setup star forest objects used by MatIS. 152cf0a3239SStefano Zampini 153cf0a3239SStefano Zampini Collective on MPI_Comm 154cf0a3239SStefano Zampini 155cf0a3239SStefano Zampini Input Parameters: 156cf0a3239SStefano Zampini + A - the matrix 157cf0a3239SStefano Zampini 158cf0a3239SStefano Zampini Level: advanced 159cf0a3239SStefano Zampini 1603d996552SStefano Zampini Notes: This function does not need to be called by the user. 161cf0a3239SStefano Zampini 162cf0a3239SStefano Zampini .keywords: matrix 163cf0a3239SStefano Zampini 164cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 165cf0a3239SStefano Zampini @*/ 166cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 167cf0a3239SStefano Zampini { 1687fa8f2d3SStefano Zampini PetscErrorCode ierr; 1697fa8f2d3SStefano Zampini 1707fa8f2d3SStefano Zampini PetscFunctionBegin; 171cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 172cf0a3239SStefano Zampini PetscValidType(A,1); 173cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 1747fa8f2d3SStefano Zampini PetscFunctionReturn(0); 1757fa8f2d3SStefano Zampini } 1767fa8f2d3SStefano Zampini 1777fa8f2d3SStefano Zampini #undef __FUNCT__ 1785e3038f0Sstefano_zampini #define __FUNCT__ "MatConvert_Nest_IS" 1795e3038f0Sstefano_zampini PETSC_INTERN PetscErrorCode MatConvert_Nest_IS(Mat A,MatType type,MatReuse reuse,Mat *newmat) 1805e3038f0Sstefano_zampini { 1815e3038f0Sstefano_zampini Mat **nest,*snest,**rnest,lA,B; 1825e3038f0Sstefano_zampini IS *iscol,*isrow,*islrow,*islcol; 1835e3038f0Sstefano_zampini ISLocalToGlobalMapping rl2g,cl2g; 1845e3038f0Sstefano_zampini MPI_Comm comm; 1855b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 1865b003df0Sstefano_zampini PetscInt i,j,nr,nc,rbs,cbs; 1879e7b2b25Sstefano_zampini PetscBool convert,lreuse,*istrans; 1885e3038f0Sstefano_zampini PetscErrorCode ierr; 1895e3038f0Sstefano_zampini 1905e3038f0Sstefano_zampini PetscFunctionBeginUser; 1915e3038f0Sstefano_zampini ierr = MatNestGetSubMats(A,&nr,&nc,&nest);CHKERRQ(ierr); 1925e3038f0Sstefano_zampini lreuse = PETSC_FALSE; 1935e3038f0Sstefano_zampini rnest = NULL; 1945e3038f0Sstefano_zampini if (reuse == MAT_REUSE_MATRIX) { 1955e3038f0Sstefano_zampini PetscBool ismatis,isnest; 1965e3038f0Sstefano_zampini 1975e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 1985e3038f0Sstefano_zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 1995e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 2005e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)lA,MATNEST,&isnest);CHKERRQ(ierr); 2015e3038f0Sstefano_zampini if (isnest) { 2025e3038f0Sstefano_zampini ierr = MatNestGetSubMats(lA,&i,&j,&rnest);CHKERRQ(ierr); 2035e3038f0Sstefano_zampini lreuse = (PetscBool)(i == nr && j == nc); 2045e3038f0Sstefano_zampini if (!lreuse) rnest = NULL; 2055e3038f0Sstefano_zampini } 2065e3038f0Sstefano_zampini } 2075e3038f0Sstefano_zampini ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 2085b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lr,nc,&lc);CHKERRQ(ierr); 2099e7b2b25Sstefano_zampini ierr = PetscCalloc6(nr,&isrow,nc,&iscol, 2105e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 2119e7b2b25Sstefano_zampini nr*nc,&snest,nr*nc,&istrans);CHKERRQ(ierr); 2125e3038f0Sstefano_zampini ierr = MatNestGetISs(A,isrow,iscol);CHKERRQ(ierr); 2135e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 2145e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 2155e3038f0Sstefano_zampini PetscBool ismatis; 2169e7b2b25Sstefano_zampini PetscInt l1,l2,lb1,lb2,ij=i*nc+j; 2175e3038f0Sstefano_zampini 2185e3038f0Sstefano_zampini /* Null matrix pointers are allowed in MATNEST */ 2195e3038f0Sstefano_zampini if (!nest[i][j]) continue; 2205e3038f0Sstefano_zampini 2215e3038f0Sstefano_zampini /* Nested matrices should be of type MATIS */ 2229e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATTRANSPOSEMAT,&istrans[ij]);CHKERRQ(ierr); 2239e7b2b25Sstefano_zampini if (istrans[ij]) { 2249e7b2b25Sstefano_zampini Mat T,lT; 2259e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 2269e7b2b25Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)T,MATIS,&ismatis);CHKERRQ(ierr); 2279e7b2b25Sstefano_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); 2289e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 2299e7b2b25Sstefano_zampini ierr = MatCreateTranspose(lT,&snest[ij]);CHKERRQ(ierr); 2309e7b2b25Sstefano_zampini } else { 2315e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 2325e3038f0Sstefano_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); 2339e7b2b25Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 2349e7b2b25Sstefano_zampini } 2355e3038f0Sstefano_zampini 2365e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 2375e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 2389e7b2b25Sstefano_zampini ierr = MatGetBlockSizes(snest[ij],&lb1,&lb2);CHKERRQ(ierr); 2395e3038f0Sstefano_zampini if (!l1 || !l2) continue; 2405e3038f0Sstefano_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); 2415e3038f0Sstefano_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); 2425e3038f0Sstefano_zampini lr[i] = l1; 2435e3038f0Sstefano_zampini lc[j] = l2; 2445e3038f0Sstefano_zampini 2455e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 2465e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 2475e3038f0Sstefano_zampini } 2485e3038f0Sstefano_zampini } 2495e3038f0Sstefano_zampini 2505e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 2515e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 2525e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 2535e3038f0Sstefano_zampini rl2g = NULL; 2545e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 2555e3038f0Sstefano_zampini PetscInt n1,n2; 2565e3038f0Sstefano_zampini 2575e3038f0Sstefano_zampini if (!nest[i][j]) continue; 2589e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 2599e7b2b25Sstefano_zampini Mat T; 2609e7b2b25Sstefano_zampini 2619e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[i][j],&T);CHKERRQ(ierr); 2629e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,NULL,&cl2g);CHKERRQ(ierr); 2639e7b2b25Sstefano_zampini } else { 2645e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 2659e7b2b25Sstefano_zampini } 2665e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 2675e3038f0Sstefano_zampini if (!n1) continue; 2685e3038f0Sstefano_zampini if (!rl2g) { 2695e3038f0Sstefano_zampini rl2g = cl2g; 2705e3038f0Sstefano_zampini } else { 2715e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 2725e3038f0Sstefano_zampini PetscBool same; 2735e3038f0Sstefano_zampini 2745e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 2755e3038f0Sstefano_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); 2765e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 2775e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 2785e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 2795e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 2805e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 2815e3038f0Sstefano_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); 2825e3038f0Sstefano_zampini } 2835e3038f0Sstefano_zampini } 2845e3038f0Sstefano_zampini } 2855e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 2865e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 2875e3038f0Sstefano_zampini rl2g = NULL; 2885e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 2895e3038f0Sstefano_zampini PetscInt n1,n2; 2905e3038f0Sstefano_zampini 2915e3038f0Sstefano_zampini if (!nest[j][i]) continue; 2929e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 2939e7b2b25Sstefano_zampini Mat T; 2949e7b2b25Sstefano_zampini 2959e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(nest[j][i],&T);CHKERRQ(ierr); 2969e7b2b25Sstefano_zampini ierr = MatGetLocalToGlobalMapping(T,&cl2g,NULL);CHKERRQ(ierr); 2979e7b2b25Sstefano_zampini } else { 2985e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 2999e7b2b25Sstefano_zampini } 3005e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 3015e3038f0Sstefano_zampini if (!n1) continue; 3025e3038f0Sstefano_zampini if (!rl2g) { 3035e3038f0Sstefano_zampini rl2g = cl2g; 3045e3038f0Sstefano_zampini } else { 3055e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 3065e3038f0Sstefano_zampini PetscBool same; 3075e3038f0Sstefano_zampini 3085e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 3095e3038f0Sstefano_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); 3105e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 3115e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 3125e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 3135e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 3145e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 3155e3038f0Sstefano_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); 3165e3038f0Sstefano_zampini } 3175e3038f0Sstefano_zampini } 3185e3038f0Sstefano_zampini } 3195e3038f0Sstefano_zampini #endif 3205e3038f0Sstefano_zampini 3215e3038f0Sstefano_zampini B = NULL; 3225e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 3235b003df0Sstefano_zampini PetscInt stl; 3245b003df0Sstefano_zampini 3255e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 3265e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 3275e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3285b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 3295e3038f0Sstefano_zampini Mat usedmat; 3305e3038f0Sstefano_zampini Mat_IS *matis; 3315e3038f0Sstefano_zampini const PetscInt *idxs; 3325e3038f0Sstefano_zampini 3335e3038f0Sstefano_zampini /* local IS for local NEST */ 3345b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 3355e3038f0Sstefano_zampini 3365e3038f0Sstefano_zampini /* l2gmap */ 3375e3038f0Sstefano_zampini j = 0; 3385e3038f0Sstefano_zampini usedmat = nest[i][j]; 3399e7b2b25Sstefano_zampini while (!usedmat && j < nc-1) usedmat = nest[i][++j]; 3409e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid row mat"); 3419e7b2b25Sstefano_zampini 3429e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 3439e7b2b25Sstefano_zampini Mat T; 3449e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 3459e7b2b25Sstefano_zampini usedmat = T; 3469e7b2b25Sstefano_zampini } 34782d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3485e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3495e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 3509e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 3519e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3529e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3539e7b2b25Sstefano_zampini } else { 3545e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3555e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3569e7b2b25Sstefano_zampini } 3575e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 3585e3038f0Sstefano_zampini stl += lr[i]; 3595e3038f0Sstefano_zampini } 3605e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 3615e3038f0Sstefano_zampini 3625e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 3635e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 3645e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3655b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 3665e3038f0Sstefano_zampini Mat usedmat; 3675e3038f0Sstefano_zampini Mat_IS *matis; 3685e3038f0Sstefano_zampini const PetscInt *idxs; 3695e3038f0Sstefano_zampini 3705e3038f0Sstefano_zampini /* local IS for local NEST */ 3715b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 3725e3038f0Sstefano_zampini 3735e3038f0Sstefano_zampini /* l2gmap */ 3745e3038f0Sstefano_zampini j = 0; 3755e3038f0Sstefano_zampini usedmat = nest[j][i]; 3769e7b2b25Sstefano_zampini while (!usedmat && j < nr-1) usedmat = nest[++j][i]; 3779e7b2b25Sstefano_zampini if (!usedmat) SETERRQ(comm,PETSC_ERR_SUP,"Cannot find valid column mat"); 3789e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 3799e7b2b25Sstefano_zampini Mat T; 3809e7b2b25Sstefano_zampini ierr = MatTransposeGetMat(usedmat,&T);CHKERRQ(ierr); 3819e7b2b25Sstefano_zampini usedmat = T; 3829e7b2b25Sstefano_zampini } 38382d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3845e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3855e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 3869e7b2b25Sstefano_zampini if (istrans[j*nc+i]) { 3879e7b2b25Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3889e7b2b25Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3899e7b2b25Sstefano_zampini } else { 3905e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3915e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3929e7b2b25Sstefano_zampini } 3935e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 3945e3038f0Sstefano_zampini stl += lc[i]; 3955e3038f0Sstefano_zampini } 3965e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 3975e3038f0Sstefano_zampini 3985e3038f0Sstefano_zampini /* Create MATIS */ 3995e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 4005e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 4015e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 4025e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 4035e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 4045e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 4055e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 4065e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 4075e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 4089e7b2b25Sstefano_zampini for (i=0;i<nr*nc;i++) { 4099e7b2b25Sstefano_zampini if (istrans[i]) { 4109e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 4119e7b2b25Sstefano_zampini } 4129e7b2b25Sstefano_zampini } 4135e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 4145e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 4155e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4165e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4175e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 4185e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 4195e3038f0Sstefano_zampini } else { 4205e3038f0Sstefano_zampini *newmat = B; 4215e3038f0Sstefano_zampini } 4225e3038f0Sstefano_zampini } else { 4235e3038f0Sstefano_zampini if (lreuse) { 4245e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4255e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4265e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 4275e3038f0Sstefano_zampini if (snest[i*nc+j]) { 4285e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 4299e7b2b25Sstefano_zampini if (istrans[i*nc+j]) { 4309e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i*nc+j]);CHKERRQ(ierr); 4319e7b2b25Sstefano_zampini } 4325e3038f0Sstefano_zampini } 4335e3038f0Sstefano_zampini } 4345e3038f0Sstefano_zampini } 4355e3038f0Sstefano_zampini } else { 4365b003df0Sstefano_zampini PetscInt stl; 4375b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 4385b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 4395b003df0Sstefano_zampini stl += lr[i]; 4405e3038f0Sstefano_zampini } 4415b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 4425b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 4435b003df0Sstefano_zampini stl += lc[i]; 4445e3038f0Sstefano_zampini } 4455e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 4469e7b2b25Sstefano_zampini if (istrans[i]) { 4479e7b2b25Sstefano_zampini ierr = MatDestroy(&snest[i]);CHKERRQ(ierr); 4489e7b2b25Sstefano_zampini } 4495e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 4505e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 4515e3038f0Sstefano_zampini } 4525e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4535e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4545e3038f0Sstefano_zampini } 4555e3038f0Sstefano_zampini 4565b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 4575b003df0Sstefano_zampini convert = PETSC_FALSE; 4585b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 4595b003df0Sstefano_zampini if (convert) { 4605b003df0Sstefano_zampini Mat M; 4615b003df0Sstefano_zampini MatISLocalFields lf; 4625b003df0Sstefano_zampini PetscContainer c; 4635b003df0Sstefano_zampini 4645b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4655b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 4665b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 4675b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4685b003df0Sstefano_zampini 4695b003df0Sstefano_zampini /* attach local fields to the matrix */ 4705b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 4715b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 4725b003df0Sstefano_zampini for (i=0;i<nr;i++) { 4735b003df0Sstefano_zampini PetscInt n,st; 4745b003df0Sstefano_zampini 4755b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 4765b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 4775b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 4785b003df0Sstefano_zampini } 4795b003df0Sstefano_zampini for (i=0;i<nc;i++) { 4805b003df0Sstefano_zampini PetscInt n,st; 4815b003df0Sstefano_zampini 4825b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 4835b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 4845b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 4855b003df0Sstefano_zampini } 4865b003df0Sstefano_zampini lf->nr = nr; 4875b003df0Sstefano_zampini lf->nc = nc; 4885b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 4895b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 4905b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 4915b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 4925b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 4935b003df0Sstefano_zampini } 4945b003df0Sstefano_zampini 4955e3038f0Sstefano_zampini /* Free workspace */ 4965e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4975e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 4985e3038f0Sstefano_zampini } 4995e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 5005e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 5015e3038f0Sstefano_zampini } 5029e7b2b25Sstefano_zampini ierr = PetscFree6(isrow,iscol,islrow,islcol,snest,istrans);CHKERRQ(ierr); 5035b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 5045e3038f0Sstefano_zampini PetscFunctionReturn(0); 5055e3038f0Sstefano_zampini } 5065e3038f0Sstefano_zampini 5075e3038f0Sstefano_zampini #undef __FUNCT__ 508ad219c80Sstefano_zampini #define __FUNCT__ "MatDiagonalScale_IS" 509ad219c80Sstefano_zampini static PetscErrorCode MatDiagonalScale_IS(Mat A, Vec l, Vec r) 510ad219c80Sstefano_zampini { 511ad219c80Sstefano_zampini Mat_IS *matis = (Mat_IS*)A->data; 512ad219c80Sstefano_zampini Vec ll,rr; 513ad219c80Sstefano_zampini const PetscScalar *Y,*X; 514ad219c80Sstefano_zampini PetscScalar *x,*y; 515ad219c80Sstefano_zampini PetscErrorCode ierr; 516ad219c80Sstefano_zampini 517ad219c80Sstefano_zampini PetscFunctionBegin; 518ad219c80Sstefano_zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 519ad219c80Sstefano_zampini if (l) { 520ad219c80Sstefano_zampini ll = matis->y; 521ad219c80Sstefano_zampini ierr = VecGetArrayRead(l,&Y);CHKERRQ(ierr); 522ad219c80Sstefano_zampini ierr = VecGetArray(ll,&y);CHKERRQ(ierr); 523ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 524ad219c80Sstefano_zampini } else { 525ad219c80Sstefano_zampini ll = NULL; 526ad219c80Sstefano_zampini } 527ad219c80Sstefano_zampini if (r) { 528ad219c80Sstefano_zampini rr = matis->x; 529ad219c80Sstefano_zampini ierr = VecGetArrayRead(r,&X);CHKERRQ(ierr); 530ad219c80Sstefano_zampini ierr = VecGetArray(rr,&x);CHKERRQ(ierr); 531ad219c80Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 532ad219c80Sstefano_zampini } else { 533ad219c80Sstefano_zampini rr = NULL; 534ad219c80Sstefano_zampini } 535ad219c80Sstefano_zampini if (ll) { 536ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_SCALAR,Y,y);CHKERRQ(ierr); 537ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(l,&Y);CHKERRQ(ierr); 538ad219c80Sstefano_zampini ierr = VecRestoreArray(ll,&y);CHKERRQ(ierr); 539ad219c80Sstefano_zampini } 540ad219c80Sstefano_zampini if (rr) { 541ad219c80Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_SCALAR,X,x);CHKERRQ(ierr); 542ad219c80Sstefano_zampini ierr = VecRestoreArrayRead(r,&X);CHKERRQ(ierr); 543ad219c80Sstefano_zampini ierr = VecRestoreArray(rr,&x);CHKERRQ(ierr); 544ad219c80Sstefano_zampini } 545ad219c80Sstefano_zampini ierr = MatDiagonalScale(matis->A,ll,rr);CHKERRQ(ierr); 546ad219c80Sstefano_zampini PetscFunctionReturn(0); 547ad219c80Sstefano_zampini } 548ad219c80Sstefano_zampini 549ad219c80Sstefano_zampini #undef __FUNCT__ 550b4319ba4SBarry Smith #define __FUNCT__ "MatGetInfo_IS" 551b4319ba4SBarry Smith static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 552b4319ba4SBarry Smith { 553b4319ba4SBarry Smith Mat_IS *matis = (Mat_IS*)A->data; 554b4319ba4SBarry Smith MatInfo info; 555b4319ba4SBarry Smith PetscReal isend[6],irecv[6]; 556b4319ba4SBarry Smith PetscInt bs; 557b4319ba4SBarry Smith PetscErrorCode ierr; 558b4319ba4SBarry Smith 559b4319ba4SBarry Smith PetscFunctionBegin; 560b4319ba4SBarry Smith ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 561b4319ba4SBarry Smith if (matis->A->ops->getinfo) { 562b4319ba4SBarry Smith ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 563b4319ba4SBarry Smith isend[0] = info.nz_used; 564b4319ba4SBarry Smith isend[1] = info.nz_allocated; 565b4319ba4SBarry Smith isend[2] = info.nz_unneeded; 566b4319ba4SBarry Smith isend[3] = info.memory; 567b4319ba4SBarry Smith isend[4] = info.mallocs; 568b4319ba4SBarry Smith } else { 569b4319ba4SBarry Smith isend[0] = 0.; 570b4319ba4SBarry Smith isend[1] = 0.; 571b4319ba4SBarry Smith isend[2] = 0.; 572b4319ba4SBarry Smith isend[3] = 0.; 573b4319ba4SBarry Smith isend[4] = 0.; 574b4319ba4SBarry Smith } 575b4319ba4SBarry Smith isend[5] = matis->A->num_ass; 576b4319ba4SBarry Smith if (flag == MAT_LOCAL) { 577b4319ba4SBarry Smith ginfo->nz_used = isend[0]; 578b4319ba4SBarry Smith ginfo->nz_allocated = isend[1]; 579b4319ba4SBarry Smith ginfo->nz_unneeded = isend[2]; 580b4319ba4SBarry Smith ginfo->memory = isend[3]; 581b4319ba4SBarry Smith ginfo->mallocs = isend[4]; 582b4319ba4SBarry Smith ginfo->assemblies = isend[5]; 583b4319ba4SBarry Smith } else if (flag == MAT_GLOBAL_MAX) { 584b4319ba4SBarry Smith ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 585b4319ba4SBarry Smith 586b4319ba4SBarry Smith ginfo->nz_used = irecv[0]; 587b4319ba4SBarry Smith ginfo->nz_allocated = irecv[1]; 588b4319ba4SBarry Smith ginfo->nz_unneeded = irecv[2]; 589b4319ba4SBarry Smith ginfo->memory = irecv[3]; 590b4319ba4SBarry Smith ginfo->mallocs = irecv[4]; 591b4319ba4SBarry Smith ginfo->assemblies = irecv[5]; 592b4319ba4SBarry Smith } else if (flag == MAT_GLOBAL_SUM) { 593b4319ba4SBarry Smith ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 594b4319ba4SBarry Smith 595b4319ba4SBarry Smith ginfo->nz_used = irecv[0]; 596b4319ba4SBarry Smith ginfo->nz_allocated = irecv[1]; 597b4319ba4SBarry Smith ginfo->nz_unneeded = irecv[2]; 598b4319ba4SBarry Smith ginfo->memory = irecv[3]; 599b4319ba4SBarry Smith ginfo->mallocs = irecv[4]; 600b4319ba4SBarry Smith ginfo->assemblies = A->num_ass; 601b4319ba4SBarry Smith } 602b4319ba4SBarry Smith ginfo->block_size = bs; 603b4319ba4SBarry Smith ginfo->fill_ratio_given = 0; 604b4319ba4SBarry Smith ginfo->fill_ratio_needed = 0; 605b4319ba4SBarry Smith ginfo->factor_mallocs = 0; 606a8116848SStefano Zampini PetscFunctionReturn(0); 607a8116848SStefano Zampini } 608a8116848SStefano Zampini 609a8116848SStefano Zampini #undef __FUNCT__ 610b4319ba4SBarry Smith #define __FUNCT__ "MatTranspose_IS" 611b4319ba4SBarry Smith PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 612b4319ba4SBarry Smith { 613b4319ba4SBarry Smith Mat C,lC,lA; 614b4319ba4SBarry Smith PetscErrorCode ierr; 615b4319ba4SBarry Smith 616b4319ba4SBarry Smith PetscFunctionBegin; 617*cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 618*cf37664fSBarry Smith ISLocalToGlobalMapping rl2g,cl2g; 619b4319ba4SBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 620b4319ba4SBarry Smith ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 621b4319ba4SBarry Smith ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 622b4319ba4SBarry Smith ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 623b4319ba4SBarry Smith ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 624b4319ba4SBarry Smith ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 625*cf37664fSBarry Smith } else { 626*cf37664fSBarry Smith C = *B; 627b4319ba4SBarry Smith } 628b4319ba4SBarry Smith 629b4319ba4SBarry Smith /* perform local transposition */ 630b4319ba4SBarry Smith ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 631b4319ba4SBarry Smith ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 632b4319ba4SBarry Smith ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 633b4319ba4SBarry Smith ierr = MatDestroy(&lC);CHKERRQ(ierr); 634b4319ba4SBarry Smith 635*cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 636b4319ba4SBarry Smith *B = C; 637b4319ba4SBarry Smith } else { 638b4319ba4SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 639b4319ba4SBarry Smith } 640b4319ba4SBarry Smith PetscFunctionReturn(0); 641b4319ba4SBarry Smith } 642b4319ba4SBarry Smith 643b4319ba4SBarry Smith #undef __FUNCT__ 644b4319ba4SBarry Smith #define __FUNCT__ "MatDiagonalSet_IS" 645b4319ba4SBarry Smith PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 646b4319ba4SBarry Smith { 647b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 648b4319ba4SBarry Smith PetscErrorCode ierr; 649b4319ba4SBarry Smith 650b4319ba4SBarry Smith PetscFunctionBegin; 651b4319ba4SBarry Smith if (!D) { /* this code branch is used by MatShift_IS */ 652b4319ba4SBarry Smith ierr = VecSet(is->y,1.);CHKERRQ(ierr); 653b4319ba4SBarry Smith } else { 654b4319ba4SBarry Smith ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 655b4319ba4SBarry Smith ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 656b4319ba4SBarry Smith } 657b4319ba4SBarry Smith ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 658b4319ba4SBarry Smith ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 659b4319ba4SBarry Smith PetscFunctionReturn(0); 660b4319ba4SBarry Smith } 661b4319ba4SBarry Smith 662b4319ba4SBarry Smith #undef __FUNCT__ 663b4319ba4SBarry Smith #define __FUNCT__ "MatShift_IS" 664b4319ba4SBarry Smith PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 665b4319ba4SBarry Smith { 666b4319ba4SBarry Smith PetscErrorCode ierr; 667b4319ba4SBarry Smith 668b4319ba4SBarry Smith PetscFunctionBegin; 669b4319ba4SBarry Smith ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 670b4319ba4SBarry Smith PetscFunctionReturn(0); 671b4319ba4SBarry Smith } 672b4319ba4SBarry Smith 673b4319ba4SBarry Smith #undef __FUNCT__ 674b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_SubMat_IS" 675b4319ba4SBarry Smith static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 676b4319ba4SBarry Smith { 677b4319ba4SBarry Smith PetscErrorCode ierr; 678b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 679b4319ba4SBarry Smith PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 680b4319ba4SBarry Smith 681b4319ba4SBarry Smith PetscFunctionBegin; 682b4319ba4SBarry Smith #if defined(PETSC_USE_DEBUG) 683b4319ba4SBarry Smith 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); 684b4319ba4SBarry Smith #endif 685b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 686b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 687b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 688b4319ba4SBarry Smith PetscFunctionReturn(0); 689b4319ba4SBarry Smith } 690b4319ba4SBarry Smith 691b4319ba4SBarry Smith #undef __FUNCT__ 692b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesBlockedLocal_SubMat_IS" 693b4319ba4SBarry Smith static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 694b4319ba4SBarry Smith { 695b4319ba4SBarry Smith PetscErrorCode ierr; 696b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 697b4319ba4SBarry Smith PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 698b4319ba4SBarry Smith 699b4319ba4SBarry Smith PetscFunctionBegin; 700b4319ba4SBarry Smith #if defined(PETSC_USE_DEBUG) 701b4319ba4SBarry Smith 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); 702b4319ba4SBarry Smith #endif 703b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 70428f4e0baSStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 70528f4e0baSStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 706a8116848SStefano Zampini PetscFunctionReturn(0); 707a8116848SStefano Zampini } 708a8116848SStefano Zampini 709a8116848SStefano Zampini #undef __FUNCT__ 710a8116848SStefano Zampini #define __FUNCT__ "PetscLayoutMapLocal_Private" 711a8116848SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 712a8116848SStefano Zampini { 713a8116848SStefano Zampini PetscInt *owners = map->range; 714a8116848SStefano Zampini PetscInt n = map->n; 715a8116848SStefano Zampini PetscSF sf; 716a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 717a8116848SStefano Zampini PetscSFNode *ridxs; 718a8116848SStefano Zampini PetscMPIInt rank; 719a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 720a8116848SStefano Zampini PetscErrorCode ierr; 721a8116848SStefano Zampini 722a8116848SStefano Zampini PetscFunctionBegin; 723fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 724a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 725a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 726a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 727a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 728a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 729a8116848SStefano Zampini for (r = 0; r < N; ++r) { 730a8116848SStefano Zampini const PetscInt idx = idxs[r]; 731a8116848SStefano 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); 732a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 733a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 734a8116848SStefano Zampini } 735a8116848SStefano Zampini ridxs[r].rank = p; 736a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 737a8116848SStefano Zampini } 738a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 739a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 740a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 741a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 742a8116848SStefano Zampini if (ogidxs) { /* communicate global idxs */ 743a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 744a8116848SStefano Zampini 745a8116848SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 746a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 747a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 748a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 749a8116848SStefano Zampini start -= cum; 750a8116848SStefano Zampini cum = 0; 751a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 752a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 753a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 754a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 755a8116848SStefano Zampini } 756a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 757a8116848SStefano Zampini /* Compress and put in indices */ 758a8116848SStefano Zampini for (r = 0; r < n; ++r) 759a8116848SStefano Zampini if (lidxs[r] >= 0) { 760a8116848SStefano Zampini if (work) work[len] = work[r]; 761a8116848SStefano Zampini lidxs[len++] = r; 762a8116848SStefano Zampini } 763a8116848SStefano Zampini if (on) *on = len; 764a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 765a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 766a8116848SStefano Zampini PetscFunctionReturn(0); 767a8116848SStefano Zampini } 768a8116848SStefano Zampini 769a8116848SStefano Zampini #undef __FUNCT__ 770a8116848SStefano Zampini #define __FUNCT__ "MatGetSubMatrix_IS" 771a8116848SStefano Zampini static PetscErrorCode MatGetSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 772a8116848SStefano Zampini { 773a8116848SStefano Zampini Mat locmat,newlocmat; 774a8116848SStefano Zampini Mat_IS *newmatis; 775a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 776a8116848SStefano Zampini Vec rtest,ltest; 777a8116848SStefano Zampini const PetscScalar *array; 778a8116848SStefano Zampini #endif 779a8116848SStefano Zampini const PetscInt *idxs; 780a8116848SStefano Zampini PetscInt i,m,n; 781a8116848SStefano Zampini PetscErrorCode ierr; 782a8116848SStefano Zampini 783a8116848SStefano Zampini PetscFunctionBegin; 784a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 785a8116848SStefano Zampini PetscBool ismatis; 786a8116848SStefano Zampini 787a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 788a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 789a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 790a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 791a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 792a8116848SStefano Zampini } 793a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 794a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 795a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 796a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 797a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 798a8116848SStefano Zampini for (i=0;i<n;i++) { 799a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 800a8116848SStefano Zampini } 801a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 802a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 803a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 804a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 805a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 806a8116848SStefano Zampini 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])); 807a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 808a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 809a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 810a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 811a8116848SStefano Zampini for (i=0;i<n;i++) { 812a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 813a8116848SStefano Zampini } 814a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 815a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 816a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 817a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 818a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 819a8116848SStefano Zampini 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])); 820a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 821a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 822a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 823a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 824a8116848SStefano Zampini #endif 825a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 826a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 827a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 828a8116848SStefano Zampini IS is; 829a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 830a8116848SStefano Zampini PetscInt ll,newloc; 831a8116848SStefano Zampini MPI_Comm comm; 832a8116848SStefano Zampini 833a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 834a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 835a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 836a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 837a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 838a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 839a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 840a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 841a8116848SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 842a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 8433d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 8443d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 845a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 846a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 847a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 848a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 849a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 8503d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 851a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 852a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8533d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 854a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 855a8116848SStefano Zampini lidxs[newloc] = i; 856a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 857a8116848SStefano Zampini } 858a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 859a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 860a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 861a8116848SStefano Zampini /* local is to extract local submatrix */ 862a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 863a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 864a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 865a8116848SStefano Zampini PetscBool cong; 866a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 867a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 868a8116848SStefano Zampini else mat->congruentlayouts = 0; 869a8116848SStefano Zampini } 870a8116848SStefano Zampini if (mat->congruentlayouts && irow == icol) { 871a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 872a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 873a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 874a8116848SStefano Zampini } else { 875a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 876a8116848SStefano Zampini 877a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 878a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 879f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 880a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 8813d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 882a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 883a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 884a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 885a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 886a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 8873d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 888a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 889a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 8903d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 891a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 892a8116848SStefano Zampini lidxs[newloc] = i; 893a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 894a8116848SStefano Zampini } 895a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 896a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 897a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 898a8116848SStefano Zampini /* local is to extract local submatrix */ 899a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 900a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 901a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 902a8116848SStefano Zampini } 903a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 904a8116848SStefano Zampini } else { 905a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 906a8116848SStefano Zampini } 907a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 908a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 909a8116848SStefano Zampini ierr = MatGetSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 910a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 911a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 912a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 913a8116848SStefano Zampini } 914a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 915a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 916a8116848SStefano Zampini PetscFunctionReturn(0); 917a8116848SStefano Zampini } 918a8116848SStefano Zampini 919a8116848SStefano Zampini #undef __FUNCT__ 9202b404112SStefano Zampini #define __FUNCT__ "MatCopy_IS" 921a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 9222b404112SStefano Zampini { 9232b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 9242b404112SStefano Zampini PetscBool ismatis; 9252b404112SStefano Zampini PetscErrorCode ierr; 9262b404112SStefano Zampini 9272b404112SStefano Zampini PetscFunctionBegin; 9282b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 9292b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 9302b404112SStefano Zampini b = (Mat_IS*)B->data; 9312b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 9322b404112SStefano Zampini PetscFunctionReturn(0); 9332b404112SStefano Zampini } 9342b404112SStefano Zampini 9352b404112SStefano Zampini #undef __FUNCT__ 9366bd84002SStefano Zampini #define __FUNCT__ "MatMissingDiagonal_IS" 937a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 9386bd84002SStefano Zampini { 939527b2640SStefano Zampini Vec v; 940527b2640SStefano Zampini const PetscScalar *array; 941527b2640SStefano Zampini PetscInt i,n; 9426bd84002SStefano Zampini PetscErrorCode ierr; 9436bd84002SStefano Zampini 9446bd84002SStefano Zampini PetscFunctionBegin; 945527b2640SStefano Zampini *missing = PETSC_FALSE; 946527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 947527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 948527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 949527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 950527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 951527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 952527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 953527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 954527b2640SStefano Zampini if (d) { 955527b2640SStefano Zampini *d = -1; 956527b2640SStefano Zampini if (*missing) { 957527b2640SStefano Zampini PetscInt rstart; 958527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 959527b2640SStefano Zampini *d = i+rstart; 960527b2640SStefano Zampini } 961527b2640SStefano Zampini } 9626bd84002SStefano Zampini PetscFunctionReturn(0); 9636bd84002SStefano Zampini } 9646bd84002SStefano Zampini 9656bd84002SStefano Zampini #undef __FUNCT__ 966cf0a3239SStefano Zampini #define __FUNCT__ "MatISSetUpSF_IS" 967cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 96828f4e0baSStefano Zampini { 96928f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 97028f4e0baSStefano Zampini const PetscInt *gidxs; 9714f2d7cafSStefano Zampini PetscInt nleaves; 97228f4e0baSStefano Zampini PetscErrorCode ierr; 97328f4e0baSStefano Zampini 97428f4e0baSStefano Zampini PetscFunctionBegin; 9754f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 97628f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 9773bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9784f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 9794f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 9803bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 9814f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 982a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 9833d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 984a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 985a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9863d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 987a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 9883d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 989a8116848SStefano Zampini } else { 990a8116848SStefano Zampini matis->csf = matis->sf; 991a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 992a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 993a8116848SStefano Zampini } 99428f4e0baSStefano Zampini PetscFunctionReturn(0); 99528f4e0baSStefano Zampini } 9962e1947a5SStefano Zampini 9972e1947a5SStefano Zampini #undef __FUNCT__ 9982e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 999eb82efa4SStefano Zampini /*@ 1000a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 1001a88811baSStefano Zampini 1002a88811baSStefano Zampini Collective on MPI_Comm 1003a88811baSStefano Zampini 1004a88811baSStefano Zampini Input Parameters: 1005a88811baSStefano Zampini + B - the matrix 1006a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 1007a88811baSStefano Zampini (same value is used for all local rows) 1008a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 1009a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1010a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 1011a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 1012a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 1013a88811baSStefano Zampini the diagonal entry even if it is zero. 1014a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1015a88811baSStefano Zampini submatrix (same value is used for all local rows). 1016a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 1017a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1018a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 1019a88811baSStefano Zampini structure. The size of this array is equal to the number 1020a88811baSStefano Zampini of local rows, i.e 'm'. 1021a88811baSStefano Zampini 1022a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 1023a88811baSStefano Zampini 1024a88811baSStefano Zampini Level: intermediate 1025a88811baSStefano Zampini 1026a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 1027a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 1028a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 1029a88811baSStefano Zampini 1030a88811baSStefano Zampini .keywords: matrix 1031a88811baSStefano Zampini 10323c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 1033a88811baSStefano Zampini @*/ 10342e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10352e1947a5SStefano Zampini { 10362e1947a5SStefano Zampini PetscErrorCode ierr; 10372e1947a5SStefano Zampini 10382e1947a5SStefano Zampini PetscFunctionBegin; 10392e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10402e1947a5SStefano Zampini PetscValidType(B,1); 10412e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 10422e1947a5SStefano Zampini PetscFunctionReturn(0); 10432e1947a5SStefano Zampini } 10442e1947a5SStefano Zampini 10452e1947a5SStefano Zampini #undef __FUNCT__ 10462e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 10477230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 10482e1947a5SStefano Zampini { 10492e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 105028f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 10512e1947a5SStefano Zampini PetscErrorCode ierr; 10522e1947a5SStefano Zampini 10532e1947a5SStefano Zampini PetscFunctionBegin; 10546c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 1055cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 10564f2d7cafSStefano Zampini 10574f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 10584f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 10594f2d7cafSStefano Zampini 10604f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 10614f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 10624f2d7cafSStefano Zampini 106328f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 106428f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 106528f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 106628f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 10674f2d7cafSStefano Zampini 10684f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 106928f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 10704f2d7cafSStefano Zampini 10714f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 107228f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10734f2d7cafSStefano Zampini 10744f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 107528f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 10762e1947a5SStefano Zampini PetscFunctionReturn(0); 10772e1947a5SStefano Zampini } 1078b4319ba4SBarry Smith 1079b4319ba4SBarry Smith #undef __FUNCT__ 10803927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 10813927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 10823927de2eSStefano Zampini { 10833927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 10843927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1085ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 10863927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 10873927de2eSStefano Zampini PetscInt lrows,lcols; 10883927de2eSStefano Zampini PetscInt local_rows,local_cols; 10893927de2eSStefano Zampini PetscMPIInt nsubdomains; 10903927de2eSStefano Zampini PetscBool isdense,issbaij; 10913927de2eSStefano Zampini PetscErrorCode ierr; 10923927de2eSStefano Zampini 10933927de2eSStefano Zampini PetscFunctionBegin; 10943927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 10953927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 10963927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10973927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 10983927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 10993927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1100ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1101ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 11027230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1103ecf5a873SStefano Zampini } else { 1104ecf5a873SStefano Zampini global_indices_c = global_indices_r; 1105ecf5a873SStefano Zampini } 1106ecf5a873SStefano Zampini 11073927de2eSStefano Zampini if (issbaij) { 11083927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 11093927de2eSStefano Zampini } 11103927de2eSStefano Zampini /* 1111ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 11123927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 11133927de2eSStefano Zampini */ 1114cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 11153927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 11163927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 11173927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 11183927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 11193927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 11203927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 11213927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 11223927de2eSStefano Zampini row_ownership[j] = i; 11233927de2eSStefano Zampini } 11243927de2eSStefano Zampini } 11257230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 11263927de2eSStefano Zampini 11273927de2eSStefano Zampini /* 11283927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 11293927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 11303927de2eSStefano Zampini */ 11313927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 11323927de2eSStefano Zampini /* preallocation as a MATAIJ */ 11333927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 11343927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 1135ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 11363927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 11373927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1138ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 11393927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11403927de2eSStefano Zampini my_dnz[i] += 1; 11413927de2eSStefano Zampini } else { /* offdiag block */ 11423927de2eSStefano Zampini my_onz[i] += 1; 11433927de2eSStefano Zampini } 11443927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 11453927de2eSStefano Zampini if (i != j) { 11463927de2eSStefano Zampini owner = row_ownership[index_col]; 11473927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 11483927de2eSStefano Zampini my_dnz[j] += 1; 11493927de2eSStefano Zampini } else { 11503927de2eSStefano Zampini my_onz[j] += 1; 11513927de2eSStefano Zampini } 11523927de2eSStefano Zampini } 11533927de2eSStefano Zampini } 11543927de2eSStefano Zampini } 1155bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1156bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1157bb1015c3SStefano Zampini PetscBool done; 1158bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1159bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 1160bb1015c3SStefano Zampini jptr = jj; 1161bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1162bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1163bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1164bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1165bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1166bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1167bb1015c3SStefano Zampini my_dnz[i] += 1; 1168bb1015c3SStefano Zampini } else { /* offdiag block */ 1169bb1015c3SStefano Zampini my_onz[i] += 1; 1170bb1015c3SStefano Zampini } 1171bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1172bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1173bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1174bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1175bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1176bb1015c3SStefano Zampini } else { 1177bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1178bb1015c3SStefano Zampini } 1179bb1015c3SStefano Zampini } 1180bb1015c3SStefano Zampini } 1181bb1015c3SStefano Zampini } 1182bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1183bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 1184bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 11853927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 11863927de2eSStefano Zampini const PetscInt *cols; 1187ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 11883927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 11893927de2eSStefano Zampini for (j=0;j<ncols;j++) { 11903927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1191ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 11923927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 11933927de2eSStefano Zampini my_dnz[i] += 1; 11943927de2eSStefano Zampini } else { /* offdiag block */ 11953927de2eSStefano Zampini my_onz[i] += 1; 11963927de2eSStefano Zampini } 11973927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1198d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 11993927de2eSStefano Zampini owner = row_ownership[index_col]; 12003927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1201d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 12023927de2eSStefano Zampini } else { 1203d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 12043927de2eSStefano Zampini } 12053927de2eSStefano Zampini } 12063927de2eSStefano Zampini } 12073927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 12083927de2eSStefano Zampini } 12093927de2eSStefano Zampini } 1210ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1211ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 12127230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1213ecf5a873SStefano Zampini } 12143927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1215ecf5a873SStefano Zampini 1216ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 12173927de2eSStefano Zampini if (maxreduce) { 12183927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 12193927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1220bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 12213927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 12223927de2eSStefano Zampini } else { 12233927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 12243927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1225bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 12263927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 12273927de2eSStefano Zampini } 12283927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 12293927de2eSStefano Zampini 12303927de2eSStefano Zampini /* Resize preallocation if overestimated */ 12313927de2eSStefano Zampini for (i=0;i<lrows;i++) { 12323927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 12333927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 12343927de2eSStefano Zampini } 12351670daf9Sstefano_zampini 12361670daf9Sstefano_zampini /* Set preallocation */ 12373927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 12383927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 12393927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 12403927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 12413927de2eSStefano Zampini } 12423927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12433927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 12443927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 12453927de2eSStefano Zampini if (issbaij) { 12463927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 12473927de2eSStefano Zampini } 12483927de2eSStefano Zampini PetscFunctionReturn(0); 12493927de2eSStefano Zampini } 12503927de2eSStefano Zampini 12513927de2eSStefano Zampini #undef __FUNCT__ 1252b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 12537230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1254b7ce53b6SStefano Zampini { 1255b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1256d9a9e74cSStefano Zampini Mat local_mat; 1257b7ce53b6SStefano Zampini /* info on mat */ 12583cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1259b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1260b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1261b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1262b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1263b9ed4604SStefano Zampini #endif 12647c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1265b7ce53b6SStefano Zampini /* values insertion */ 1266b7ce53b6SStefano Zampini PetscScalar *array; 1267b7ce53b6SStefano Zampini /* work */ 1268b7ce53b6SStefano Zampini PetscErrorCode ierr; 1269b7ce53b6SStefano Zampini 1270b7ce53b6SStefano Zampini PetscFunctionBegin; 1271b7ce53b6SStefano Zampini /* get info from mat */ 12727c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 12737c03b4e8SStefano Zampini if (nsubdomains == 1) { 12741670daf9Sstefano_zampini Mat B; 12751670daf9Sstefano_zampini IS rows,cols; 1276acdf38a7Sstefano_zampini IS irows,icols; 12771670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 12781670daf9Sstefano_zampini 12791670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 12801670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 12811670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 12821670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 12831670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 12841670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1285acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1286acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1287acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1288acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1289acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1290acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 1291acdf38a7Sstefano_zampini ierr = MatConvert(matis->A,MATAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1292acdf38a7Sstefano_zampini ierr = MatGetSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1293acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1294acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1295acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 12967c03b4e8SStefano Zampini PetscFunctionReturn(0); 12977c03b4e8SStefano Zampini } 1298b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1299b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 13003cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1301b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1302b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 1303686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1304b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1305b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1306b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1307b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1308b9ed4604SStefano Zampini lb[0] = isseqdense; 1309b9ed4604SStefano Zampini lb[1] = isseqaij; 1310b9ed4604SStefano Zampini lb[2] = isseqbaij; 1311b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1312b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1313b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1314b9ed4604SStefano Zampini #endif 1315b7ce53b6SStefano Zampini 1316b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 13173927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 13183cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 13193927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 1320b9ed4604SStefano Zampini if (!isseqsbaij) { 1321b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1322b9ed4604SStefano Zampini } else { 1323b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1324b9ed4604SStefano Zampini } 13253927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1326b7ce53b6SStefano Zampini } else { 13273cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1328b7ce53b6SStefano Zampini /* some checks */ 1329b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1330b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 13313cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 13326c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 13336c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 13346c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 13356c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 13366c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1337b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1338b7ce53b6SStefano Zampini } 1339d9a9e74cSStefano Zampini 1340b9ed4604SStefano Zampini if (isseqsbaij) { 1341d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1342d9a9e74cSStefano Zampini } else { 1343d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1344d9a9e74cSStefano Zampini local_mat = matis->A; 1345d9a9e74cSStefano Zampini } 1346686e3a49SStefano Zampini 1347b7ce53b6SStefano Zampini /* Set values */ 1348ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1349b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 1350ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 1351ecf5a873SStefano Zampini 1352ecf5a873SStefano Zampini if (local_rows != local_cols) { 1353ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 1354ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1355ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 1356ecf5a873SStefano Zampini } else { 1357ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 1358ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1359ecf5a873SStefano Zampini dummy_cols = dummy_rows; 1360ecf5a873SStefano Zampini } 1361b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1362d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 1363ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 1364d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 1365ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 1366ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 1367ecf5a873SStefano Zampini } else { 1368ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 1369ecf5a873SStefano Zampini } 1370686e3a49SStefano Zampini } else if (isseqaij) { 1371ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1372686e3a49SStefano Zampini PetscBool done; 1373686e3a49SStefano Zampini 1374d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1375bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 1376d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1377686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1378ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1379686e3a49SStefano Zampini } 1380d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1381bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 1382d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1383686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1384ecf5a873SStefano Zampini PetscInt i; 1385c0962df8SStefano Zampini 1386686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1387686e3a49SStefano Zampini PetscInt j; 1388ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1389686e3a49SStefano Zampini 1390ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1391ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1392ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1393686e3a49SStefano Zampini } 1394b7ce53b6SStefano Zampini } 1395b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1396d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1397b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1398b9ed4604SStefano Zampini if (isseqdense) { 1399b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1400b7ce53b6SStefano Zampini } 1401b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1402b7ce53b6SStefano Zampini } 1403b7ce53b6SStefano Zampini 1404b7ce53b6SStefano Zampini #undef __FUNCT__ 1405b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 1406b7ce53b6SStefano Zampini /*@ 1407b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1408b7ce53b6SStefano Zampini 1409b7ce53b6SStefano Zampini Input Parameter: 1410b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1411b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1412b7ce53b6SStefano Zampini 1413b7ce53b6SStefano Zampini Output Parameter: 1414b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1415b7ce53b6SStefano Zampini 1416b7ce53b6SStefano Zampini Level: developer 1417b7ce53b6SStefano Zampini 1418eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1419b7ce53b6SStefano Zampini 1420b7ce53b6SStefano Zampini .seealso: MATIS 1421b7ce53b6SStefano Zampini @*/ 1422b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1423b7ce53b6SStefano Zampini { 1424b7ce53b6SStefano Zampini PetscErrorCode ierr; 1425b7ce53b6SStefano Zampini 1426b7ce53b6SStefano Zampini PetscFunctionBegin; 1427b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1428b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1429b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1430b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1431b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1432b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 14336c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1434b7ce53b6SStefano Zampini } 1435b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1436b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1437b7ce53b6SStefano Zampini } 1438b7ce53b6SStefano Zampini 1439b7ce53b6SStefano Zampini #undef __FUNCT__ 1440ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 1441ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1442ad6194a2SStefano Zampini { 1443ad6194a2SStefano Zampini PetscErrorCode ierr; 1444ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1445ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1446ad6194a2SStefano Zampini Mat B,localmat; 1447ad6194a2SStefano Zampini 1448ad6194a2SStefano Zampini PetscFunctionBegin; 1449ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1450ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1451ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1452e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1453ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1454ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1455b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1456ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1457ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1458ad6194a2SStefano Zampini *newmat = B; 1459ad6194a2SStefano Zampini PetscFunctionReturn(0); 1460ad6194a2SStefano Zampini } 1461ad6194a2SStefano Zampini 1462ad6194a2SStefano Zampini #undef __FUNCT__ 146369796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 1464a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 146569796d55SStefano Zampini { 146669796d55SStefano Zampini PetscErrorCode ierr; 146769796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 146869796d55SStefano Zampini PetscBool local_sym; 146969796d55SStefano Zampini 147069796d55SStefano Zampini PetscFunctionBegin; 147169796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1472b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 147369796d55SStefano Zampini PetscFunctionReturn(0); 147469796d55SStefano Zampini } 147569796d55SStefano Zampini 147669796d55SStefano Zampini #undef __FUNCT__ 147769796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 1478a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 147969796d55SStefano Zampini { 148069796d55SStefano Zampini PetscErrorCode ierr; 148169796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 148269796d55SStefano Zampini PetscBool local_sym; 148369796d55SStefano Zampini 148469796d55SStefano Zampini PetscFunctionBegin; 148569796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1486b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 148769796d55SStefano Zampini PetscFunctionReturn(0); 148869796d55SStefano Zampini } 148969796d55SStefano Zampini 149069796d55SStefano Zampini #undef __FUNCT__ 149145471136SStefano Zampini #define __FUNCT__ "MatIsStructurallySymmetric_IS" 149245471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 149345471136SStefano Zampini { 149445471136SStefano Zampini PetscErrorCode ierr; 149545471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 149645471136SStefano Zampini PetscBool local_sym; 149745471136SStefano Zampini 149845471136SStefano Zampini PetscFunctionBegin; 149945471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 150045471136SStefano Zampini *flg = PETSC_FALSE; 150145471136SStefano Zampini PetscFunctionReturn(0); 150245471136SStefano Zampini } 150345471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 150445471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 150545471136SStefano Zampini PetscFunctionReturn(0); 150645471136SStefano Zampini } 150745471136SStefano Zampini 150845471136SStefano Zampini #undef __FUNCT__ 1509b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 1510a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1511b4319ba4SBarry Smith { 1512dfbe8321SBarry Smith PetscErrorCode ierr; 1513b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1514b4319ba4SBarry Smith 1515b4319ba4SBarry Smith PetscFunctionBegin; 15166bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1517e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1518e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 15196bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 15206bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 15213fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1522a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1523a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1524a8116848SStefano Zampini if (b->sf != b->csf) { 1525a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1526a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1527a8116848SStefano Zampini } 152828f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 152928f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1530bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1531dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1532bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1533b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1534b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 15352e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1536cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 1537b4319ba4SBarry Smith PetscFunctionReturn(0); 1538b4319ba4SBarry Smith } 1539b4319ba4SBarry Smith 1540b4319ba4SBarry Smith #undef __FUNCT__ 1541b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 1542a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1543b4319ba4SBarry Smith { 1544dfbe8321SBarry Smith PetscErrorCode ierr; 1545b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1546b4319ba4SBarry Smith PetscScalar zero = 0.0; 1547b4319ba4SBarry Smith 1548b4319ba4SBarry Smith PetscFunctionBegin; 1549b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1550e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1551e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1552b4319ba4SBarry Smith 1553b4319ba4SBarry Smith /* multiply the local matrix */ 1554b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1555b4319ba4SBarry Smith 1556b4319ba4SBarry Smith /* scatter product back into global memory */ 15572dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1558e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1559e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1560b4319ba4SBarry Smith PetscFunctionReturn(0); 1561b4319ba4SBarry Smith } 1562b4319ba4SBarry Smith 1563b4319ba4SBarry Smith #undef __FUNCT__ 15642e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 1565a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 15662e74eeadSLisandro Dalcin { 1567650997f4SStefano Zampini Vec temp_vec; 15682e74eeadSLisandro Dalcin PetscErrorCode ierr; 15692e74eeadSLisandro Dalcin 15702e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1571650997f4SStefano Zampini if (v3 != v2) { 1572650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1573650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1574650997f4SStefano Zampini } else { 1575650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1576650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1577650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1578650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1579650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1580650997f4SStefano Zampini } 15812e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15822e74eeadSLisandro Dalcin } 15832e74eeadSLisandro Dalcin 15842e74eeadSLisandro Dalcin #undef __FUNCT__ 15852e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 1586a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 15872e74eeadSLisandro Dalcin { 15882e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 15892e74eeadSLisandro Dalcin PetscErrorCode ierr; 15902e74eeadSLisandro Dalcin 1591e176bc59SStefano Zampini PetscFunctionBegin; 15922e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1593e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1594e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15952e74eeadSLisandro Dalcin 15962e74eeadSLisandro Dalcin /* multiply the local matrix */ 1597e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 15982e74eeadSLisandro Dalcin 15992e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1600e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1601e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1602e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16032e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16042e74eeadSLisandro Dalcin } 16052e74eeadSLisandro Dalcin 16062e74eeadSLisandro Dalcin #undef __FUNCT__ 16072e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1608a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 16092e74eeadSLisandro Dalcin { 1610650997f4SStefano Zampini Vec temp_vec; 16112e74eeadSLisandro Dalcin PetscErrorCode ierr; 16122e74eeadSLisandro Dalcin 16132e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1614650997f4SStefano Zampini if (v3 != v2) { 1615650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1616650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1617650997f4SStefano Zampini } else { 1618650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1619650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1620650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1621650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1622650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1623650997f4SStefano Zampini } 16242e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16252e74eeadSLisandro Dalcin } 16262e74eeadSLisandro Dalcin 16272e74eeadSLisandro Dalcin #undef __FUNCT__ 1628b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 1629a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1630b4319ba4SBarry Smith { 1631b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1632dfbe8321SBarry Smith PetscErrorCode ierr; 1633b4319ba4SBarry Smith PetscViewer sviewer; 1634ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1635b4319ba4SBarry Smith 1636b4319ba4SBarry Smith PetscFunctionBegin; 1637ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1638ee2491ecSStefano Zampini if (isascii) { 1639ee2491ecSStefano Zampini PetscViewerFormat format; 1640ee2491ecSStefano Zampini 1641ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1642ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1643ee2491ecSStefano Zampini } 1644ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 16453f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1646b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 16473f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 16486e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1649b4319ba4SBarry Smith PetscFunctionReturn(0); 1650b4319ba4SBarry Smith } 1651b4319ba4SBarry Smith 1652b4319ba4SBarry Smith #undef __FUNCT__ 1653b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 1654a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1655b4319ba4SBarry Smith { 1656dfbe8321SBarry Smith PetscErrorCode ierr; 1657e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1658b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1659b4319ba4SBarry Smith IS from,to; 1660e176bc59SStefano Zampini Vec cglobal,rglobal; 1661b4319ba4SBarry Smith 1662b4319ba4SBarry Smith PetscFunctionBegin; 1663784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1664e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 16653bbff08aSStefano Zampini /* Destroy any previous data */ 166670cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 166770cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 16683fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1669e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1670e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 16711c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 167228f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 167328f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 16743bbff08aSStefano Zampini 16753bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1676fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1677fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1678fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1679fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1680b4319ba4SBarry Smith 1681b4319ba4SBarry Smith /* Create the local matrix A */ 1682e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1683e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1684e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1685e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1686f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1687e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1688e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1689e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1690ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1691ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1692b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1693b4319ba4SBarry Smith 1694f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1695b4319ba4SBarry Smith /* Create the local work vectors */ 16963bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1697b4319ba4SBarry Smith 1698e176bc59SStefano Zampini /* setup the global to local scatters */ 1699e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1700e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1701784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1702e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1703e176bc59SStefano Zampini if (rmapping != cmapping) { 1704e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1705e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1706e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1707e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1708e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1709e176bc59SStefano Zampini } else { 1710e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1711e176bc59SStefano Zampini is->cctx = is->rctx; 1712e176bc59SStefano Zampini } 17133fd1c9e7SStefano Zampini 17143fd1c9e7SStefano Zampini /* interface counter vector (local) */ 17153fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 17163fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 17173fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17183fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17193fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17203fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17213fd1c9e7SStefano Zampini 17223fd1c9e7SStefano Zampini /* free workspace */ 1723e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1724e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 17256bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 17266bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1727f26d0771SStefano Zampini } 172848ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1729b4319ba4SBarry Smith PetscFunctionReturn(0); 1730b4319ba4SBarry Smith } 1731b4319ba4SBarry Smith 17322e74eeadSLisandro Dalcin #undef __FUNCT__ 17332e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 1734a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 17352e74eeadSLisandro Dalcin { 17362e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 17372e74eeadSLisandro Dalcin PetscErrorCode ierr; 173897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 173997563a80SStefano Zampini PetscInt i,zm,zn; 174097563a80SStefano Zampini #endif 1741f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 17422e74eeadSLisandro Dalcin 17432e74eeadSLisandro Dalcin PetscFunctionBegin; 17442e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1745f26d0771SStefano 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); 174697563a80SStefano Zampini /* count negative indices */ 174797563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 174897563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 17492e74eeadSLisandro Dalcin #endif 175097563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 175197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 175297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 175397563a80SStefano Zampini /* count negative indices (should be the same as before) */ 175497563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 175597563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 175697563a80SStefano 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"); 175797563a80SStefano 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"); 175897563a80SStefano Zampini #endif 17592e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 17602e74eeadSLisandro Dalcin PetscFunctionReturn(0); 17612e74eeadSLisandro Dalcin } 17622e74eeadSLisandro Dalcin 1763b4319ba4SBarry Smith #undef __FUNCT__ 176497563a80SStefano Zampini #define __FUNCT__ "MatSetValuesBlocked_IS" 1765a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 176697563a80SStefano Zampini { 176797563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 176897563a80SStefano Zampini PetscErrorCode ierr; 176997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 177097563a80SStefano Zampini PetscInt i,zm,zn; 177197563a80SStefano Zampini #endif 1772f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 177397563a80SStefano Zampini 177497563a80SStefano Zampini PetscFunctionBegin; 177597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1776f26d0771SStefano 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); 177797563a80SStefano Zampini /* count negative indices */ 177897563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 177997563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 178097563a80SStefano Zampini #endif 178197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 178297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 178397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 178497563a80SStefano Zampini /* count negative indices (should be the same as before) */ 178597563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 178697563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 178797563a80SStefano 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"); 178897563a80SStefano 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"); 178997563a80SStefano Zampini #endif 179097563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 179197563a80SStefano Zampini PetscFunctionReturn(0); 179297563a80SStefano Zampini } 179397563a80SStefano Zampini 179497563a80SStefano Zampini #undef __FUNCT__ 1795b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 1796a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1797b4319ba4SBarry Smith { 1798dfbe8321SBarry Smith PetscErrorCode ierr; 1799b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1800b4319ba4SBarry Smith 1801b4319ba4SBarry Smith PetscFunctionBegin; 1802b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1803b4319ba4SBarry Smith PetscFunctionReturn(0); 1804b4319ba4SBarry Smith } 1805b4319ba4SBarry Smith 1806b4319ba4SBarry Smith #undef __FUNCT__ 1807f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 1808a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1809f0006bf2SLisandro Dalcin { 1810f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1811f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1812f0006bf2SLisandro Dalcin 1813f0006bf2SLisandro Dalcin PetscFunctionBegin; 1814f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1815f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1816f0006bf2SLisandro Dalcin } 1817f0006bf2SLisandro Dalcin 1818f0006bf2SLisandro Dalcin #undef __FUNCT__ 1819f0ae7da4SStefano Zampini #define __FUNCT__ "MatISZeroRowsColumnsLocal_Private" 1820f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 1821f0ae7da4SStefano Zampini { 1822f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1823f0ae7da4SStefano Zampini PetscErrorCode ierr; 1824f0ae7da4SStefano Zampini 1825f0ae7da4SStefano Zampini PetscFunctionBegin; 1826f0ae7da4SStefano Zampini if (!n) { 1827f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1828f0ae7da4SStefano Zampini } else { 1829f0ae7da4SStefano Zampini PetscInt i; 1830f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1831f0ae7da4SStefano Zampini 1832f0ae7da4SStefano Zampini if (columns) { 1833f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1834f0ae7da4SStefano Zampini } else { 1835f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1836f0ae7da4SStefano Zampini } 1837f0ae7da4SStefano Zampini if (diag != 0.) { 1838f0ae7da4SStefano Zampini const PetscScalar *array; 1839f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1840f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1841f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1842f0ae7da4SStefano Zampini } 1843f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1844f0ae7da4SStefano Zampini } 1845f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1846f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1847f0ae7da4SStefano Zampini } 1848f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1849f0ae7da4SStefano Zampini } 1850f0ae7da4SStefano Zampini 1851f0ae7da4SStefano Zampini #undef __FUNCT__ 1852f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_Private_IS" 1853f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 18542e74eeadSLisandro Dalcin { 18556e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 18566e520ac8SStefano Zampini PetscInt nr,nl,len,i; 18576e520ac8SStefano Zampini PetscInt *lrows; 18582e74eeadSLisandro Dalcin PetscErrorCode ierr; 18592e74eeadSLisandro Dalcin 18602e74eeadSLisandro Dalcin PetscFunctionBegin; 1861f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1862f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1863f0ae7da4SStefano Zampini PetscBool cong; 1864f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1865f0ae7da4SStefano Zampini if (!cong && columns) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Columns can be zeroed if and only if A->rmap and A->cmap are congruent for MATIS"); 1866f0ae7da4SStefano Zampini if (!cong && diag != 0.) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Nonzero diagonal value supported if and only if A->rmap and A->cmap are congruent for MATIS"); 1867f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1868f0ae7da4SStefano Zampini } 1869f0ae7da4SStefano Zampini #endif 18706e520ac8SStefano Zampini /* get locally owned rows */ 1871f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 18726e520ac8SStefano Zampini /* fix right hand side if needed */ 18736e520ac8SStefano Zampini if (x && b) { 18746e520ac8SStefano Zampini const PetscScalar *xx; 18756e520ac8SStefano Zampini PetscScalar *bb; 18766e520ac8SStefano Zampini 18776e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 18786e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 18796e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 18806e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 18816e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 18822e74eeadSLisandro Dalcin } 18836e520ac8SStefano Zampini /* get rows associated to the local matrices */ 18843d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 18856e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 18866e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 18876e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 18886e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 18896e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18906e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18916e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18926e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 18936e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1894f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 18956e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 18962e74eeadSLisandro Dalcin PetscFunctionReturn(0); 18972e74eeadSLisandro Dalcin } 18982e74eeadSLisandro Dalcin 18992e74eeadSLisandro Dalcin #undef __FUNCT__ 1900f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRows_IS" 1901f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1902b4319ba4SBarry Smith { 1903dfbe8321SBarry Smith PetscErrorCode ierr; 1904b4319ba4SBarry Smith 1905b4319ba4SBarry Smith PetscFunctionBegin; 1906f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1907f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1908f0ae7da4SStefano Zampini } 19092205254eSKarl Rupp 1910f0ae7da4SStefano Zampini #undef __FUNCT__ 1911f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_IS" 1912f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1913f0ae7da4SStefano Zampini { 1914f0ae7da4SStefano Zampini PetscErrorCode ierr; 1915f0ae7da4SStefano Zampini 1916f0ae7da4SStefano Zampini PetscFunctionBegin; 1917f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1918b4319ba4SBarry Smith PetscFunctionReturn(0); 1919b4319ba4SBarry Smith } 1920b4319ba4SBarry Smith 1921b4319ba4SBarry Smith #undef __FUNCT__ 1922b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 1923a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1924b4319ba4SBarry Smith { 1925b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1926dfbe8321SBarry Smith PetscErrorCode ierr; 1927b4319ba4SBarry Smith 1928b4319ba4SBarry Smith PetscFunctionBegin; 1929b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1930b4319ba4SBarry Smith PetscFunctionReturn(0); 1931b4319ba4SBarry Smith } 1932b4319ba4SBarry Smith 1933b4319ba4SBarry Smith #undef __FUNCT__ 1934b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 1935a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1936b4319ba4SBarry Smith { 1937b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1938dfbe8321SBarry Smith PetscErrorCode ierr; 1939b4319ba4SBarry Smith 1940b4319ba4SBarry Smith PetscFunctionBegin; 1941b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1942b4319ba4SBarry Smith PetscFunctionReturn(0); 1943b4319ba4SBarry Smith } 1944b4319ba4SBarry Smith 1945b4319ba4SBarry Smith #undef __FUNCT__ 1946b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 1947a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1948b4319ba4SBarry Smith { 1949b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1950b4319ba4SBarry Smith 1951b4319ba4SBarry Smith PetscFunctionBegin; 1952b4319ba4SBarry Smith *local = is->A; 1953b4319ba4SBarry Smith PetscFunctionReturn(0); 1954b4319ba4SBarry Smith } 1955b4319ba4SBarry Smith 1956b4319ba4SBarry Smith #undef __FUNCT__ 1957b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 1958b4319ba4SBarry Smith /*@ 1959b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1960b4319ba4SBarry Smith 1961b4319ba4SBarry Smith Input Parameter: 1962b4319ba4SBarry Smith . mat - the matrix 1963b4319ba4SBarry Smith 1964b4319ba4SBarry Smith Output Parameter: 1965eb82efa4SStefano Zampini . local - the local matrix 1966b4319ba4SBarry Smith 1967b4319ba4SBarry Smith Level: advanced 1968b4319ba4SBarry Smith 1969b4319ba4SBarry Smith Notes: 1970b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1971b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1972b4319ba4SBarry Smith of the MatSetValues() operation. 1973b4319ba4SBarry Smith 1974b4319ba4SBarry Smith .seealso: MATIS 1975b4319ba4SBarry Smith @*/ 19767087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1977b4319ba4SBarry Smith { 19784ac538c5SBarry Smith PetscErrorCode ierr; 1979b4319ba4SBarry Smith 1980b4319ba4SBarry Smith PetscFunctionBegin; 19810700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1982b4319ba4SBarry Smith PetscValidPointer(local,2); 19834ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1984b4319ba4SBarry Smith PetscFunctionReturn(0); 1985b4319ba4SBarry Smith } 1986b4319ba4SBarry Smith 19873b03a366Sstefano_zampini #undef __FUNCT__ 19883b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 1989a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 19903b03a366Sstefano_zampini { 19913b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 19923b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 19933b03a366Sstefano_zampini PetscErrorCode ierr; 19943b03a366Sstefano_zampini 19953b03a366Sstefano_zampini PetscFunctionBegin; 19964e4c7dbeSStefano Zampini if (is->A) { 19973b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 19983b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1999f0ae7da4SStefano 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); 20004e4c7dbeSStefano Zampini } 20013b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 20023b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 20033b03a366Sstefano_zampini is->A = local; 20043b03a366Sstefano_zampini PetscFunctionReturn(0); 20053b03a366Sstefano_zampini } 20063b03a366Sstefano_zampini 20073b03a366Sstefano_zampini #undef __FUNCT__ 20083b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 20093b03a366Sstefano_zampini /*@ 2010eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 20113b03a366Sstefano_zampini 20123b03a366Sstefano_zampini Input Parameter: 20133b03a366Sstefano_zampini . mat - the matrix 2014eb82efa4SStefano Zampini . local - the local matrix 20153b03a366Sstefano_zampini 20163b03a366Sstefano_zampini Output Parameter: 20173b03a366Sstefano_zampini 20183b03a366Sstefano_zampini Level: advanced 20193b03a366Sstefano_zampini 20203b03a366Sstefano_zampini Notes: 20213b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 20223b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 20233b03a366Sstefano_zampini 20243b03a366Sstefano_zampini .seealso: MATIS 20253b03a366Sstefano_zampini @*/ 20263b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 20273b03a366Sstefano_zampini { 20283b03a366Sstefano_zampini PetscErrorCode ierr; 20293b03a366Sstefano_zampini 20303b03a366Sstefano_zampini PetscFunctionBegin; 20313b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2032b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 20333b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 20343b03a366Sstefano_zampini PetscFunctionReturn(0); 20353b03a366Sstefano_zampini } 20363b03a366Sstefano_zampini 20376726f965SBarry Smith #undef __FUNCT__ 20386726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 2039a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 20406726f965SBarry Smith { 20416726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 20426726f965SBarry Smith PetscErrorCode ierr; 20436726f965SBarry Smith 20446726f965SBarry Smith PetscFunctionBegin; 20456726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 20466726f965SBarry Smith PetscFunctionReturn(0); 20476726f965SBarry Smith } 20486726f965SBarry Smith 20496726f965SBarry Smith #undef __FUNCT__ 20502e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 2051a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 20522e74eeadSLisandro Dalcin { 20532e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 20542e74eeadSLisandro Dalcin PetscErrorCode ierr; 20552e74eeadSLisandro Dalcin 20562e74eeadSLisandro Dalcin PetscFunctionBegin; 20572e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 20582e74eeadSLisandro Dalcin PetscFunctionReturn(0); 20592e74eeadSLisandro Dalcin } 20602e74eeadSLisandro Dalcin 20612e74eeadSLisandro Dalcin #undef __FUNCT__ 20622e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 2063a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 20642e74eeadSLisandro Dalcin { 20652e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 20662e74eeadSLisandro Dalcin PetscErrorCode ierr; 20672e74eeadSLisandro Dalcin 20682e74eeadSLisandro Dalcin PetscFunctionBegin; 20692e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 2070e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 20712e74eeadSLisandro Dalcin 20722e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 20732e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 2074e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2075e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20762e74eeadSLisandro Dalcin PetscFunctionReturn(0); 20772e74eeadSLisandro Dalcin } 20782e74eeadSLisandro Dalcin 20792e74eeadSLisandro Dalcin #undef __FUNCT__ 20806726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 2081a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 20826726f965SBarry Smith { 20836726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 20846726f965SBarry Smith PetscErrorCode ierr; 20856726f965SBarry Smith 20866726f965SBarry Smith PetscFunctionBegin; 20874e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 20886726f965SBarry Smith PetscFunctionReturn(0); 20896726f965SBarry Smith } 20906726f965SBarry Smith 2091284134d9SBarry Smith #undef __FUNCT__ 2092f26d0771SStefano Zampini #define __FUNCT__ "MatAXPY_IS" 2093f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 2094f26d0771SStefano Zampini { 2095f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 2096f26d0771SStefano Zampini Mat_IS *x; 2097f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2098f26d0771SStefano Zampini PetscBool ismatis; 2099f26d0771SStefano Zampini #endif 2100f26d0771SStefano Zampini PetscErrorCode ierr; 2101f26d0771SStefano Zampini 2102f26d0771SStefano Zampini PetscFunctionBegin; 2103f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2104f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 2105f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 2106f26d0771SStefano Zampini #endif 2107f26d0771SStefano Zampini x = (Mat_IS*)X->data; 2108f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 2109f26d0771SStefano Zampini PetscFunctionReturn(0); 2110f26d0771SStefano Zampini } 2111f26d0771SStefano Zampini 2112f26d0771SStefano Zampini #undef __FUNCT__ 2113f26d0771SStefano Zampini #define __FUNCT__ "MatGetLocalSubMatrix_IS" 2114f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 2115f26d0771SStefano Zampini { 2116f26d0771SStefano Zampini Mat lA; 2117f26d0771SStefano Zampini Mat_IS *matis; 2118f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2119f26d0771SStefano Zampini IS is; 2120f26d0771SStefano Zampini const PetscInt *rg,*rl; 2121f26d0771SStefano Zampini PetscInt nrg; 2122f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 2123f26d0771SStefano Zampini PetscErrorCode ierr; 2124f26d0771SStefano Zampini 2125f26d0771SStefano Zampini PetscFunctionBegin; 2126f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2127f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 2128f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 2129f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 2130f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2131f0ae7da4SStefano 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); 2132f26d0771SStefano Zampini #endif 2133f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 2134f26d0771SStefano Zampini /* map from [0,nrl) to row */ 2135f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 2136f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2137f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 2138f26d0771SStefano Zampini #else 2139f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 2140f26d0771SStefano Zampini #endif 2141f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 2142f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 2143f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2144f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2145f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2146f26d0771SStefano Zampini /* compute new l2g map for columns */ 2147f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2148f26d0771SStefano Zampini const PetscInt *cg,*cl; 2149f26d0771SStefano Zampini PetscInt ncg; 2150f26d0771SStefano Zampini PetscInt ncl; 2151f26d0771SStefano Zampini 2152f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2153f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2154f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2155f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2156f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2157f0ae7da4SStefano 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); 2158f26d0771SStefano Zampini #endif 2159f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2160f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2161f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2162f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2163f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2164f26d0771SStefano Zampini #else 2165f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2166f26d0771SStefano Zampini #endif 2167f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2168f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2169f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2170f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2171f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2172f26d0771SStefano Zampini } else { 2173f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2174f26d0771SStefano Zampini cl2g = rl2g; 2175f26d0771SStefano Zampini } 2176f26d0771SStefano Zampini /* create the MATIS submatrix */ 2177f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2178f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2179f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2180f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2181b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2182f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2183f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2184f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2185f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2186f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2187f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2188f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2189f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2190f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2191f26d0771SStefano Zampini /* remove unsupported ops */ 2192f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2193f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2194f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2195f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2196f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2197f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2198f26d0771SStefano Zampini PetscFunctionReturn(0); 2199f26d0771SStefano Zampini } 2200f26d0771SStefano Zampini 2201f26d0771SStefano Zampini #undef __FUNCT__ 2202284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 2203284134d9SBarry Smith /*@ 22043c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2205284134d9SBarry Smith process but not across processes. 2206284134d9SBarry Smith 2207284134d9SBarry Smith Input Parameters: 2208284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2209e176bc59SStefano Zampini . bs - block size of the matrix 2210df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2211e176bc59SStefano Zampini . rmap - local to global map for rows 2212e176bc59SStefano Zampini - cmap - local to global map for cols 2213284134d9SBarry Smith 2214284134d9SBarry Smith Output Parameter: 2215284134d9SBarry Smith . A - the resulting matrix 2216284134d9SBarry Smith 22178e6c10adSSatish Balay Level: advanced 22188e6c10adSSatish Balay 22193c212e90SHong Zhang Notes: See MATIS for more details. 22206fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 22216fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 22223c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2223284134d9SBarry Smith 2224284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2225284134d9SBarry Smith @*/ 2226e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2227284134d9SBarry Smith { 2228284134d9SBarry Smith PetscErrorCode ierr; 2229284134d9SBarry Smith 2230284134d9SBarry Smith PetscFunctionBegin; 22316fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2232284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 22336fdf41d1SStefano Zampini if (bs > 0) { 2234d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 22356fdf41d1SStefano Zampini } 2236284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 2237284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2238e176bc59SStefano Zampini if (rmap && cmap) { 2239e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2240e176bc59SStefano Zampini } else if (!rmap) { 2241e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2242e176bc59SStefano Zampini } else { 2243e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2244e176bc59SStefano Zampini } 2245284134d9SBarry Smith PetscFunctionReturn(0); 2246284134d9SBarry Smith } 2247284134d9SBarry Smith 2248b4319ba4SBarry Smith /*MC 2249f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2250b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2251b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2252b4319ba4SBarry Smith product is handled "implicitly". 2253b4319ba4SBarry Smith 2254b4319ba4SBarry Smith Operations Provided: 22556726f965SBarry Smith + MatMult() 22562e74eeadSLisandro Dalcin . MatMultAdd() 22572e74eeadSLisandro Dalcin . MatMultTranspose() 22582e74eeadSLisandro Dalcin . MatMultTransposeAdd() 22596726f965SBarry Smith . MatZeroEntries() 22606726f965SBarry Smith . MatSetOption() 22612e74eeadSLisandro Dalcin . MatZeroRows() 22622e74eeadSLisandro Dalcin . MatSetValues() 226397563a80SStefano Zampini . MatSetValuesBlocked() 22646726f965SBarry Smith . MatSetValuesLocal() 226597563a80SStefano Zampini . MatSetValuesBlockedLocal() 22662e74eeadSLisandro Dalcin . MatScale() 22672e74eeadSLisandro Dalcin . MatGetDiagonal() 22682b404112SStefano Zampini . MatMissingDiagonal() 22692b404112SStefano Zampini . MatDuplicate() 22702b404112SStefano Zampini . MatCopy() 2271f26d0771SStefano Zampini . MatAXPY() 2272f26d0771SStefano Zampini . MatGetSubMatrix() 2273f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2274d7f69cd0SStefano Zampini . MatTranspose() 22756726f965SBarry Smith - MatSetLocalToGlobalMapping() 2276b4319ba4SBarry Smith 2277b4319ba4SBarry Smith Options Database Keys: 2278b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 2279b4319ba4SBarry Smith 2280b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 2281b4319ba4SBarry Smith 2282b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2283b4319ba4SBarry Smith 2284b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2285eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2286b4319ba4SBarry Smith 2287b4319ba4SBarry Smith Level: advanced 2288b4319ba4SBarry Smith 2289f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2290b4319ba4SBarry Smith 2291b4319ba4SBarry Smith M*/ 2292b4319ba4SBarry Smith 2293b4319ba4SBarry Smith #undef __FUNCT__ 2294b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 22958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2296b4319ba4SBarry Smith { 2297dfbe8321SBarry Smith PetscErrorCode ierr; 2298b4319ba4SBarry Smith Mat_IS *b; 2299b4319ba4SBarry Smith 2300b4319ba4SBarry Smith PetscFunctionBegin; 2301b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2302b4319ba4SBarry Smith A->data = (void*)b; 2303b4319ba4SBarry Smith 2304e176bc59SStefano Zampini /* matrix ops */ 2305e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2306b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 23072e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 23082e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 23092e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2310b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2311b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 23122e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 231398921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2314b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2315f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 23162e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2317f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2318b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2319b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2320b4319ba4SBarry Smith A->ops->view = MatView_IS; 23216726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 23222e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 23232e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 23246726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 232569796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 232669796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 232745471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2328ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 23296bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 23302b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2331659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 2332a8116848SStefano Zampini A->ops->getsubmatrix = MatGetSubMatrix_IS; 2333f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 23343fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 23353fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2336d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 23377fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 2338ad219c80Sstefano_zampini A->ops->diagonalscale = MatDiagonalScale_IS; 2339b4319ba4SBarry Smith 2340b7ce53b6SStefano Zampini /* special MATIS functions */ 2341bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 2342bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2343b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 23442e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2345cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 234617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2347b4319ba4SBarry Smith PetscFunctionReturn(0); 2348b4319ba4SBarry Smith } 2349